je souhaite avoir un sonde intérieur et extérieur dans mon camion si la température intérieur dépasse de 2 degrés la température extérieur un relais s'enclenche pour activer des ventilateurs.
mon code a l'air de fonctionner à un détail prêt la temp inter et exter son inversée sur l’affichage mon écran.
j'ai inversé l' ordre les sondes et même problème.
Quelqu'un peut il me dépanner merci.
#include <OneWire.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
OneWire ds(8); // on pin 8 (a 4.7K resistor is necessary)
const int relaispin = 5;
bool ticktock = TRUE;
float tempout, tempin, tempinzone;
float tempdiv = 2;
bool relais = FALSE;
String relaistxt = "off";
String firstline = "firstline";
String secondline = "secondline";
String thirdline = "thirdline";
void setup(void) {
Serial.begin(9600);
pinMode(relaispin, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC);
display.display(); // show splashscreen
delay(1000);
display.clearDisplay(); // clears the screen and buffer
}
void loop() {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
ds.reset();
ds.select(addr);
ds.write(0xBE);
delay(1000);
present = ds.reset();
ds.select(addr);
ds.write(0x44);
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
if (ticktock) {
tempout = celsius;
ticktock = FALSE;
}
else {
tempin = celsius;
ticktock = TRUE;
}
tempinzone = tempin - tempdiv;
if (tempinzone >= tempout ) {
relais = TRUE;
digitalWrite(relaispin, HIGH);
}
else {
relais = FALSE;
digitalWrite(relaispin, LOW);
}
Serial.print(" Temperature = ");
Serial.print(tempin);
Serial.print(" Celsius insite and ");
Serial.print(tempout);
Serial.print(" Celsius outsite. The Relais is");
if (relais) {
Serial.println(" on.");
}
else {
Serial.println(" off.");
}
// display text
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("INT: ");
display.println(tempin);
display.print("EXT: ");
display.println(tempout);
display.print("Fan: ");
if (relais) {
display.println("on");
}
else {
display.println("off");
}
display.display();
delay(2000);
display.clearDisplay();
}
je souhaite avoir un sonde intérieur et extérieur dans mon camion si la température intérieur dépasse de 2 degrés la température extérieur un relais s'enclenche pour activer des ventilateurs.
mon code a l'air de fonctionner à un détail prêt la temp inter et exter son inversée sur l’affichage mon écran.
j'ai inversé l' ordre les sondes et même problème.
Bonsoir
quand tu dis , j'ai inversé l"ordre des sondes , tu veux dire que tu à mis physiquement celle qui etait à l'exterieur à l’intérieur , et réciproquement ?
c'est quoi exactement tes "sondes" , je suppose du DS18B20 , mais presenté comment (compo simple , tubage inox , ...autres
DS18B20 alimentés comment ? en "parasitic power" ou en standard ?
que donne la lecture des 2 DS18B20 reliés "thermiquement entre eux dans un même endroit"
oui c'est ce que j'ai fais.
ce sont des ds18b20 classiques connectées en mode parasite 1 est connectée sur la carte de prototypage avec une connexion mâle /femelle et l'autre avec un câble d'env 2 mètre à l' extérieur du véhicule.
ce qui m'agace c'est qu'en teste à la maison ça fonctionnait !!!
oui c'est ce que j'ai fais.
ce sont des ds18b20 classiques connectées en mode parasite 1 est connectée sur la carte de prototypage avec une connexion mâle /femelle et l'autre avec un câble d'env 2 mètre à l' extérieur du véhicule.
ce qui m'agace c'est qu'en teste à la maison ça fonctionnait !!!
Quel Δ t° max entre tes 2 DS18B20 sur 5 minutes ?
les 2 DS18B20 maintenus fermement ensemble "face à face" ?
sur ta carte ?
au bout du cable ?
il faut aussi se rappeller que la précision (ne pas confondre avec la résolution) d'un DS18B20 est "seulement" de +/- 0.5 °C
entre -10 et +85 °C
les sondes fonctionnent correctement
si je mets un glaçon sur la sonde extérieur : la température descend bien mais sur l'affichage de mon écran c'est la température intérieur qui descend.
si je mets mon doigt sur la sonde intérieur : la température monte bien mais sur l'affichage de mon écran c'est la température extérieur qui monte
j'ai donc un problème d'affichage sur mon écran oled
int affiche la température exterieur
ext affiche la température intérieur
les sondes fonctionnent correctement
si je mets un glaçon sur la sonde extérieur : la température descend bien mais sur l'affichage de mon écran c'est la température intérieur qui descend.
si je mets mon doigt sur la sonde intérieur : la température monte bien mais sur l'affichage de mon écran c'est la température extérieur qui monte
j'ai donc un problème d'affichage sur mon écran oled
int affiche la température exterieur
ext affiche la température intérieur
Ok
es tu vraiment sur et certain dans tes tests précédents d'avoir bien inversé physiquement les 2 DS18B20 ?
Il n'y a rien sur les boitiers en TO92 qui permette de discriminer un DS18B20 d'un autre
j'ai tout remonté pareil il détecte la sonde intérieur comme extérieur.
y a pas moyen de forcer les sondes de dire celle ci c'est l’intérieur et l'autre l'extérieur
j'ai tout remonté pareil il détecte la sonde intérieur comme extérieur.
y a pas moyen de forcer les sondes de dire celle ci c'est l’intérieur et l'autre l'extérieur
bonjour
là tu travaille en découverte systématique d'adresse onewire
et tu tente de discriminer tes sondes avec test sur if (ticktock)
si une recherche d'adresse foire tu inverse automatiquement interne/externe
il faut passer par de l'adressage fixe
mais ça n'explique pas cette inversion
la découverte se faisant toujours dans le même ordre
doubleve:
peut être le faite que la sonde cablée mette plus de temps à répondre du coup par défaut il met en extérieur à cause du ticktock
Je n'ai pas de quoi faire un test avant la mi-journée
mais de toutes façons ta methode (ticktok) n'est pas une bonne methode
tu n'aura jamais la certitude que la sonde lue soit l'interne ou l'externe
tu peux avoir tous les cas de figure :
tu prends une sonde, tu chope son adresse, idem pour l'autre
tu donne un nom à chaque sonde, interieur avec address 0x55, exterieur avec addresse 0x77 par exemple
je mets n'importe quoi en address, donc à toi de trouver les address une par une via un scanner I2C
après il suffit de lire chaque sonde via son petit nom
tu affiche à chaque fois en ligne 1 interieur et ligne 2 exterieur, toujours en exemple
en ce qui concerne ton code avec l'afficheur oled
j'ai testé sur un "uno"
tu n'a pas une "alerte" mémoire basse à la compilation ?
montre aussi le log de compilation
#include <OneWire.h>
OneWire ds(8); // bus 1wire sur pin x ds(x) (ne pas oublier une resistance de 4.7K entre cette ligne et +5V)
void setup(void) {
Serial.begin(115200);
}
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
byte crc;
if ( !ds.search(addr)) {
Serial.println("-----------------. FIN DU SCAN ADRESSE---------------");
Serial.println();
Serial.println();
Serial.println(" DEBUT DU SCAN ADRESSE");
Serial.println(" FC <-- ADRESSE --> CK"); // FC Family Code , CK Cheksum
ds.reset_search();
delay(250);
return;
}
//Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
if (addr[i]<16) Serial.print("0");
Serial.print(addr[i], HEX);
}
Serial.print(" ");
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.print(" Chip = DS18S20 "); // or old DS1820 ou ds1920 ibutton
type_s = 1;
break;
case 0x28:
Serial.print(" Chip = DS18B20 ");
type_s = 0;
break;
case 0x22:
Serial.print(" Chip = DS1822 ");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
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.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
if (data[i]<16) Serial.print("0");
Serial.print(data[i], HEX);
Serial.print(" ");
}
//Serial.print(" CRC=");
crc=OneWire::crc8(data, 8);
//if (crc<16) Serial.print("0");
//Serial.print(crc,HEX);
//Serial.print(" ");
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
}
else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
//fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.println();
}
Chez moi les différents tests fait avec un oled ssd1306 , lib adafruit et la lib onewire (derniere version de PJRC) conduise à du n'importe quoi sur un uno
il y a de la bouillie dans la memoire du UNO
voir photo
je suis etonné que chez toi tu ai un semblant d'info cohérentes , mais bon ...
les petits oled ssd1306 sont sympa , mais tres gourmand en ressources , ça ne laisse pas beaucoup de marge sur des bases genre UNO
tente le code ci-dessous EDIT : j'ai testé avec 2 DS18B20 discriminé, c'est aussi du n'importe quoi !
j'ai discriminé tempin et tempout en fonction d'une partie non identique de l'adresse onewire , il faut donc utiliser les 2 ds18b20 qui ont servi à ton test précédent.
#include <OneWire.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
OneWire ds(8); // on pin 8 (a 4.7K resistor is necessary)
const int relaispin = 5;
bool ticktock = TRUE;
float tempout, tempin, tempinzone;
float tempdiv = 2;
bool relais = FALSE;
String relaistxt = "off";
String firstline = "firstline";
String secondline = "secondline";
String thirdline = "thirdline";
void setup(void) {
Serial.begin(9600);
pinMode(relaispin, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC);
display.display(); // show splashscreen
delay(1000);
display.clearDisplay(); // clears the screen and buffer
}
void loop() {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
if ( !ds.search(addr)) {
ds.reset_search();
delay(250);
return;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
ds.reset();
ds.select(addr);
ds.write(0xBE);
delay(1000);
present = ds.reset();
ds.select(addr);
ds.write(0x44);
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
if (addr[2]==0x11) tempin=celsius; // test sur 3eme poste addresse pour discrimination
if (addr[2]==0xA7) tempout=celsius; // attention c'est du codage dur pas propre
tempinzone = tempin - tempdiv;
if (tempinzone >= tempout ) {
relais = TRUE;
digitalWrite(relaispin, HIGH);
}
else {
relais = FALSE;
digitalWrite(relaispin, LOW);
}
Serial.print(" Temperature = ");
Serial.print(tempin);
Serial.print(" Celsius insite and ");
Serial.print(tempout);
Serial.print(" Celsius outsite. The Relais is");
if (relais) {
Serial.println(" on.");
}
else {
Serial.println(" off.");
}
// display text
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("INT: ");
display.println(tempin);
display.print("EXT: ");
display.println(tempout);
display.print("Fan: ");
if (relais) {
display.println("on");
}
else {
display.println("off");
}
display.display();
delay(2000);
display.clearDisplay();
}
Je confirme un probleme de memoire sur 328
j'ai testé sur MEGA avec le programme ci-dessous et ça passe sans probleme
alors que sur UNO , c'est du n'importe quoi
NB les discriminants sont pour mes DS18B20 de test c'est donc à adapter
#include <OneWire.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
// http://www.pjrc.com/teensy/td_libs_OneWire.html
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
OneWire ds(8); // on pin 8 (a 4.7K resistor is necessary)
const int relaispin = 5;
bool ticktock = TRUE;
float tempout, tempin, tempinzone;
float tempdiv = 2;
bool relais = FALSE;
String relaistxt = "off";
String firstline = "firstline";
String secondline = "secondline";
String thirdline = "thirdline";
void setup(void) {
Serial.begin(115200);
pinMode(relaispin, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC);
display.clearDisplay(); // clears the screen and buffer
}
void loop() {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius;
byte crc;
//----------------------
if ( !ds.search(addr)) {
Serial.println("------------------ FIN DU SCAN ADRESSE---------------");
Serial.println();
Serial.println();
Serial.println(" DEBUT DU SCAN ADRESSE");
Serial.println(" FC <-- ADRESSE --> CK"); // FC Family Code , CK Cheksum
ds.reset_search();
delay(250);
return;
}
//Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
if (addr[i]<16) Serial.print("0");
Serial.print(addr[i], HEX);
}
Serial.print(" ");
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.print(" Chip = DS18S20 "); // or old DS1820 ou ds1920 ibutton
type_s = 1;
break;
case 0x28:
Serial.print(" Chip = DS18B20 ");
type_s = 0;
break;
case 0x22:
Serial.print(" Chip = DS1822 ");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
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.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
if (data[i]<16) Serial.print("0");
Serial.print(data[i], HEX);
Serial.print(" ");
}
//Serial.print(" CRC=");
crc=OneWire::crc8(data, 8);
//if (crc<16) Serial.print("0");
//Serial.print(crc,HEX);
//Serial.print(" ");
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
}
else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
// ---------------------
// discrimination sur le 3 poste du tableau adresse
if (addr[2]==0xFB) tempin=celsius; // test sur 3eme poste addresse pour discrimination
if (addr[2]==0x5C) tempout=celsius; // attention c'est du codage dur pas propre
tempinzone = tempin - tempdiv;
if (tempinzone >= tempout ) {
relais = TRUE;
digitalWrite(relaispin, HIGH);
}
else {
relais = FALSE;
digitalWrite(relaispin, LOW);
}
Serial.print(" Temperature = ");
Serial.print(tempin);
Serial.print(" Celsius insite and ");
Serial.print(tempout);
Serial.print(" Celsius outsite. The Relais is");
if (relais) {
Serial.println(" on.");
}
else {
Serial.println(" off.");
}
// display text
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("INT: ");
display.println(tempin);
display.print("EXT: ");
display.println(tempout);
display.print("Fan: ");
if (relais) {
display.println("on");
}
else {
display.println("off");
}
display.display();
delay(2000);
display.clearDisplay();
}