Serveur de température 1wire avec un Arduino
Pour gérer mes sondes de températures 1wire (DS18b20) en un point unique et de manière propre, j’ai créé un serveur à base d’Arduino qui créé une page json avec la température de toutes les sondes raccordées. Explications.
Introduction
Afin de faire un projet propre, j’ai utilisé 3 cartes différentes :
- 1 arduino Uno
- 1 carte Ethernet W5100 pour Arduino
- 1 carte prototype DFrobot
Ces cartes sont empilées les unes sur les autres afin de faire un bloc unique qui sera voué à aller dans un tableau électrique, sur un rail din (le support DIN sera imprimé en 3D.
Une fois les cartes empilées, nous disposerons des ports 2-3-5-6-7-8-9, les autres ports sont utilisées pour le RJ45 (liaison SPI sur 10 à 13) et carte SD (pin 4). Cela nous fera alors 7 ports utilisables pour connecter nos sondes DS18b20.
Avec la carte proto, on a l’avantage d’avoir des lignes de 5V et de GND, ce qui permet de câbler les résistances de manière très propre.

Cablage sonde DS18b20
Une sonde DS18B20 dispo de 3 pin, qui doivent être câblées comme suit :
- gauche : GND
- milieu : à l’arduino et au +5V via une résistance de 4,7 kohms
- droite : +5V

Les sondes DS18b20 peuvent se mettent en parallèle sur un bus de données et communiquer via 1 port unique. Mais pour récolter les valeurs de manière précise, cela signifie de connaitre les id de tous les id de chaque sonde et de les mettre en dur dans le code.
J’ai donc pris le parti de dire : 1 port arduino = 1 sonde. Cela permet de gérer le résultat sans aucun problème. La carte prototype sert donc à ramener toutes les résistances de 4,7 kohms et les leds d’affichage que je voulais faire apparaitre très facilement. Le câblage est facilité et le résultat propre et net !
Assemblage
Plutôt qu’un long discours, je vous met une série de photo.


J’ai demandé à Madame de m’imprimer en 3D un support pour rail DIN, vous pourrez trouver le modèle pour arduino uno ici.



L’arduino sera alimenté via un transfo 12V 1A, ce qui sera largement suffisant. Vu qu’il est en tableau électrique, c’est un moyen propre et facile d’alimentation.
Le code source
Il faut d’abord commencer par inclure les fichiers entête nécessaires (voir l’article sur la station météo pour ajouter des librairies dans Arduino)
#include <Ethernet.h> #include <DallasTemperature.h> #include <OneWire.h>
Ensuite, il faut assigner une adresse mac à votre carte Arduino. Cela permettra ensuite de faire une réservation DHCP sur votre box/routeur pour retrouver facilement votre Arduino. On déclare ensuite un serveur Ethernet sur le port 80
//Gestion web server byte mac[6] = { 0xBE, 0xEF, 0x00, 0xFD, 0xC7, 0x93 }; char macstr[18]; EthernetServer server(80);
Je déclare ensuite mes 4 LEDS pour pouvoir les utiliser ensuite. Les 4 LEDS sont branchées sur les 4 ports analogiques, je garde les pin digitales pour les sondes DS18b20.
const int LED_NETWORK = A0; const int LED_CONNECTION = A1; const int LED_ERROR_ACTIVITY = A2; const int LED_OK_ACTIVITY = A3; int pin[4]={A0,A1,A2,A3};
Viens ensuite la fonction setup où l’on va initier la mac address, démarrer le serveur web et allumer les leds correspondantes si le serveur est bien démarré avec une IP.
void setup() { Serial.begin(9600); pinMode(LED_CONNECTION, OUTPUT); pinMode(LED_NETWORK, OUTPUT); pinMode(LED_ERROR_ACTIVITY, OUTPUT); pinMode(LED_OK_ACTIVITY, OUTPUT); snprintf(macstr, 18, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); Serial.print("DHCP : "); Serial.println(macstr); if(!Ethernet.begin(mac)){ Serial.println("Network failed"); } else{ //Initialisation server.begin(); Serial.println(Ethernet.localIP()); Serial.println(Ethernet.gatewayIP()); digitalWrite(LED_CONNECTION, LOW); digitalWrite(LED_NETWORK, HIGH); digitalWrite(LED_ERROR_ACTIVITY, LOW); digitalWrite(LED_OK_ACTIVITY, LOW); delay(1000); } }
Viens ensuite la boucle qui est commentée pas à pas. Elle va générer une page formattée en json avec le résultat des 7 sondes DS18b20.
void loop() { //on déclare le serveur web disponible EthernetClient client = server.available(); //Si un client appelle la page if (client) { boolean currentLineIsBlank = true; //Tant que le client est connecté while (client.connected()) { if (client.available()) { //Allumage led connexion page web digitalWrite(LED_CONNECTION, HIGH); char c = client.read(); if (c == '\n' && currentLineIsBlank) { //création du code HTML pour générer un JSON client.println("HTTP/1.1 200 OK"); client.println("Content-Type: application/json"); client.println("Access-Control-Allow-Origin: *"); client.println(); client.print("[{"); //boucle pour parcourir les ports 2 à 9 sur l'arduino for(int i=2;i<10;i++){ //initialisation 1wire OneWire oneWire(i); DallasTemperature sensors(&oneWire); //on démarre la capture de données du capteur sensors.begin(); sensors.requestTemperatures(); // Send the command to get temperatures //on prépare le code json client.print("\"TempOneWire"); client.print(i); client.print("\":"); //si on a -127, c'est que rien n'est connecté if(sensors.getTempCByIndex(0) ==-127){ client.print("\"N/A\""); //on affiche la led rouge 300ms digitalWrite(LED_ERROR_BME, HIGH); delay(300); digitalWrite(LED_ERROR_BME, LOW); } else{ //recupération de la température client.print(sensors.getTempCByIndex(0)); //on affiche la led verte 300ms digitalWrite(LED_OK_BME, HIGH); delay(300); digitalWrite(LED_OK_BME, LOW); } client.print(","); } //vu que l'on est dans une boucle et qu'il faut terminer le json sans virgule, on rajoute une info fixe : ici l'adresse ip client.print("\"IP\":"); client.print("\""); client.print(Ethernet.localIP()); client.print("\""); client.print("}]"); delay(1000); //Extinction led connexion page web digitalWrite(LED_CONNECTION, LOW); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } delay(1); client.stop(); } }
Astuce : Vous pouvez retrouver les sources du projet ici sur mon espace Bitbucket.
Résultat
Voici le résultat visuel lorsque l’on appelle la page (dans mon cas, http://192.168.1.5)

C’est alors très facile de récupérer les valeurs et d’alimenter n’importe quel serveur domotique !
Bon bricolage.
Bonjour
quelle est la longueur maxi de fil entre une sonde de température DS18b20 et l’arduino?
Cordialement
Bressy Frederic
Je suis déjà monté à 20m sans problème, mais il faut bien avoir une alimentation externe pour le 5V.