I have to simulate an ADC that behaves as an I2C slave. The simulated values that the ADC shall expose are sent over serial, saved on an attribute and are requested by a master device over I2C.
A simplified solution is the following. I have a struct ADC that describes the converter:
struct ADC
{
uint32_t register_1;
uint32_t register_2;
void write_register_1(uint32_t data){
register_1 = data;
}
void write_register_2(uint32_t data){
register_2 = data;
}
uint8_t read(){
return register_1;
}
// some other methods to setup...
};
In loop(), I read the serial in order to update the ADC::register value and in the onRequest handler I eventually send the requested data by accessing ADC::register:
ADC adc{};
void setup(){
// setup adc, Wire and Serial here
Wire.onRequest(slaveTransmitterHandler)
}
void loop(){
if (Serial.available() > 0)
{
// read serial, parse received data and check them
uint32_t data = parse_serial(); // do anything is needed to check data...
// update adc attribute
uint8_t oldSREG = SREG;
noInterrupts(); // disable interrupts to update uint32
adc.write_register_1(data);
SREG = oldSREG;
}
}
void slaveTransmitterHandler(){
Wire.beginTransmission(ADDRESS);
Wire.write(adc.read());
Wire.endTransmission();
}
void slaveReceiverHandler(){
uint32_t i2c_received_data;
while (Wire.available){
// fill i2c_received_data with Wire.read()
}
adc.write_register_2(i2c_received_data);
}
I'm not sure if I have to declare the adc object as volatile (this would mean to declare all ADC methods and variables as volatile). Is it safe to use an object inside the I2C handler called by the I2C interrupt?
As far as I know, it is not (I can find no reason why it should be different from non-class variables), but I have always worked with non-class variables and never with cpp objects. Also, I can't find any information about this topic.
It could be possible that I'm wrong with the whole design, even if it seems to me to be very consistent. I'm open to change it for something better, so please if this design is nonsense, comment on that! I'm here to learn :)
Thanks.
Luca
Edit: Some clarification, since my question seems not to be clear enough: I'm doing HIL simulation, that is simulating the real hardware with its real interfaces with a simulated environment (that includes sensors and actuators). See here for more info.
One of my sensors measures a voltage and stores it in a register of an ADC (that has multiple registers). I'm simulating the behaviour of ADC registers in Arduino, and they shall communicate via I2C with the real hardware.
Hope this is more clear now.