Débimètre et Bluetooth

Bonjour,
J'ai pour projet de mesurer le volume d'eau lorsque je prend ma douche !
pour cela j'ai une carte bluetooth HC-05 et un capteur de débit
Voici le code pour le capteur de débit :

double flow; //Liters of passing water volume
unsigned long pulse_freq;

void setup()
{
  pinMode(2, INPUT);
  Serial.begin(9600);
  attachInterrupt(0, pulse, RISING); // Setup Interrupt
  
}

void loop ()
{
    flow = .00225 * pulse_freq;
    Serial.print(flow, DEC);
    Serial.println("L");
    delay(500);
  
}
void pulse () // Interrupt function

{
  pulse_freq++;
}

Comment est ce que je peux maintenant transmettre ces informations sur mon smartphone grâce aux bluetooth de façon à avoir les données ?
Un grand merci pour votre aide !!

Bonjour kaertblan

Si tu as un UNO, les données sont transmises au HC-05 via SoftwareSerial et pour le smartphone, tu as MIT App Inventor pour écrire l'application.

Cordialement
jpbbricole

Bonjour @kaertblan

alternative à la création, avec MIT App Inventor, d'une application dédiée : utiliser une application polyvalente (Android) configurée et pilotée intégralement par le code côté Arduino et gérant toutes les trois le Bluetooth Classique des HC-05:
Gui-O
RemoteXY
Bluetooth Electronics

les solutions ne manquent donc pas pour réceptionner en BT+ visualiser les données sur l'écran du smartphone... il y en a pour tous le goûts !

Bonjour al1fch

Oupsss! J'avais oublié cette excellent application et surtout simple à mettre en œuvre :wink:

Cordialement
jpbbricole

Bonsoir @jpbbricole
je trouve également que ce type d'application rend de grands services avec très peu d'efforts :wink: !

(de mon côté GUI-O a pris la place de Bluetooth Electronics en raison du vaste choix de connections possibles entre Arduino ou ESP32 et le smartphone : USB Host, WiFi + MQTT , BT, BLE au prix d'un petit effort de codage)

Bluetooth Electronics a fait des émules. et n'évolue plus

Bien entendu si on envisage du traitement de données sur le smartphone il faut passer à Mit App Inventor .....avec une courbe d'apprentissage plus longue...

1 Like

Dans ton code, il fait remettre pulse_freq à zéro, sinon ton débit va (apparement) augmenter, augmenter ...

Okay merci mais dans mon programme je voudrais faire un système de session (avec un selecteur). J'utilise RemoteXY ! :slight_smile:
Par exemple quand je sélectionne la session 0 alors j'obtiens la valeur du débit d'eau particulière... Pareil pour session 1,2 et 3.
Tous les résultats sont exprimés sous la forme d'un graphique.
Le problème est que les valeurs sont gérer par un seul et même compteur d'impulsions... donc à chaque fois que je change de session mes débits s'incrémente directement par rapport aux derniers....avez-vous des solutions ?

Voici mon code

double totalflow; // Liters of passing water volume
double flow1; // Liters of passing water volume
double flow2; // Liters of passing water volume
double flow3; // Liters of passing water volume
double flow4; // Liters of passing water volume
unsigned long pulse_freq;



//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library 
#define REMOTEXY_MODE__SOFTSERIAL
#include <SoftwareSerial.h>
#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL_RX 10
#define REMOTEXY_SERIAL_TX 11
#define REMOTEXY_SERIAL_SPEED 9600


// RemoteXY configurate  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =   // 30 bytes
  { 255,1,0,20,0,23,0,16,31,1,3,132,11,15,41,11,2,26,68,21,
  4,45,56,48,8,36,135,94,204,233 };
  
// this structure defines all the variables and events of your control interface 
struct {

    // input variables
  uint8_t select_1; // =0 if select position A, =1 if position B, =2 if position C, ... 

    // output variables
  float onlineGraph_1_var1;
  float onlineGraph_1_var2;
  float onlineGraph_1_var3;
  float onlineGraph_1_var4;
  float onlineGraph_1_var5;

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

void setup() 
{
  RemoteXY_Init (); 
  pinMode(2,INPUT);
  attachInterrupt(0, pulse, RISING); // Setup Interrupt 
}

void loop() 
{ 
  RemoteXY_Handler ();
  if (RemoteXY.select_1 == 3) {
    // Si select_1 est égal à 3
  flow4 = 0.00225 * pulse_freq;
  RemoteXY.onlineGraph_1_var4 = float (flow4);
} else if (RemoteXY.select_1 == 2) {
    // Si select_1 est égal à 2
  flow3 = 0.00225 * pulse_freq;
  RemoteXY.onlineGraph_1_var3 = float (flow3);
} else if (RemoteXY.select_1 == 1) {
    // Si select_1 est égal à 1
  flow2 = 0.00225 * pulse_freq;
  RemoteXY.onlineGraph_1_var2 = float (flow2);
} else if (RemoteXY.select_1 == 0) {
    // Si select_1 est égal à 0
  flow1 = 0.00225 * pulse_freq;
  RemoteXY.onlineGraph_1_var1 = float (flow1);
}
 double totalflow = flow1 + flow2 + flow4+ flow3; // Additionner les trois variables
  RemoteXY.onlineGraph_1_var5 = float (totalflow);

  RemoteXY_delay(1000) ;
  }
void pulse() // Interrupt function
{
  pulse_freq++;
}

Merci beaucoup :slight_smile:

Et bin tu remets ton compteur à zéro:

  • à chaque fois que tu le lis pour calculer un débit
  • à chaque fois que tu changes de session

Oui je pensais comme toi et j'ai bien modifié selon tes indications mais avec attachInterrupt et mon void pulse ça ne fonctionne pas je pense....
Mon débit est toujours égale à zéro et ne décolle jamais :disappointed_relieved:

double totalflow; // Liters of passing water volume
double flow1; // Liters of passing water volume
double flow2; // Liters of passing water volume
double flow3; // Liters of passing water volume
double flow4; // Liters of passing water volume
unsigned long pulse_freq = 0; // Initialise pulse_freq à zéro
//////////////////////////////////////////////
//        RemoteXY include library          //
//////////////////////////////////////////////

// RemoteXY select connection mode and include library 
#define REMOTEXY_MODE__SOFTSERIAL
#include <SoftwareSerial.h>
#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL_RX 10
#define REMOTEXY_SERIAL_TX 11
#define REMOTEXY_SERIAL_SPEED 9600


// RemoteXY configurate  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =   // 30 bytes
  { 255,1,0,20,0,23,0,16,31,1,3,132,11,15,41,11,2,26,68,21,
  4,45,56,48,8,36,135,94,204,233 };
  
// this structure defines all the variables and events of your control interface 
struct {

    // input variables
  uint8_t select_1; // =0 if select position A, =1 if position B, =2 if position C, ... 

    // output variables
  float onlineGraph_1_var1;
  float onlineGraph_1_var2;
  float onlineGraph_1_var3;
  float onlineGraph_1_var4;
  float onlineGraph_1_var5;

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

void setup() 
{
  RemoteXY_Init (); 
  pinMode(2,INPUT);
  attachInterrupt(0, pulse, RISING); // Setup Interrupt 
//  Serial.begin(9600);
}


void loop() 
{ 
  RemoteXY_Handler ();

  if (RemoteXY.select_1 == 3) {
    // Si select_1 est égal à 3
    pulse_freq = 0; // Réinitialiser pulse_freq
    flow4 = 0.00225 * pulse_freq;
    RemoteXY.onlineGraph_1_var4 = float(flow4);
  } else if (RemoteXY.select_1 == 2) {
    // Si select_1 est égal à 2
    pulse_freq = 0; // Réinitialiser pulse_freq
    flow3 = 0.00225 * pulse_freq;
    RemoteXY.onlineGraph_1_var3 = float(flow3);
  } else if (RemoteXY.select_1 == 1) {
    // Si select_1 est égal à 1
    pulse_freq = 0; // Réinitialiser pulse_freq
    flow2 = 0.00225 * pulse_freq;
    RemoteXY.onlineGraph_1_var2 = float(flow2);
  } else if (RemoteXY.select_1 == 0) {
    // Si select_1 est égal à 0
    pulse_freq = 0; // Réinitialiser pulse_freq
    flow1 = 0.00225 * pulse_freq;
    RemoteXY.onlineGraph_1_var1 = float(flow1);
  }

  double totalflow = flow1 + flow2 + flow4 + flow3; // Additionner les débits
  RemoteXY.onlineGraph_1_var5 = float(totalflow);

  RemoteXY_delay(1000);
}
void pulse() // Interrupt function
{
  pulse_freq++;
}

A ton avis, que vaut flow4 ? :thinking:
Tu remets pulse_freq à zéro avant de l'utiliser !!!

De plus, comme pulse_freq est modifié sous interruption, tu dois le déclarer volatile:
volatile unsigned long pulse_freq = 0; // Initialise pulse_freq à zéro

Ouiii c'est vrai le bétâ ici... :sweat_smile:
Mais du coup je fais comment ? :thinking:
Merci pour cette suptilité (désolé je débute :slight_smile: )

bin ????? tu inverses les lignes:

flow4 = 0.00225 * pulse_freq;
pulse_freq = 0; // Réinitialiser pulse_freq

idem pour les autres flow1, 2, 3...
et n'oublie pas le qualificatif volatile (rien à voir avec les poulets :slight_smile:) dans la déclaration (comme je l'ai écrit plus haut)

Oui j'avais compris ça mais j'obtiens une courbe qui dès que l'écoulement s'arrête elle revient à zéro.... (à cause du pulse_freq que je réinitialise à zéro)...

Comme ceci:

Moi ce que je voudrais c'est avoir le volume donc un graphique qui ne fait que s'incrémenter pour avoir la consommation d'eau de la personne 1 puis de la personne 2 etc...

Et ça reviens toujours au problème de l'incrémentation car quand je change de session vu que mon pulse_freq est par exemple égale à 50 quand je change de session j'aimerai que pulse_freq retourne à 0 ! Je sais pas si c'est compréhensible :sweat_smile:

Si tu veux cumuler, il faut a moment ou un autre que tu cumule des valeurs non?
Par exemple si ta courbe violet représente la variable flow1.
donc a chaque fois que tu passe sur une instruction flow1 = 0.00225 * pulse_freq, tu perds tout historique.
As tu essayer plutôt de cumuler les valeurs avec flow += 0.00225 * pulse_freq ?

Ce que tu veux faire s'appelle une intégration. C'est à dire un cumul.
Il te faut deux variables (par session)
flow pour le débit (c-à-d flow1, flow2...)
volume pour le cumul.
donc, à chaque étape:

flow4 = 0.00225 * pulse_freq;
volume4 = volume4 + flow4 * delta_t;
pulse_freq = 0; // Réinitialiser pulse_free

où delta_t est l'intervalle de temps entre deux mesures.
Si flow s'exprime en litres/seconde, alors delta_t doit être en secondes, ainsi volume est en litres.
Initialiser les volumes à zéro (au bon moment)

j'ai compris ce que tu as fais merci et je pense que c'est un bon moyen oui mais comment je peux déclarer delta_t comme étant l'intervalle de temps entre deux mesures ?! :sweat_smile:
De plus je l'ai sans doute mal présenter mais flow me donne un volume en litre ! (je sais c'est incohérent je vais réctifier dans le code haha)

Bonjour @kaertblan

comment je peux déclarer delta_t comme étant l'intervalle de temps entre deux mesures ?!

Si tu ne gères pas toi même la cadence des mesures tu peux lire la valeur de millis() à chaque mesure puis calcule delta_t par la différence entre deux valeurs successives

@al1fich a raison : utilises milles() à chaque lecture. Attention millis() donne des millisecondes, à diviser par 1000. pour avoir des secondes (le point collé à 1000 est fondamental)

Dans ton code tu utilises un facteur 0.00225 pour convertir le nombre d'impulsions en volume : ça sort d'où ? probablement de la documentation du capteur ? cette dernière doit absolument préciser quelles sont les unités utilisées. Si tu ne sais pas si ça donne des litres/seconde, des gallons/secondes ou des chopes à bière par seconde, tu ne peux rien en faire !
Et puis, pour être précis, flow ne donne pas, comme tu écris, un volume (en litre ou autre chose) mais un débit (en litres/seconde ou machins/seconde)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.