Hi, people, I'm getting a similar problem.
I'm triying to control a brake pedal with a linear actuator. I have the next configuration.
One arduino Nano is reading an incremental encoder (from the linear actuator) by interruptions and sending the value of the counter to an Arduino UNO, every 20 ms.
The arduino UNO reads the value with the recvWithEndMarker()[/b] function, proposed by @Robin2 at this great post about Serial communication , every 20 ms (I tried with both arduinos at 20 ms, but the problem persist)
When the counter is one or two digits there is no problem, the communication behaves stable, but when the counter is 3 digits long sometimes the UNO receives only two digits, as you can see in the next sample (crt for current position, tgt for target position).
** **B_pos(crt: 89, tgt: 123), B_err:34 B_pos(crt: 90, tgt: 123), B_err:33 B_pos(crt: 92, tgt: 123), B_err:31 B_pos(crt: 93, tgt: 123), B_err:30 B_pos(crt: 93, tgt: 123), B_err:30 B_pos(crt: 94, tgt: 123), B_err:29 B_pos(crt: 95, tgt: 123), B_err:28 B_pos(crt: 97, tgt: 123), B_err:26 B_pos(crt: 98, tgt: 123), B_err:25 B_pos(crt: 98, tgt: 123), B_err:25 B_pos(crt: 99, tgt: 123), B_err:24 B_pos(crt: 100, tgt: 123), B_err:23 B_pos(crt: 10, tgt: 123), B_err:113 B_pos(crt: 102, tgt: 123), B_err:21 B_pos(crt: 102, tgt: 123), B_err:21 B_pos(crt: 10, tgt: 123), B_err:113 B_pos(crt: 106, tgt: 123), B_err:17 B_pos(crt: 10, tgt: 123), B_err:113 B_pos(crt: 111, tgt: 123), B_err:12 B_pos(crt: 111, tgt: 123), B_err:12 B_pos(crt: 11, tgt: 123), B_err:112 B_pos(crt: 115, tgt: 123), B_err:8 B_pos(crt: 118, tgt: 123), B_err:5 B_pos(crt: 119, tgt: 123), B_err:4 B_pos(crt: 119, tgt: 123), B_err:4 B_pos(crt: 12, tgt: 123), B_err:111 B_pos(crt: 12, tgt: 123), B_err:111 B_pos(crt: 12, tgt: 110), B_err:98 B_pos(crt: 126, tgt: 92), B_err:-34 B_pos(crt: 126, tgt: 67), B_err:-59 B_pos(crt: 12, tgt: 43), B_err:31 B_pos(crt: 128, tgt: 24), B_err:-104 B_pos(crt: 128, tgt: 12), B_err:-116 B_pos(crt: 125, tgt: 0), B_err:-125 B_pos(crt: 125, tgt: 0), B_err:-125 B_pos(crt: 12, tgt: 0), B_err:-12 B_pos(crt: 115, tgt: 0), B_err:-115 B_pos(crt: 112, tgt: 0), B_err:-112 B_pos(crt: 108, tgt: 0), B_err:-108 B_pos(crt: 108, tgt: 0), B_err:-108 B_pos(crt: 10, tgt: 0), B_err:-10 B_pos(crt: 98, tgt: 0), B_err:-98 B_pos(crt: 96, tgt: 0), B_err:-96 B_pos(crt: 93, tgt: 12), B_err:-81 B_pos(crt: 93, tgt: 12), B_err:-81 B_pos(crt: 89, tgt: 12), B_err:-77 B_pos(crt: 85, tgt: 12), B_err:-73 B_pos(crt: 82, tgt: 0), B_err:-82 B_pos(crt: 78, tgt: 0), B_err:-78** **
When this happen the error value gets high and the actuator start to oscillate.
Both Arduinos are working at 115200 bauds, both with hardware serial. I try at 38400 first but the same behavior appears.
Arduino Nano Code.
```
**#include <Arduino.h>
// Rotary Encoder Inputs
#define CH_A 2 // Cable verde encoder.
#define CH_B 3 // Cable negro encoder.
int counter = 0, lastCounter = 0;
int currentStateCH_A;
int lastStateCH_A;
String currentDirection = "";
long lastTime = 0, currentTime = 0;
unsigned int period = 25;
void updateEncoder(){
// Read the current state of CLK
currentStateCH_A = digitalRead(CH_A);
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCH_A != lastStateCH_A && currentStateCH_A == 1)
{
// If the DT state is different than the CLK state then
// the encoder is rotating CCW so decrement
if (digitalRead(CH_B) != currentStateCH_A)
{
counter ++;
currentDirection = "CCW";
} else
{
// Encoder is rotating CW so increment
counter --;
currentDirection = "CW";
}
}
// Remember last CLK state
lastStateCH_A = currentStateCH_A;
}
void setup() {
// Set encoder pins as inputs
pinMode(CH_A, INPUT); // (CLK)
pinMode(CH_B, INPUT); // (DT)
// Setup Serial Monitor
//Serial.begin(38400);
Serial.begin(115200);
// Read the initial state of CLK
lastStateCH_A = digitalRead(CH_A);
// Call updateEncoder() when any high/low changed seen
// on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
lastTime = millis();
}
void loop() {
//Serial.print(" | Counter: ");
//Serial.println(counter);
currentTime = millis();
if( (currentTime - lastTime) >= period )
{
if(lastCounter != counter)
{
Serial.println(counter);
lastCounter = counter;
}
lastTime = currentTime;
}
}**
** **Simplified Arduino UNO Code** **
**const byte numChars = 32;
char receivedChars[numChars];
bool newData = false;
int dataNumber = 0;
long currentTime = 0, lastTime = 0, peri
uint8_t periodoDeseado = 20;
int BrakeActuator_Pos;
void recvWithEndMarker()
{
static byte ndx = 0;
char endMarker = '\n';
char rc;
//if(Serial.available() > 0 && newData == false)
while(Serial.available() > 0 && newData == false)
{
//Serial.println("Entré a Serial.available()");
rc = Serial.read();
if(rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if(ndx >= numChars)
{
ndx = numChars - 1;
}
} else { // rc == endMarker
receivedChars[ndx] = '\0'; //Caracter de fin de cadena
ndx = 0;
newData = true;
//break; // Esto si se usa while en lugar de if.
}
}
}
void recoverIntData(int* positionVariable)
{
if(newData)
{
dataNumber = 0;
dataNumber = atoi(receivedChars);
*variablePorAsignar = dataNumber;
newData = false;
}
}
void setup()
{
Wire.begin();
//Serial.begin(19200);
//Serial.begin(38400);
Serial.begin(115200);
Serial.println("Comm init.");
}
void loop()
{
currentTime = millis();
if( (currentTime - lastTime) >= period )
{
recvWithEndMarker();
recoverIntData(&BrakeActuator_Pos);
Serial.print(", B_pos(cnt: "); Serial.print(ActuadorFreno_Posicion);
Serial.print(",\t tgt: "); Serial.print(ActuadorFreno_PosDeseada);
Serial.print(")");
// Other stuff...
}
}**
```
We already try using the recvWithStartEndMarkers() function, incrementing the period of the Nano to 25 ms, lowering the baudrate of both arduinos to 38400 bps and making an offering to Odin, with no satisfactory results.
Any tips or references that we can review?
Thanks in advance, people!