Go Down

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

kamill

Si tu ne fais pas de println, c'est que content contiens des caractères non imprimables (\r\n peut être).
Avant de faire ton lcd.print(content); fais content.trim();

gaelcom

Si tu ne fais pas de println, c'est que content contiens des caractères non imprimables (\r\n peut être).
Avant de faire ton lcd.print(content); fais content.trim();
Merci, ça fonctionne!
Par contre du coup, je souhaite afficher sur le LCD le "C" après la température. Code ci-joint
Code: [Select]
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
  content.trim();
  lcd.print(content);   
  lcd.print("C");
 
  delay(1000);
  }
  }       


Et là, j'ai l'aperçu suivant (cf. photo). Je ne comprends pas pourquoi le "C" se met avant et après la lecture de température. Je lis C5.06C au lieu de 25.06C
Pour être plus précis, j'ai l'affichage en plusieurs étapes:
1) 2
2) 25
3) 25.
4) 25.0
5) 25.06
6) 25.06C
7) C5.06C

Merci de me donner ton éclairage.

kamill

Parce que tu affiches aussi quand content est vide.
Testes si content est vide avant d'afficher avec if (content!="")

gaelcom

Je me suis trompé, voici ce qui s'affiche:
1) 2C
2) 25C
3) 25.C
4) 25.0C
5) 25.06C
6) 25.06C
7) C5.06C

J'ai essayé avec en testant content !="" mais cela ne fonctionne pas.
Code: [Select]
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");   

 if (content!=""){
  lcd.setCursor(0,1); //Affichage sur LCD
  content.trim();
  lcd.print(content);
  lcd.print("C");  }
 
 
 
  delay(1000);
  }
  }        [code]

savoriano

Après le '\r' peut être que il y a un '\n', et c'est ce dernier qui dérange.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

kamill

Il faut mettre le trim() avant le if

gaelcom

Grandiose. Ça fonctionne. Merci! ;)


kamill



gaelcom

#25
Aug 24, 2019, 04:48 am Last Edit: Aug 24, 2019, 05:02 am by gaelcom
Bon, finalement je n'en ai pas fini!
J'ai voulu comprendre et appliquer le tuto conseillé par lesept, tutoriel rédigé par Gammon https://www.gammon.com.au/serial

J'en ai profité pour ajouter comme indication sur l'écran en plus de la température la tension de la batterie.
J'ai pas mal galéré pour parvenir à dissocier les deux et à afficher le "C" après la témpérature et le "V" après la tension (cf. photo; à ce sujet la photo est trompeuse, il y a bien une virgule après chaque chiffre avec deux zéros mais ce sont bien des valeurs arrondies). Pour se faire j'ai utilisé des délimiteurs de début et de fin différents pour les deux paramètres.
Le seul hic, c'est que le tutoriel de Gammon vaut pour des nombres entiers. J'ai donc préparé mes codes en fonction.

code 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>
//# include <JeeLib.h> // Appel librairie pour économiser batterie


// Constants
#define DELAY 500 // Delay between two measurements in ms
//ISR(WDT_vect) {Sleepy::watchdogEvent();} //setup the watchdog
const char startOfNumberDelimiter = '<';
const char endOfNumberDelimiter   = '>';
const char startOfNumberDelimiter1  = '[';
const char endOfNumberDelimiter2  = ']';


// Parameters
const byte BROCHE_ONEWIRE = A0;
//int ThermistorPin = 0;
int alimSonde=5;
const int tensionPiles=A1;


/* 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(int *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);
  pinMode(tensionPiles, INPUT);

}

/** Fonction loop() **/
void loop() {
  int temperature;
  digitalWrite(alimSonde, LOW);
sleepForTwoMinutes();

  digitalWrite(alimSonde, HIGH);
 delay(8000);

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

 
  /*lit tension piles rechargeables*/
  int lectureTensionPiles=analogRead(tensionPiles);
  float valeurTensionPiles=lectureTensionPiles*(5.0/1023.0);
  int TensionPiles = (int)valeurTensionPiles; //transformer float en entier
 
 
   
   // Send voltage and temperature value to app
  HC05.print (startOfNumberDelimiter); 
  HC05.print(temperature);//essayer HC05.println (temperature,2);
  HC05.print (endOfNumberDelimiter);
 
  HC05.print (startOfNumberDelimiter1);
  HC05.print(TensionPiles);
  HC05.print (endOfNumberDelimiter2);

     
  delay(DELAY); 


}

void sleepForTwoMinutes()
{
  for(int i=0;i<1;i++)
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); //Mise en sommeil pendant 8s (à terme une mesure toutes les demi-heures)
}


code affichage LCD

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 bluetooth (10,11); //TX sur 10 RX sur 11

char c;

const char startOfNumberDelimiter = '<';
const char endOfNumberDelimiter   = '>';
const char startOfNumberDelimiter1  = '[';
const char endOfNumberDelimiter2  = ']';

static long receivedNumber = 0;
static boolean negative = false;

void setup() {
Serial.begin(9600);
lcd.begin (16,2);
lcd.print ("Temp eau piscine:");
bluetooth.begin(9600);
lcd.setCursor(0,1); //Affichage sur LCD
}

void processNumber (float n)
  {
    lcd.print(n);
  }  // end of processNumber

void loop(){
 lcd.setCursor(0,1); //Affichage sur LCD
 while(bluetooth.available()){
   c = bluetooth.read();
Serial.println (c);

 
  switch (c)
    {
     
    case endOfNumberDelimiter:  //pour la température
        processNumber (receivedNumber);
        lcd.print ("C ");   
        break;

    case endOfNumberDelimiter2:  // pour la tension
        processNumber (receivedNumber);
        lcd.print ("V");
        break;

    // fall through to start a new number (température)
    case startOfNumberDelimiter:
        receivedNumber = 0;
        negative = false;
        break;

     // fall through to start a new number (tension)
     case startOfNumberDelimiter1:
         receivedNumber = 0;
         negative = false;
         break;
     
    case '0' ... '9':
        receivedNumber *= 10;
        receivedNumber += c - '0';
        break;     
       
    } // end of switch 
  }  // end of processInput

 
 }
   
   
 
 



Je souhait désormais afficher la température et la tension avec des nombres à virgule donc des float. Et là je sèche...

Auriez-vous une idée, tout en respectant le recours aux délimiteurs (<>, []), très pratiques pour dissocier les informations?
Merci d'avance :)

kamill

#26
Aug 24, 2019, 08:57 am Last Edit: Aug 24, 2019, 08:59 am by kamill
Bonjour,

Tu transformes tes float en entier. Il suffit de ne pas le faire et de conserver les float.
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>
//# include <JeeLib.h> // Appel librairie pour économiser batterie


// Constants
#define DELAY 500 // Delay between two measurements in ms
//ISR(WDT_vect) {Sleepy::watchdogEvent();} //setup the watchdog
const char startOfNumberDelimiter = '<';
const char endOfNumberDelimiter   = '>';
const char startOfNumberDelimiter1  = '[';
const char endOfNumberDelimiter2  = ']';


// Parameters
const byte BROCHE_ONEWIRE = A0;
//int ThermistorPin = 0;
int alimSonde=5;
const int tensionPiles=A1;


/* 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 =((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);
  pinMode(tensionPiles, INPUT);

}

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

  digitalWrite(alimSonde, HIGH);
 delay(8000);

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

 
  /*lit tension piles rechargeables*/
  int lectureTensionPiles=analogRead(tensionPiles);
  float TensionPiles=lectureTensionPiles*(5.0/1023.0);
 
 
   
   // Send voltage and temperature value to app
  HC05.print (startOfNumberDelimiter); 
  HC05.print(temperature,2);
  HC05.print (endOfNumberDelimiter);
 
  HC05.print (startOfNumberDelimiter1);
  HC05.print(TensionPiles,2);
  HC05.print (endOfNumberDelimiter2);

     
  delay(DELAY); 


}

void sleepForTwoMinutes()
{
  for(int i=0;i<1;i++)
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); //Mise en sommeil pendant 8s (à terme une mesure toutes les demi-heures)
}

gaelcom

Bonjour,

Tu transformes tes float en entier. Il suffit de ne pas le faire et de conserver les float.
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>
//# include <JeeLib.h> // Appel librairie pour économiser batterie


// Constants
#define DELAY 500 // Delay between two measurements in ms
//ISR(WDT_vect) {Sleepy::watchdogEvent();} //setup the watchdog
const char startOfNumberDelimiter = '<';
const char endOfNumberDelimiter   = '>';
const char startOfNumberDelimiter1  = '[';
const char endOfNumberDelimiter2  = ']';


// Parameters
const byte BROCHE_ONEWIRE = A0;
//int ThermistorPin = 0;
int alimSonde=5;
const int tensionPiles=A1;


/* 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 =((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);
  pinMode(tensionPiles, INPUT);

}

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

  digitalWrite(alimSonde, HIGH);
 delay(8000);

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

 
  /*lit tension piles rechargeables*/
  int lectureTensionPiles=analogRead(tensionPiles);
  float TensionPiles=lectureTensionPiles*(5.0/1023.0);
  
 
    
   // Send voltage and temperature value to app
  HC05.print (startOfNumberDelimiter);  
  HC05.print(temperature,2);
  HC05.print (endOfNumberDelimiter);
  
  HC05.print (startOfNumberDelimiter1);
  HC05.print(TensionPiles,2);
  HC05.print (endOfNumberDelimiter2);

      
  delay(DELAY);  


}

void sleepForTwoMinutes()
{
  for(int i=0;i<1;i++)
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); //Mise en sommeil pendant 8s (à terme une mesure toutes les demi-heures)
}

De retour de congé, je m'y remets...
J'ai fait comme tu me l'as indiqué, par contre, maintenant j'ai l'affichage suivant:
2587.00C  500.00V au lieu de 25.87C  5.00V
Quand je fais un Serialprint(température) et Serialprint(valeurTensionPiles) sur l'arduino qui comporte la sonde, j'ai bien 25.87 et 5.00 qui s'affichent. L'erreur provient donc du code qui permet l'affichage.
J'ai bien essayé de diviser les valeurs par 100.0 mais du coup je me retrouve avec l'affichage suivant : 26.00C  5.00V. Ce sont des valeurs arrondies du coup.
Je bataille depuis plus d'une heure et je ne comprends pas. Help!
Besoin de tes lumières Merci :)

kamill

#28
Sep 01, 2019, 10:58 am Last Edit: Sep 01, 2019, 11:32 am by kamill
Bonjour,

Tu as un problème en réception. Tu ne traites pas le point décimal.

Le plus simple serait de faire ça en réception
Code: [Select]
void processNumber (float n)
  {
    lcd.print(n/100.0);
  }  // end of processNumber


mais il serait mieux de traiter correctement la réception du float car si tu modifies le nombre de chiffres après la virgule ça ne va plus fonctionner.

Tu peux aussi plus simplement afficher la chaîne de caractères reçue telle quelle.

gaelcom

Effectivement dans cette partie de code, le point décimal n'est pas traité.
Code: [Select]
case '0' ... '9':
        receivedNumber *= 10;
        receivedNumber += c - '0';
        break;     


As-tu une piste à me proposer?

Go Up