domotisation cuve 1000L - modif mysensors

Bonjour à tous

Voila j'ai besoin de votre aide pour modifier un capteur mysensors afin de domotiser ma cuve de 1000L.

Pour les connaisseurs le site mysensors propose le montage suivant:

le capteur se monte en général sur le bouchon et envoie un "Ping" et donne la distance entre le haut de l'eau et le capteur.


N'aimant pas ce type de capteur et surtout au vue des retours sur la vie des capteurs en milieu humide j'ai plutôt préféré une méthode plus mécanique a savoir des capteurs flottant immergé (10 au totals) monté sur un tube étanche.

ce que je souhaite c'est remplacer la procédure de ping par un contrôle de ces fameux capteurs

en gros le système vérifie les entrées et envoie la valeur la plus haute.

je m'explique:

lorsque le système "ping" je souhaite qu'il vérifie la pin correspondante au capteur le plus haut actionné

exemple - jusqu’à maintenant c’était le capteur L200 qui était validé et lors de ce ping c'est le L400

le montage renvoie la nouvelle information de 400L

-si jamais la cuve est toujours a 200 le montage ne change rien


par rapport au programme d'origine j'ai retirer ce qui concernait le newping

ainsi que ce qui concerne le capteur

j'ai rajouté en définition:

#define L100_PIN  3  // Arduino pin 100 Litres
#define L200_PIN  4  // Arduino pin 200 Litres
#define L300_PIN  5  // Arduino pin 300 Litres
#define L400_PIN  6  // Arduino pin 400 Litres
#define L500_PIN  7  // Arduino pin 500 Litres
#define L600_PIN  8  // Arduino pin 600 Litres
#define L700_PIN  A0  // Arduino pin 700 Litres
#define L800_PIN  A1  // Arduino pin 800 Litres
#define L900_PIN  A2  // Arduino pin 900 Litres
#define L101_PIN  A3  // Arduino pin 1000 Litres

qui correspond aux flotteurs dans la cuve


maintenant voila la partie que je souhaite modifier, j'ai supprimer la partie de ligne de code suivante

int dist = [color=red]metric?sonar.ping_cm():sonar.ping_in();[/color]

et dans le code j'aimerai que ce soit la qu'on aille contrôler la valeur de capteur la plus haute mais je ne sait pas comment faire

MyMessage msg(CHILD_ID, V_DISTANCE);
int lastDist;
bool metric = true;

void setup()  
{ 
  metric = getControllerConfig().isMetric;
}

void presentation() {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Distance Sensor", "1.0");

  // Register all sensors to gw (they will be created as child devices)
  present(CHILD_ID, S_DISTANCE);
}

void loop()      
{     
  int dist = [color=limegreen]Controle la valeur la plus haute du capteur [/color]
  Serial.print("Ping: ");
  Serial.print(dist); // Convert ping time to distance in cm and print result (0 = outside set distance range)
  Serial.println(metric?" cm":" in");

  if (dist != lastDist) {
      send(msg.set(dist));
      lastDist = dist;
  }

  sleep(SLEEP_TIME);
}

si quelqu’un peut m'aider a faire ça ce serait bien gentil

bonne soirée et bonne fin de confinement :slight_smile:

Je trouve que tu devrais partir d'une feuille vierge pour ce programme .

J'ai fait un système similaire pour ma serre . De mémoire, l'état de chaque entrée est soit à 1 ou à 0.

J'avais fait une variable qui était une somme de tous les états en mettant un coeff .

Ca donnait un truc du genre (pour 4 flotteurs )

int total = etat11000 + etat2100 + etat3*10 + etat4.

si tout est plein , tu as donc total = 1111; si c'est vide 0 . Si c'est à la moitié 11. Au 3/4 , 111.

Avec un switch case (ou des if), tu codes ce que tu veux en fonction de la valeur de total .

Ca marche , c'est sans doute pas trés académique mais bon ..

bonjour

merci pour ta réponse le problème c’est que partir d’un programme vierge pose le soucis de ne plus avoir le fonctionnement mysensors

S_DISTANCE n'est certainement pas approprié, ni V_DISTANCE d'ailleurs.

Le dispositif devrait être plutôt être du type S_WATER et le message envoyé du type V_VOLUME.

Ensuite je ne connais pas l'unité de base employée par le serveur mais quelle soir en litres, en dm3 ou en m3 importe peu. Tu multiplies ou tu divises comme cela t'arrange.

merci pour ta réponse le problème c'est que partir d'un programme vierge pose le soucis de ne plus avoir le fonctionnement mysensors

C'est clairement évident.

Bonjour,
Je me permets de te donner une idée pour faire ton montage.
Tu peux prendre un capteur à ultrason que tu mets sur le bouchon avec un arduino nano.
J’ai fait un montage qui va t’aider. Il s’agit du niveau aval et amont d’une grille.
Le programme est avec. Tu peux t’en inspirer. C’est assez simple.

Il peut afficher le volume sur un ecran:

[/#include <LiquidCrystal.h>
#include <Wire.h>

int niveau_aval = 0 ;// déclaration de la variable en entier niveau_aval et initialisation à 0
int niveau_amont = 0 ;// déclaration de la variable en entier niveau_amont et initialisation à 0
int difference =0 ;// déclaration de la variable différence et initialisation à 0
int UltrasonicReturnCM(int trigPin, int echoPin)// déclaration du renvoie de la fonction en entier avec declaration en entier des paramètres utiliser
{
  long duration;
  int mesure; // déclaration du renvoie d'une fonction en entier avec declaration en entier des paramètres utilisés
  pinMode(trigPin, OUTPUT); // déclaration 
  pinMode(echoPin, INPUT);// déclaration
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2); // attendre 2 microsecondes
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(20);// attendre 10 microsecondes
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);//
  
  mesure = duration / 59; // 58,8 ;// x0,0017 cm
 if ((mesure < 2) || (mesure > 300)){ return false;}
return mesure;
}
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// déclaration de l'afficheur LCD sur les broches 12,11 5,4,3,2

void setup()// fonction principale ||
{
  niveau_aval = 0 ;// initialisation à 0
  niveau_amont = 0 ;// initialisation à 0
  difference =0 ;// initialisation à 0
  
  pinMode( 10 , OUTPUT);// configurer la broche 10 en sortie
 
  lcd.begin(20, 4);// configurer afficheur lcd de 20 caractères sur 4 lignes
  

}

void loop()// fonction boucle
{
 
  
  (niveau_aval) = UltrasonicReturnCM( 9, 8 ) ;// niveau_aval égal la valeur que retour la fonction UltrasonicReturnCM pour le module 1 à ultrason en broche 8 ET 9
  
  //delay(10);//attendre 100 miliseconde
  
  (niveau_amont) = UltrasonicReturnCM( 7, 6 ) ;// niveau_amont égal la valeur que retour la fonction UltrasonicReturnCM pour le module 2 à ultrason en broche 7 ET 6
   
   //delay(10);//attendre 100 miliseconde
  
  
  difference = (( niveau_amont ) - ( niveau_aval ));// calcul de la difference entre ces deux valeurs de chaque mesure
  
 
  if (difference > 1){ // boucle si le difference entre ces deux valeurs est supèrieur à 1 cm faire:
    
    digitalWrite(10 , HIGH);// écrire niveau haut sur broche 10
    
  }
  else{ //si non faire:
    
    digitalWrite(10 , LOW);// écrire niveau bas sur broche 10
   
  }

  
  lcd.setCursor(0, 0);// mettre le depart curseur à la ligne 0 et à la colonne 0
  
  lcd.print( "niveau aval:  " );
  lcd.print( niveau_aval );
  lcd.print( " cm" );
  
  lcd.setCursor(0, 1);// mettre le depart curseur à la ligne 1 et à la colonne 0
  lcd.print( "niveau amont: " );
  lcd.print( niveau_amont );
  lcd.print( " cm" );
  
  lcd.setCursor(0, 2);// mettre le depart curseur à la ligne 1 et à la colonne 0
  lcd.print( "la difference:" );
  
 lcd.print( difference );
  lcd.print( " cm" );
  
  delay(4000);// attendre 4000 milisecondes ou 4 s
  lcd.clear();
 }code]

DD91:
bonjour

merci pour ta réponse le problème c'est que partir d'un programme vierge pose le soucis de ne plus avoir le fonctionnement mysensors

Bah colle la variable dans un champ mysensor s ...

bonjour a tous

effectivement j’ai modifier les constantes S-WATER et V_volume qui effectivement sont plus adapté

par contre je ne sait pas comment faire par rapport a tes 4 flotteurs et surtout l’incrémenter a la place des anciens test

Pour répondre à l’utilisation du capteur à ultrason je poste une photo de mon système tel qu’il est dans la cuve

merci a tous

De quels 4 flotteurs parles-tu ? de quels tests ?

Salut ,

Tu crees simplement un tableau avec tes pins en commenceant par le pin 1000 l , puis 900 etc

Esnuite tu fais une boucle qui verifie si l’ etat de chaque capteur est a 1 , et tu balances un break; des qu ’ il y a un 1 de recuperer

4 a 5 lignes de codes .

genre comme ca :

tableauPinsCapteurNiveauCuve[10] = {A3, A2, A1, A0, 8, 7, 6, 5, 4, 3};

for byte (i=0; i< 10; i++) {
	if ( /*recuperation valeur capteur == 1*/ ) {
		uint8_t  litres = 1000 - i * 100;
		Serial.print("'le capteur numero ");
		Serial.print(i);
		Serial.print("'est en niveau haut . Nous avons donc ");
		Serial.print(litres);
		Serial.print("' litre (s) d ' eau dans la cuve");
		break;
	}
}

ce code ne marche pas , il faut l’ adapter bien sur !

Propre la tige de flotteurs !

Décompose ce que tu veux faire .

1- Trouves une solution pour connaitre le niveau . On t'a donné des pistes qui fonctionnent.

2- Gères la partie MySensors ensuite . Je ne peux pas t'aider de ce côté là..

:wink:

quand tu parle d'adapter le code car il ne marche pas c'est intégré ce que tu a mis dans le mysensors ou bien il faut tout reprendre?

je ne suis pas vraiment un pro de la programmation ma partie est plus la fabrication d'ou la tige des flotteurs

Il vaut mieux partir de l’exemple MYSENSORS de ton premier post en remplaçant S_DISTANCE et V_DISTANCE par S_WATER V_VOLUME.

Ensuite dans la loop() utilise la solution proposée par iznobe :

tableauPinsCapteurNiveauCuve[10] = {A3, A2, A1, A0, 8, 7, 6, 5, 4, 3};

// dans setup() ajouter
for byte (i=0; i< 10; i++) {
  pinMode(tableauPinsCapteurNiveauCuve[i], INPUT_PULLUP);
}

// dans loop() ajouter
for byte (i=0; i< 10; i++) {
  if (digitalRead(tableauPinsCapteurNiveauCuve[i] == LOW) {
 uint8_t  litres = 1000 - i * 100;
 Serial.print("'le capteur numero ");
 Serial.print(i);
 Serial.print("'est en niveau haut . Nous avons donc ");
 Serial.print(litres);
 Serial.print("' litre (s) d ' eau dans la cuve");
        send(msg.set(litres));
 break;
  }
}

En supposant que les capteurs soient branchés entre entrée et GND et que A3 soit le capteur du haut.
Je ne connais pas l’unité : m3 ou litres ? essaie avec litres tu verras bien ce que le serveur affiche.

hbachetti:
Il vaut mieux partir de l’exemple MYSENSORS de ton premier post en remplaçant S_DISTANCE et V_DISTANCE par S_WATER V_VOLUME.

Ensuite dans la loop() utilise la solution proposée par iznobe :

tableauPinsCapteurNiveauCuve[10] = {A3, A2, A1, A0, 8, 7, 6, 5, 4, 3};

// dans setup() ajouter
for byte (i=0; i< 10; i++) {
  pinMode(tableauPinsCapteurNiveauCuve[i], INPUT_PULLUP);
}

// dans loop() ajouter
for byte (i=0; i< 10; i++) {
  if (digitalRead(tableauPinsCapteurNiveauCuve[i] == LOW) {
uint8_t  litres = 1000 - i * 100;
Serial.print("'le capteur numero “);
Serial.print(i);
Serial.print(”‘est en niveau haut . Nous avons donc “);
Serial.print(litres);
Serial.print(”’ litre (s) d ’ eau dans la cuve");
        send(msg.set(litres));
break;
  }
}




En supposant que les capteurs soient branchés entre entrée et GND et que A3 soit le capteur du haut.
Je ne connais pas l'unité : m3 ou litres ? essaie avec litres tu verras bien ce que le serveur affiche.

+1 , je ferais comme ca , ca parait le plus simple !

bonjour a tous je vais tester ça rapidement

Pour mes capteurs effectivement il sont branché entre les sorties et le GND (commun a tous)

ensuite le capteur haut c'est adaptable vu que rien n'est fait physiquement pour le moment

Je vous tient au courant si ça fonctionne ou non

merci en tout cas toujours bien reçu ici :wink:

j’ai fait le code avec les éléments donnés par contre j’ai des erreurs dans le code

/**
 * The MySensors Arduino library handles the wireless radio link and protocol
 * between your home built sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each
 * repeater and gateway builds a routing tables in EEPROM which keeps track of the
 * network topology allowing messages to be routed to nodes.
 *
 * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
 * Copyright (C) 2013-2015 Sensnology AB
 * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
 *
 * Documentation: http://www.mysensors.org
 * Support Forum: http://forum.mysensors.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 *******************************
 *
 * REVISION HISTORY
 * Version 1.0 - Henrik EKblad
 * 
 * DESCRIPTION
 * This sketch provides an example how to implement a distance sensor using HC-SR04 
 * http://www.mysensors.org/build/distance
 */

// Enable debug prints
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69

#include <MySensors.h>  

#define CHILD_ID 1
#define tableauPinsCapteurNiveauCuve[10] = {A3, A2, A1, A0, 8, 7, 6, 5, 4, 3};

unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in milliseconds)

MyMessage msg(CHILD_ID, S_WATER);
int lastDist;
bool metric = true;

void setup()  
{ 
  for byte (i=0; i< 10; i++) {
  pinMode(tableauPinsCapteurNiveauCuve[i], INPUT_PULLUP);
}

void presentation() {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Distance Sensor", "1.0");

  // Register all sensors to gw (they will be created as child devices)
  present(CHILD_ID, V_VOLUME);
}

void loop()      
{     
  for byte (i=0; i< 10; i++) {
  if (digitalRead(tableauPinsCapteurNiveauCuve[i] == LOW) {
 uint8_t  litres = 1000 - i * 100;
 Serial.print("'le capteur numero ");
 Serial.print(i);
 Serial.print("'est en niveau haut . Nous avons donc ");
 Serial.print(litres);
 Serial.print("' litre (s) d ' eau dans la cuve");
        send(msg.set(litres));
 break;
  }
}

sur les lignes For byte surtout

Tu as inversé :
MyMessage msg(CHILD_ID, V_STATUS);
present(CHILD_ID, S_WATER);

Et ce n’est pas tout. Mea culpa, je n’avais pas vérifié le code proposé par iznobe.
Je te renvoie le code il y a trop d’erreurs :

// Enable debug prints
#define MY_DEBUG

// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69

#include <MySensors.h>

#define CHILD_ID 1
const byte tableauPinsCapteurNiveauCuve[10] = {A3, A2, A1, A0, 8, 7, 6, 5, 4, 3};

unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in milliseconds)

MyMessage msg(CHILD_ID, V_STATUS);
int lastDist;
bool metric = true;

void setup()
{
  for (byte  i = 0; i < 10; i++) {
    pinMode(tableauPinsCapteurNiveauCuve[i], INPUT_PULLUP);
  }
}

void presentation() {
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Distance Sensor", "1.0");

  // Register all sensors to gw (they will be created as child devices)
  present(CHILD_ID, S_WATER);
}

void loop()
{
  for (byte  i = 0; i < 10; i++) {
    if (digitalRead(tableauPinsCapteurNiveauCuve[i]) == LOW) {
      uint8_t  litres = 1000 - i * 100;
      Serial.print("'le capteur numero ");
      Serial.print(i);
      Serial.print("'est en niveau haut . Nous avons donc ");
      Serial.print(litres);
      Serial.print("' litre (s) d ' eau dans la cuve");
      send(msg.set(litres));
      break;
    }
  }
}

effectivement je n'ai plus d'erreur, je te remercie

je vais tester ça demain pour voir comment ça se comporte avec le serveur domotique

je vous tient au courant :stuck_out_tongue:

Dans un for, la parenthèse suit immédiatement le for

for (byte i=0; i< 10; i++)

bonjour a tous

j'ai testé le montage on est sur la bonne voie :slight_smile:

le montage est bien reconnu par le serveur domotique et communique bien avec

j'ai retirer le break; et je l'ai remplacé par sleep(SLEEP_TIME); car sinon le capteur communiquait en permanence avec la box et ça bloquait les autres capteurs

les points qui ne fonctionne pas sont les suivants

-quand je n'ai pas de capteur engagé le montage n'indique pas qu'il y a zéro. il ne communique même pas

  • de ce que j'ai vu le serveur fonctionne en m3 et pas en litre.

-quand je test pinoche par pinoche ça donne :
A3 : 23.200m3
A2 : 13.200m3
A1 : 3.200m3
A0 : 18.800m3
8 : 8.800m3
7 : 24.400m3
6 : 14.400m3
5 : 4.400m3
4 : 20.000m3
3 : 10.000m3

ce qui est étonnant c'est que ce n'est pas chronologique et l'on devrait avoir de 0 à 1m3

une idée?

merci a tous

c ’ est de ma faute :stuck_out_tongue:

j ’ ai ecrit le code proposé au depart a la va vite , c ’ etait a titre d’ exemple .

il faut juste remplacer uint8_t par uint16t dans la boucle des litres .

void loop()
{
  for (byte  i = 0; i < 10; i++) {
    if (digitalRead(tableauPinsCapteurNiveauCuve[i]) == LOW) {
      uint16_t  litres = 1000 - i * 100; // ici //
      Serial.print("'le capteur numero ");
      Serial.print(i);
      Serial.print("'est en niveau haut . Nous avons donc ");
      Serial.print(litres);
      Serial.print("' litre (s) d ' eau dans la cuve");
      send(msg.set(litres));
      break;
    }
  }
}

    Report to moderato

par contre les " ’ " dans les Serial.print , c ’ est fait expres ? ca ne gene pas , mais ca parait bizzare .

si le serveur exprime les valeurs en metres cube , le calcul est pas bon : il faut remplacer par :

uint16_t  litres = 1 - i * 0.1;