Created
February 13, 2024 04:48
-
-
Save thorrak/22961491abfa794a4d9ece4a4a31dce9 to your computer and use it in GitHub Desktop.
Rough PoC for testing BrewPi's stringToTempDiff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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