tenez étudiez un peu ce code que j'avais fait il y a quelques temps pour quelqu'un d'autre
comme composants il faut
- 2 DS18820 sur la pin 9 (avec une résistance de 4.7KΩ entre 5V et pin 9)
- 1 potentiomètre branché sur A0
- 1 bouton câblé ainsi pin 8 --> entrée bouton ---> BOUTON --> sortie bouton --> GND que l'on mettra dans le code en INPUT PULLUP
- 1 écran LCD connecté en I2C 16x2 ou 20x4
appuyez sur le bouton, faites varier le potentiomètre ou faites chauffer ou refroidir les DS18820 et vous verrez comment ça se comporte
// Gestion des DS18820
#include <OneWire.h>
#include <DallasTemperature.h>
const byte onewireBusPin = 9; // pin 9 pour le bus 1 wire avec une résistance de 4.7KΩ entre 5V et pin 9
OneWire oneWire(onewireBusPin);
DallasTemperature sensors(&oneWire);
const byte nbCapteurs = 2;
DeviceAddress DS18820Address[nbCapteurs];
float temperatures[nbCapteurs];
const int resolution = 10; // en bits --> Max 12 bit, min 9 bit (9bit prends 95ms, 10bit 187ms, 11bit 375ms et 12bit 750ms)
// on va lire la température seulement de temps en temps
unsigned long chronoTemperatures = 0;
const unsigned long periodeLecture = 250; // 250 est OK pour une résolutoin en 10 bits. au minimum attendre (750 / (1 << (12 - resolution)));
// Gestion du LCD
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// adresse LDC 0x27 16 caractères, 2 lignes
const byte nbColumns = 20;
const byte nbLines = 2;
LiquidCrystal_I2C lcd(0x27, nbColumns, nbLines);
// ou avec 4 lignes
//const byte nbColumns = 20;
//const byte nbLines = 4;
//LiquidCrystal_I2C lcd( 0x3F, nbColumns, nbLines); // my LCD is at I2C address 0x3F, 20 cols, 4 rows
const byte symboleFlecheDroite = 126;
const byte symboleFlecheGauche = 127;
const byte symboleBlocBlanc = 255;
const byte symboleEgal = '=';
// La librairie de gestion des boutons
#include <OneButton.h> // https://github.com/mathertel/OneButton
// le bouton pour les modes
const byte buttonPin = 8; // notre bouton est sur la pin 8
OneButton button(buttonPin, true); // true pour le mettre en INPUT_PULLUP
// les mode
enum : byte {eteint, manuel, automatique} mode = eteint;
// le potentiomètre
const byte pinConsigne = A0;
int tempConsigne = 0;
void afficheTemperature(int t, byte ligne, byte col)
{
// on sait que la température est entre -55° et 125°, donc la longeur max de la chaîne 125°C = 5 caractères
char affichage[9]; // 9 = 8 carcatère dédiés à la consigne + 1 '\0'
char tmpBuffer[9];
itoa(t, tmpBuffer, 10); // connvertir en chaîne, cf http://www.cplusplus.com/reference/cstdlib/itoa/?kw=itoa
strcat(tmpBuffer, "\337C"); // \337 est le symbole '°'
size_t l = strlen(tmpBuffer);
memset(affichage, ' ', 8 - l); // on met des espaces à gauche
strcpy(affichage + 8 - l, tmpBuffer);
lcd.setCursor(col, ligne);
lcd.print(affichage);
}
int lireEtAfficherTemperature()
{
float t;
for (int i = 0; i < nbCapteurs; i++) {
t = sensors.getTempCByIndex(i); // lire les T°. ici exemple de code avec des DS18820
if (((int) t) != ((int) temperatures[i])) { // on n'affiche qu'en nombre entier vu la précision nécessaire
afficheTemperature((int) t, 1, 8 * i);
}
temperatures[i] = t; // mais on stocke bien la bonne valeur
}
}
void lireEtAfficherConsigne()
{
int c;
analogRead(pinConsigne); // double lecture pour stabiliser la mesure
c = map(analogRead(pinConsigne), 0, 1023, -20, 100);
if (c != tempConsigne) {
tempConsigne = c;
afficheTemperature(c, 0, 8);
}
}
void afficherMode()
{
// occupe 6 caractères de l'afficheur
lcd.setCursor(0, 0);
switch (mode) {
case eteint:
lcd.noBacklight();
lcd.clear();
lcd.print(F("Eteint"));
digitalWrite(LED_BUILTIN, LOW);
for (int i = 0; i < nbCapteurs; i++) temperatures[i] = -99; // valeur arbitraire en mode off
tempConsigne = -99;
break;
case manuel:
lcd.print(F("Manuel"));
digitalWrite(LED_BUILTIN, HIGH);
lcd.backlight();
break;
case automatique:
lcd.print(F(" Auto "));
digitalWrite(LED_BUILTIN, HIGH);
lcd.backlight();
break;
}
}
// La fonction de call back, appellée automatiquement quand on clique
void simpleclick()
{
switch (mode) {
case eteint:
mode = manuel;
sensors.requestTemperatures(); // on lance une demande de lecture qui sera prête plus tard
chronoTemperatures = millis();
// *** ICI ALLUMER LA REGULATION DE COURANT ***
break;
case manuel:
mode = automatique;
sensors.requestTemperatures(); // on lance une demande de lecture qui sera prête plus tard
chronoTemperatures = millis();
// *** ICI ALLUMER LA REGULATION DE COURANT ***
break;
case automatique:
mode = eteint;
// *** ICI ETEINDRE LA REGULATION DE COURANT ***
break;
}
afficherMode();
}
void regulation()
{
static byte oldSymbole = 0;
byte symbole;
switch (mode) {
case eteint:
symbole = symboleBlocBlanc;
break;
case manuel:
case automatique:
if ((int) tempConsigne > (int) temperatures[1]) {
symbole = symboleFlecheDroite;
} else if ((int) tempConsigne == (int) temperatures[1]) {
symbole = symboleEgal;
} else {
symbole = symboleFlecheGauche;
}
break;
}
// pour éviter de clignotter pour rien
if (symbole != oldSymbole) {
// occupe 1 caractère de l'afficheur
lcd.setCursor(7, 0);
lcd.write(symbole);
oldSymbole = symbole;
}
// ************************************************************************************
// ici piloter les alimentations pour contrôler la température comme vous le souhaitez
// ************************************************************************************
// A FAIRE
// ************************************************************************************
}
void setup() {
Serial.begin(115200);
pinMode(pinConsigne, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// on initialise les capteurs de températures
sensors.begin();
for (byte i = 0; i < nbCapteurs; i++) {
sensors.getAddress(DS18820Address[i], i);
sensors.setResolution(DS18820Address[i], resolution);
}
sensors.setWaitForConversion(false); // on travaillera en asynchrone, on n'attend pas les lectures
sensors.requestTemperatures(); // on lance une demande de lecture qui sera prête plus tard
chronoTemperatures = millis();
// initialiser the LCD
lcd.begin();
lcd.noBacklight();
// On attache la fonction simpleClick() comme callBack en cas de simple click
button.attachClick(simpleclick);
afficherMode();
}
void loop() {
// On vérifie l'état des boutons, ce qui déclenche l'appel d'une des fonctions callBack si nécessaire
button.tick();
if (mode != eteint) {
// est-ce le moment le lire les capteurs de température?
if (millis() - chronoTemperatures >= periodeLecture) {
lireEtAfficherTemperature();
// on relance une requete pour la prochaine fois
sensors.requestTemperatures();
chronoTemperatures = millis();
}
lireEtAfficherConsigne();
// ici on peut gérer la régulation, cette fonction est appelée souvent mais la température n'est lue que de temps en temps
regulation();
}
}