mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.1.5 AtomicWeight
This commit is contained in:
parent
f93645a5b4
commit
43235d51a2
@ -2,7 +2,7 @@
|
||||
// FILE: AtomicWeight.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-03-09
|
||||
// VERSION: 0.1.4
|
||||
// VERSION: 0.1.5
|
||||
// PURPOSE: Arduino library for atomic weights
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
|
||||
@ -177,43 +177,68 @@ uint8_t PTOE::protons(const uint8_t el)
|
||||
|
||||
float PTOE::weight(const uint8_t el)
|
||||
{
|
||||
if (el > _size) return 0; // catch out of range.
|
||||
return elements[el].weight * _weightFactor;
|
||||
}
|
||||
|
||||
|
||||
float PTOE::weight(const char * formula, const char * el)
|
||||
float PTOE::weight(const char * formula, const char * abbrev)
|
||||
{
|
||||
p = (char *)formula;
|
||||
return _weight('\0', el);
|
||||
return _weight('\0', abbrev);
|
||||
}
|
||||
|
||||
|
||||
float PTOE::massPercentage(const char * formula, const char * el)
|
||||
float PTOE::massPercentage(const char * formula, const char * abbrev)
|
||||
{
|
||||
float total = weight(formula);
|
||||
if (total == 0) return 0;
|
||||
p = (char *)formula;
|
||||
return 100.0 * _weight('\0', el) / total;
|
||||
return 100.0 * _weight('\0', abbrev) / total;
|
||||
}
|
||||
|
||||
|
||||
char * PTOE::name(const uint8_t el)
|
||||
{
|
||||
// catch out of range.
|
||||
if (el > _size) return NULL;
|
||||
return elements[el].name;
|
||||
}
|
||||
|
||||
|
||||
uint8_t PTOE::find(const char * abbrev)
|
||||
{
|
||||
// how about caching here?
|
||||
// case insensitive?
|
||||
// caching?
|
||||
// param check?
|
||||
// uint8_t len = strlen(abbrev);
|
||||
// if ((len == 1) || (len == 2))
|
||||
// {
|
||||
for (uint8_t i = 0; i < _size; i++)
|
||||
{
|
||||
if (strcmp(elements[i].name, abbrev) == 0) return i;
|
||||
}
|
||||
// }
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CONVERSION
|
||||
//
|
||||
float PTOE::moles2grams(const char * formula, float moles)
|
||||
{
|
||||
return moles * weight(formula);
|
||||
}
|
||||
|
||||
|
||||
float PTOE::grams2moles(const char * formula, float grams)
|
||||
{
|
||||
return grams / weight(formula);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DEBUG
|
||||
@ -275,14 +300,14 @@ uint8_t PTOE::splitElements(const char * formula)
|
||||
bool found = false;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (_elems[i] == z)
|
||||
if (_splitList[i] == z)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found == false)
|
||||
if ((found == false) && (count < ATOMIC_WEIGHT_MAX_SPLIT_LIST))
|
||||
{
|
||||
_elems[count] = z;
|
||||
_splitList[count] = z;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -292,9 +317,9 @@ uint8_t PTOE::splitElements(const char * formula)
|
||||
// {
|
||||
// Serial.print(i);
|
||||
// Serial.print('\t');
|
||||
// Serial.print(_elems[i]);
|
||||
// Serial.print(_splitList[i]);
|
||||
// Serial.print('\t');
|
||||
// Serial.println(name(_elems[i]));
|
||||
// Serial.println(name(_splitList[i]));
|
||||
// }
|
||||
|
||||
_found = count;
|
||||
@ -305,7 +330,7 @@ uint8_t PTOE::splitElements(const char * formula)
|
||||
uint8_t PTOE::element(uint8_t el)
|
||||
{
|
||||
if (el >= _found) return 255;
|
||||
return _elems[el];
|
||||
return _splitList[el];
|
||||
}
|
||||
|
||||
|
||||
@ -329,7 +354,7 @@ float PTOE::atomPercentage(const char * formula, const char * el)
|
||||
//
|
||||
// PRIVATE
|
||||
//
|
||||
float PTOE::_weight(const char sep, const char * el)
|
||||
float PTOE::_weight(const char sep, const char * abbrev)
|
||||
{
|
||||
float sum = 0;
|
||||
float w = 0;
|
||||
@ -343,7 +368,7 @@ float PTOE::_weight(const char sep, const char * el)
|
||||
if (*p == '(')
|
||||
{
|
||||
p++; // skip '('
|
||||
w = _weight(')', el);
|
||||
w = _weight(')', abbrev);
|
||||
p++; // skip ')'
|
||||
}
|
||||
else
|
||||
@ -359,7 +384,7 @@ float PTOE::_weight(const char sep, const char * el)
|
||||
p++;
|
||||
}
|
||||
// can be optimized?
|
||||
if ((el == NULL) || (strcmp(elem, el) == 0))
|
||||
if ((abbrev == NULL) || (strcmp(elem, abbrev) == 0))
|
||||
{
|
||||
int z = find(elem);
|
||||
if (z == 255) return 0; // fail
|
||||
@ -381,13 +406,13 @@ float PTOE::_weight(const char sep, const char * el)
|
||||
// Serial.println(w);
|
||||
// Serial.println(count);
|
||||
|
||||
sum += w * count;
|
||||
sum += (w * count);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
uint32_t PTOE::_count(const char sep, const char * el)
|
||||
uint32_t PTOE::_count(const char sep, const char * abbrev)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
char elem[3] = { 0, 0, 0 };
|
||||
@ -400,7 +425,7 @@ uint32_t PTOE::_count(const char sep, const char * el)
|
||||
if (*p == '(')
|
||||
{
|
||||
p++; // skip '('
|
||||
w = _count(')', el);
|
||||
w = _count(')', abbrev);
|
||||
p++; // skip ')'
|
||||
}
|
||||
else
|
||||
@ -417,7 +442,7 @@ uint32_t PTOE::_count(const char sep, const char * el)
|
||||
p++;
|
||||
}
|
||||
// can be optimized
|
||||
if ((el == NULL) || (strcmp(elem, el) == 0))
|
||||
if ((abbrev == NULL) || (strcmp(elem, abbrev) == 0))
|
||||
{
|
||||
int z = find(elem);
|
||||
if (z == 255) return 0; // fail
|
||||
|
@ -3,14 +3,19 @@
|
||||
// FILE: AtomicWeight.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-03-09
|
||||
// VERSION: 0.1.4
|
||||
// VERSION: 0.1.5
|
||||
// PURPOSE: Arduino library for atomic weights
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define ATOMIC_WEIGHT_LIB_VERSION (F("0.1.4"))
|
||||
#define ATOMIC_WEIGHT_LIB_VERSION (F("0.1.5"))
|
||||
|
||||
|
||||
#ifndef ATOMIC_WEIGHT_MAX_SPLIT_LIST
|
||||
#define ATOMIC_WEIGHT_MAX_SPLIT_LIST 20
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
@ -33,15 +38,20 @@ public:
|
||||
float weight(const uint8_t el);
|
||||
// if (el != NULL) weights one element in a formula, e.g el == "H"
|
||||
// if (el == NULL) weights the whole formula
|
||||
float weight(const char * formula, const char * el = NULL);
|
||||
float weight(const char * formula, const char * abbrev = NULL);
|
||||
// mass percentage of one element in a formula.
|
||||
float massPercentage(const char * formula, const char * el);
|
||||
float massPercentage(const char * formula, const char * abbrev);
|
||||
|
||||
|
||||
char * name(const uint8_t el);
|
||||
uint8_t find(const char * abbrev);
|
||||
|
||||
|
||||
// CONVERSION
|
||||
float moles2grams(const char * formula, float moles = 1.0);
|
||||
float grams2moles(const char * formula, float grams = 1.0);
|
||||
|
||||
|
||||
// DEBUG
|
||||
float weightFactor();
|
||||
|
||||
@ -67,12 +77,12 @@ private:
|
||||
const float _weightFactor = 1.0 / 222.909;
|
||||
|
||||
// if (el == NULL) ==> whole weight otherwise only of element.
|
||||
float _weight(char sep, const char * el);
|
||||
uint32_t _count(const char sep, const char * el);
|
||||
float _weight(char sep, const char * abbrev);
|
||||
uint32_t _count(const char sep, const char * abbrev);
|
||||
char *p; // for _weight() and _count()
|
||||
|
||||
// for splitElements
|
||||
uint8_t _elems[20]; // max 20 elements in formula.
|
||||
uint8_t _splitList[ATOMIC_WEIGHT_MAX_SPLIT_LIST]; // default 20
|
||||
uint8_t _found;
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.1.5] - 2023-04-13
|
||||
- add **moles2grams(formula, moles)**
|
||||
- add **grams2moles(formula, grams)**
|
||||
- add example.
|
||||
- add guarding with **size** parameter in **weight()**
|
||||
- improved usage **abbrev**(name) versus **el**(index).
|
||||
- improved readme.md.
|
||||
- add define for **ATOMIC_WEIGHT_MAX_SPLIT_LIST**
|
||||
- update keywords.txt.
|
||||
- minor edits.
|
||||
|
||||
|
||||
## [0.1.4] - 2023-04-12
|
||||
- add **splitElements()** split a formula in an internal list of elements.
|
||||
- add **element()** access to split elements. See example.
|
||||
@ -16,7 +28,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- update keywords.txt
|
||||
- minor edits.
|
||||
|
||||
|
||||
## [0.1.3] - 2023-01-01
|
||||
- refactor interface
|
||||
- add **weight(formula, element)**
|
||||
|
@ -8,44 +8,52 @@
|
||||
|
||||
# AtomicWeight
|
||||
|
||||
Arduino library for atomic weights.
|
||||
Arduino library for atomic weights, and related functions.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
This library is mainly to be used as a base for educational purposes.
|
||||
Learning the **periodic table of elements**, the abbreviations and weight.
|
||||
This library is mainly written to be used for educational purposes.
|
||||
Learning the **periodic table of elements**, the abbreviations and weights.
|
||||
It also provides the number of electrons, neutrons and protons per element.
|
||||
|
||||
Furthermore the library has a **weight()** function, which returns the weight
|
||||
of either an element or of a formula (e.g. a molecule).
|
||||
The weight function can also be used to get the weight of a particular element
|
||||
from a formula, e.g. the weight of the Oxygen atoms in the **H2SO4** molecule.
|
||||
|
||||
within a formula, e.g. the total weight of all Oxygen atoms in a **H2SO4** molecule.
|
||||
This latter function allows the library to calculate the **massPercentage()** too.
|
||||
|
||||
The library also has a **count()** function, to count the atoms in a formula.
|
||||
Derived is the **atomPercentage()** function to give the percentage of atoms
|
||||
that is a certain element.
|
||||
The library has a **count()** function, to count the atoms in a given formula.
|
||||
Derived is the **atomPercentage()** function which returns the percentage of atoms
|
||||
that is of a certain element. Oxygen in H2S04 is 4 in 7 which is about 57%.
|
||||
|
||||
Note: library is experimental. More testing is needed.
|
||||
Since 0.1.5 the library supports conversion from moles to grams and back.
|
||||
This allows one to easily get the amount of grams of some formula one has to weigh
|
||||
to get a needed amount of moles.
|
||||
With these functions, in combination with a load cell, one could create a "molar-scale".
|
||||
Another application for the conversion functions is create lookup-tables, see example.
|
||||
|
||||
Note: the library is experimental. More testing is needed. Feedback welcome.
|
||||
|
||||
|
||||
#### Internal
|
||||
|
||||
The PTOE class uses a table that has compressed weight to save RAM.
|
||||
The PTOE class uses a table that has "compressed" weight to save RAM.
|
||||
- it stores weights as **uint16_t**, 0..65535 instead of floats.
|
||||
- weight factor = 222.909 = 65535.0 / weight heaviest element(118)
|
||||
- error < 0.3%
|
||||
- the table (and thus the class) does not handle isotopes.
|
||||
- relative error per element is less than 0.15%
|
||||
- the table (and thus the class) does not handle isotopes of elements.
|
||||
|
||||
|
||||
#### Related
|
||||
|
||||
Useful list of formulae.
|
||||
|
||||
List of formulae to play with.
|
||||
- https://en.wikipedia.org/wiki/Glossary_of_chemical_formulae
|
||||
|
||||
Libraries useful to build the "molar-scale"
|
||||
- https://github.com/RobTillaart/HX711
|
||||
- https://github.com/RobTillaart/weight
|
||||
|
||||
|
||||
## Interface
|
||||
|
||||
@ -54,25 +62,27 @@ Useful list of formulae.
|
||||
```
|
||||
|
||||
The parameter **element** in the following functions is 0..118.
|
||||
(element 0 being a single neutron).
|
||||
(element 0 being 'n' == a single neutron).
|
||||
|
||||
- **PTOE()** Constructor (Periodic Table Of Elements)
|
||||
- **PTOE(uint8_t size = 118)** Constructor (Periodic Table Of Elements).
|
||||
Default it holds all 118 elements.
|
||||
The parameter size is used in the **find()** and guards some parameters.
|
||||
- **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 is less than 0.15%, as the internal table uses "compression" to save RAM.
|
||||
- **float weight(char \* formula, char \* abbreviation == NULL)** see below.
|
||||
- If (el != NULL) returns the total weight of one element in a formula.
|
||||
- if (el == NULL) returns the weight of the whole formula.
|
||||
- Returns 0 if it cannot parse the formula given.
|
||||
- if (abbreviation == NULL) returns the weight of the whole formula.
|
||||
- If (abbreviation != NULL) returns the total weight of one element in a formula.
|
||||
- Returns 0 if it cannot parse the given formula.
|
||||
- **float massPercentage(char \* formula, char \* abbreviation)**
|
||||
Returns mass percentage of a selected element in a formula.
|
||||
|
||||
|
||||
Returns mass percentage of a given element in a formula.
|
||||
- **uint8_t find(char \* abbreviation)** returns the element number.
|
||||
This function is relative expensive as it searches linear through the internal array of elements.
|
||||
Note: the find function is case sensitive.
|
||||
- **char \* name(uint8_t element)** returns the abbreviation of element.
|
||||
If the element is out of range **NULL** will be returned.
|
||||
|
||||
|
||||
#### SplitElements
|
||||
@ -80,60 +90,79 @@ This function is relative expensive as it searches linear through the internal a
|
||||
(0.1.4 experimental)
|
||||
- **uint8_t splitElements(const char \* formula)** split a formula in an internal list of elements.
|
||||
Returns the number of different elements found.
|
||||
Max nr of elements is hardcoded to 20.
|
||||
Maximum number of elements is hardcoded to 20, which is often enough.
|
||||
- **uint8_t element(uint8_t el)** access the internal list of elements by index el.
|
||||
Note: el should be between 0 and the max nr returned by **splitElements()**.
|
||||
Note: el should be between 0 and the maximum number returned by **splitElements()**.
|
||||
See example.
|
||||
|
||||
|
||||
#### AtomPercentage
|
||||
|
||||
(0.1.4 experimental)
|
||||
- **uint32_t count(const char \* formula, const char \* el = NULL)**
|
||||
- If (el != NULL) returns the total atoms of one element in a formula.
|
||||
- if (el == NULL) returns the total atoms of the whole formula.
|
||||
- **uint32_t count(const char \* formula, const char \* abbreviation = NULL)**
|
||||
- If (abbreviation != NULL) returns the total atoms of one element in a formula.
|
||||
- if (abbreviation == NULL) returns the total atoms of the whole formula.
|
||||
- Returns 0 if it cannot parse the formula given.
|
||||
- **float atomPercentage(const char \* formula, const char \* el)**
|
||||
- **float atomPercentage(const char \* formula, const char \* abbreviation)**
|
||||
Returns atom percentage of the selected element in a formula.
|
||||
|
||||
|
||||
#### Conversion grams moles
|
||||
|
||||
- **float moles2grams(const char \* formula, float moles = 1.0)**
|
||||
Returns the amount of grams needed for a given amount of moles.
|
||||
The default moles == 1, returns the basic conversion factor.
|
||||
- **float grams2moles(const char \* formula, float grams = 1.0)**
|
||||
Returns the amount of moles for a given amount of grams.
|
||||
The default moles == 1, returns the basic conversion factor.
|
||||
|
||||
These functions can be used, e.g. if one wants to solve 2 moles of KOH
|
||||
into 10 litres of water to get a defined pH, now much grams I need to weigh?
|
||||
|
||||
|
||||
#### Weight
|
||||
|
||||
The **weight(uint8_t element)** call returns the weight of a single atom (by index).
|
||||
The **weight(formula)** call is meant to calculate the weight of a molecule.
|
||||
The **weight(formula)** call is meant to calculate the weight of a molecule defined by the formula.
|
||||
A molecule is defined as one or more atoms.
|
||||
|
||||
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 one or two characters long.
|
||||
The first char must be upper case, the (optional) second must be lower case.
|
||||
If no number is provided the count of 1 is assumed.
|
||||
|
||||
The functions returns a float, so to get the integer weight, one should use **round()**.
|
||||
|
||||
If the formula can not be parsed it will return a weight of 0.
|
||||
If the formula can not be parsed, e.g. it contains non existing elements,
|
||||
the **weight()** function will return a weight of 0.
|
||||
|
||||
The **weight(formula, element)** function is meant to calculate the total weight of one element
|
||||
in a molecule. E.g one can weigh the H atoms in H2O (2 of 18).
|
||||
The **weight(formula, abbreviation)** function is meant to calculate the total weight
|
||||
of one element (by abbreviation) in a molecule.
|
||||
E.g one can weigh the H atoms in H2O (2 of 18).
|
||||
|
||||
|
||||
#### Formulas
|
||||
|
||||
The weight formula parsing supports round brackets () to indicate groups in the formula.
|
||||
All element abbreviations are one or two characters long.
|
||||
The first char must be upper case, the (optional) second must be lower case.
|
||||
(except for element 0, n == neutronium, which is added as placeholder).
|
||||
Elements can be followed by a number indicating an amount, no number implies 1.
|
||||
|
||||
Formulas do not care about the order of the atoms.
|
||||
So "C6H6" is equal to "H6C6" or even "CCCCCCHHHHHH" or "C3H3C3H3" etc.
|
||||
|
||||
The formula parsing supports round brackets () to indicate groups in the formula.
|
||||
The library does **not** support square brackets to indicate a group.
|
||||
|
||||
The library does **not** support \*6H20 to indicate hydration.
|
||||
|
||||
Valid formula's might look like:
|
||||
- "B" = single element
|
||||
- "Na" = single element
|
||||
- "C6" = single element, multiple times
|
||||
- "H2SO4" compound molecule, no groups
|
||||
- "C6(COOH)2" compound molecule, with a repeating group
|
||||
- "YBa2Cu3O7" some superconductor-ish material
|
||||
- "B" = single element, Hydrogen, 1 atom.
|
||||
- "Na" = single element, Sodium, 1 atom..
|
||||
- "C6" = single element, multiple times, Benzene.
|
||||
- "H2SO4" compound molecule, no groups (sulphuric acid).
|
||||
- "C6(COOH)2" repeating group, (artificial example).
|
||||
- "YBa2Cu3O7" compound molecule, == some superconductor-ish material.
|
||||
- "Ba((OH)4(COOH)2)c" recursive repeating groups (artificial example).
|
||||
|
||||
|
||||
#### MassPercentage
|
||||
|
||||
The **massPercentage(formula, element)** function can determine the percentage of the weight
|
||||
The **massPercentage(formula, abbreviation)** function can determine the percentage of the weight
|
||||
a selected element has in a formula, e.g. the weight of the Oxygen in **H2SO4**.
|
||||
This is calculated by dividing the weight of the element by the total weight.
|
||||
|
||||
@ -153,6 +182,9 @@ minimize the memory used for the elements mass lookup table.
|
||||
|
||||
- improve documentation
|
||||
- reorganize.
|
||||
- A better weight factor would be 201.3868 (see example)
|
||||
- relative error is less than 0.09% (which is 40% better than 0.15%)
|
||||
- for 0.2.0 release.
|
||||
|
||||
|
||||
#### Should
|
||||
@ -160,10 +192,10 @@ minimize the memory used for the elements mass lookup table.
|
||||
- add examples
|
||||
- extend formula parser with error codes.
|
||||
- which ones?
|
||||
- support \[] square brackets too.
|
||||
- (NH4)2\[Pt(SCN)6]
|
||||
- look for optimizations
|
||||
- 3x almost same parser
|
||||
- PROGMEM ?
|
||||
|
||||
|
||||
#### Could
|
||||
|
||||
@ -173,14 +205,22 @@ minimize the memory used for the elements mass lookup table.
|
||||
- room temperature + sea level pressure
|
||||
- (short) table of English names
|
||||
- which ones ?
|
||||
- case (in)sensitive **find()**
|
||||
- always or configurable
|
||||
- more expensive search
|
||||
- alphabetical array?
|
||||
- separate include file?
|
||||
- rename **name()** to **abbrev()** ?
|
||||
- add **longName()**?
|
||||
- performance **find()**
|
||||
- alphabetical array? tree?
|
||||
- ==> more memory
|
||||
- support \[] square brackets too.
|
||||
- (NH4)2\[Pt(SCN)6]
|
||||
- optimize weigh-factor
|
||||
- Arduino sketch
|
||||
|
||||
|
||||
#### Wont (unless)
|
||||
|
||||
- case insensitive **find()**
|
||||
element 0 is defined as n conflict with N
|
||||
- support hydrates ?
|
||||
- **Ba(BrO3)2·2H2O** new separator + starts with number.
|
||||
- other liquids than water?
|
||||
@ -192,8 +232,11 @@ minimize the memory used for the elements mass lookup table.
|
||||
- parameters element should be less than \_size
|
||||
- user responsibility
|
||||
- more information?
|
||||
- will not handle isotopes (too much memory needed)
|
||||
- database needed
|
||||
- Electron bands K L M etc?
|
||||
- Electron bands
|
||||
- K L M etc?
|
||||
- valence
|
||||
- temperatures,
|
||||
- melt
|
||||
- evaporate
|
||||
|
@ -0,0 +1,62 @@
|
||||
// FILE: atomic_grams_moles.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo conversion grams <> moles. Creates a lookup table.
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "AtomicWeight.h"
|
||||
|
||||
PTOE ptoe;
|
||||
|
||||
char formula[24] = "KOH";
|
||||
// char formula[24] = "NaCl";
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
|
||||
Serial.print("\n\t");
|
||||
Serial.print(formula);
|
||||
Serial.println(" moles to grams");
|
||||
float moles2grams = ptoe.moles2grams(formula); // default 1 mole.
|
||||
for (int i = 1; i <= 40; i++)
|
||||
{
|
||||
if (i % 20 == 1) Serial.println("\n\tMOLES\t\tGRAMS");
|
||||
float moles = i * 0.100;
|
||||
float grams = moles * moles2grams;
|
||||
Serial.print("\t");
|
||||
Serial.print(moles, 2);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(grams, 2);
|
||||
}
|
||||
|
||||
Serial.println("\n==========================================================\n");
|
||||
Serial.print("\n\t");
|
||||
Serial.print(formula);
|
||||
Serial.println(" grams to moles");
|
||||
float grams2moles = ptoe.grams2moles(formula); // default 1 gram.
|
||||
for (int i = 1; i <= 40; i++)
|
||||
{
|
||||
if (i % 20 == 1) Serial.println("\n\tGRAMS\t\tMOLES");
|
||||
float grams = i * 5;
|
||||
float moles = grams * grams2moles;
|
||||
Serial.print("\t");
|
||||
Serial.print(grams, 2);
|
||||
Serial.print("\t\t");
|
||||
Serial.println(moles, 4);
|
||||
}
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -9,6 +9,9 @@
|
||||
#include "Arduino.h"
|
||||
#include "elements_float.h"
|
||||
|
||||
// VERSION FACTOR
|
||||
// 0.1.x 222.909
|
||||
// 0.2.x 201.3868
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
//
|
||||
// FILE: elements_float.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2022-03-09
|
||||
// PURPOSE: list of weights (float)
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// float periodic table
|
||||
//
|
||||
struct element
|
||||
{
|
||||
char name[3];
|
||||
float weight;
|
||||
}
|
||||
elements[119] =
|
||||
{
|
||||
{"n", 1.00794}, // neutronium
|
||||
{"H" , 1.00794},
|
||||
{"He", 4.002602},
|
||||
{"Li", 9.80665},
|
||||
{"Be", 9.012182},
|
||||
{"B" , 10.811},
|
||||
{"C" , 12.0107},
|
||||
{"N" , 14.0067},
|
||||
{"O" , 15.9994},
|
||||
{"F" , 18.9984032},
|
||||
{"Ne", 20.1797},
|
||||
{"Na", 22.989770},
|
||||
{"Mg", 24.3050},
|
||||
{"Al", 26.981538},
|
||||
{"Si", 28.0855},
|
||||
{"P" , 30.973761},
|
||||
{"S" , 32.065},
|
||||
{"Cl", 35.453},
|
||||
{"Ar", 39.948},
|
||||
{"K" , 39.0983},
|
||||
{"Ca", 40.078},
|
||||
{"Sc", 44.955910},
|
||||
{"Ti", 47.867},
|
||||
{"V" , 50.9415},
|
||||
{"Cr", 51.9961},
|
||||
{"Mn", 54.938049},
|
||||
{"Fe", 55.845},
|
||||
{"Co", 58.933200},
|
||||
{"Ni", 58.6934},
|
||||
{"Cu", 63.546},
|
||||
{"Zn", 65.409},
|
||||
{"Ga", 69.723},
|
||||
{"Ge", 72.64},
|
||||
{"As", 74.92160},
|
||||
{"Se", 78.96},
|
||||
{"Br", 79.904},
|
||||
{"Kr", 83.798},
|
||||
{"Rb", 85.4678},
|
||||
{"Sr", 87.62},
|
||||
{"Y" , 88.90585},
|
||||
{"Zr", 91.224},
|
||||
{"Nb", 92.90638},
|
||||
{"Mo", 95.94},
|
||||
{"Tc", 98},
|
||||
{"Ru", 101.07},
|
||||
{"Rh", 102.90550},
|
||||
{"Pd", 106.42},
|
||||
{"Ag", 107.8682},
|
||||
{"Cd", 112.411},
|
||||
{"In", 114.818},
|
||||
{"Sn", 118.710},
|
||||
{"Sb", 121.760},
|
||||
{"Te", 127.60},
|
||||
{"I" , 126.90447},
|
||||
{"Xe", 131.293},
|
||||
{"Cs", 132.90545},
|
||||
{"Ba", 137.327},
|
||||
{"La", 138.9055},
|
||||
{"Ce", 140.116},
|
||||
{"Pr", 140.90765},
|
||||
{"Nd", 144.24},
|
||||
{"Pm", 145},
|
||||
{"Sm", 150.36},
|
||||
{"Eu", 151.964},
|
||||
{"Gd", 157.25},
|
||||
{"Tb", 158.92534},
|
||||
{"Dy", 162.500},
|
||||
{"Ho", 164.93032},
|
||||
{"Er", 167.259},
|
||||
{"Tm", 168.93421},
|
||||
{"Yb", 173.04},
|
||||
{"Lu", 174.967},
|
||||
{"Hf", 178.49},
|
||||
{"Ta", 180.9479},
|
||||
{"W" , 183.84},
|
||||
{"Re", 186.207},
|
||||
{"Os", 190.23},
|
||||
{"Ir", 192.217},
|
||||
{"Pt", 195.078},
|
||||
{"Au", 196.96655},
|
||||
{"Hg", 200.59},
|
||||
{"Tl", 204.3833},
|
||||
{"Pb", 207.2},
|
||||
{"Bi", 208.98038},
|
||||
{"Po", 209},
|
||||
{"At", 210},
|
||||
{"Rn", 222},
|
||||
{"Fr", 223},
|
||||
{"Ra", 226},
|
||||
{"Ac", 227},
|
||||
{"Th", 232.0381},
|
||||
{"Pa", 231.03588},
|
||||
{"U" , 238.02891},
|
||||
{"Np", 237},
|
||||
{"Pu", 244},
|
||||
{"Am", 243},
|
||||
{"Cm", 247},
|
||||
{"Bk", 247},
|
||||
{"Cf", 251},
|
||||
{"Es", 252},
|
||||
{"Fm", 257},
|
||||
{"Md", 258},
|
||||
{"No", 259},
|
||||
{"Lr", 262},
|
||||
{"Rf", 261},
|
||||
{"Db", 262},
|
||||
{"Sg", 266},
|
||||
{"Bh", 264},
|
||||
{"Hs", 277},
|
||||
{"Mt", 268},
|
||||
{"Ds", 281},
|
||||
{"Rg", 272},
|
||||
{"Cn", 285},
|
||||
{"Nh", 286},
|
||||
{"Fl", 289},
|
||||
{"Mc", 289},
|
||||
{"Lv", 293},
|
||||
{"Ts", 294},
|
||||
{"Og", 294}
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,66 @@
|
||||
// FILE: search_for_weight_factor.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// URL: https://github.com/RobTillaart/AtomicWeight
|
||||
// PURPOSE: find an optimal weight factor.
|
||||
//
|
||||
//
|
||||
// takes serious time
|
||||
//
|
||||
// best relative error found so far
|
||||
// FACTOR SUM REL MAXVAL
|
||||
// 201.3868 0.1383 8.865 8.865 59208 (that is 0.008%)
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "elements_float.h"
|
||||
|
||||
float best = 202;
|
||||
float error = 10000;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
Serial.println(__FILE__);
|
||||
|
||||
float minError = 100;
|
||||
for (float factor = 197.0; factor <= 223.0; factor += 0.001)
|
||||
{
|
||||
float sum = 0;
|
||||
float mx = 0;
|
||||
uint32_t val;
|
||||
for (int i = 0; i < 119; i++)
|
||||
{
|
||||
val = round(elements[i].weight * factor);
|
||||
float absError = abs( elements[i].weight - val / factor);
|
||||
float relError = absError / elements[i].weight;
|
||||
if (relError > mx) mx = relError;
|
||||
sum += absError;
|
||||
}
|
||||
if (mx < minError)
|
||||
{
|
||||
minError = mx;
|
||||
Serial.print(factor, 4);
|
||||
Serial.print("\t");
|
||||
Serial.print(sum, 4);
|
||||
Serial.print("\t");
|
||||
Serial.print(mx * 100, 3);
|
||||
Serial.print("\t");
|
||||
Serial.print(minError * 100, 3);
|
||||
Serial.print("\t");
|
||||
Serial.println(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Serial.println("\ndone");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -24,7 +24,12 @@ element KEYWORD2
|
||||
count KEYWORD2
|
||||
atomPercentage KEYWORD2
|
||||
|
||||
moles2grams KEYWORD2
|
||||
grams2moles KEYWORD2
|
||||
|
||||
|
||||
# Constants ( LITERAL1)
|
||||
ATOMIC_WEIGHT_LIB_VERSION LITERAL1
|
||||
|
||||
ATOMIC_WEIGHT_MAX_SPLIT_LIST LITERAL1
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/AtomicWeight.git"
|
||||
},
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=AtomicWeight
|
||||
version=0.1.4
|
||||
version=0.1.5
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for atomic weights, calculate massPercentage of elements in a formula.
|
||||
|
Loading…
Reference in New Issue
Block a user