Visualisation températures en temps réel

Je me suis présenté dans la rubrique « Bar » Présentation.
Pour demander de l’aide c’est plutôt ici qu’il faut intervenir. Alors allons y. Pour mieux cerner mes questions, je vous suggère cependant de parcourir ma présentation.
Dans un premier temps je voudrais afficher 8 températures horodatées sur un LCD. Ce problème a déjà été abordé par FlorianLG dans un post qui débutait en avril 2014. j’ai lu ce post jusqu’au bout mais il ne semble pas avoir été résolu.
Voilà un exemple de ce que je souhaite obtenir sur un LCD 20 caractères 4 lignes :

12,3 15,6 16,4 18,5
14,2 15,1 16,3 17,9
temp moy 14,2
03:10:15 13H27

Les 2 premières lignes sont les températures de sortie de 8 capteurs solaires thermiques, qui reflètent la disposition géométrique exacte de ces capteurs. La connaissance de ces températures permettra d’égaliser le débit de chaque capteur. Chacun étant muni d’une vanne de réglage. La 3eme ligne est la temp. moyenne de ces valeurs, la 4eme est la date heure.
Comme sensor de temp. j’avais envisagé des LM 35 ou LM135 ou AD590 que je connais car habitué à l’analogique, finalement j’ai opté pour le DS18B20 car il n’utilise qu’une entrée et aussi parce que j’ai réussi à lire huit 18B20 au bout d’un câble 3 conducteurs de 15m sur le sérial port de la méga.
Je souhaite afficher sur LCD une fois toutes les 5mn et que le LCD garde ces valeurs visibles pendant ce temps. Pour améliorer la précision j’aimerais faire un relevé par minute et afficher la moyenne de chaque valeur au bout de 5 minutes, (donc moyenne de 5 valeurs), ceci pour chaque capteurs bien sûr. Je ne pense pas avoir besoin de fixer le 18B20 à 12bits, 10bits seraient bien assez. Cela devrait permettre de gagner en rapidité. Quant à l’affichage de la température, un chiffre après la virgule est suffisant.
Pour les essais je travaille avec 2 capteurs seulement, pour passer à 8 cela ne devrait pas être le plus difficile. J’ai récupéré sur ce site quelques fragments de code que j’ai mis bout à bout. Je lis des valeurs sur le LCD, mais je lis 2 fois la valeur 1 puis 3 secondes plus tard 2 fois la valeur 2. Il faudrait sans doute imbriquer 2 boucles, mais c’est un peu compliqué pour mes vieux neurones (79 au compteur !).
Voici le bricolo de code :

#include <stdio.h>
#include <string.h>
#include <OneWire.h>

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity
 
#define NBRE_CAPTEUR 2 // nombre de capteur sur l'arduino

// *********** declararation des variables gestion des capteurs de temperature  *******************
typedef struct Temperature Temperature;
struct Temperature
{
  float valeur;         // temperature en Celsius, 1 chiffre apres la virgule
  byte addr[8];         // identifiant capteur
  int pin;              // numero de pin a utiliser
  char mnemo[32];       // mnemonique de la variable
// float TempMoy;        // temp moyenne
};

Temperature temperature[NBRE_CAPTEUR];    //creation des instances

// *********** fin declararation des variables gestion des capteurs de temperature  *******************


void setup(){
 
        Serial.begin(9600);       // initialisation de la liaison serie
//float TempMoy;        // temp moyenne

// *********** initialisation des variables gestion des capteurs de temperature  *******************
  
  


  temperature[0].addr[0]= 0x28; // capteur noir 1 anneau
  temperature[0].addr[1]= 0xeb; // Capt. sol. numérotés 1 à 8 de G à D et Haut en bas 
  temperature[0].addr[2]= 0xfd; // voir ci-dessous
  temperature[0].addr[3]= 0x28; // 1357
  temperature[0].addr[4]= 0x07; // 2468
  temperature[0].addr[5]= 0x00;
  temperature[0].addr[6]= 0x00;
  temperature[0].addr[7]= 0x93;
  temperature[0].pin=10;
  temperature[0].valeur=0;      // temperature en °C, 1 chiffre apres la virgule
        strcpy(temperature[0].mnemo,"TCS1");//ex Temp Capt Sol 1

  temperature[1].addr[0]= 0x28; // capteur N°2
  temperature[1].addr[1]= 0x83;
  temperature[1].addr[2]= 0X0A;
  temperature[1].addr[3]= 0x29;
  temperature[1].addr[4]= 0x07;
  temperature[1].addr[5]= 0x00;
  temperature[1].addr[6]= 0x00;
  temperature[1].addr[7]= 0x89;
  temperature[1].pin=10;
  temperature[1].valeur=1;      // temperature en °C, 1 chiffre apres la virgule
        strcpy(temperature[1].mnemo,"TCS2");// ex: Temp Capt Sol2



//  TempMoy = (temperature[1].valeur + temperature[0].valeur)/2;
  // strcpy(TempMoy.mnemo,"TMoy");
}





void loop(){
 
 
gestion_temperature();

delay(3000);

}


void gestion_temperature()
{

/********************************************************************************
  Cette fonction permet d'interroger tous les capteurs de temperature OneWire
  qui ont ete declare dans "temperature[i]"
********************************************************************************/

  byte i=0;

  for(i=0; i<NBRE_CAPTEUR; i++){
  
  Serial.print(temperature[i].mnemo);
    Serial.print(" = ");
    temperature[i].valeur =getStuff(temperature[i].addr,temperature[i].pin);
    Serial.print(temperature[i].valeur);
    Serial.println(" C ");
    //Serial.print("\r\n");// ligne blanche pour aérer
    //Serial.print("Tempmoy");
    //Serial.println(" C ");
    //Serial.print("\r\n"); //ligne blanche pour aerer
    
    lcd.begin(20,4);
     lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print(temperature[i].valeur);
     //lcd.clear();
    // lcd.setCursor(0, 0);
   // lcd.print(temperature[i].valeur);
   //lcd clear
   //lcd.setCursor(6,0);
   //lcd.print("3");
    
    lcd.setCursor(6, 0);
   lcd.print(temperature[i].valeur);
   // lcd.print("Row number: ");
  //  lcd.setCursor(16,1);
   // lcd.print("3");
    
     delay(100);

  }
}//fin prog


// Serial.print("\r\n");// ligne blanche pour aérer
//}


 
//void setup()
//{
   // lcd.begin(20,4);
   // lcd.backlight();
   // lcd.setCursor(0, 0);
  //  lcd.print("temperature[i].valeur");
  //  lcd.setCursor(0, 1);
   // lcd.print("Row number: ");
   // lcd.setCursor(16,1);
   // lcd.print("3");
//}
//void loop()
//{
 
//}

 
 
 
 
 
 
 //TempMoy = (temperature[1].valeur + temperature[0].valeur)/2;
// strcpy(TempMoy.mnemo,"TMoy");

// Serial.print("\r\n");// ligne blanche pour aérer

float getStuff(byte addr[8], int pin) // indiquer le n? de pin ? utiliser
{
 //Serial.print("\r\n");// ligne blanche pour aérer
/********************************************************************************
  Cette fonction permet d'interroger le capteur de temperature OneWire
  qui a ?t? d?clar? dans "temperature[i]"
********************************************************************************/

  OneWire  ds(pin);  // creation d'un objet OneWire avec le bon n? de pin

  byte i;
  byte present = 0;
  byte data[12];

  float real_temp;
  float temp_count;
  float read_temp;

// Fonction recherche d?sactiv?e car non utilis?e
/*if ( !ds.search(addr)) {
      Serial.print("No more addresses.\n");
      ds.reset_search();
}


  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 998;
  }
 
  if ( addr[0] != 0x10) {
    Serial.print("Device is not a DS18S20 family device.\n");
    return 999;
  }
*/
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power off at the end (1=parasite mode)
 
  delay(1000);     // delay de 1s si mode parasite. 100ms en mode normal
  // 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


    for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }

  read_temp=((data[1]<<8) | data[0]) >> 1 ;            // Divide the temperature by 2
  temp_count=float(data[7] - data[6])/(float)data[7];  // Convert to real temperature
  real_temp = ((float)read_temp-0.25)+temp_count;

  // arrondi 1 chiffre apres la virgule
  int temp = real_temp*10;
  real_temp = (float)temp/100;

  // Serial.println();
 
  return real_temp;
}

Par la suite je voudrais visualiser ces valeurs graphiquement en temps réel sur un PC. Si c’est plus facile je veux bien essayer directement cette solution sans passer par le stade LCD.

Bonsoir,

J'utilise des sondes ds18b20 et leur mesure est très stable (si la température à mesurer est constante, la sonde va à peine fluctuer) ... Le moyennage me semble superflu et au pire il va intégrer des fluctuations "extérieures" du genre un nuage qui passe devant tes capteurs ...

Tu peux afficher tes valeurs plus rapidement sur le lcd, justement pour voir comment ton système réagit quand tu fais un reglages ou qu'un "événement" extérieur ne vienne perturber ton système.

Si tu veux voir tes courbes sur un pc, il faudra qu'il soit connecté en permanence à ton arduino ... Sinon il faudra ajouter un lecteur de carte sd a l'arduino pour y stocker les valeurs que tu visualisera a posteriori sur le pc ou des solutions de stockage en ligne (via connexion internet)

Ensuite ton code actuel est un peu .... Brouillon ...

il y a une librairie genre dallastemperature qui te facilitera bien la vie ...

Salut,

Librairie pour la gestion des DS18B20 :

https://github.com/milesburton/Arduino-Temperature-Control-Library.

@+