Campionare il sensore di temperatura DS18B20 1Wire con l'ESP8266, RTOS

Capionare il sensore di temperatura DS18B20

Introduzione al sensore di temperatura DS18B20

È un sensore di temperatura, prodotto da Maxim, che utilizza il bus one-wire. Ha una precisone di 0.5°C. L'ESP8266 con FreeRTOS ha già il software necessario, per campionare il sensore di temperatura e si trova già un esempio di codice all'interno del repository stesso.

Schema circuitale

Lo schema mostra come collegare i sensori di temperatura. Sul bus è evidente la presenza di una resistenza di pull-up. La resistenza è da 4,7 KOhm. La topologia del bus potrebbe essere molto grande,  anche decine di metri.  Senza dilungarmi allego il link all'Application note di Maxim: https://www.maximintegrated.com/en/app-notes/index.mvp/id/148.

Codice sorgente di esempio

Un esempio di codice possiamo trovarlo nel repository all'interno della della cartellaexamples/ds18b20_onewire : https://github.com/SuperHouse/esp-open-rtos.

#define SENSOR_GPIO 13      // Definisce il GPIO da utilizzare come BUS onewire
#define MAX_SENSORS 8       // Numero massimo di sensori sul bus

// Numero di letture oltre il quale rieffettuare il rescan del bus alla ricerca di nuovi/abbandono di vecchi.
#define RESCAN_INTERVAL 8
   
#define LOOP_DELAY_MS 250 // Delay del bus.


// callback del task di lettura
void print_temperature(void *pvParameters) {
    ds18b20_addr_t addrs[MAX_SENSORS];
    float temps[MAX_SENSORS];
    int sensor_count;
    
    // Imposto il GPIO in pull-up
    gpio_set_pullup(SENSOR_GPIO, true, true);

    while(1) {
        // Scansiono il bus onewire alla ricerca di periferiche collegate al bus.
        sensor_count = ds18b20_scan_devices(SENSOR_GPIO, addrs, MAX_SENSORS);

        if (sensor_count < 1) {
            printf("\nNo sensors detected!\n");
        } else {
            printf("\n%d sensors detected:\n", sensor_count);
            if (sensor_count > MAX_SENSORS) sensor_count = MAX_SENSORS;

            for (int i = 0; i < RESCAN_INTERVAL; i++) {
                // Apposita funzione effettua la lettura di tutti i sensori
                ds18b20_measure_and_read_multi(SENSOR_GPIO, addrs, sensor_count, temps);

                // Per ogni valore letto, stampo Indirizzo del sensore e temperatura letta.
                // Questo esempio converte anche in °F.
                for (int j = 0; j < sensor_count; j++) {
                    uint32_t addr0 = addrs[j] >> 32;
                    uint32_t addr1 = addrs[j];
                    float temp_c = temps[j];
                    float temp_f = (temp_c * 1.8) + 32;
                    printf("  Sensor %08x%08x reports %f deg C (%f deg F)\n", addr0, addr1, temp_c, temp_f);
                }
                printf("\n");

                // E' importante sottolineare che questo Task non sara' eseguito ogni 250ms,
                // perchè in realtà il tempo di esecuzione cosiste nel tempo di lettura dei
                // sensori più 250ms.
                // Esiste un'apposita funzione di freeRTOS per effettuare un'operazione ogni X ms
                // https://www.freertos.org/vtaskdelayuntil.html

                vTaskDelay(LOOP_DELAY_MS / portTICK_PERIOD_MS);
            }
        }
    }
}