I am writing a code that performs a PID loop on an arduino. A raspberry pi is connected to the arduino, communicating over i2c. The Pi can change things such as the setpoint and pid values, and has a user interface. In the interface, I plot the current position that is being sent over from the arduino. The pi is requesting this information every 100 ms. I send over two bytes (LSB,MSB) using Wire.write(sData,2); and receive on the Pi using i2ctest = wiringPiI2CReadReg16(fd,0x00);.
It seems that most of the time, the eighth bit on the LSB gets switched from 1 to 0 more often than not, though sometimes it isnt switched. If I print anything to serial within the interrupt then this problem goes away. I will post the relevant code below.
void setup() {
Wire.begin(SLAVE_ADDRESS);
Wire.setClock(1000000);
Serial.begin(115200);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
myDAC.begin(9);
pinMode(2,INPUT);
zeroPoint = analogRead(disppin);
myDAC.analogWrite(512*4); //here we send out 512 because that should correspond to 0 current
}
void loop() {
disp = analogRead(disppin);
tosend=disp;
current = analogRead(currentpin);
//Serial.println(disp);
//Serial.println(current);
if(current<=100 || current>=830){ //if the current is outside threshold, reset system
myDAC.analogWrite(512*4);
//exit(0);
}
else{
currentTime = millis();
elapsedTime = currentTime-previousTime;
val = disp-zeroPoint;
error = (setPoint) - val;
//Serial.println(error);
cumError += error*elapsedTime;
rateError = (error-lastError)/elapsedTime;
Output = Kp*error+Ki*cumError+Kd*rateError;
lastError = error;
previousTime = currentTime;
Output = max(100.0,min(900.0,Output)); //here we can make sure that we don't overload the servo valve
//Serial.print("Output:");
//Serial.println(Output+512);
myDAC.analogWrite(4*(Output));
}
}
void sendData(){
//Serial.println(data);
//Serial.println("Sent");
//disp = analogRead(disppin);
//tosend=1023;
sData[1] = (tosend >>8) & 0xFF;
sData[0] = tosend & 0xFF;
//Wire.beginTransmission();
//Serial.print(sData[1],BIN);
Serial.println(sData[0],BIN); //printing this fixes the issue.
Wire.write(sData,2);
//Wire.endTransmission();
}
and then on the Pi
i2ctest = wiringPiI2CReadReg16(fd,0x00);
Please let me know if anyone is aware of how to fix this, or why printing something fixes the issue. While printing seems to work, it is slow and I would rather not have to print anything to serial as it will slow down my PID loop.