Salve, ho un problema molto strano e particolare, che non sono riuscito a capire per quale motivo si presenta.
Dopo molti test sono riuscito ad isolare il problema, e quindi tramite poche righe di codice posso sottoporvelo e dirvi come poterlo ricreare.
Praticamente ho un'applicazione in python che deve inviare ad un arduino nano (atmega 328@16Mhz) delle stringhe di numeri separati tra di loro da un accapo. Lo sketch sull'arduino si occupa di separare i numeri dall'accapo ed usarli per fare delle operazioni che non sto qui a spiegare perchè non riguardano il problema.
Se la stringa di numeri da inviare all'arduino è "abbastanza lunga" (si parla di appena 70-90 caratteri circa, non di cifre eccessivamente alte), e le operazioni che faccio sui dati nella funzione loop() richiedono più di 100-200ms, la stringa viene misteriosamente troncata dopo un tot, con conseguente perdita dei dati sucessivi.
Ecco il codice python sul pc:
import serial
ser = serial.Serial("/dev/ttyUSB0", 9600) # open first serial port
ser.write("545\n546\n547\n548\n801\n802\n803\n804\n1057\n1058\n1059\n1060\n1313\n1314\n1315\n1316\n1569\n1570\n1571\n1572\n1825\n1826\n1827\n1828\n") # write a string
output=""
while (1):
x = ser.read() # read one byte
if (x == "\n"):
print output
output = ""
else:
output += x
In ser.write() c'è un esempio di stringa che provo ad inviare all'arduino.
Ora il codice sull'arduino:
String inputString = ""; // a string to hold incoming data
unsigned long inputnumber;
unsigned long time;
int ardNumber;
void setup() {
Serial.begin(9600);
inputString.reserve(600);
Serial.print("Pronto\n");
}
void loop() {
time = millis();
char convertString[inputString.length()+1];
inputString.toCharArray(convertString, sizeof(convertString));
char *ultimoAccapo = NULL;
char *commands;
char *result = NULL;
char delims[] = "\n";
ultimoAccapo = strrchr (convertString, (int)'\n');
if (ultimoAccapo != NULL){
if (convertString+strlen(convertString) > ultimoAccapo+1) {
int command_size = ultimoAccapo-convertString+1;
commands=(char*)malloc(command_size);
strncpy(commands,convertString,command_size);
commands[command_size-1]='\0';
inputString = inputString.substring(command_size-1);
}
else {
inputString = "";
commands=convertString;
}
result = strtok( commands, delims );
while( result != NULL ) {
inputnumber = atoi(result);
[b] Serial.println(inputnumber);
delay(300);[/b]
result = strtok( NULL, delims );
}
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
}
}
Praticamente in loop il codice ha il compito di prendere la stringa che arriva dalla seriale e splittare i singoli numeri secondo i "\n".
In grassetto, all'interno del while, c'è la parte della mia applicazione dove prendo uno ad uno i numeri arrivati dalla seriale e li elaboro. e l'elaborazione richiede per ogni numero, un tempo variabile, da 0 a 700ms. Ricordo che questo è un demo per ricreare l'errore, perchè altrimenti il codice sarebbe stato troppo complesso da leggere e capire, non è la mia vera applicazione. Il delay ha lo scopo di simulare la perdita di tempo dell'ellaborazione dei dati.
E qui c'è la stranezza: se quel delay è di 100ms o inferiore, l'arduino riesce a stamparmi correttamente tutti i numeri che gli arrivano dalla seriale. Se invece il delay supera i 200 ms, si blocca attorno a metà della stringa.
La mia sensazione è come se si saturasse il buffer, ma se non erro il buffer dell'arduino nano dovrebbe aggirarsi attorno ai 4kb, possibile che sia già pieno con solo così pochi dati? Sbaglio qualcosa nella gestione del flusso dalla seriale? C'è qualche timeout/flow controll o simile da togliere/impostare?
Grazie in anticipo.