Skip to content

Instantly share code, notes, and snippets.

@thorrak
Created February 13, 2024 04:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thorrak/22961491abfa794a4d9ece4a4a31dce9 to your computer and use it in GitHub Desktop.
Save thorrak/22961491abfa794a4d9ece4a4a31dce9 to your computer and use it in GitHub Desktop.
Rough PoC for testing BrewPi's stringToTempDiff
#include <iostream>
#include <cstring>
#include <stdint.h>
// Constants from the header file
#define TEMP_FIXED_POINT_BITS 9
#define TEMP_FIXED_POINT_SCALE (1 << TEMP_FIXED_POINT_BITS)
#define TEMP_FIXED_POINT_MASK (TEMP_FIXED_POINT_SCALE - 1)
#define CALIBRATION_OFFSET_PRECISION (4)
#define C_OFFSET -24576
#define MIN_TEMP INT16_MIN // Assuming INT16_MIN
#define MAX_TEMP INT16_MAX // Assuming INT16_MAX
// just for clarity, typedefs are used instead of normal integers.
// Addition and shifting can be done normally. When two fixed points values are multiplied, you have shift the result
typedef int16_t fixed7_9; //!< 7 signed int bits and 9 fraction bits
typedef int32_t fixed23_9; //!< 23 signed int bits and 9 fraction bits. Used when results can overflow
typedef int32_t fixed7_25; //!< 7 signed int bits and 25 fraction bits. Used when extra precision is needed
typedef int16_t fixed12_4; //!< 1 sign bit, 11 integer bits, and 4 fraction bits - encoding returned by DS18B20 sensors.
typedef int8_t fixed4_4; //!< 1-sign bit, 3 int bits and 4 fraction bits. Corresponds with precision of DS18B20 sensors
// Auxiliary type definitions
typedef int16_t temperature;
typedef int8_t temp_int; //!< Temperature expressed as an integer.
typedef fixed7_9 temperature; //!< Common temperature representation
typedef fixed23_9 long_temperature; //!< Long temperature representation
typedef fixed7_25 temperature_precise; //!< Precise temperature representation
// Function prototypes
bool stringToTempDiff(temperature *result, const char *numberString);
bool stringToFixedPoint(long_temperature *result, const char *numberString);
long convertToInternalTempDiff(long rawTempDiff);
long constrainTemp16(long val);
long my_strtol(const char *str, char **tail);
// Main function for demonstration
int main() {
temperature parsedVal;
const char *testString = "-0.7";
if (stringToTempDiff(&parsedVal, testString)) {
std::cout << "Converted temperature difference: " << parsedVal << " (512=1)" << std::endl;
} else {
std::cout << "Conversion failed." << std::endl;
}
fixed4_4 calibrationAdjust = fixed4_4(parsedVal >> (TEMP_FIXED_POINT_BITS - CALIBRATION_OFFSET_PRECISION));
int printableCalibrationAdjust = calibrationAdjust;
std::cout << "calibrationAdjust: " << printableCalibrationAdjust << " (16=1)" << std::endl;
return 0;
}
// Implementation of functions
bool stringToTempDiff(temperature *result, const char *numberString) {
long_temperature longResult;
if (stringToFixedPoint(&longResult, numberString)) {
longResult = convertToInternalTempDiff(longResult);
*result = constrainTemp16(longResult);
return true;
}
return false;
}
bool stringToFixedPoint(long_temperature *result, const char *numberString)
{
// receive new temperature as null terminated string: "19.20"
long_temperature newValue;
long_temperature decimalValue = 0;
// char *decimalPtr;
char *end;
// Check if - is in the string
bool positive = (0 == strchr(numberString, '-'));
newValue = my_strtol(numberString, &end); // convert string to integer
if (end == numberString) {
return false; // No digits were found
}
newValue = newValue << TEMP_FIXED_POINT_BITS; // shift to fixed point
std::cout << "stringToFixedPoint called my_strtol with " << numberString << " - Converted to " << newValue << std::endl;
// find the point in the string to know whether we have decimals
const char *decimalPtr = strchr(numberString, '.'); // returns pointer to the point.
// decimalPtr = const_cast<char *>(strchr(numberString, '.'));
if (decimalPtr != 0)
{
// decimalPtr++; // skip decimal point
// convert decimals to integer
decimalValue = my_strtol(decimalPtr+1, &end) << TEMP_FIXED_POINT_BITS;
if (end == numberString) {
return false; // No digits were found
}
uint8_t charsAfterPoint = end - (decimalPtr+1); // actually used # digits after point
std::cout << "stringToFixedPoint has " << charsAfterPoint << " charsAfterPoint - With decimalValue " << decimalValue << std::endl;
while (charsAfterPoint-- > 0)
{
decimalValue = (decimalValue + 5) / 10;
}
}
*result = positive ? newValue + decimalValue : newValue - decimalValue;
return true;
}
long convertToInternalTempDiff(long rawTempDiff) {
return rawTempDiff; // Assuming no additional logic is needed
}
long constrainTemp16(long val) {
if (val < MIN_TEMP) {
return MIN_TEMP;
}
if (val > MAX_TEMP) {
return MAX_TEMP;
}
return val;
}
long int my_strtol(const char *str, char **tail)
{
long val = 0;
bool positive = true;
*tail = (char *)str;
uint16_t read = 0;
while (1) {
if (**tail == '\0') {
break;
} else if (**tail == ' ') {
if (read != 0) {
break; // only leading zeros allowed
}
} else if (**tail == '-') {
positive = false;
} else if (**tail >= '0' && **tail <= '9') {
val = val * 10 + (**tail - '0');
read++;
} else {
break;
}
(*tail)++;
}
if (read == 0) {
*tail = (char *)str;
}
std::cout << "my_strtol called with " << str << " - Converted to " << (positive ? val : -val) << std::endl;
return positive ? val : -val;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment