Dâabord un peut de thĂ©orie
Généralité sur le Bus 1-Wire
Le bus 1-Wire (ou OneWire) est un bus conçu par Dallas Semiconductor. Il permet de connecter et de faire dialoguer entre eux des circuits sur un seul fil. Il fonctionne suivant le principe maßtre / esclave. Il y a donc un seul maßtre, qui pourra dialoguer avec un ou plusieurs esclaves.
Le niveau de tension normalisé sur ce bus est +5V (Standard TTL). Ce bus supporte une topologie de réseau1 en série, parallÚle ou étoile.
Dans le cas des composants Dallas la tension du bus doit ĂȘtre comprise entre 3 et 5V. Cela permet de les utiliser dans aucune adaptation complĂ©mentaire, aussi bien sur des Arduino UNO en 5V, quâavec des Arduino Mini en 3,3V comme pour les Raspberry-Pi qui travaillent aussi en 3,3V pour les GPIO.
Sur le schĂ©ma ci-dessus, on voit que le bus 1-wire est reliĂ© au +3,3 V par une rĂ©sistance de tirage de 4,7 kΩ. En fonction de la longueur des fils de liaison, il sera parfois nĂ©cessaire dâajuster sa valeur. Tous les appareils sont branchĂ©s en parallĂšle sur le bus et câest en mettant (ou pas) leur sortie Ă la masse quâils envoient les donnĂ©es au maĂźtre.
La topologie dâun rĂ©seau correspond Ă son architecture physique. En ce sens ou leur structure dĂ©termine leur type.
Raccordement au Filaire au Bus OneWire en mode Standard :
Lâavantage de ce bus est quâil peut ĂȘtre utilisĂ© en mode « parasite » (alimentation Ă partir du fil de donnĂ©es). Cela permet dâutiliser seulement 2 fils (et non un seul comme le nom le laisse supposer), un fil de donnĂ©es et un fil de masse.
Raccordement des abonnés du Bus OneWire en mode Parasite :
Dans le mode parasite, lâesclave est connectĂ© en reliant ses broches dâalimentation ensemble et en les reliant Ă la masse. Il nây a plus besoin dans ce cas que de deux fils pour assurer la liaison avec les esclaves connectĂ©s au bus 1-wire.
Lorsque le bus est au niveau 1, un condensateur interne au composant esclave est chargĂ©, et câest lui qui assurera lâalimentation du composant pendant que le niveau du bus sera bas.
Chaque circuit possĂšde une adresse physique unique, gravĂ©e dans la puce Ă la fabrication. Câest une des raisons expliquant la rĂ©ticence de Dallas Ă permettre la crĂ©ation dâesclave 1-Wire autres que ceux quâil produit : avoir la maĂźtrise de lâidentification des esclaves du bus.
Généralement utilisé pour des mesures de températures, il existe une gamme complÚte de composants compatibles.
Principe du protocole 1-Wire
La communication sur le bus 1-Wire est caractĂ©risĂ©e par un ensemble de « pulse » ou changement dâĂ©tat. LâĂ©tat par dĂ©faut de la ligne data est +5V, ce qui permet dâalimenter les diffĂ©rents composants Ă partir de la ligne data en mode parasite.
Avant toute communication, le maĂźtre met le bus Ă lâĂ©tat bas (0V) pendant 480 ÎŒs pour faire une initialisation (reset) des composants connectĂ©s. AprĂšs un dĂ©lai de 15 Ă 60 ÎŒs, le ou les esclaves connectĂ©s, forcent le bus Ă lâĂ©tat bas pendant 60 Ă 240 ÎŒs pour signaler leur prĂ©sence. Le maĂźtre est alors informĂ© des esclaves connectĂ©s sur le bus.
Chaque circuit possĂšde une adresse physique unique, gravĂ©e dans la puce Ă la fabrication. Cette adresse est constituĂ©e de 64 bits soit 8 octets. Le premier octet dĂ©termine le type de famille auquel appartient le circuit. Les 6 octets suivants, constituent le code propre du circuit. Le dernier octet est le CRC. Câest un octet de contrĂŽle calculĂ© Ă partir des 56 bits prĂ©cĂ©dents.
Toute transaction entre un maĂźtre et un ou plusieurs esclaves, dĂ©bute par une initialisation, constituĂ©e par lâenvoi du pulse de Reset par le maĂźtre. Le maĂźtre doit ensuite envoyer une commande de type ROM qui est propre au protocole 1-Wire, et que tous les circuits de ce type vont reconnaĂźtre. Cela va permettre entre autre de sĂ©lectionner un circuit parmi les diffĂ©rents esclaves qui ont rĂ©pondu prĂ©sents au pulse de Reset. Le dialogue et lâĂ©change de donnĂ©es pourra ensuite commencer, entre le maĂźtre et lâesclave sĂ©lectionnĂ©.
Pour Ă©mettre un bit sur le bus, le maĂźtre force le bus à « 0 » pendant 1 Ă 15 ÎŒs. Lâesclave va lire le bus entre 15 et 45 ÎŒs aprĂšs le front descendant ( valeur typique 30 ÎŒs).
Si on veut Ă©mettre un « 1 », il faut repasser le bus à « 1 » immĂ©diatement, et ne plus rien faire jusquâĂ t = 60 ÎŒs.
Pour Ă©mettre un « 0 » il faut laisser le bus à « 0 » jusquâĂ t = 60 ÎŒs, puis repasser le bus à « 1 ».
La durĂ©e total dâun bit est donc de 60us, ce qui donne une vitesse de communication maximale de 16kbits/s.
AprĂšs la rĂ©ception dâune commande du maĂźtre, lâesclave peut renvoyer des donnĂ©es. Pour lire les donnĂ©es de lâesclave, le maĂźtre force le bus à « 0 » pendant au moins 1 ÎŒs. Si lâesclave veut Ă©mettre un « 1 », il laisse le bus libre, donc tirĂ© à « 1 ». Pour Ă©mettre un « 0 », lâesclave doit tirer le bus à « 0 » pendant 15 ÎŒs au minimum.
Le maĂźtre devra donc dans tous les cas lire le bus 15 ÎŒs maximum aprĂšs avoir tirĂ© le bus à « 0 » pendant 1 ÎŒs. LâĂ©tat du bus donnera alors le bit transmis par lâesclave.
Ceci est une description assez sommaire du protocole 1-Wire. Il faut ensuite se reporter Ă la datasheet de chaque composant 1-Wire pour connaĂźtre les fonctions qui sont supportĂ©es et les zones de donnĂ©es qui peuvent ĂȘtre lues pour obtenir les tempĂ©ratures, niveaux de tensionsâŠ
Pour allez plus loin :
Sur la comprĂ©hension dĂ©taillĂ© du bus 1-Wire, notamment sur le calcul du CRC jâinvite les intĂ©ressĂ© Ă consulter le document pdf de Daniel Menesplier, qui ma servi Ă faire cette introduction.
Le DS18B20 a une gamme de mesure qui sâĂ©tend de -55 °C Ă +125 °C. Il transmet sa mesure directement en degrĂ©s Celsius, codĂ©e sur 16 bits. Sa prĂ©cision est de ±0,5 °C entre -10 °C et +85 °C.
Avec une plage de tension dâalimentation allant de 3v Ă 5,5v, le DS18B20 est un candidat idĂ©al pour utiliser un Arduino, utilisant soit une tension de fonctionnement de 3,3V comme les Arduino Pro-Mini ou un plus classique 5V utilisĂ© par les Arduino Uno.
Pour ma part jâai plutĂŽt optĂ© pour un Arduino Pro-Mini de 3.3V, dans le but dâune future utilisation « portable » alimentĂ©e par une batterie Li-Po de 3,7V. (Forme de thermomĂštre mobile et autonome)
Le montage avec lâArduino Pro-Mini
Pour cette phase de « programmation » dans lâenvironnement Arduino.
Nous allons avoir besoin de :
Lâ environnement de programmation Arduino adaptĂ© Ă votre plate-forme (Mac OS, Windows, LinuxâŠ), Ă tĂ©lĂ©charger ici, pour ceux qui ne lâaurait pas encore installĂ©.
La librairie OneWire disponible ici. A décompresser dans votre répertoire < Arduino >/Librairies/ .
La librairie Dallas Temperature Control â DTC â disponible ici. Idem Ă dĂ©compresser dans votre rĂ©pertoire < Arduino >/Librairies/ .
Lâautre mĂ©thode pour lâinstallation des librairies, consiste Ă ouvrir lâIDE Arduino, puis sous le menu âCroquis->Inclure une bibliothĂšque->Ajouter la bibliothĂšque .ZIPâ sĂ©lectionner le fichier CompressĂ© .ZIP .
La prise en compte sera effective au prochain dĂ©marrage de lâIDE.
Une foi les 2 librairies installées, le programme utilisé est le suivant :
#include <OneWire.h> #include <DallasTemperature.h> // On utilise la Pin #2 pour connecter le DS18B20 #define ONE_WIRE_BUS 2 // Initialisation de la librairie OneWire OneWire oneWire(ONE_WIRE_BUS); // Lien avec la librairie Dallas Temperature Control DallasTemperature sensors(&oneWire); void setup(void) { // On initialise le port série Serial.begin(9600); Serial.println("Démonstration de prise de température avec le DS18B20"); // On initialise la librairie DTC sensors.begin(); } void loop(void) { // On réalise un appel pour tous les "esclaves" connectés Serial.print(" Demande de température en cours..."); sensors.requestTemperatures(); // Envoi de la demande Serial.println("DONE"); // Confirmation de l'envoi de la demande Serial.print("La temperature pour le DS18B20 est de: "); Serial.print(sensors.getTempCByIndex(0)); // Le 0 corresponant au premier esclave trouvé (nous n'en avons qu'un). delay(1000); // On attend une seconde avant la prochaine mesure }
Rien de particulier Ă signaler dans ce code si ce nâest lâutilisation de nos deux librairies.
Jâai inserĂ© un dĂ©lai dâune seconde entre chaque mesure mais que dans la pratique lâopĂ©ration de conversion prenant environ 750 ms, il se passe ainsi presque 2 secondes (1,75s pour ĂȘtre prĂ©cis) entre chaque affichage sur le moniteur sĂ©rie.
Vous pouvez désormais compiler ce code et lancer la programmation de votre Arduino aprÚs avoir pris soin de sélectionner le bon type de carte et le port série associé.
En activant le moniteur série, vous devriez désormais voir apparaßtre les informations suivantes:
Démonstration de prise de température avec le DS18B20 Demande de température en cours...DONE La temperature pour le DS18B20 est de: 19.81 Demande de température en cours...DONE La temperature pour le DS18B20 est de: 19.87 Demande de température en cours...DONE La temperature pour le DS18B20 est de: 19.87 Demande de température en cours...DONE La temperature pour le DS18B20 est de: 19.94 Demande de température en cours...DONE La temperature pour le DS18B20 est de: 19.94 Demande de température en cours...DONE
Cela clos cette premiÚre utilisation, de la sonde de température DS18B20, avec un Arduino.
Je vous propose dâentrer un peut plus loin dans le dĂ©tail de la librairie OneWire :
Ătude de la librairie OneWire :
Méthodes et utilisation :
OneWire myWire(pin);
DĂ©clare un objet du type OneWire sur la broche « pin », il est possible de dĂ©clarer plusieurs objets OneWire sur la mĂȘme broche Ă©tant donnĂ©e quâil sâagit dâun bus.
myWire.search(addrArray) ;
Cherche des modules compatible OneWire sur le bus.
Si un module est trouvĂ© la fonction renvoi True et lâadresse du module est placĂ© dans « addrArray » (addrArray qui correspond Ă un tableau de 8 byte), si aucun module nâest trouvĂ© elle retourne False.
(Ps: Câest une fonction de recherche « glissante », cela signifie que si plusieurs module Dallas sont prĂ©sent, il faudra appeler la fonction autant de fois quâil y a de modules sur le bus)
myWire.reset_search() ;
Fait repartir la recherche de zéro, utile pour rescanner tous les modules présent sur le bus.
myWire.reset() ;
Relance le bus 1-Wire, obligatoire avant de communiquer avec la plupart des modules Dallas.
myWire.select(addrArray) ;
SĂ©lectionne un module dâadresse addrArray afin de pouvoir communiquer avec lui.
Toutes les communications rĂ©alisĂ©es jusquâau prochain reset se feront avec ce module.
myWire.skip() ;
Permet dâoutre passer la sĂ©lection du module avec qui communiquer.
Utile dans le cas ou il nây a quâun module Dallas sur le bus et oĂč, par consĂ©quent, faire une recherche serait inutilement lourd.
(ne fonctionne QUE sâil nây a quâun module Dallas sur le bus)
myWire.write(valeur) ;
Ăcrit un octet « valeur » sur le bus.
(Note: bien prendre le temps de lire le datasheet du module utilisé, la plupart possÚde un « scratchpad » qui sert de mémoire tampon entre la mémoire physique et une mémoire ram virtuelle.
Si les données contenu dans le « scratchpad » ne sont pas transférées dans la mémoire physique en suivant la procédure qui va bien elle ne seront tout simplement pas sauvegardées)
myWire.write(valeur, 1) ;
Ăcrit un octet « valeur » sur le bus, mais conserve lâalimentation sur le bus Ă la fin de la transmission.
(utile dans le cas dâun cĂąblage en mode parasite)
myWire.read();
Lit un octet depuis le bus.
myWire.crc8(dataArray, length) ;
Calcul la checksum (CRC8) du tableau « dataArray » de taille « length », trÚs utile pour savoir si les données reçu sont corrompu ou non.
Passons maintenant au Raspberry-PI / Odroid pour un usage un peut similaire.
Montage avec un Raspberry-Pi
Linux nâest pas Temps RĂ©el (RT)
Nous avons vu que lâutilisation du Bus OneWire exige une gestion temporelle trĂšs prĂ©cise de lâordre de quelque ”S.
Si les ”ContrĂŽleur comme lâArduino ou ses semblables sont bien taillĂ© pour de telles performances, câest quâil ne fonctionnent pas dans un mode MultitĂąche prĂ©emptif, oĂč voir pire en mode collaboratif.
Cette caractĂ©ristique de fonctionner dans un mode sĂ©quentiel monotĂąche, garantie une temporalitĂ© du programme exĂ©cutĂ©s. Il nây en Ă quâun et il nâest pas interrompu.
Pour un SystĂšme MultitĂąche prĂ©emptif, comme Linux sur le Rasberry-Pi, le contrĂŽle dâun bus sĂ©quencĂ© par une horloge externe nâest pas possible sans adaptations particuliĂšre.
Il est indispensable, lors des phases de dialogues (le contrĂŽle du bus), dâavoir la maĂźtrise du temps dâexĂ©cution du processeur. Pour ce faire il faut pouvoir âgelerâ temporairement, la capacitĂ© de lâOS Ă prĂ©empter, notre tache de dialogue sur le bus OneWire.
Rassurez-vous une tel gestion est prĂ©vus par le noyau de Linux. Il faut donc pouvoir intervenir au niveau du noyau, câest le rĂŽles des modules de noyau complĂ©mentaire.
Les fonctions de gestion du bus OneWire ne seront donc pas, comme câĂ©tait le cas pour lâArduino, de simples librairies (extensions fonctionnelles du langage), mais des modules du noyau de Linux. Qui auront en charge de bloquer le mode prĂ©emptif de Linux pendant lâexĂ©cution de ces routines particuliĂšres.
Pour résumer :
Pour que le noyau Linux sache gérer le composant OneWire DS18B20, il faut lui adjoindre un module pour la gestion du OneWire, et un module pour la gestion des composants de la famille 28h, capteurs de température.
Cela parait trĂšs simple, mais en rĂ©alitĂ© le travail Ă exĂ©cuter âŠ. Bref dâautres lâon considĂ©rablement simplifiĂ© pour nous.
Passons maintenant au concret !
Quels modules noyaux et comme les ajouter ?
Les modules en question sont :
Comment installer ces modules au noyau ?
Ce nâest pas lâobjectif, que de faire un cours sur la gestion du noyau Linux et des modules de pĂ©riphĂ©riques (pilotes).
Toutefois quelques notions me sembles importantes à préciser.
GĂ©nĂ©ralement ignorĂ©, les modules noyaux sont sont au cĆur du systĂšme, globalement chargĂ©s dâinterfacer un matĂ©riel avec le noyau Linux.
Les modules noyaux existent sous 2 formes :
Soit ils ont Ă©tĂ© compilĂ© au sein mĂȘme du noyau, on dit parfois compilĂ© âen durâ,
Soit ils ont été compilé sous forme de modules externes.
Vous aurez devinez que dans notre cas, on va utiliser des modules externes. Dans le cas dâune distribution Debian, qui se trouve ĂȘtre la distribution principal utilisĂ© sur le Raspberry-Pi et nommĂ© dans ce cas âRaspbianâ.
Deux façons de monter un module :
en mode direct
Charger les modules du kernel pour prendre en charge le capteur. w1-gpio est le module pour les capteurs avec un seul fil, w1-therm est celui pour les sondes de température.
modprobe w1-gpio
modprobe w1-therm
Par configuration:
Les modules externes sont définis dans le fichier :
/etc/ modules
Il suffit dâĂ©diter, avec votre Ă©diteur de fichier prĂ©fĂ©rĂ© en mode root, puis de complĂ©ter ce fichier avec les lignes suivantes :
w1-therm w1-gpio pullup=1
Votre fichier de modules devrait ressembler un peut Ă ceci :
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. # Parameters can be specified after the module name. i2c-dev i2c-bcm2708 spi-bcm2708 snd-bcm2835 w1-therm w1-gpio pullup=1
La prise en charge par le noyau, de cette nouvelle configuration, se fait au plus simple par un redémarrage.
Schéma de raccordement de la sonde DS18B20 au Raspberry-Pi
Pour une sonde en boĂźtier industriel.
En mode labo sur un Breadboard
Lecture de la température de notre sonde DS18B20
Dans un premier temps vérifions, aprÚs notre petit montage, que le systÚme a bien reconnu la sonde :
>pi@rasphil $ cd /sys/bus/w1/devices >pi@rasphil /sys/bus/w1/devices $ ls 28-0000054c2ec2 w1_bus_master1
Ma sonde a effectivement Ă©tĂ© dĂ©tectĂ©e. Elle porte le numĂ©ro 28-0000054c2ec2 (numĂ©ro unique au monde, je vous le rappelle). Le systĂšme a créé un rĂ©pertoire Ă son nom et câest dans ce dossier que nous allons trouver les informations qui nous intĂ©ressent.
Dans un premier temps, et pour bien comprendre comment le systĂšme (lâOS) gĂšre la sonde, on va effectuer cette lecture directement en ligne de commande.
Remarque :
il nây Ă pas rĂ©ellement dâautre maniĂšre de communiquer directement avec un pĂ©riphĂ©rique sous Linux. En effet tout pĂ©riphĂ©rique dialogue avec un fichier dâinterface disponible dans le rĂ©pertoire des âdevicesâ.
Un programme sous python ou autre ne fera rien dâautre que dâinvoquer ce mĂȘme fichier pour communiquer avec la sonde.
Il est donc intĂ©ressant dâĂ©tudier ce mĂ©canisme au travers de notre exemple de lecture la sonde DS18B20.
Allons directement sous le répertoire de notre sonde :
>cd /sys/bus/w1/devices/28-0000054c2ec2
>ls -la driver id name power subsystem uevent w1_slave
Lecture du fichier âw1_slaveâ
>cat w1_slave 7c 01 4b 46 7f ff 04 10 09 : crc=09 YES 7c 01 4b 46 7f ff 04 10 09 t=23750
Le fichier w1_slave contient sur la premiÚre ligne le code correspondant au numéro de la sonde, avec son CRC qui a été vérifié (YES), et sur la deuxiÚme ligne la température en hexadécimal (peu utilisable) mais aussi en miliÚmes de degrés Celsius.
Il suffira de diviser par 1000 pour obtenir la tempĂ©rature rĂ©elle. On peut arrondir Ă un chiffre aprĂšs la virgule sans vergogne, puisque la prĂ©cision nâest que de ±0,5 °C.
Une topologie de rĂ©seau est en informatique une dĂ©finition de lâarchitecture dâun rĂ©seau. Elle donne une certaine disposition des diffĂ©rents postes informatiques du rĂ©seau et une hiĂ©rarchie de ces postes. â©