ai miei tempi gli attiny funzionavano meglio..............

Che naturalmente è uno dei miei titoli un po’ ad effetto
ma che io abbia un problema con un attiny e che prima andasse bene è vero
premessa:
sempre con il mio collega inganniere stiamo scrivendo il rogramma per i “satelliti” del sistema di rilevazione temperature distribuite (un 5 gradi a te, 12 a quello la, 7 me lo tengo io)
OPS, sbagliavo: sistema distribuito di rilevazione temperatura
è distribuito il sistema, non la temperatura
comunque, causa errato acquisto sono arrivati degli attiny 45, che sapevo essere insufficenti per i miei scopi, ma almeno ho provato a pezzi le varie funzioni del programma
ecco lo scketch che mi fa dannare:

#include <SoftwareSerial.h>
#define RX    1   // *** D1, Pin 6
#define TX    2   // *** D2, Pin 7
#define LED   4   // *** D4, Pin 3
SoftwareSerial Serial(RX, TX);
unsigned long int tempo;
float temp;


// Librerie termometro
//#include <OneWire.h>
//#include <DallasTemperature.h>
//#define ONE_WIRE_BUS 3 // *** D3, Pin 2
// Su il protocollo onewire
//OneWire oneWire(ONE_WIRE_BUS);
// dichiariamo un termometro sul bus unewire
//DallasTemperature sensors(&oneWire);





#define INDIRIZZO 'A'
#define START '#'



#include <avr/sleep.h>
#include <avr/wdt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
volatile boolean f_wdt = 1;



void setup()

{
    pinMode(4, OUTPUT);
    digitalWrite(4, 0);
    Serial.begin(9600);
    setup_watchdog(9); // 8 secondi
    //  sensors.begin();
}


void trasmetti()
{
    digitalWrite(4, 1);
    // al pin 4 un led, per sapere che sta lavorando
    Serial.begin(9600);
    delay(100);
    Serial.write(START);
    Serial.write(INDIRIZZO);
    Serial.println(1250);
    delay(100);
    digitalWrite(4, 0);
}


void loop()
{
    if (f_wdt == 1)
    {
        f_wdt = 0;
        // digitalWrite(4, 1); // energia al termometro
        // delay(100);// per dare il tempo di stabilizzarsi
        // leggo
        // temp = sensors.getTempCByIndex(0);
        // digitalWrite(4, 0);
        trasmetti();
        system_sleep();
    }
}




void system_sleep()
{
    cbi(ADCSRA, ADEN);                   // switch Analog to Digitalconverter OFF
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
    sleep_enable();
    sleep_mode();                        // System sleeps here
    sleep_disable();                     // System continues execution here when watchdog timed out
    sbi(ADCSRA, ADEN);                   // switch Analog to Digitalconverter ON
}


// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii)
{
    byte bb;
    int ww;

    if (ii > 9) ii = 9;

    bb = ii & 7;

    if (ii > 7) bb |= (1 << 5);

    bb |= (1 << WDCE);
    ww = bb;
    MCUSR &= ~(1 << WDRF);
    // start timed sequence
    WDTCR |= (1 << WDCE) | (1 << WDE);
    // set new watchdog timeout value
    WDTCR = bb;
    WDTCR |= _BV(WDIE);
}

// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect)
{
    f_wdt = 1; // set global flag
}

che ho barbaramente copiato in giro, lo ammetto senza alcuna vergogna (sono uno svergognato, lo so)
il problema?
con una attiny 45 va che è una meraviglia, attraverso un link radio HC12, non perde un colpo, che comunque faro un checksum e una ritrasmissione su errore, dopo
oggi arriva un (1) solo uno, ecceccavolo, mi sembrava di averne ordinati di più, ma tantè
dicevo, arriva un attiny 85
vai che ci do che ci do…
cambio impostazione del processore, carico il programma e vai bello…
NON VA
che delusione
avvabbe’, devo mettere clock internal 8Mhz, ettipareva
emmipareva sì, NON VA nemmeno con clock 8Mhz, nel terminale seriale arrivano caratteri non stampabili
ad ogni “raffica” di trasmissione mi arrivano 4 caratteri non stampabili, che il terminale non mi mostra, ogni tanto compare una f o una x, così a caso…
ovvio che ho un problema di timing
ma purtroppo sono arrivato più o meno al confine delle mie conoscenze, mi spiace
chi mi da una spinta?

Oggi nessuna novità, ma ho una roadmap per stasera:
Scarpo via tutta la gestione sleep
Controllo l’aggiornamento del core
Controllo l’aggiornamento della libreria software serial
Elimino le radio e vado di filo
Provo varie velocità
Ma temo che non basti

mi spiace... non posso aiutarti ma seguo :slight_smile:

Grazie, lo stesso.
Nel frattempo ho scoperto un bacherozzo:
Lo attiny non è arrivato a me, ma al mio collega
È smd e lo ha smontato dalla sua scheda, con la pistola ad aria calda e riscaldato su zoccolo dip
Non credo, ma potrebbe aver subito una scaldata e il suo oscillatore andato fuori specifica
Spero arrivino a breve i dip che abbiamo ordinato

OK ieri sera fatto campagna di prove, e tempesta nel cervello con il mio collega
con il bel risultato di un nulla di fatto
core: quello che si trova qui: http://drazzy.com/package_drazzy.com_index.json
ma tanto ho provato anche questo (che è quello con cui son partito):https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json che se ricordo bene è consigliato da Miliani
quindi lato core nulla di fatto
lato libreria, quella che usa è per compilare è
/home/nelson/arduino-1.8.5/portable/packages/ATTinyCore/hardware/avr/1.1.5/libraries/SoftwareSerial/SoftwareSerial.cpp
che credo essere distribuita assieme al core…
vabbe, pive nel sacco
quindi abbiamo comincato a usare il metodo Montacarlo
prova a caso fino a riuscirci (io direi il metodo Disperazione, comunque…)
ecco il programma

#include <SoftwareSerial.h>
#define RX    1
#define TX    2
SoftwareSerial Radio(RX, TX);


int veloc = 10000;

void setup()
{
    Radio.begin(veloc);
}


void loop()
{
    tras(veloc = veloc - 50);
    delay(2000);
}


void tras(int veloc)
{
    Radio.begin(veloc);
    delay(100);

    for (byte i = 0; i < 4; i++)
    {
        Radio.println(veloc);
    }

    Radio.println("The quick brown fox jump over the lazy dog");
}

Edit, ho messo il programma giusto, che stamane nella fretta mi son sbagliato
che come vedete prova tutte le velocità
rispetto al programma originale ho anche usato pin differenti, (sono i ddue inutilizzati in programmazione), per non dover togliere il chip dal programmatore, ho aggiunto due fili al programmatore e ho fatto la connessione seriale da li
ho eliminato le radio e ci siamo armati di grappa e pazienza
a 4800 bps ha cominciato a vedersi quelcosa, offuscato da errori e fumi di grappa
il meglio è stato intorno a 4400 bps, pochi errori (fumi aumentati causa festeggiamenti, ma questo è un fattore positivo)
rimessa la radio invece il minimo degli errori sembra intorno a 4500 4600 bps
quindi: ocillatore interno dell’arduino pià lento del previsto, radio un po’ “rigida” nell’accettare trasmissioni senza un bel timing,
ma sopratutto: un fattore 2 che non si capisce da dove arriva, solo per attini 85, dato che attiny 45 si comporta come dovrebbe
ho dato uno sguardo in giro, per i vari file puntoacca, ma non ho trovato errori evidenti, speravo una cosa del tipo #define 8MHZ_CPU 4000000 che mi sarebbe molto piaciuto
invece ad un primo controllo sembra tutto regolare, ma solo per il 85 devo scrivere velocità dimezzate rispetto a quello che voglio

Invece un'altra considerazione:
io speravo di accendere il DS18B20 quando mi serviva, per risparmiare pile
sembra che il DS18B20 debba essere acceso prima della misura, ben prima, se lo accendo 2 secondi prima della misura mi restituisce misure ciccate (85 che non ricordo cosa significhi, -127 sarebbe sensore assente, ma 85 non ricordo)
ieri era tardi, non sono andato mlto avanti con le prove, ma se lo accendo 10 secondi prima fa letture OK, 2 secondi cicca
certo che accendere 10 secondi ogni minuto per fare una lettura che dura 750mS non è grandissimo risparmio...
se ricordo bene gli LM35 vanno a regime in microsecondi....
vabbe' ormai abbiao scelto
comunque, per prova abbiamo usato delle pile 18650 e sembra che vadano benino
anche se il target continua ad essere 3 belle stilo alcaline, a prova di moglie: non va? cambia la pila

Una volta ho vissuto una simile disavventura.
Nel mio caso, però, la soluzione era semplice: avevo dimenticato di fare "scrivi il bootloader" :slight_smile:

Prova a fare un blink del led con periodo 1 secondo, così saprai se la velocità è quella prevista.

Per paulus:
io so di aver scritto il bootloader, ma adesso vengono anche dei dubbi, sarà andato a buon fine oppure mi ricordo male?
comunque un secondo di lampeggio è un secondo di lampeggio, questa prova la avevo fatta
vabbe', dai che oggi finalmente sono arrivati i "miei" attiny 85, quindi riprovo da zero,

OK, attiny nuovo vita nuova
nessun probelma di timing con questo, anche se dopo aver fatto qualche prova credo che convenga tenere un qualche percento più bassa la velocità, la trasmissione va bene lo stesso ma sembra che ci sia più margine d’errore verso il basso che verso l’alto
diamo per assodato che lo attiny precedente avessa qualche problema, non saprei che altro dire
ecco il risultato della serata di programmazione disperata

#include <SoftwareSerial.h>
#define RX    1   // *** D1, Pin 6
#define TX    2   // *** D2, Pin 7
#define LED   4   // *** D4, Pin 3
#define AT    0   // *** D0, pin 4
SoftwareSerial Radio(RX, TX);
unsigned long int tempo;
int temp; // temperatura in centesimi di grado
int oldt; // vecchia temperatura


// Librerie termometro
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3 // *** D3, Pin 2
// Su il protocollo onewire
OneWire oneWire(ONE_WIRE_BUS);
// dichiariamo un termometro sul bus unewire
DallasTemperature sensors(&oneWire);

#define TEMPOSTABILE 20000


#define INDIRIZZO 'A'
#define START '#'
char messaggio[] = "#A0123x"; // inizializzare stringa di trasmissione


#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif


EMPTY_INTERRUPT(WDT_vect)




void setup(void)
{
    pinMode(4, OUTPUT);
    pinMode(AT, OUTPUT);
    digitalWrite(4, 0);
    digitalWrite(AT, 1);
    Radio.begin(9600);// sembra sia meglio tenere le velocità casomai un poco piu' basse
}


void loop(void)
{
    digitalWrite(4, 1); // energia al termometro
    delay(TEMPOSTABILE);// per dare il tempo di stabilizzarsi
    sensors.begin();
    // leggo
    sensors.requestTemperatures(); // Send the command to get temperatures
    temp = sensors.getTempCByIndex(0) * 100;

    if (temp < 0)
    {
        temp = 0;
    }

    if (temp > 9000)
    {
        temp = 9000;
    }

    digitalWrite(4, 0);

    // spengo il termometro
    // ora, solo se la temperatura è cambiata
   
    if (abs(temp - oldt) > 50)
    {
        // solo se è cambiata piu' di mezzo grado
        oldt = temp;
        trasmetti();
    }

    Sleep_now(1, 7); //quanti cicli di sleep, divisore
    // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
    // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
}




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);
    Radio.print(messaggio);
    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(40);
    // via set
    digitalWrite(AT, 1);
    // adesso la radio è spenta
}

void Config_wdt(byte timeout)
{
    cli();
    wdt_reset();                  // reset watchdog timer
    MCUSR &= ~(1 << WDRF);        // clear reset flag
    WDTCR = (1 << WDE) | (1 << WDCE); // enable watchdog
    WDTCR = (1 << WDIE) | timeout; // watchdog interrupt instead of reset
    //+reset, timeout can be 15,30,60,120,250,500ms or 1,2,4,8s
    sei();
}

void Sleep_now(byte i, byte timeout)
{
    // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
    // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
    Config_wdt(timeout);

    for (byte y = i; y > 0; --y)
    {
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // set type of sleepmode
        power_all_disable();                  // disable unneeded loads
        wdt_reset();                          // timer should start at zero
        sleep_enable();                       // approach sleep mode
        sleep_mode();                         // enter sleep mode (confirm)
        sleep_disable();                      // entrance point when woken up
        power_all_enable();                   // re-enable the loads
    }
}


char checkchar(char messaggio[])
{
    // restituisce il carattere di controllo per il messaggio in ingresso
    // una cosa semplice, non troppo elaborata
    byte appoggio = 0;
    byte index = 0;

    while (messaggio[index])
    {
        appoggio = ((appoggio >> 1) | (appoggio << 7)) ^ messaggio[index++];
    }

    return (char)(appoggio % 93) + 33;
}

che manda in sleep lo attiny per un tempo programmabile
dopo lo sleep legge la temperatura, preaccendendo il termometro per 20 secondi (essi’ un’eternità, ma tant’è)
spegne il termometro
solo se la temperatura è cambiata, ricrea la stringa di trasmissione: START INDIRIZZO valore e checksum
sveglia la radio dal sonno
trasmette
e rimanda a nanna la radio

manca da sviluppare la parte che ritrasmette in mancanza di un ack dalla centrale
quella domani, oggi sono steso
buonanotte a voi del forum, e grazie per l’aiuto

Bene, a me piacciono molto gli Attiny85: piccoli, economici, montaggio TH, li alimenti anche con un colpo di tosse.
Recentemente, tanto per raccontarne una, un modesto Attiny mi ha risolto un guaio su un aristocratico Teensy 3.6:
la Teensy è una bella scheda ma è un po' schizzinosa per l'alimentazione (sarà un retaggio aristocratico) e litigava con un alimentatore TDK-lambda che per i primi secondi dopo l'avvio invia un po' di spazzatura sulle linee di alimentazione.
Anche l'uso del "power good" forniva risultati imprevedibili e nulla di economico e compatto sembrava in grado di filtrare decentemente.
Il nostro modesto e popolano Attiny, con l'aiuto di un paio di componenti, è riuscito a metterli d'accordo fornendo l'alimentazione alla scheda Teensy dopo la perfetta stabilizzazione delle linee. Avrei potuto ottenere lo stesso risultato con un circuito di ritardo dopo il power good, ma con un sistema meno flessibile e più ingombrante.

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?

madonna che errore da principiante:

if( . . . . . );

unica scusante ero stanco.....
naturalmente me ne sono accorto subio DOPO aver postato......
mannaggia che figura
adesso sembra andare, metto a posto la centrale e stasera posto i definitivi

Prima legge di Nelson, che sono io, sugli if
Quando fai un if metti anche la sua else, anche se vuota, se ti scappa un pontoevirgola in compilazione te lo dice

Standardoil:
Prima legge di Nelson, che sono io, sugli if
Quando fai un if metti anche la sua else, anche se vuota, se ti scappa un pontoevirgola in compilazione te lo dice

:smiley: :smiley:

ecco il succo del mio cerebro, non è definitivo, non ci ho tolto i bacherozzi, ma cominciamo con questo
Satelliti, tutti uguali, cambia solo la loro #define

#include <SoftwareSerial.h>
#define RX    1   // *** D1, Pin 6
#define TX    2   // *** D2, Pin 7
#define LED   4   // *** D4, Pin 3
#define AT    0   // *** D0, pin 4
SoftwareSerial Radio(RX, TX);
unsigned long int tempo;
int temp; // temperatura in centesimi di grado
int oldt; // vecchia temperatura


// Librerie termometro
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3 // *** D3, Pin 2
// Su il protocollo onewire
OneWire oneWire(ONE_WIRE_BUS);
// dichiariamo un termometro sul bus unewire
DallasTemperature sensors(&oneWire);

#define TEMPOSTABILE 20000


#define INDIRIZZO 'A'
#define START '#'
char messaggio[] = "#A0123x"; // inizializzare stringa di trasmissione
#define TIMEOUT 1000 // timeout per ricevere ack;
#define TENTATIVI 3 // numero di ritentativi di trasmissione


#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif


EMPTY_INTERRUPT(WDT_vect)




void setup(void)
{
    pinMode(4, OUTPUT);
    pinMode(AT, OUTPUT);
    digitalWrite(4, 0);
    digitalWrite(AT, 1);
}


void loop(void)
{
    digitalWrite(4, 1); // energia al termometro
    delay(TEMPOSTABILE);// per dare il tempo di stabilizzarsi
    sensors.begin();
    // leggo
    sensors.requestTemperatures(); // Send the command to get temperatures
    temp = sensors.getTempCByIndex(0) * 100;

    if (temp < 0)
    {
        temp = 0;
    }

    if (temp > 9000)
    {
        temp = 9000;
    }

    digitalWrite(4, 0);

    // spengo il termometro
    // ora, solo se la temperatura è cambiata
    if (abs(temp - oldt) > 50)
    {
        // solo se è cambiata piu' di mezzo grado
        oldt = temp;
        trasmetti();
    }

    Sleep_now(1, 7); //quanti cicli di sleep, divisore
    // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
    // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
}


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
        {
            break;
        }

        // se confermata esce dal ciclo subito
        // male, 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
}

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 1;
                // dovrebbe essere 1
            }
        }
    }

    return 0;
}
void Config_wdt(byte timeout)
{
    cli();
    wdt_reset();                  // reset watchdog timer
    MCUSR &= ~(1 << WDRF);        // clear reset flag
    WDTCR = (1 << WDE) | (1 << WDCE); // enable watchdog
    WDTCR = (1 << WDIE) | timeout; // watchdog interrupt instead of reset
    //+reset, timeout can be 15,30,60,120,250,500ms or 1,2,4,8s
    sei();
}
void Sleep_now(byte i, byte timeout)
{
    // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
    // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
    Config_wdt(timeout);

    for (byte y = i; y > 0; --y)
    {
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // set type of sleepmode
        power_all_disable();                  // disable unneeded loads
        wdt_reset();                          // timer should start at zero
        sleep_enable();                       // approach sleep mode
        sleep_mode();                         // enter sleep mode (confirm)
        sleep_disable();                      // entrance point when woken up
        power_all_enable();                   // re-enable the loads
    }
}
char checkchar(char messaggio[])
{
    // restituisce il carattere di controllo per il messaggio in ingresso
    // una cosa semplice, non troppo elaborata
    byte appoggio = 0;
    byte index = 0;

    while (messaggio[index])
    {
        appoggio = ((appoggio >> 1) | (appoggio << 7)) ^ messaggio[index++];
    }

    return (char)(appoggio % 93) + 33;
}

e questo è dopo la prima passata col Neocid, spero che di bacherozzi non ce ne siano più

// Non e' piu' stagione di riscaldamento,
// di Nelson StandardOil e il suo collega anonimo
#define INDIRIZZO 'A'
// define spostata qui per trovarla facilmente al cambio di satellite


#include <SoftwareSerial.h>
#define RX    1   // *** D1, Pin 6
#define TX    2   // *** D2, Pin 7
#define TER   4   // *** D4, Pin 3
#define AT    0   // *** D0, pin 4
SoftwareSerial Radio(RX, TX);

int temp; // temperatura in centesimi di grado
int oldt; // temperatura precedente, per trasmettere solo se cambia
#define SOGLIA 50 // valore di soglia per la trasmissione nuova temperatura


// Librerie termometro
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3 // *** D3, Pin 2
// Su il protocollo onewire
OneWire oneWire(ONE_WIRE_BUS);
// dichiariamo un termometro sul bus unewire
DallasTemperature sensors(&oneWire);
#define TEMPOSTABILE 20000
// 20 secondi per stabilizzare il termometro...........

// per la comunicazione
#define START '#'
char messaggio[] = "#A0123x"; // inizializzare stringa di trasmissione
#define TIMEOUT 1000 // timeout per ricevere ack;
#define TENTATIVI 3 // numero di ritentativi di trasmissione


#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif


EMPTY_INTERRUPT(WDT_vect)

void setup(void)
{
    pinMode(TER, OUTPUT);
    pinMode(AT, OUTPUT);
    digitalWrite(TER, 0);
    digitalWrite(AT, 1);
}


void loop(void)
{
    digitalWrite(TER, 1); // energia al termometro
    delay(TEMPOSTABILE);// per dare il tempo di stabilizzarsi
    sensors.begin();
    // leggo
    sensors.requestTemperatures(); // Send the command to get temperatures
    temp = sensors.getTempCByIndex(0) * 100;

    if (temp < 0)
    {
        temp = 0;
    }

    if (temp > 9000)
    {
        temp = 9000;
    }

    // spengo il termometro
    digitalWrite(TER, 0);

    // ora, solo se la temperatura è cambiata oltre SOGLIA
    if (abs(temp - oldt) > SOGLIA)
    {
        oldt = temp;
        trasmetti(temp);
    }

    Sleep_now(1, 7); //quanti cicli di sleep, divisore
    // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
    // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
}


void trasmetti(int temp)
{
    //variabile locale stesso nome di variabile globale, per non alterare la globale
    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); // forse non serve questo delay

    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
        {
            break;
        }

        // se confermata esce dal ciclo subito
        // se invece sono arrivato fin qui...
        // male, 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, spero
        // 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: si vede che 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); // anche questo delay forse non serve
    // via set
    digitalWrite(AT, 1);
    // adesso la radio è spenta
}

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, ma...)
    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
        // se un'altro satellite sta scrivendo, gli lascio il tempo di finire
        // salvo il caso di 2 trasmissioni quasi contemporanee al millisecondo
    }

    // 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, ottenuto per tentativi
    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 1;
                // dovrebbe essere 1
            }
        }
    }

    return 0; // giusta regola qui ci dovremmo arrivare solo in caso si timeout
}


void Config_wdt(byte timeout)
{
    cli();
    wdt_reset();                      // reset watchdog timer
    MCUSR &= ~(1 << WDRF);            // clear reset flag
    WDTCR = (1 << WDE) | (1 << WDCE); // enable watchdog
    WDTCR = (1 << WDIE) | timeout;    // watchdog interrupt al posto di reset
    //+reset, timeout can be 15,30,60,120,250,500ms or 1,2,4,8s
    sei();
}
void Sleep_now(byte i, byte timeout)
{
    // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
    // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
    Config_wdt(timeout);

    for (byte y = i; y > 0; --y)
    {
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // set type of sleepmode
        power_all_disable();                  // disable unneeded loads
        wdt_reset();                          // timer should start at zero
        sleep_enable();                       // approach sleep mode
        sleep_mode();                         // enter sleep mode (confirm)
        sleep_disable();                      // entrance point when woken up
        power_all_enable();                   // re-enable the loads
    }
}
char checkchar(char messaggio[])
{
    // restituisce il carattere di controllo per il messaggio in ingresso
    // una cosa semplice, non troppo elaborata
    byte appoggio = 0;
    byte index = 0;

    while (messaggio[index])
    {
        appoggio = ((appoggio >> 1) | (appoggio << 7)) ^ messaggio[index++];
    }

    return (char)(appoggio % 93) + 33;
}

con questo il progetto è quasi completo, manca solo di mettere le pile alcaline, e costruire qualche satellite
credo però che aprirò un post nuovo per il problema del termometro, dei suoi tempi, intendo