Ciao a tutti!
Ho un problema nel capire perché la seguente espressione non funziona se si usano il tipo di dato "Byte" (lo sketch è diviso in 3 file):
File principale:
#define Led_Debug 13
#define Cycle 100
unsigned long Time_Out_A = 10;
unsigned long Counter_A;
unsigned long Last_Counter_A;
unsigned long Numero_A;
byte Time_Out_B = 10; //se la imposto ad unsigned long funziona
byte Counter_B;
byte Last_Counter_B;
byte Numero_B;
bool Led;
void setup() {
delay(10);
Serial.begin(115200);
pinMode(Led_Debug, OUTPUT);
Counter_A = 95;
Counter_B = 95;
delay(100);
}
void loop() {
//Programma_A(); //Funzionante
Programma_B(); //Non funzionante
}
Programma A:
void Programma_A() {
Timer_A();
Last_Counter_A = Counter_A;
do {
Timer_A();
Numero_A = Counter_A - Last_Counter_A;
Serial.print("Counter : ");
Serial.println(Counter_A);
Serial.print("LCounter : ");
Serial.println(Last_Counter_A);
Serial.print("Numero : ");
Serial.println(Numero_A);
Serial.println("------------------");
delay(500);
} while (Counter_A - Last_Counter_A < Time_Out_A);
Serial.println("END");
Serial.println("------------------");
delay(1000);
}
void Timer_A() {
if (Counter_A < Cycle) {
Counter_A++;
} else {
Counter_A = 0;
}
}
Programma B (non funzionante):
void Programma_B() {
Timer_B();
Last_Counter_B = Counter_B;
do {
Timer_B();
Numero_B = Counter_B - Last_Counter_B;
Serial.print("Counter : ");
Serial.println(Counter_B);
Serial.print("LCounter : ");
Serial.println(Last_Counter_B);
Serial.print("Numero : ");
Serial.println(Numero_B);
Serial.println("------------------");
delay(500);
} while (Counter_B - Last_Counter_B < Time_Out_B);
Serial.println("END");
Serial.println("------------------");
delay(1000);
}
void Timer_B() {
if (Counter_B < Cycle) {
Counter_B++;
} else {
Counter_B = 0;
}
}
Questo programma emula la funzione "timeRead()" della classe "Stream.cpp" perché mi era sorto un dubbio sul fatto che se "millis()" si resetta e torna a zero succede che il tempo minimo per la lettura dei dati seriali si blocca e fa disastri ecc ecc...
Perché ho creato un orologio che scrive via seriale l'ora in vari terminali usando una funzione che dipende da "timeRead()" e di conseguenza "millis()"... anche se i messaggi hanno sempre il carattere di terminazione quindi dovrei stare tranquillo... cioè spero che mi duri più di 50 giorni... viste che è un orlogio...
Praticamente ho capito, da tale programma, tutto funziona, dove la funzione "Timer_#" mi emula l'incremento del contatore in "millis()" e poi con la variabile "Counter" ottengo il numero del tempo fittizio.
Codice della funzione "timeRead()":
int Stream::timedRead()
{
int c;
_startMillis = millis();
do {
c = read();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
Ho creato il blocco do, while() come nella funzione "timeRead()" per vedere cosa succede se la variabile "Counter" è minore della variabile "Last_Counter":
} while (Counter_B - Last_Counter_B < Time_Out_B);
Ho letto in dei libri che usando tipi di dato senza segno la sottrazione per numeri negativi su numeri interi genera un rollover e infatti non capitato situazioni problematiche se uso i tipi di dato "unsigned long" come nella classe Stream.
PROBLEMA:
Nello sketch il "Programma_B" non funziona correttamente cioè è identico a il "Programma_A" solo che le variabili sono di tipo "byte".
Per logica un "byte" dovrebbe essere un "unsigned char" e quindi senza segno da 0 a 255.
Noto che l'espressione matematica all'interno del "while" non viene interpretata correttamente.
Infatti ho la variabile "Numero" che giustamente mi dà il risultato coretto della sottrazione applicando il rollover.
PS: nel "void setup()" i "Counter_#" vengono settati a valore 95 per vedere da subito se
dopo l'azzeramento la sottrazione avviene con successo tramite il monitor seriale...
Ma stranamente la espressione diretta scritta cosi non funziona, succede che il risultato della sottrazione grazie alla variabile "Numero_B" è corretto:
Counter = 0
Last Counter = 96
Numero = 160
solo che poi la variabile "Numero_B" continua ad aumentare, quando 160 non è minore della varibile "Time_Out_B" che ha il valore 10, dovrebbe uscirmi dal ciclo e non lo fa rimane dentro
} while (Counter_B - Last_Counter_B < Time_Out_B);
Se invece uso la variabile "Numero_B" come memoria tampone tutto funziona:
Numero_B = Counter_B - Last_Counter_B;
} while (Numero_B < Time_Out_B);
E non capisco il perché...
Ho scoperto anche che se la varibile "Time_Out_B" la trasformo in "unsigned long" funziona.
Ho provato a cambiarla anche con un "#define" e non funziona... come se il compilatore fa delle cose strane
GRAZIE A TUTTI DELL' AIUTO!!