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

View File

@ -3,7 +3,7 @@
// FILE: AtomicWeight.h
// AUTHOR: Rob Tillaart
// DATE: 2022-03-09
// VERSION: 0.2.0
// VERSION: 0.2.1
// PURPOSE: Arduino library for atomic weights
// URL: https://github.com/RobTillaart/AtomicWeight
@ -11,7 +11,7 @@
#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

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/).
## [0.2.1] - 2023-10-17
- update readme.md
## [0.2.0] - 2023-04-15
- use new weight factor 201.3868 to reduce maximum relative error
- create **elements_uint16.h** file.
@ -23,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- update readme.md
- update keywords.txt.
----
## [0.1.5] - 2023-04-13
- 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-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)
[![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)
[![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
@ -291,6 +294,7 @@ minimize the memory used for the elements mass lookup table.
- ==> more memory...
- support \[] square brackets too.
- (NH4)2\[Pt(SCN)6]
- add a derived class PERIODIC_TABLE?
#### Wont (unless)
@ -314,8 +318,18 @@ minimize the memory used for the elements mass lookup table.
- K L M etc?
- valence
- temperatures,
- melt
- evaporate
- melting point
- evaporate point
- 2 bytes per temp 4 x 118 = 476 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",
"url": "https://github.com/RobTillaart/AtomicWeight.git"
},
"version": "0.2.0",
"version": "0.2.1",
"license": "MIT",
"frameworks": "arduino",
"frameworks": "*",
"platforms": "*",
"headers": "AtomicWeight.h"
}

View File

@ -1,5 +1,5 @@
name=AtomicWeight
version=0.2.0
version=0.2.1
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.