From 43235d51a21db0ae4db619279dadf9b8fad0fbf3 Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Fri, 14 Apr 2023 13:34:00 +0200 Subject: [PATCH] 0.1.5 AtomicWeight --- libraries/AtomicWeight/AtomicWeight.cpp | 63 ++++--- libraries/AtomicWeight/AtomicWeight.h | 24 ++- libraries/AtomicWeight/CHANGELOG.md | 15 +- libraries/AtomicWeight/README.md | 157 +++++++++++------- .../atomic_grams_moles/atomic_grams_moles.ino | 62 +++++++ .../generate_uint16_table.ino | 3 + .../search_for_weight_factor/elements_float.h | 143 ++++++++++++++++ .../search_for_weight_factor.ino | 66 ++++++++ libraries/AtomicWeight/keywords.txt | 5 + libraries/AtomicWeight/library.json | 2 +- libraries/AtomicWeight/library.properties | 2 +- 11 files changed, 455 insertions(+), 87 deletions(-) create mode 100644 libraries/AtomicWeight/examples/atomic_grams_moles/atomic_grams_moles.ino create mode 100644 libraries/AtomicWeight/examples/search_for_weight_factor/elements_float.h create mode 100644 libraries/AtomicWeight/examples/search_for_weight_factor/search_for_weight_factor.ino diff --git a/libraries/AtomicWeight/AtomicWeight.cpp b/libraries/AtomicWeight/AtomicWeight.cpp index ac738cfe..11ac1ed1 100644 --- a/libraries/AtomicWeight/AtomicWeight.cpp +++ b/libraries/AtomicWeight/AtomicWeight.cpp @@ -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 diff --git a/libraries/AtomicWeight/AtomicWeight.h b/libraries/AtomicWeight/AtomicWeight.h index f99ab5ec..a2bedb73 100644 --- a/libraries/AtomicWeight/AtomicWeight.h +++ b/libraries/AtomicWeight/AtomicWeight.h @@ -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; }; diff --git a/libraries/AtomicWeight/CHANGELOG.md b/libraries/AtomicWeight/CHANGELOG.md index fcc74968..8e96e091 100644 --- a/libraries/AtomicWeight/CHANGELOG.md +++ b/libraries/AtomicWeight/CHANGELOG.md @@ -6,17 +6,28 @@ 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. - add **count()** to count atoms in a formula. - add **atomPercentage()** to calculate percentage of atoms of an element. - add examples. -- update readme.md +- update readme.md - update keywords.txt - minor edits. - ## [0.1.3] - 2023-01-01 - refactor interface - add **weight(formula, element)** diff --git a/libraries/AtomicWeight/README.md b/libraries/AtomicWeight/README.md index 1117a47d..e647ea75 100644 --- a/libraries/AtomicWeight/README.md +++ b/libraries/AtomicWeight/README.md @@ -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 + - 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 diff --git a/libraries/AtomicWeight/examples/atomic_grams_moles/atomic_grams_moles.ino b/libraries/AtomicWeight/examples/atomic_grams_moles/atomic_grams_moles.ino new file mode 100644 index 00000000..1d25361c --- /dev/null +++ b/libraries/AtomicWeight/examples/atomic_grams_moles/atomic_grams_moles.ino @@ -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 -- diff --git a/libraries/AtomicWeight/examples/generate_uint16_table/generate_uint16_table.ino b/libraries/AtomicWeight/examples/generate_uint16_table/generate_uint16_table.ino index 8e05ef5d..31abb797 100644 --- a/libraries/AtomicWeight/examples/generate_uint16_table/generate_uint16_table.ino +++ b/libraries/AtomicWeight/examples/generate_uint16_table/generate_uint16_table.ino @@ -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() { diff --git a/libraries/AtomicWeight/examples/search_for_weight_factor/elements_float.h b/libraries/AtomicWeight/examples/search_for_weight_factor/elements_float.h new file mode 100644 index 00000000..122fd4b5 --- /dev/null +++ b/libraries/AtomicWeight/examples/search_for_weight_factor/elements_float.h @@ -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 -- diff --git a/libraries/AtomicWeight/examples/search_for_weight_factor/search_for_weight_factor.ino b/libraries/AtomicWeight/examples/search_for_weight_factor/search_for_weight_factor.ino new file mode 100644 index 00000000..05f1088e --- /dev/null +++ b/libraries/AtomicWeight/examples/search_for_weight_factor/search_for_weight_factor.ino @@ -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 -- diff --git a/libraries/AtomicWeight/keywords.txt b/libraries/AtomicWeight/keywords.txt index 3f1f3af2..1357b1b0 100644 --- a/libraries/AtomicWeight/keywords.txt +++ b/libraries/AtomicWeight/keywords.txt @@ -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 + diff --git a/libraries/AtomicWeight/library.json b/libraries/AtomicWeight/library.json index cc71bc8c..f0f7f040 100644 --- a/libraries/AtomicWeight/library.json +++ b/libraries/AtomicWeight/library.json @@ -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": "*", diff --git a/libraries/AtomicWeight/library.properties b/libraries/AtomicWeight/library.properties index 4434222c..19e33084 100644 --- a/libraries/AtomicWeight/library.properties +++ b/libraries/AtomicWeight/library.properties @@ -1,5 +1,5 @@ name=AtomicWeight -version=0.1.4 +version=0.1.5 author=Rob Tillaart maintainer=Rob Tillaart sentence=Arduino library for atomic weights, calculate massPercentage of elements in a formula.