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

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