GY-63_MS5611/libraries/AtomicWeight/AtomicWeight.cpp

360 lines
6.3 KiB
C++
Raw Normal View History

2022-12-31 12:30:42 -05:00
//
// FILE: AtomicWeight.cpp
// AUTHOR: Rob Tillaart
// DATE: 2022-03-09
2024-04-07 11:42:13 -04:00
// VERSION: 0.2.2
2022-12-31 12:30:42 -05:00
// PURPOSE: Arduino library for atomic weights
// URL: https://github.com/RobTillaart/AtomicWeight
#include "AtomicWeight.h"
2023-04-15 14:15:18 -04:00
#include "elements_uint16.h"
2022-12-31 12:30:42 -05:00
2023-04-15 14:15:18 -04:00
PTOE::PTOE(const uint8_t size)
{
2023-10-17 13:50:25 -04:00
_size = size;
_found = 0;
2023-04-15 14:15:18 -04:00
}
////////////////////////////////////////////////////////////////
2022-12-31 12:30:42 -05:00
//
2023-04-15 14:15:18 -04:00
// BASIC
2022-12-31 12:30:42 -05:00
//
2023-04-15 14:15:18 -04:00
uint8_t PTOE::size()
{
2023-10-17 13:50:25 -04:00
return _size;
2023-04-15 14:15:18 -04:00
}
2022-12-31 12:30:42 -05:00
2024-04-07 11:42:13 -04:00
char * PTOE::name(const uint8_t element)
2022-12-31 12:30:42 -05:00
{
2023-10-17 13:50:25 -04:00
// catch out of range.
2024-04-07 11:42:13 -04:00
if (element > _size) return NULL;
return elements[element].name;
2022-12-31 12:30:42 -05:00
}
2023-04-15 14:15:18 -04:00
uint8_t PTOE::find(const char * abbrev)
2022-12-31 12:30:42 -05:00
{
2023-10-17 13:50:25 -04:00
// case insensitive?
// caching?
2024-04-07 11:42:13 -04:00
// parameter check?
// uint8_t length = strlen(abbrev);
// if ((length == 1) || (length == 2) || (length == 3))
2023-10-17 13:50:25 -04:00
// {
for (uint8_t i = 0; i < _size; i++)
{
if (strcmp(elements[i].name, abbrev) == 0) return i;
}
// }
2024-04-07 11:42:13 -04:00
return 255; // out of range.
2022-12-31 12:30:42 -05:00
}
2024-04-07 11:42:13 -04:00
uint8_t PTOE::electrons(const uint8_t element)
2022-12-31 12:30:42 -05:00
{
2024-04-07 11:42:13 -04:00
return element;
2022-12-31 12:30:42 -05:00
}
2024-04-07 11:42:13 -04:00
uint8_t PTOE::neutrons(const uint8_t element)
2022-12-31 12:30:42 -05:00
{
2024-04-07 11:42:13 -04:00
return round(weight(element)) - element;
2022-12-31 12:30:42 -05:00
}
2024-04-07 11:42:13 -04:00
uint8_t PTOE::protons(const uint8_t element)
2022-12-31 12:30:42 -05:00
{
2024-04-07 11:42:13 -04:00
return element;
2022-12-31 12:30:42 -05:00
}
2023-04-15 14:15:18 -04:00
////////////////////////////////////////////////////////////////
//
// WEIGHT
//
2024-04-07 11:42:13 -04:00
float PTOE::weight(const uint8_t element)
2022-12-31 12:30:42 -05:00
{
2024-04-07 11:42:13 -04:00
if (element > _size) return 0; // catch out of range.
return elements[element].weight * ATOMIC_WEIGHT_FACTOR;
2022-12-31 12:30:42 -05:00
}
2023-04-14 07:34:00 -04:00
float PTOE::weight(const char * formula, const char * abbrev)
2022-12-31 12:30:42 -05:00
{
2023-10-17 13:50:25 -04:00
p = (char *)formula;
return _weight('\0', abbrev);
2022-12-31 12:30:42 -05:00
}
2023-04-14 07:34:00 -04:00
float PTOE::massPercentage(const char * formula, const char * abbrev)
2022-12-31 12:30:42 -05:00
{
2023-10-17 13:50:25 -04:00
float total = weight(formula);
if (total == 0) return 0;
p = (char *)formula;
return 100.0 * _weight('\0', abbrev) / total;
2022-12-31 12:30:42 -05:00
}
2023-01-02 07:02:36 -05:00
2023-04-14 07:34:00 -04:00
////////////////////////////////////////////////////////////////
//
// CONVERSION
//
float PTOE::moles2grams(const char * formula, float moles)
{
2023-10-17 13:50:25 -04:00
return moles * weight(formula);
2023-04-14 07:34:00 -04:00
}
float PTOE::grams2moles(const char * formula, float grams)
{
2023-10-17 13:50:25 -04:00
return grams / weight(formula);
2023-04-14 07:34:00 -04:00
}
2023-01-02 07:02:36 -05:00
////////////////////////////////////////////////////////////////
//
2023-04-15 14:15:18 -04:00
// SPLIT FORMULA IN ELEMENTS
2023-01-02 07:02:36 -05:00
//
2023-04-15 14:15:18 -04:00
uint8_t PTOE::splitElements(const char * formula)
{
2023-10-17 13:50:25 -04:00
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;
}
// GET ELEMENT := [ Upper | Upper,lower ]
elem[0] = 0;
elem[1] = 0;
2024-04-07 11:42:13 -04:00
if (! isupper(*p))
{
return 0; // fail
}
2023-10-17 13:50:25 -04:00
elem[0] = *p;
p++;
if (islower(*p))
{
elem[1] = *p;
p++;
}
// FIND INDEX OF ELEMENT
2024-04-07 11:42:13 -04:00
int index = find(elem);
if (index == 255)
2023-10-17 13:50:25 -04:00
{
return 0; // fail
}
// DO WE HAVE IDENTIFIED IT ALREADY?
bool found = false;
for (int i = 0; i < count; i++)
{
2024-04-07 11:42:13 -04:00
if (_splitList[i] == index)
2023-10-17 13:50:25 -04:00
{
found = true;
}
}
if ((found == false) && (count < ATOMIC_WEIGHT_MAX_SPLIT_LIST))
{
2024-04-07 11:42:13 -04:00
_splitList[count] = index;
2023-10-17 13:50:25 -04:00
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]));
// }
_found = count;
return count;
2023-04-12 10:52:57 -04:00
}
2024-04-07 11:42:13 -04:00
uint8_t PTOE::element(uint8_t element)
2023-04-12 10:52:57 -04:00
{
2024-04-07 11:42:13 -04:00
if (element >= _found)
{
return 255; // out of range
}
return _splitList[element];
2023-04-12 10:52:57 -04:00
}
2023-04-15 14:15:18 -04:00
////////////////////////////////////////////////////////////////
//
// COUNT
//
2024-04-07 11:42:13 -04:00
uint32_t PTOE::count(const char * formula, const char * element)
2023-04-12 10:52:57 -04:00
{
2023-10-17 13:50:25 -04:00
p = (char *)formula;
2024-04-07 11:42:13 -04:00
return _count('\0', element);
2023-04-12 10:52:57 -04:00
}
2024-04-07 11:42:13 -04:00
float PTOE::atomPercentage(const char * formula, const char * element)
2023-04-12 10:52:57 -04:00
{
2023-10-17 13:50:25 -04:00
float total = count(formula);
if (total == 0) return 0;
p = (char *)formula;
2024-04-07 11:42:13 -04:00
return 100.0 * _count('\0', element) / total;
2023-04-15 14:15:18 -04:00
}
////////////////////////////////////////////////////////////////
//
// DEBUG
//
float PTOE::weightFactor()
{
2023-10-17 13:50:25 -04:00
return ATOMIC_WEIGHT_FACTOR;
2023-04-12 10:52:57 -04:00
}
2023-01-02 07:02:36 -05:00
////////////////////////////////////////////////////////////////
//
// PRIVATE
//
2024-04-07 11:42:13 -04:00
float PTOE::_weight(const char separator, const char * abbrev)
2022-12-31 12:30:42 -05:00
{
2023-10-17 13:50:25 -04:00
float sum = 0;
float w = 0;
char elem[3] = { 0, 0, 0 };
uint32_t count = 0;
2024-04-07 11:42:13 -04:00
while (*p != separator)
2023-10-17 13:50:25 -04:00
{
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))
{
2024-04-07 11:42:13 -04:00
int index = find(elem);
if (index == 255) return 0; // fail
w = weight(index);
2023-10-17 13:50:25 -04:00
}
}
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;
2022-12-31 12:30:42 -05:00
}
2024-04-07 11:42:13 -04:00
uint32_t PTOE::_count(const char separator, const char * abbrev)
2023-04-12 10:52:57 -04:00
{
2023-10-17 13:50:25 -04:00
uint32_t sum = 0;
char elem[3] = { 0, 0, 0 };
uint32_t count = 0;
int w = 0;
2024-04-07 11:42:13 -04:00
while (*p != separator)
2023-10-17 13:50:25 -04:00
{
// 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))
{
2024-04-07 11:42:13 -04:00
int index = find(elem);
if (index == 255) return 0; // fail
2023-10-17 13:50:25 -04:00
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;
// DEBUG
// Serial.println(w);
// Serial.println(count);
sum += w * count;
}
return sum;
2023-04-12 10:52:57 -04:00
}
// -- END OF FILE --
2022-12-31 12:30:42 -05:00