Hi Community,
iam on my way to build a 'communication-interface' between some arduinos (using serial)
the concept is that every arduino knows all data of the hole system.
(changes are 'broadcastet' to every arduino)
at the moment iam writing the heart of the thing - the 'parse incoming / send data / set / get' handler.
on the main thing i use a big switch case to map the incoming id to the internal variable name.
as i have begin to write this big thing i came to the idea to use function pointers and variable pointers
so that in the switch case only the datatype handling is done -
and after this the real action (operation : receive / transmit / set / get) is done.
i have written a striped down sketch to test the concept.
my problem is that i don't know how to best handle the different datatypes that i have
(at the moment word, byte, boolean)
here the test sketch:
/*
Test sketch for function pointers and data handling
Public Domain
*/
class xLocalTestClass {
public:
// public consts :
static const byte state_NotValid = 11;
static const byte state_Standby = 12;
static const byte hdOperation_SET = 's';
static const byte hdOperation_SETINT = 'i';
static const byte hdOperation_GET = 'g';
static const byte hdOperation_RECEIVE = 'r';
static const byte hdOperation_TRANSMIT = 't';
private:
// per object data general
// ID
const byte cbID;
// flag to check if the begin function is already called and the class is ready to work.
boolean bReady;
// internal state
byte bState;
// Internal representation of complete 2ChControl System:
// left right
struct sSideIO {
byte bButtonStates;
byte bButtonEvent[5];
word wLEDsRaw;
int iFader_position_current;
int iFader_position_target;
byte bFader_touch;
word wRotaryEncoder_position;
};
// system
struct sSystem {
bool bSlidingSwitch_Left;
bool bSlidingSwitch_Right;
byte bSDCard_State;
byte bPowerMux_State;
word wPowerIN_Voltage;
word bInfoLEDsRaw;
};
// display
struct sDisplay {
byte bBGLight_State;
byte bBGLight_Value;
byte bContrast_State;
byte bContrast_Value;
};
sSideIO memory_LeftRight[2];
sSystem memory_System;
sDisplay memory_Display;
// private methods
bool checkChanged_Value(word *pMemory, word *pValue, byte bBitIndex) {
bool bResult = 0;
if (*pMemory != *pValue) {
bResult = 1;
}
return bResult;
}
bool checkChanged_2Bit(word *pMemory, word *pValue, byte bBitIndex) {
bool bResult = 0;
if (((*pMemory >> (bBitIndex*2)) & 0b0000000000000011) != *pValue) {
bResult = 1;
}
return bResult;
}
void setValue_Value(word *pMemory, word *pValue, byte bBitIndex) {
*pMemory = *pValue;
}
void setValue_2Bit(word *pMemory, word *pValue, byte bBitIndex) {
if (*pValue){
// set Bit
*pMemory |= (*pValue << (bBitIndex*2));
} else {
// clear Bit
*pMemory &= ~(*pValue << (bBitIndex*2));
}
}
public:
// Constructor
xLocalTestClass(
const byte cbID_New
) :
cbID(cbID_New)
{
//do some initialisation
bReady = false;
};
// Destructor
~xLocalTestClass() {
// nothing to do here ?!
};
// public methods general
// get ID
const byte getID() {
return cbID;
};
// check if class is ready to operate.
boolean isReady() {
return bReady;
};
// start
void begin() {
if (bReady == false) {
bReady = true;
}
};
// update system
// returns state
byte update() {
byte bStateTemp = state_NotValid;
if (bReady) {
bStateTemp = bState;
} // end if bReady
return bStateTemp;
};
// public methods functional
// start Counting up to an given value; if Value is reached generates an state changed event.
byte test(byte bOperation, char cSwitchMemory, byte bBitIndex, word *pValue, word wValueReceive) {
// default to left
byte bLRIndex = 0;
if ( 1 != 1) {
// set to right
bLRIndex = 1;
}
// pointer to Memory Value
word *pMemory = NULL;
// tCbfuncCheckChanged fc_CheckChanged = NULL;
bool (xLocalTestClass::*fc_CheckChanged) (word *pMemory, word *pValue, byte bBitIndex) = NULL;
void (xLocalTestClass::*fc_SetValue) (word *pMemory, word *pValue, byte bBitIndex) = NULL;
switch (cSwitchMemory) {
case 'a': {
pMemory = &memory_LeftRight[bLRIndex].wRotaryEncoder_position;
fc_CheckChanged = &xLocalTestClass::checkChanged_Value;
fc_SetValue = &xLocalTestClass::setValue_Value;
} break;
case 'b': {
pMemory = &memory_LeftRight[bLRIndex].wLEDsRaw;
fc_CheckChanged = &xLocalTestClass::checkChanged_2Bit;
fc_SetValue = &xLocalTestClass::setValue_2Bit;
} break;
case 'c': {
pMemory = &memory_System.bSlidingSwitch_Left;
fc_CheckChanged = &xLocalTestClass::checkChanged_Value;
fc_SetValue = &xLocalTestClass::setValue_Value;
} break;
} // end switch level2
// do things with function pointers
// remember Original Operation
byte bOperationOld = bOperation;
// do as long as Operation changes:
do {
bOperationOld = bOperation;
switch (bOperation) {
case hdOperation_GET: {
Serial.println(F("hdOperation_GET"));
*pValue = *pMemory;
}
case hdOperation_RECEIVE: {
Serial.println(F("hdOperation_RECEIVE"));
//*pValue = getValue_Byte(caValue);
*pValue = wValueReceive;
bOperation = hdOperation_SETINT;
} break;
case hdOperation_SETINT:
case hdOperation_SET: {
Serial.println(F("hdOperation_SET(INT)"));
// check if value changes:
if ((*this.*fc_CheckChanged)(pMemory, pValue, bBitIndex) ) {
// set value
(*this.*fc_SetValue)(pMemory, pValue, bBitIndex);
// check if need to transmit new value
if (bOperation == hdOperation_SET) {
bOperation = hdOperation_TRANSMIT;
} else {
// callback 'ValueChanged'
}
}
} break;
case hdOperation_TRANSMIT:{
Serial.println(F("hdOperation_TRANSMIT"));
Serial.print(F(" MemoryValue:"));
Serial.println(*pMemory);
//printValue_Byte(streamCommunication, *pMemory);
} break;
} // end switch bOperation
} while (bOperationOld != bOperation);
return 1;
};
}; // end class slight_Test
xLocalTestClass myLocalTestObject(42);
void setup() {
Serial.println(F("test_functionpointer.ino"));
myLocalTestObject.begin();
word wValue = 0;
word *pValue = &wValue;
//byte test(byte bOperation, byte bSwitchMemory, byte bBitIndex, word *pValue, wValueReceive)
Serial.println(F("\t SET: pValue = &500;"));
*pValue = 500;
myLocalTestObject.test(xLocalTestClass::hdOperation_SET, 'a', 1, pValue, 0);
Serial.println(F("\t TRANSMIT:"));
myLocalTestObject.test(xLocalTestClass::hdOperation_TRANSMIT, 'a', 1, pValue, 0);
Serial.println(F("\t GET:"));
myLocalTestObject.test(xLocalTestClass::hdOperation_GET, 'a', 1, pValue, 0);
Serial.print(F("\t return value:"));
Serial.println(*pValue);
Serial.println(F("\t RECEIVE:"));
myLocalTestObject.test(xLocalTestClass::hdOperation_RECEIVE, 'a', 1, pValue, 0);
}
void loop() {
1;
}
Errors:
test_functionpointer.ino: In member function 'byte xLocalTestClass::test(byte, char, byte, word*, word)':
test_functionpointer:183: error: cannot convert 'bool*' to 'word*' in assignment
this is the problem with the different datatypes...
i think i could do something like this with an void* pointer??
or is there some from ground up other way to do something like this?
sunny greetings
stefan