Go Down

Topic: Thermomètre Piscine bluetooth HC06 et HC05 [RESOLU] (Read 554 times) previous topic - next topic

gaelcom

Bonjour à tous et merci d'avance pour le temps que vous prendrez pour me répondre.
J'ai comme projet de réaliser un thermomètre en bluetooth. Le dispositif est le suivant:
1) en mode esclave le HC06 avec le lecteur LCD (le tout connecté à un arduino Pro mini)
2) en mode maître le HC05 qui récupère la température via une thermistance et l'envoie en bluetooth au HC06 qui l'affiche alors. Le HC05 est connecté à un Arduino Uno.

J'ai réussi à appareiller les deux modules HC05 et HC06 (La led du HC05 clignote 2 fois puis s'éteint quelques secondes et cela en boucle alors que la led du HC06 est allumée fixe). J'arrive à afficher via l'IDE la température sur l'écran de mon PC. Le HC05 envoie une information au HC06 qui affiche sur l'écran une valeur qui oscille entre 49 et 55 mais ce n'est pas la température qui est autour de 26 actuellement. J'ai l'impression que dans le code, le HC05 ne peut envoyer d'un byte et non pas une chaîne de caractère d'où le problème que je rencontre. Avez-vous une idée de l'erreur?
Ci-dessous le code Esclave HC06 récupérer sur un site:

Code: [Select]
//arduino nano avec LCD et thermistance suivant branchement du site http://www.circuitbasics.com/arduino-thermistor-temperature-sensor-tutorial/

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
SoftwareSerial ArduinoSlave(10,11); //TX sur 10 RX sur 11
int temp=0;

void setup() {
Serial.begin(9600);
lcd.begin (16,2);
lcd.print ("Temp eau:");
ArduinoSlave.begin(9600);
}

void loop(){
 
  if (ArduinoSlave.available() >0) {
  temp = ArduinoSlave.read();  //gets one byte from serial buffer
     
 
  Serial.print("Temperature: "); //Affichage sur ordi
  Serial.print(temp);
  Serial.println(" C");   

  lcd.setCursor(0,1); //Affichage sur LCD
  lcd.print(temp);   
  lcd.print("C");
 
  delay(1000);           
 // lcd.clear();
 }
   
   }


Le code Maître avec le HC05:
Code: [Select]
//Aller sur site pour comprendre code et montage physique http://www.circuitbasics.com/arduino-thermistor-temperature-sensor-tutorial/

#include <SoftwareSerial.h>                         
SoftwareSerial HC05(10,11); // TX sur 10 et RX sur 11

// Constants
#define DELAY 1000 // Delay between two measurements in ms

// Parameters
int ThermistorPin = 0;

// Variables
float voltage, temperature;
int Vo;
float R1 = 10000;
float logR2, R2, T, Tc, Tf;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

void setup(void) {
  Serial.begin(9600);
  HC05.begin(9600);
}

void loop(void) {
  Vo = analogRead(ThermistorPin);
  Serial.print("Vo=");
  Serial.println(Vo);
  R2 = R1 * (1023.0 / (float)Vo - 1.0);
  logR2 = log(R2);
  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
  Tc = T - 273.15;
  int temp= (int) Tc;

  Serial.print("Temperature: ");
  Serial.print(temp);
  Serial.println(" C");   

  delay(500);
 
 
   // Send voltage and temperature value to app
  HC05.print(temp);
   
 
  delay(DELAY); 

  HC05.flush();
}


Le "bloc" Uno+ Thermistance fonctionne car quand je serre entre mes doigts la thermistance, la température sur l'IDE augmente. Par contre le chiffre visible sur l'écran LCD avec le HC06 ne bouge pas.
Mon montage du "bloc" Pro mini+LCD fonctionne car j'ai pu envoyer dessus du texte via l'IDE.
Je ne pense pas qu'il s'agisse d'un problème de montage mais plus de code.
Une suggestion?

savoriano

#1
Jul 10, 2019, 09:10 am Last Edit: Jul 10, 2019, 09:16 am by savoriano
Je ne suis pas un expert mais je peux te donner une piste.
Code: [Select]
HC05.print(temp);
Envois peut être ta temp en hex sur 2 octets donc pour 26 il envoi 50 et 54.
Si c'est le cas il faut s'attendre à recevoir 2 octets.
Essaye de transformer ta temp en Hex et envoyer ton octet en HEX.
Du côté HC06 tu lis l'octet en HEX et tu le transforme en DEC  
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

lesept

Un lien vers un bon tuto pour apprendre à communiquer sur une liaison série. On en trouve aussi sur le forum dans la section idoine
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

gaelcom

Un lien vers un bon tuto pour apprendre à communiquer sur une liaison série. On en trouve aussi sur le forum dans la section idoine
Merci pour ton retour mais quelque chose m'échappe. Tous les tutos (y compris celui que tu me conseilles) semblent passer par une communication série (Serial print, Serial Available, Serial Read) donc par la liaison serie USB avec l'IDE du PC. N'est-il pas possible de faire communiquer les deux modules HC05 et HC06 sans passer par l'IDE mais uniquement par bluetooth (bibliothèque SoftwareSerial.h)? En effet, j'ai le projet de mettre cela en boitier et donc déconnecté de l'ordinateur.


lesept

Bien sur. Softwareserial comme son nom l'indique est une liaison série, la seule différence est qu'elle n'est pas purement matérielle. Elle est émulée en logiciel
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

gaelcom

Bonjour
Je viens de faire le test suivant. J'ai forcé la température à 1 degré sur le programme avec le HC05. Le HC06 recoit bien l'information et elle s'affiche sur le LCD. Si je change et mets 4 degrés, cela fonctionne également.
Si je force à 25 degrés, j'ai le chiffre 2 qui s'affiche, il disparaît et est remplacé par le chiffre 5. Il me suffit donc d'arriver à afficher sur 2 "pixels" la température. Avez-vous un moyen d'y parvenir?
Merci.

lesept

Tu n'as pas lu le tuto, j'ai l'impression. J-M-L en a fait un similaire aussi.
Les deux t'apprennent à recevoir des données sur plusieurs octets.

Ton code reçoit le permet octet, le '2' et l'affiche.
Puis il reçoit le second octet, '5' et l'affiche. Mais comme ce sont les mêmes lignes de code qui affichent, la second est superposé au premier, affiché au même endroit.

Soit tu fais comme dans le tuto, soit tu comptes les octets, tu calcules la valeur de température lorsque tu as reçu le second et tu affiches lorsque ce calcul est fait, mais pas avant.

Problème, ça ne fonctionne que pour une donnée sur deux octets, c'est un pansement sur une jambe de bois comme on dit chez moi...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

savoriano

#7
Jul 10, 2019, 09:46 pm Last Edit: Jul 10, 2019, 09:48 pm by savoriano
Quote
afficher sur 2 "pixels" la température
et si t'a une température inférieur a -9? Tu aura un problème!
Je trouve que la méthode du tuto est parfaite.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

kamill

Bonjour,

Je suis étonné que ton programme fonctionne pour les valeurs 1 et 4. Tu envoies les valeurs en ascii et tu les interprètes en binaire décimal. Donc pour temp=1 tu devrais afficher 49 (code ascii de '1').

Pour transmettre tu peux utiliser préférentiellement la méthode proposé par lesept, soit tu peux transmettre directement la valeur en binaire pur.
Tu remplaces
  HC05.print(temp);
par
  HC05.write(temp);
Bien sur les températures transmises sont limitées aux valeurs entre 0 et 255.

gaelcom

#9
Aug 20, 2019, 03:26 pm Last Edit: Aug 20, 2019, 03:31 pm by gaelcom
Bonjour,
Après bien des essais (je ne suis pas arrivé à mettre en pratique le tuto qui m'a été conseillé par Lesept), j'ai pu finaliser mon projet et le mettre en boîte. Le tout fonctionne: j'ai un boitier avec une sonde qui plonge dans ma piscine et un circuit imprimé avec écran LCD dans ma maison afin de lire toutes les demi-heures la température de l'eau par liaison bluetooth. J'en ai profité pour mettre en sommeil le module avec la sonde (alimenté par 4 piles 1,5v), le boitier intérieur avec le LCD est lui directement alimenté par du 5v depuis un petit transformateur.
Le seul problème que je n'arrive pas à corriger c'est l'affichage juste après la température de deux sigles composés de 4 barres horizontales (à droite de 27.00, cf. photo). Je ne comprends pas d'où cela provient. Si vous avez une idée?
Ci-joint le code de la sonde:
Code: [Select]
//Aller sur site pour comprendre code et montage physique http://www.circuitbasics.com/arduino-thermistor-temperature-sensor-tutorial/

#include "LowPower.h"
#include <SoftwareSerial.h>                          
SoftwareSerial HC05(10,11); // TX sur 10 et RX sur 11
#include <OneWire.h>

// Constants
#define DELAY 500 // Delay between two measurements in ms
//ISR(WDT_vect) {Sleepy::watchdogEvent();} //setup the watchdog

// Parameters
const byte BROCHE_ONEWIRE = A0;
int alimSonde=5;


/* Code de retour de la fonction getTemperature() */
enum DS18B20_RCODES {
  READ_OK,  // Lecture ok
  NO_SENSOR_FOUND,  // Pas de capteur
  INVALID_ADDRESS,  // Adresse reçue invalide
  INVALID_SENSOR  // Capteur invalide (pas un DS18B20)
};


/* Création de l'objet OneWire pour manipuler le bus 1-Wire */
OneWire ds(BROCHE_ONEWIRE);
 
 
/**
 * Fonction de lecture de la température via un capteur DS18B20.
 */
byte getTemperature(float *temperature, byte reset_search) {
  byte data[9], addr[8];
  // data[] : Données lues depuis le scratchpad
  // addr[] : Adresse du module 1-Wire détecté
  
  /* Reset le bus 1-Wire ci nécessaire (requis pour la lecture du premier capteur) */
  if (reset_search) {
    ds.reset_search();
  }
 
  /* Recherche le prochain capteur 1-Wire disponible */
  if (!ds.search(addr)) {
    // Pas de capteur
    return NO_SENSOR_FOUND;
  }
  
  /* Vérifie que l'adresse a été correctement reçue */
  if (OneWire::crc8(addr, 7) != addr[7]) {
    // Adresse invalide
    return INVALID_ADDRESS;
  }
 
  /* Vérifie qu'il s'agit bien d'un DS18B20 */
  if (addr[0] != 0x28) {
    // Mauvais type de capteur
    return INVALID_SENSOR;
  }
 
  /* Reset le bus 1-Wire et sélectionne le capteur */
  ds.reset();
  ds.select(addr);
  
  /* Lance une prise de mesure de température et attend la fin de la mesure */
  ds.write(0x44, 1);
  delay(800);
  
  /* Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad */
  ds.reset();
  ds.select(addr);
  ds.write(0xBE);
 
 /* Lecture du scratchpad */
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
  
  /* Calcul de la température en degré Celsius */
  *temperature = (int16_t) ((data[1] << 8) | data[0]) * 0.0625;
  
  // Pas d'erreur
  return READ_OK;
}
 



void setup(void) {
  Serial.begin(9600);
  HC05.begin(9600);
  pinMode(alimSonde, OUTPUT);
}

/** Fonction loop() **/
void loop() {
  float temperature;
  digitalWrite(alimSonde, LOW);
 sleepForThirtyMinutes();

  digitalWrite(alimSonde, HIGH);
  delay(15000); //délai pour permettre aux deux modules bluetooth de se reconnaitre

  
  
  /* Lit la température ambiante à ~1Hz */
  if (getTemperature(&temperature, true) != READ_OK) {
    Serial.println(F("Erreur de lecture du capteur"));
    return;
  }

  /* Affiche la température sur écran ordinateur */
  Serial.print(F("Temperature : "));
  Serial.print(temperature, 2);
 // Serial.write(176); // Caractère degré
 Serial.write('C');
  Serial.println();




  
  
   // Send temperature value to app
    
  HC05.println(temperature);
    
  delay(DELAY);  

 HC05.flush();

}

void sleepForThirtyMinutes()
{
  for(int i=0;i<225;i++)
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
}


Et le code de l'écran LCD récepteur
Code: [Select]
#include <LiquidCrystal.h>
#include <SoftwareSerial.h>


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
SoftwareSerial bluetooth (10,11); //TX sur 10 RX sur 11

String content;
char character;

void setup() {
Serial.begin(9600);
lcd.begin (16,2);
lcd.print ("Temp eau piscine:");
bluetooth.begin(9600);
}

void loop(){
 
 while(bluetooth.available()){
    character = bluetooth.read();
    content.concat(character);
   if(character == '\r'){ // find if there is carriage return
     content = ""; //clear buffer
     Serial.println();}

      
  
  Serial.print("Temperature: "); //Affichage sur ordi
  Serial.print(content);
  Serial.println(" C");    

  lcd.setCursor(0,1); //Affichage sur LCD
  lcd.print(content);  
 // lcd.print("C");
  
  delay(1000); }   }        

kamill

Tu fais un     Serial.println(" C");
Ton lcd ne traite pas les sauts de ligne et affiche donc n'importe quoi.
Fais simplement     Serial.print(" C");

gaelcom

Tu fais un     Serial.println(" C");
Ton lcd ne traite pas les sauts de ligne et affiche donc n'importe quoi.
Fais simplement     Serial.print(" C");
Serial.println ("C") c'est pour l'affichage sur l'écran de l'ordinateur. A ce niveau là ça fonctionne, c'est l'affichage sur le LCD qui pose problème. J'ai d'ailleurs mis le "C" en commentaire dans mon code pour l'affichage LCD ( // lcd.print("C")). Si j'enlève le //, cela m'affiche la température suivie des deux symboles avec les 4 barres horizontales puis le C.


kamill

#12
Aug 20, 2019, 04:45 pm Last Edit: Aug 20, 2019, 04:48 pm by kamill
Oups. Autant pour moi, je voulais parler du lcd
Tu es sur que tu n'as pas fait un lcd.println()? car ça fait exactement ce que tu montres sur la photo.

gaelcom

Oups. Autant pour moi, je voulais parler du lcd
Tu es sur que tu n'as pas fait un lcd.println()? car ça fait exactement ce que tu montres sur la photo.
Je viens de téléverser le code du dessus (lcd.print(content)) et j'ai toujours les deux symboles.

supercc

Bonjour,

pour laisser le temps à kamill de deboguer la bibliothèque lcd ;-)

Et lcd.println("3.14"); ?
Et lcd.println(content+"      "); ?


Go Up