Questa poi è bella...
mi mancava solo lo ack, e anche questo mi fa dannare
ho cambiato la trasmissione:
void trasmetti(void)
{
messaggio[0] = START;
messaggio[1] = INDIRIZZO;
messaggio[5] = temp % 10 + '0';
temp = temp / 10;
messaggio[4] = temp % 10 + '0';
temp = temp / 10;
messaggio[3] = temp % 10 + '0';
temp = temp / 10;
messaggio[2] = temp % 10 + '0';
messaggio[6] = '\0';
messaggio[6] = checkchar(messaggio);
messaggio[7] = '\0';
// accendo la radio
digitalWrite(AT, 0); // abbasso set
delay(80); //tempo di reazione
digitalWrite(AT, 1); // alzo set, radio accesa
delay(200); // tempo di reazione, adesso è ON
Radio.begin(9600);// sembra sia meglio tenere le velocità casomai un poco piu' basse
delay(100);
for (byte i = 0; i < TENTATIVI; i++)
{
// esegue una serie di tentativi di trasmissione
// esce se riceve esito OK
if (txconfermata(messaggio)); // esegue una trasmissione confermata del messaggio
{
for (byte j = 0; j < 10; j++)
{
digitalWrite(4, 1);
delay(100);
digitalWrite(4, 0);
delay(100);
}
break;
// se confermata esce dal ciclo subito
}
// ok, trasmissione non confermata
// per evitare il pericolo di collisione
// aspetto un tempo proporzionale al mio indirizzo
// un minimo per garantire la fine della trasmissione attuale
delay(100);// che speriamo bastino
// adesso quello che prima stava trasmettendo è fermo
// la parte proporzionale
delay((INDIRIZZO + 1 - 'A') * 10); // 10 millisecondi per A, 20 per B e così via
}
// se sono arrivato qui delle due l'una: una trasmissione confermata
// oppure tanti tentativi ciccati, comunque torno a dormire, sarà la centrale spenta
delay(80);
// spengo la radio
digitalWrite(AT, 0); // abbasso set
delay(80); //tempo di reazione, adesso siamo in AT mode
Radio.print("AT+SLEEP");
delay(80);
// via set
digitalWrite(AT, 1);
// adesso la radio è spenta
che come vedete ri-manda ad una funzione specifica per lo ack
se true esce, dopo una simpatica animazione sul pin 4 (accensione termometro, ma per il debug ho un led in parallelo al termometro
se false ritenta, dopo un tempo di attesa variabile con l'indirizzo (per evitare collisioni)
eccola
bool txconfermata(char messaggio[])
{
// esegue una trasmissione confermata del messaggio
// restituisce true se ha ricevuto ack
// svuoto il buffer di seriale (che dovrebbe essere già vuoto)
delay(2);
// se ci fosse una trasmissione in corso, questo ritardo mi da il tempo di intercettarla
while (Radio.available())
{
Radio.read();
delay(1);
// siccome la velocità di svuotamento è circa uguale a quella di trasmissione
// salvo il caso di 2 trasmissione quasi contemporanee al millisecondo
// se un'altro satellite sta scrivendo, gli lascio il tempo di finire
}
// trasmetto il messaggio
Radio.print(messaggio);
// adesso aspetto un timeout
// e leggo il buffer di seriale
byte stato = 0; // per la macchina a stati che riconosce ack
unsigned long int tempo = millis(); // per il timeout
delay(10); // tempo per la centrale di elaborare il messaggio e ritrasmettere
char messaggiocorretto [] = {START, INDIRIZZO, 'O', 'K'};
while (millis() - tempo < TIMEOUT)
{
if (Radio.available())
{
char cx = Radio.read();
if (cx == messaggiocorretto [stato])
{
stato++;
}
else
{
return 0;
}
if (stato == 4)
{
return 0;
// dovrebbe essere 1
}
}
}
return 0;
}
che come vedete trasmette, e fa il check,
e restituirebbe 0 se no good 1 se good
ho messo sempre 0 per provocare falso per prova
magia: trasmette sempre una volta sola, anche se non ho lo ack
non esegue mai la ritrasmissione, come se la funzione resttuisse sempre 1
opporcaloca, non capisco più...
forse sono troppo stanco
PS naturalmente in origine usavo true e false, ma per disperazione sono arrivato a scrivere 1 e 0
suggerimenti?