New method to set reset bits

This commit is contained in:
Emmanuel HC
2025-10-23 22:03:58 -05:00
parent c6aaf5186e
commit 5ab69c81cc
3 changed files with 80 additions and 3 deletions

View File

@@ -87,6 +87,15 @@ protected:
* @param strategy A pointer to the Strategy_Behavior object. The State takes ownership.
*/
void addStrategy(const std::string& pointDescription, Strategy_Behavior* strategy);
/**
* @brief Modify specifyc bits of a Modbus point in this state.
* @param equipment Pointer to the Equipment instance.
* @param pointName The description key of the Modbus point to write to.
* @param bitPosition The position to which the function will write to.
* @param state The new state of the selected bit.
*/
void setBitValue(Equipment<T>* equipment, const std::string& pointName, int bitPosition, bool state);
/**
* @brief returns a behavior strategy for a specific Modbus point in this state.
* @param pointDescription The description of the Modbus point your need to get.
@@ -218,4 +227,44 @@ void State<T>::_applyStrategies(Equipment<T>* equipment) {
}
}
/**
* @brief Controls a specific bit within an integer Modbus word (like a Holding or Input Register).
*
* This function bypasses the standard float logic to perform direct bit manipulation.
*
* @param equipment Pointer to the Equipment instance.
* @param pointName The description key of the Modbus point to modify.
* @param bitPosition The 0-based index of the bit to set/clear (0-15 for a 16-bit word).
* @param state If true, the bit is set (to 1); if false, the bit is cleared (to 0).
*/
template<typename T>
void State<T>::setBitValue(Equipment<T>* equipment, const std::string& pointName, int bitPosition, bool state) {
Modbus_Point<T>* point = equipment->getModbus_Point(pointName);
// Safety check: Ensure the point exists and isn't a decorated multi-word type (Float or Long)
// Note: Standard 16-bit Hreg/Ireg will return PointType::GENERIC.
if (!point || point->getType() != PointType::GENERIC || bitPosition < 0 || bitPosition > 15) {
// You can add an error logging statement here if needed, like Serial.printf(...)
return;
}
// 1. Get the current integer value directly from the point
int currentValue = point->getValue();
// 2. Create the bit mask
// '1 << bitPosition' shifts a 1 to the position we want to affect
int mask = 1 << bitPosition;
if (state) {
// 3. Set the bit (make it 1): Use the bitwise OR operator
currentValue |= mask;
} else {
// 3. Clear the bit (make it 0): Use the bitwise AND operator with the NOT (inverse) of the mask
currentValue &= ~mask;
}
// 4. Write the new integer value back
point->setValue(currentValue);
}
#endif