0.2.1 AtomicWeight

This commit is contained in:
Rob Tillaart 2023-10-17 19:50:25 +02:00
parent f0f6fe32a1
commit d72c128f92
6 changed files with 229 additions and 211 deletions

View File

@ -2,7 +2,7 @@
// FILE: AtomicWeight.cpp // FILE: AtomicWeight.cpp
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// DATE: 2022-03-09 // DATE: 2022-03-09
// VERSION: 0.2.0 // VERSION: 0.2.1
// PURPOSE: Arduino library for atomic weights // PURPOSE: Arduino library for atomic weights
// URL: https://github.com/RobTillaart/AtomicWeight // URL: https://github.com/RobTillaart/AtomicWeight
@ -13,8 +13,8 @@
PTOE::PTOE(const uint8_t size) PTOE::PTOE(const uint8_t size)
{ {
_size = size; _size = size;
_found = 0; _found = 0;
} }
@ -24,50 +24,50 @@ _found = 0;
// //
uint8_t PTOE::size() uint8_t PTOE::size()
{ {
return _size; return _size;
} }
char * PTOE::name(const uint8_t el) char * PTOE::name(const uint8_t el)
{ {
// catch out of range. // catch out of range.
if (el > _size) return NULL; if (el > _size) return NULL;
return elements[el].name; return elements[el].name;
} }
uint8_t PTOE::find(const char * abbrev) uint8_t PTOE::find(const char * abbrev)
{ {
// case insensitive? // case insensitive?
// caching? // caching?
// param check? // param check?
// uint8_t len = strlen(abbrev); // uint8_t len = strlen(abbrev);
// if ((len == 1) || (len == 2)) // if ((len == 1) || (len == 2))
// { // {
for (uint8_t i = 0; i < _size; i++) for (uint8_t i = 0; i < _size; i++)
{ {
if (strcmp(elements[i].name, abbrev) == 0) return i; if (strcmp(elements[i].name, abbrev) == 0) return i;
} }
// } // }
return 255; return 255;
} }
uint8_t PTOE::electrons(const uint8_t el) uint8_t PTOE::electrons(const uint8_t el)
{ {
return el; return el;
} }
uint8_t PTOE::neutrons(const uint8_t el) uint8_t PTOE::neutrons(const uint8_t el)
{ {
return round(weight(el)) - el; return round(weight(el)) - el;
} }
uint8_t PTOE::protons(const uint8_t el) uint8_t PTOE::protons(const uint8_t el)
{ {
return el; return el;
} }
@ -77,24 +77,24 @@ return el;
// //
float PTOE::weight(const uint8_t el) float PTOE::weight(const uint8_t el)
{ {
if (el > _size) return 0; // catch out of range. if (el > _size) return 0; // catch out of range.
return elements[el].weight * ATOMIC_WEIGHT_FACTOR; return elements[el].weight * ATOMIC_WEIGHT_FACTOR;
} }
float PTOE::weight(const char * formula, const char * abbrev) float PTOE::weight(const char * formula, const char * abbrev)
{ {
p = (char *)formula; p = (char *)formula;
return _weight('\0', abbrev); return _weight('\0', abbrev);
} }
float PTOE::massPercentage(const char * formula, const char * abbrev) float PTOE::massPercentage(const char * formula, const char * abbrev)
{ {
float total = weight(formula); float total = weight(formula);
if (total == 0) return 0; if (total == 0) return 0;
p = (char *)formula; p = (char *)formula;
return 100.0 * _weight('\0', abbrev) / total; return 100.0 * _weight('\0', abbrev) / total;
} }
@ -105,13 +105,13 @@ return 100.0 * _weight('\0', abbrev) / total;
// //
float PTOE::moles2grams(const char * formula, float moles) float PTOE::moles2grams(const char * formula, float moles)
{ {
return moles * weight(formula); return moles * weight(formula);
} }
float PTOE::grams2moles(const char * formula, float grams) float PTOE::grams2moles(const char * formula, float grams)
{ {
return grams / weight(formula); return grams / weight(formula);
} }
@ -121,82 +121,82 @@ return grams / weight(formula);
// //
uint8_t PTOE::splitElements(const char * formula) uint8_t PTOE::splitElements(const char * formula)
{ {
uint8_t count = 0; uint8_t count = 0;
char elem[3] = { 0, 0, 0 }; char elem[3] = { 0, 0, 0 };
char * p = (char *) formula; char * p = (char *) formula;
while (*p != '\0') while (*p != '\0')
{ {
// SKIP non element info // SKIP non element info
if (*p == '(') if (*p == '(')
{ {
p++; // skip '(' p++; // skip '('
continue; continue;
} }
if (*p == ')') if (*p == ')')
{ {
p++; // skip ')' p++; // skip ')'
continue; continue;
} }
if (isdigit(*p)) if (isdigit(*p))
{ {
p++; // skip digit p++; // skip digit
continue; continue;
} }
// GET ELEMENT := [ Upper | Upper,lower ] // GET ELEMENT := [ Upper | Upper,lower ]
elem[0] = 0; elem[0] = 0;
elem[1] = 0; elem[1] = 0;
if (! isupper(*p)) return 0; // fail if (! isupper(*p)) return 0; // fail
elem[0] = *p; elem[0] = *p;
p++; p++;
if (islower(*p)) if (islower(*p))
{ {
elem[1] = *p; elem[1] = *p;
p++; p++;
} }
// FIND INDEX OF ELEMENT // FIND INDEX OF ELEMENT
int z = find(elem); int z = find(elem);
if (z == 255) if (z == 255)
{ {
return 0; // fail return 0; // fail
} }
// DO WE HAVE IDENTIFIED IT ALREADY? // DO WE HAVE IDENTIFIED IT ALREADY?
bool found = false; bool found = false;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
if (_splitList[i] == z) if (_splitList[i] == z)
{ {
found = true; found = true;
} }
} }
if ((found == false) && (count < ATOMIC_WEIGHT_MAX_SPLIT_LIST)) if ((found == false) && (count < ATOMIC_WEIGHT_MAX_SPLIT_LIST))
{ {
_splitList[count] = z; _splitList[count] = z;
count++; count++;
} }
} }
// // DEBUG // // DEBUG
// for (int i = 0; i < count; i++) // for (int i = 0; i < count; i++)
// { // {
// Serial.print(i); // Serial.print(i);
// Serial.print('\t'); // Serial.print('\t');
// Serial.print(_splitList[i]); // Serial.print(_splitList[i]);
// Serial.print('\t'); // Serial.print('\t');
// Serial.println(name(_splitList[i])); // Serial.println(name(_splitList[i]));
// } // }
_found = count; _found = count;
return count; return count;
} }
uint8_t PTOE::element(uint8_t el) uint8_t PTOE::element(uint8_t el)
{ {
if (el >= _found) return 255; if (el >= _found) return 255;
return _splitList[el]; return _splitList[el];
} }
@ -206,17 +206,17 @@ return _splitList[el];
// //
uint32_t PTOE::count(const char * formula, const char * el) uint32_t PTOE::count(const char * formula, const char * el)
{ {
p = (char *)formula; p = (char *)formula;
return _count('\0', el); return _count('\0', el);
} }
float PTOE::atomPercentage(const char * formula, const char * el) float PTOE::atomPercentage(const char * formula, const char * el)
{ {
float total = count(formula); float total = count(formula);
if (total == 0) return 0; if (total == 0) return 0;
p = (char *)formula; p = (char *)formula;
return 100.0 * _count('\0', el) / total; return 100.0 * _count('\0', el) / total;
} }
@ -226,7 +226,7 @@ return 100.0 * _count('\0', el) / total;
// //
float PTOE::weightFactor() float PTOE::weightFactor()
{ {
return ATOMIC_WEIGHT_FACTOR; return ATOMIC_WEIGHT_FACTOR;
} }
@ -236,117 +236,116 @@ return ATOMIC_WEIGHT_FACTOR;
// //
float PTOE::_weight(const char sep, const char * abbrev) float PTOE::_weight(const char sep, const char * abbrev)
{ {
float sum = 0; float sum = 0;
float w = 0; float w = 0;
char elem[3] = { 0, 0, 0 }; char elem[3] = { 0, 0, 0 };
uint32_t count = 0; uint32_t count = 0;
while (*p != sep) while (*p != sep)
{ {
w = 0; w = 0;
// HANDLE GROUP (...) // HANDLE GROUP (...)
if (*p == '(') if (*p == '(')
{ {
p++; // skip '(' p++; // skip '('
w = _weight(')', abbrev); w = _weight(')', abbrev);
p++; // skip ')' p++; // skip ')'
} }
else else
{ {
// GET ELEMENT := [ Upper | Upper,lower ] // GET ELEMENT := [ Upper | Upper,lower ]
elem[1] = 0; elem[1] = 0;
if (! isupper(*p)) return 0; // fail if (! isupper(*p)) return 0; // fail
elem[0] = *p; elem[0] = *p;
p++; p++;
if (islower(*p)) if (islower(*p))
{ {
elem[1] = *p; elem[1] = *p;
p++; p++;
} }
// can be optimized? // can be optimized?
if ((abbrev == NULL) || (strcmp(elem, abbrev) == 0)) if ((abbrev == NULL) || (strcmp(elem, abbrev) == 0))
{ {
int z = find(elem); int z = find(elem);
if (z == 255) return 0; // fail if (z == 255) return 0; // fail
w = weight(z); w = weight(z);
} }
} }
count = 0; count = 0;
// get optional digits // get optional digits
while (isdigit(*p)) while (isdigit(*p))
{ {
count = count * 10 + (*p - '0'); count = count * 10 + (*p - '0');
p++; p++;
} }
// correct for no digits // correct for no digits
if (count == 0) count = 1; if (count == 0) count = 1;
// DEBUG // DEBUG
// Serial.println(w); // Serial.println(w);
// Serial.println(count); // Serial.println(count);
sum += (w * count);
sum += (w * count); }
} return sum;
return sum;
} }
uint32_t PTOE::_count(const char sep, const char * abbrev) uint32_t PTOE::_count(const char sep, const char * abbrev)
{ {
uint32_t sum = 0; uint32_t sum = 0;
char elem[3] = { 0, 0, 0 }; char elem[3] = { 0, 0, 0 };
uint32_t count = 0; uint32_t count = 0;
int w = 0; int w = 0;
while (*p != sep) while (*p != sep)
{ {
// HANDLE GROUP (...) // HANDLE GROUP (...)
if (*p == '(') if (*p == '(')
{ {
p++; // skip '(' p++; // skip '('
w = _count(')', abbrev); w = _count(')', abbrev);
p++; // skip ')' p++; // skip ')'
} }
else else
{ {
w = 0; w = 0;
// GET ELEMENT := [ Upper | Upper,lower ] // GET ELEMENT := [ Upper | Upper,lower ]
elem[1] = 0; elem[1] = 0;
if (! isupper(*p)) return 0; // fail if (! isupper(*p)) return 0; // fail
elem[0] = *p; elem[0] = *p;
p++; p++;
if (islower(*p)) if (islower(*p))
{ {
elem[1] = *p; elem[1] = *p;
p++; p++;
} }
// can be optimized // can be optimized
if ((abbrev == NULL) || (strcmp(elem, abbrev) == 0)) if ((abbrev == NULL) || (strcmp(elem, abbrev) == 0))
{ {
int z = find(elem); int z = find(elem);
if (z == 255) return 0; // fail if (z == 255) return 0; // fail
w = 1; w = 1;
} }
} }
count = 0; count = 0;
// get optional digits // get optional digits
while (isdigit(*p)) while (isdigit(*p))
{ {
count = count * 10 + (*p - '0'); count = count * 10 + (*p - '0');
p++; p++;
} }
// correct for no digits // correct for no digits
if (count == 0) count = 1; if (count == 0) count = 1;
// DEBUG // DEBUG
// Serial.println(w); // Serial.println(w);
// Serial.println(count); // Serial.println(count);
sum += w * count; sum += w * count;
} }
return sum; return sum;
} }

View File

@ -3,7 +3,7 @@
// FILE: AtomicWeight.h // FILE: AtomicWeight.h
// AUTHOR: Rob Tillaart // AUTHOR: Rob Tillaart
// DATE: 2022-03-09 // DATE: 2022-03-09
// VERSION: 0.2.0 // VERSION: 0.2.1
// PURPOSE: Arduino library for atomic weights // PURPOSE: Arduino library for atomic weights
// URL: https://github.com/RobTillaart/AtomicWeight // URL: https://github.com/RobTillaart/AtomicWeight
@ -11,7 +11,7 @@
#include "Arduino.h" #include "Arduino.h"
#define ATOMIC_WEIGHT_LIB_VERSION (F("0.2.0")) #define ATOMIC_WEIGHT_LIB_VERSION (F("0.2.1"))
#ifndef ATOMIC_WEIGHT_MAX_SPLIT_LIST #ifndef ATOMIC_WEIGHT_MAX_SPLIT_LIST

View File

@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.1] - 2023-10-17
- update readme.md
## [0.2.0] - 2023-04-15 ## [0.2.0] - 2023-04-15
- use new weight factor 201.3868 to reduce maximum relative error - use new weight factor 201.3868 to reduce maximum relative error
- create **elements_uint16.h** file. - create **elements_uint16.h** file.
@ -23,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- update readme.md - update readme.md
- update keywords.txt. - update keywords.txt.
----
## [0.1.5] - 2023-04-13 ## [0.1.5] - 2023-04-13
- add **moles2grams(formula, moles)** - add **moles2grams(formula, moles)**

View File

@ -2,8 +2,11 @@
[![Arduino CI](https://github.com/RobTillaart/AtomicWeight/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) [![Arduino CI](https://github.com/RobTillaart/AtomicWeight/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/AtomicWeight/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AtomicWeight/actions/workflows/arduino-lint.yml) [![Arduino-lint](https://github.com/RobTillaart/AtomicWeight/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AtomicWeight/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/AtomicWeight/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AtomicWeight/actions/workflows/jsoncheck.yml) [![JSON check](https://github.com/RobTillaart/AtomicWeight/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AtomicWeight/actions/workflows/jsoncheck.yml)
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/AtomicWeight.svg)](https://github.com/RobTillaart/AtomicWeight/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/AtomicWeight/blob/master/LICENSE) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/AtomicWeight/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/AtomicWeight.svg?maxAge=3600)](https://github.com/RobTillaart/AtomicWeight/releases) [![GitHub release](https://img.shields.io/github/release/RobTillaart/AtomicWeight.svg?maxAge=3600)](https://github.com/RobTillaart/AtomicWeight/releases)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/AtomicWeight.svg)](https://registry.platformio.org/libraries/robtillaart/AtomicWeight)
# AtomicWeight # AtomicWeight
@ -291,6 +294,7 @@ minimize the memory used for the elements mass lookup table.
- ==> more memory... - ==> more memory...
- support \[] square brackets too. - support \[] square brackets too.
- (NH4)2\[Pt(SCN)6] - (NH4)2\[Pt(SCN)6]
- add a derived class PERIODIC_TABLE?
#### Wont (unless) #### Wont (unless)
@ -314,8 +318,18 @@ minimize the memory used for the elements mass lookup table.
- K L M etc? - K L M etc?
- valence - valence
- temperatures, - temperatures,
- melt - melting point
- evaporate - evaporate point
- 2 bytes per temp 4 x 118 = 476 bytes - 2 bytes per temp 4 x 118 = 476 bytes
- compression 3 bytes for 2 temps 2x 12 bits = 0..4095 K = 354 bytes - compression 3 bytes for 2 temps 2x 12 bits = 0..4095 K = 354 bytes
## Support
If you appreciate my libraries, you can support the development and maintenance.
Improve the quality of the libraries by providing issues and Pull Requests, or
donate through PayPal or GitHub sponsors.
Thank you,

View File

@ -15,9 +15,9 @@
"type": "git", "type": "git",
"url": "https://github.com/RobTillaart/AtomicWeight.git" "url": "https://github.com/RobTillaart/AtomicWeight.git"
}, },
"version": "0.2.0", "version": "0.2.1",
"license": "MIT", "license": "MIT",
"frameworks": "arduino", "frameworks": "*",
"platforms": "*", "platforms": "*",
"headers": "AtomicWeight.h" "headers": "AtomicWeight.h"
} }

View File

@ -1,5 +1,5 @@
name=AtomicWeight name=AtomicWeight
version=0.2.0 version=0.2.1
author=Rob Tillaart <rob.tillaart@gmail.com> author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=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. sentence=Arduino library for atomic weights, calculate massPercentage of elements in a formula.