mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.2 AtomicWeight
This commit is contained in:
parent
ce8751d505
commit
449f943312
286
libraries/AtomicWeight/AtomicWeight.cpp
Normal file
286
libraries/AtomicWeight/AtomicWeight.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
//
|
||||
// FILE: AtomicWeight.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-03-09
|
||||
// VERSION: 0.1.1
|
||||
// PURPOSE: Arduino library for atomic weights
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
|
||||
|
||||
#include "AtomicWeight.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// list of elements
|
||||
// weight = weight * 222.909
|
||||
//
|
||||
struct element
|
||||
{
|
||||
char name[3];
|
||||
uint16_t weight;
|
||||
}
|
||||
elements[119] =
|
||||
{
|
||||
{"n", 225}, // neutronium
|
||||
{"H", 225},
|
||||
{"He", 892},
|
||||
{"Li", 2186},
|
||||
{"Be", 2009},
|
||||
{"B", 2410},
|
||||
{"C", 2677},
|
||||
{"N", 3122},
|
||||
{"O", 3566},
|
||||
{"F", 4235},
|
||||
{"Ne", 4498},
|
||||
{"Na", 5125},
|
||||
{"Mg", 5418},
|
||||
{"Al", 6014},
|
||||
{"Si", 6261},
|
||||
{"P", 6904},
|
||||
{"S", 7148},
|
||||
{"Cl", 7903},
|
||||
{"Ar", 8905},
|
||||
{"K", 8715},
|
||||
{"Ca", 8934},
|
||||
{"Sc", 10021},
|
||||
{"Ti", 10670},
|
||||
{"V", 11355},
|
||||
{"Cr", 11590},
|
||||
{"Mn", 12246},
|
||||
{"Fe", 12448},
|
||||
{"Co", 13137},
|
||||
{"Ni", 13083},
|
||||
{"Cu", 14165},
|
||||
{"Zn", 14580},
|
||||
{"Ga", 15542},
|
||||
{"Ge", 16192},
|
||||
{"As", 16701},
|
||||
{"Se", 17601},
|
||||
{"Br", 17811},
|
||||
{"Kr", 18679},
|
||||
{"Rb", 19052},
|
||||
{"Sr", 19531},
|
||||
{"Y", 19818},
|
||||
{"Zr", 20335},
|
||||
{"Nb", 20710},
|
||||
{"Mo", 21386},
|
||||
{"Tc", 21845},
|
||||
{"Ru", 22529},
|
||||
{"Rh", 22939},
|
||||
{"Pd", 23722},
|
||||
{"Ag", 24045},
|
||||
{"Cd", 25057},
|
||||
{"In", 25594},
|
||||
{"Sn", 26462},
|
||||
{"Sb", 27141},
|
||||
{"Te", 28443},
|
||||
{"I", 28288},
|
||||
{"Xe", 29266},
|
||||
{"Cs", 29626},
|
||||
{"Ba", 30611},
|
||||
{"La", 30963},
|
||||
{"Ce", 31233},
|
||||
{"Pr", 31410},
|
||||
{"Nd", 32152},
|
||||
{"Pm", 32322},
|
||||
{"Sm", 33517},
|
||||
{"Eu", 33874},
|
||||
{"Gd", 35052},
|
||||
{"Tb", 35426},
|
||||
{"Dy", 36223},
|
||||
{"Ho", 36764},
|
||||
{"Er", 37284},
|
||||
{"Tm", 37657},
|
||||
{"Yb", 38572},
|
||||
{"Lu", 39002},
|
||||
{"Hf", 39787},
|
||||
{"Ta", 40335},
|
||||
{"W", 40980},
|
||||
{"Re", 41507},
|
||||
{"Os", 42404},
|
||||
{"Ir", 42847},
|
||||
{"Pt", 43485},
|
||||
{"Au", 43906},
|
||||
{"Hg", 44713},
|
||||
{"Tl", 45559},
|
||||
{"Pb", 46187},
|
||||
{"Bi", 46584},
|
||||
{"Po", 46588},
|
||||
{"At", 46811},
|
||||
{"Rn", 49486},
|
||||
{"Fr", 49709},
|
||||
{"Ra", 50377},
|
||||
{"Ac", 50600},
|
||||
{"Th", 51723},
|
||||
{"Pa", 51500},
|
||||
{"U", 53059},
|
||||
{"Np", 52829},
|
||||
{"Pu", 54390},
|
||||
{"Am", 54167},
|
||||
{"Cm", 55059},
|
||||
{"Bk", 55059},
|
||||
{"Cf", 55950},
|
||||
{"Es", 56173},
|
||||
{"Fm", 57288},
|
||||
{"Md", 57511},
|
||||
{"No", 57733},
|
||||
{"Lr", 58402},
|
||||
{"Rf", 58179},
|
||||
{"Db", 58402},
|
||||
{"Sg", 59294},
|
||||
{"Bh", 58848},
|
||||
{"Hs", 61746},
|
||||
{"Mt", 59740},
|
||||
{"Ds", 62637},
|
||||
{"Rg", 60631},
|
||||
{"Cn", 63529},
|
||||
{"Nh", 63752},
|
||||
{"Fl", 64421},
|
||||
{"Mc", 64421},
|
||||
{"Lv", 65312},
|
||||
{"Ts", 65535},
|
||||
{"Og", 65535},
|
||||
};
|
||||
|
||||
|
||||
PTOE::PTOE(uint8_t size)
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::size()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::electrons(uint8_t el)
|
||||
{
|
||||
return el;
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::neutrons(uint8_t el)
|
||||
{
|
||||
return round(weight(el) - el);
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::protons(uint8_t el)
|
||||
{
|
||||
return el;
|
||||
}
|
||||
|
||||
|
||||
float PTOE::weight(uint8_t el)
|
||||
{
|
||||
return elements[el].weight * _weightFactor;
|
||||
}
|
||||
|
||||
|
||||
float PTOE::weight(const char * formula)
|
||||
{
|
||||
return weight((char*) formula);
|
||||
}
|
||||
|
||||
|
||||
float PTOE::weight(char * formula)
|
||||
{
|
||||
p = formula;
|
||||
return _weight('\0');
|
||||
}
|
||||
|
||||
|
||||
float PTOE::_weight(char sep)
|
||||
{
|
||||
float sum = 0;
|
||||
float w = 0;
|
||||
char elem[3] = { 0, 0, 0 };
|
||||
int count = 0;
|
||||
|
||||
// char *p = formula;
|
||||
while (*p != sep)
|
||||
{
|
||||
w = 0;
|
||||
// HANDLE GROUP (...)
|
||||
if (*p == '(')
|
||||
{
|
||||
p++; // skip '('
|
||||
w = _weight(')');
|
||||
// Serial.println(w);
|
||||
p++; // skip ')'
|
||||
}
|
||||
else
|
||||
{
|
||||
// GET ELEMENT := [ Upper | Upper,lower ]
|
||||
elem[1] = 0;
|
||||
if (! isupper(*p)) return 0; // fail
|
||||
elem[0] = *p;
|
||||
p++;
|
||||
if (islower(*p))
|
||||
{
|
||||
elem[1] = *p;
|
||||
p++;
|
||||
}
|
||||
int z = find(elem);
|
||||
if (z == 255) return 0; // fail
|
||||
w = weight(z);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
// get optional digits
|
||||
while (isdigit(*p))
|
||||
{
|
||||
count = count * 10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
// correct for no digits
|
||||
if (count == 0) count = 1;
|
||||
|
||||
// DEBUG
|
||||
// Serial.println(w);
|
||||
// Serial.println(count);
|
||||
|
||||
sum += w * count;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
char * PTOE::name(uint8_t el)
|
||||
{
|
||||
return elements[el].name;
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::find(const char * abbrev)
|
||||
{
|
||||
return find((char *) abbrev);
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::find(char * abbrev)
|
||||
{
|
||||
for (uint8_t i = 0; i < _size; i++)
|
||||
{
|
||||
if (strcmp(elements[i].name, abbrev) == 0) return i;
|
||||
}
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DEBUG
|
||||
//
|
||||
float PTOE::weightFactor()
|
||||
{
|
||||
return _weightFactor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -3,20 +3,19 @@
|
||||
// FILE: AtomicWeight.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-03-09
|
||||
// VERSION: 0.1.1
|
||||
// VERSION: 0.1.2
|
||||
// PURPOSE: Arduino library for atomic weights
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define ATOMIC_WEIGHT_LIB_VERSION (F("0.1.1"))
|
||||
#define ATOMIC_WEIGHT_LIB_VERSION (F("0.1.2"))
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IS THIS THE RIGHT FORMAT?
|
||||
// or should we build a list of elements
|
||||
// PERIODIC TABLE OF ELEMENTS Class
|
||||
//
|
||||
class PTOE
|
||||
{
|
||||
@ -36,6 +35,7 @@ public:
|
||||
|
||||
|
||||
char * name(uint8_t el);
|
||||
uint8_t find(const char * abbrev);
|
||||
uint8_t find(char * abbrev);
|
||||
|
||||
|
||||
@ -46,6 +46,9 @@ public:
|
||||
private:
|
||||
uint8_t _size;
|
||||
const float _weightFactor = 1.0 / 222.909;
|
||||
|
||||
float _weight(char sep);
|
||||
char *p; // for _weight().
|
||||
};
|
||||
|
||||
|
||||
|
@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.1.2] - 2023-01-01
|
||||
- add weight(formula) group () support
|
||||
- rewrote example
|
||||
- update readme.md.
|
||||
- add unit tests
|
||||
|
||||
|
||||
## [0.1.1] - 2022-12-30
|
||||
- fix offset in some functions
|
||||
- move code to .cpp file
|
||||
@ -13,7 +20,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- refactor and clean up a bit.
|
||||
- update readme.md.
|
||||
|
||||
|
||||
## [0.1.0] - 2022-12-30
|
||||
- initial release
|
||||
- renamed class from AtomicWeight to PTOE.
|
||||
|
@ -14,7 +14,7 @@ Arduino library for atomic weights.
|
||||
## Description
|
||||
|
||||
This library is mainly as a base for educational purposes.
|
||||
Learning the periodic table of elements, the abbreviations and weight.
|
||||
Learning the **periodic table of elements**, the abbreviations and weight.
|
||||
It also provides the number of electrons, neutrons and protons per element.
|
||||
|
||||
Furthermore the library has a **weight()** function, that returns the weight
|
||||
@ -38,12 +38,15 @@ The PTOE class uses a table that has compressed weight to save RAM
|
||||
#include "AtomicWeight.h"
|
||||
```
|
||||
|
||||
The parameter **element** in the following functions is 0..118.
|
||||
(element 0 being a single neutron).
|
||||
|
||||
- **PTOE()** Constructor (Periodic Table Of Elements)
|
||||
- **uint8_t electrons(uint8_t element)** returns the number of electrons of the element.
|
||||
- **uint8_t neutrons(uint8_t element)** returns the number of neutrons of the element.
|
||||
- **uint8_t protons(uint8_t element)** returns the number of protons of the element.
|
||||
- **float weight(uint8_t element)** returns the weight of the element.
|
||||
The error < 0.3%, table uses "weight compression"/
|
||||
The error < 0.3%, table uses "weight compression".
|
||||
- **float weight(char \* formula)** returns the weight of a molecule e.g. "H2O".
|
||||
Returns 0 if it cannot parse the formula given.
|
||||
Cannot parse complex formulas with brackets () in it.
|
||||
@ -51,23 +54,36 @@ Cannot parse complex formulas with brackets () in it.
|
||||
- **char \* name(uint8_t element)** returns the abbreviation of element.
|
||||
|
||||
|
||||
#### debug
|
||||
|
||||
- **float weightFactor()** returns weightFactor.
|
||||
|
||||
|
||||
## weight
|
||||
#### weight
|
||||
|
||||
The **weight(int n)** function returns the weight of a single atom.
|
||||
The **weight(formula)** function is meant to calculate the weight of a molecule.
|
||||
It does not care about the order of the atoms.
|
||||
So "C6H6" is equal to "H6C6" or even "CCCCCCHHHHHH" or "C3H3C3H3".
|
||||
|
||||
The latter function does not care about the order of the atoms.
|
||||
So "C6H6" is equal to "H6C6" or even "CCCCCCHHHHHH" or "C3H3C3H3" etc.
|
||||
Elements are defined as 1 or two characters long.
|
||||
The first must be uppercase, the second must be lowercase.
|
||||
If no number is provided the count of 1 is assumed.
|
||||
|
||||
The function returns a float, so to get the integer weight, one should use **round()**.
|
||||
The functions returns a float, so to get the integer weight, one should use **round()**.
|
||||
|
||||
The weight parsing does not support brackets () in the formula so "H2(SO4)2" fails.
|
||||
If the formula is not parseable it will return a weight of 0.
|
||||
|
||||
(Since 0.1.2)
|
||||
The weight formula parsing experimentally supports brackets () to indicate groups in the formula.
|
||||
|
||||
Valid formula's might look as:
|
||||
- "B" = single element
|
||||
- "Na" = single element
|
||||
- "C6" = single element, multiple times
|
||||
- "H2SO4" compound molecule, no groups
|
||||
- "C6(COOH)2" compound molecule, with repeating groups
|
||||
- "YBa2Cu3O7" some superconductor-ish material
|
||||
|
||||
|
||||
#### debug
|
||||
|
||||
- **float weightFactor()** returns weightFactor.
|
||||
|
||||
|
||||
## Operation
|
||||
@ -80,26 +96,25 @@ See examples
|
||||
#### must
|
||||
|
||||
- improve documentation
|
||||
- add examples
|
||||
|
||||
#### should
|
||||
|
||||
- extend unit tests
|
||||
- extend formula parser with () support.
|
||||
- extend formula parser with error codes?
|
||||
|
||||
- add examples
|
||||
- extend formula parser with error codes.
|
||||
|
||||
#### could
|
||||
|
||||
- extend unit tests
|
||||
- state table
|
||||
- liquid, gas, solid, unknown (2 bits per element) = ~30 bytes
|
||||
- (short) table of English names
|
||||
- which ones ?
|
||||
- function **float massPercentage("H2O", "H")** ~10%
|
||||
- function **float atomicPercentage("H2O", "H")** ~33%
|
||||
- performance **find()** ?
|
||||
- performance functions
|
||||
- especially **find()** ?
|
||||
- case (in)sensitive **find()**
|
||||
|
||||
- is there a faster data structure.
|
||||
|
||||
#### wont (unless)
|
||||
|
||||
|
@ -9,9 +9,13 @@
|
||||
|
||||
PTOE ptoe;
|
||||
|
||||
char formula1[24] = "C6H6O6";
|
||||
char formula0[24] = "C6H6O6";
|
||||
char formula1[24] = "((COH)3)2";
|
||||
char formula2[24] = "H2SO4";
|
||||
char formula3[24] = "HHSOOOO";
|
||||
char formula3[24] = "CuO2";
|
||||
// char formula4[24] = "(COH)3(COH)2COH";
|
||||
// char formula4[24] = "(CH)6O6";
|
||||
char formula4[24] = "xH2"; // fails => 0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
@ -33,9 +37,13 @@ void setup()
|
||||
Serial.print(" \t");
|
||||
Serial.println(ptoe.weight("He6"));
|
||||
|
||||
Serial.print("O6");
|
||||
Serial.print("NaCl");
|
||||
Serial.print(" \t");
|
||||
Serial.println(ptoe.weight("O6"));
|
||||
Serial.println(ptoe.weight("NaCl"));
|
||||
|
||||
Serial.print(formula0);
|
||||
Serial.print(" \t");
|
||||
Serial.println(ptoe.weight(formula0));
|
||||
|
||||
Serial.print(formula1);
|
||||
Serial.print(" \t");
|
||||
@ -48,6 +56,10 @@ void setup()
|
||||
Serial.print(formula3);
|
||||
Serial.print(" \t");
|
||||
Serial.println(ptoe.weight(formula3));
|
||||
|
||||
Serial.print(formula4);
|
||||
Serial.print(" \t");
|
||||
Serial.println(ptoe.weight(formula4));
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
@ -0,0 +1,12 @@
|
||||
UNO, 1.8.19
|
||||
|
||||
atomic_weight_formula.ino
|
||||
|
||||
ATOMIC_WEIGHT_LIB_VERSION: 0.1.1
|
||||
C 12.01
|
||||
C6 72.06
|
||||
He6 24.01
|
||||
O6 95.99
|
||||
C6H6O6 174.10
|
||||
H2SO4 98.08
|
||||
HHSOOOO 98.08
|
@ -8,9 +8,9 @@ PTOE KEYWORD1
|
||||
# Methods and Functions (KEYWORD2)
|
||||
size KEYWORD2
|
||||
|
||||
electrons KEYWORD2
|
||||
protons KEYWORD2
|
||||
neutrons KEYWORD2
|
||||
electrons KEYWORD2
|
||||
weight KEYWORD2
|
||||
|
||||
name KEYWORD2
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/AtomicWeight.git"
|
||||
},
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=AtomicWeight
|
||||
version=0.1.1
|
||||
version=0.1.2
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for AtomicWeight
|
||||
|
@ -63,8 +63,64 @@ unittest(test_constructor)
|
||||
unittest(test_find)
|
||||
{
|
||||
PTOE ptoe;
|
||||
|
||||
assertEqual( 0, ptoe.find("n"));
|
||||
assertEqual( 1, ptoe.find("H"));
|
||||
assertEqual( 6, ptoe.find("C"));
|
||||
assertEqual(10, ptoe.find("Ne"));
|
||||
assertEqual(18, ptoe.find("Ar"));
|
||||
assertEqual(26, ptoe.find("Fe"));
|
||||
assertEqual(36, ptoe.find("Kr"));
|
||||
assertEqual(47, ptoe.find("Ag"));
|
||||
assertEqual(54, ptoe.find("Xe"));
|
||||
assertEqual(79, ptoe.find("Au"));
|
||||
assertEqual(92, ptoe.find("U"));
|
||||
|
||||
assertEqual(1, ptoe.find("H"));
|
||||
assertEqual(255, ptoe.find("XX")); // Fail test
|
||||
}
|
||||
|
||||
|
||||
unittest(test_basic_atom)
|
||||
{
|
||||
PTOE ptoe;
|
||||
|
||||
int el = 0;
|
||||
|
||||
// NEUTRONIUM
|
||||
assertEqual("n", ptoe.name(el));
|
||||
assertEqual( 0, ptoe.electrons(el));
|
||||
assertEqual( 1, ptoe.neutrons(el));
|
||||
assertEqual( 0, ptoe.protons(el));
|
||||
assertEqual( 1, round(ptoe.weight(el)));
|
||||
|
||||
// HYDROGEN
|
||||
el = 1;
|
||||
assertEqual("H", ptoe.name(el));
|
||||
assertEqual( 1, ptoe.electrons(el));
|
||||
assertEqual( 0, ptoe.neutrons(el));
|
||||
assertEqual( 1, ptoe.protons(el));
|
||||
assertEqual( 1, round(ptoe.weight(el)));
|
||||
|
||||
// URANIUM
|
||||
el = 92;
|
||||
assertEqual("U", ptoe.name(el));
|
||||
assertEqual( 92, ptoe.electrons(el));
|
||||
assertEqual(146, ptoe.neutrons(el));
|
||||
assertEqual( 92, ptoe.protons(el));
|
||||
assertEqual(238, round(ptoe.weight(el)));
|
||||
}
|
||||
|
||||
|
||||
unittest(test_weight_formula)
|
||||
{
|
||||
PTOE ptoe;
|
||||
assertEqualFloat( 22.9914, ptoe.weight("Na"), 0.1);
|
||||
assertEqualFloat( 58.4454, ptoe.weight("NaCl"), 0.1);
|
||||
assertEqualFloat( 100.081, ptoe.weight("CaCO3"), 0.1);
|
||||
assertEqualFloat( 98.0759, ptoe.weight("H2SO4"), 0.1);
|
||||
assertEqualFloat( 116.065, ptoe.weight("C2H2(COOH)2"), 0.1);
|
||||
assertEqualFloat( 666.178, ptoe.weight("YBa2Cu3O7"), 0.1);
|
||||
assertEqualFloat( 72.1146, ptoe.weight("C(O(H2)2)3"), 0.1);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user