Aujourd’hui avec Alan on bricole autour de l’Arduino et des capteurs de température DS18S20 (ou DS18B20) de chez Dallas.
J’avais déjà lu un seul capteur, donc là on étend le programme à 2 capteurs…
Déjà on s’inspire fortement du code dispo là : http://playground.arduino.cc/Learning/OneWire
1ere étape : déterminer l’adresse des capteurs de température :
#include <OneWire.h> // DS18S20 Temperature chip i/o OneWire ds(10); // on pin 10 void setup() { Serial.begin(9600); } void loop() { byte i; byte present = 0; byte data[12]; byte addr[8]; int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract; ds.reset_search(); if ( !ds.search(addr)) { Serial.print("No more addresses.\n"); ds.reset_search(); return; } Serial.print("R="); for( i = 0; i < 8; i++) { Serial.print(addr[i], HEX); Serial.print(" "); } if ( OneWire::crc8( addr, 7) != addr[7]) { Serial.print("CRC is not valid!\n"); return; } if ( addr[0] == 0x10) { Serial.print("Device is a DS18S20 family device.\n"); } else if ( addr[0] == 0x28) { Serial.print("Device is a DS18B20 family device.\n"); } else { Serial.print("Device family is not recognized: 0x"); Serial.println(addr[0],HEX); return; } delay(1000); }
Voila, sur le terminal ca donne ceci :
Et pour récupérer les données une fois que l’on connait les adresses :
Etape 2 : Récupérer les données des capteurs de température.
#include <OneWire.h> // DS18S20 Temperature chip i/o OneWire ds(10); // on pin 10 byte addr1[8] = {0x28, 0xF9, 0xD9, 0x00, 0x04, 0x00, 0x00, 0xC9}; byte addr2[8] = {0x28, 0x86, 0xDF, 0x00, 0x04, 0x00, 0x00, 0xE9}; int SignBit = 0; void setup() { Serial.begin(9600); } int tc_100(byte* addr){ int HighByte, LowByte, TReading; byte data[12]; byte i; ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } LowByte = data[0]; HighByte = data[1]; TReading = (HighByte << 8) + LowByte; SignBit = TReading & 0x8000; // test most sig bit if (SignBit) // negative { TReading = (TReading ^ 0xffff) + 1; // 2's comp } return (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 } void mypr(int Tc_100) { int Whole, Fract; Whole = Tc_100 / 100; // separate off the whole and fractional portions Fract = Tc_100 % 100; if (SignBit) // If its negative { Serial.print("-"); } Serial.print(Whole); Serial.print("."); if (Fract < 10) { Serial.print("0"); } Serial.print(Fract); Serial.print("\n"); } void loop() { byte i; byte data[12]; int Tc_100; Tc_100 = tc_100(addr1); Serial.print("1: "); mypr(Tc_100); Tc_100 = tc_100(addr2); Serial.print("2: "); mypr(Tc_100); }
Ce qui donne dans le terminal pour 2 capteurs de température.
On ajoute un afficheur : (http://arduino.cc/en/Tutorial/LiquidCrystal)
#include <LiquidCrystal.h> #include <OneWire.h> // DS18S20 Temperature chip i/o OneWire ds(10); // on pin 10 byte addr1[8] = {0x28, 0xF9, 0xD9, 0x00, 0x04, 0x00, 0x00, 0xC9}; byte addr2[8] = {0x28, 0x86, 0xDF, 0x00, 0x04, 0x00, 0x00, 0xE9}; int SignBit = 0; int StartCol = 8; // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { Serial.begin(9600); // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("Temp 1:"); lcd.setCursor(0, 1); lcd.print("Temp 2:"); } int tc_100(byte* addr){ int HighByte, LowByte, TReading; byte data[12]; byte i; ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); } LowByte = data[0]; HighByte = data[1]; TReading = (HighByte << 8) + LowByte; SignBit = TReading & 0x8000; // test most sig bit if (SignBit) // negative { TReading = (TReading ^ 0xffff) + 1; // 2's comp } return (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 } void mypr(int Tc_100, int line) { int Whole, Fract; Whole = Tc_100 / 100; // separate off the whole and fractional portions Fract = Tc_100 % 100; if (SignBit) // If its negative { lcd.setCursor(StartCol,line); lcd.print("-"); } lcd.setCursor(StartCol+1,line); lcd.print(Whole); lcd.print("."); if (Fract < 10) { lcd.print("0"); } lcd.print(Fract); lcd.print("C"); } void loop() { byte i; byte data[12]; int Tc_100; Tc_100 = tc_100(addr1); mypr(Tc_100,0); Tc_100 = tc_100(addr2); mypr(Tc_100,1); }
Et voila affichée la température des 2 capteurs de température.
Comme ils sont à qq centimètres l’un de l’autre les données sont très proches.
Merci Alan !
[…] Et j’utilise des sondes DS18B20. […]