Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Contrôle de remplissage de la piscine

Un système pour surveiller le niveau d'eau, la température, pH, redox, pression du filtre, consommation électrique et fonctionnement de la pompe. Remplit la piscine si nécessaire.

Histoire

L'idée

Au cours de l'été 2015, mes fils et moi avons reconstruit tout notre système de piscine. Tout a commencé avec un problème avec les conduites d'eau et les vannes dont nous avons hérité lorsque nous avons eu la maison, des problèmes de filtres et une entreprise de piscine fondamentalement inepte qui était un vestige de l'époque où nous avons eu la maison. Une fois que ça a commencé à ressembler à ça, j'ai décidé qu'il était temps de faire quelque chose :

Notre lagon privé

Mise en route

La première priorité était de nettoyer la piscine, puis de trouver comment la garder ainsi. J'ai toujours aimé l'automatisation et j'ai pensé que c'était l'endroit parfait pour l'essayer. Peu de temps après, la piscine ressemblait à nouveau à ceci :

Retour à la normale

Mais le problème restait toujours que le système global manquait à la fois de capacité et d'intelligence, quelque chose que je voulais changer. Donc, tout d'abord, nous devions remplacer le filtre, la pompe et un tas de vannes. J'ai passé beaucoup de temps sur un site Web appelé Trouble Free Pool et c'était une bouée de sauvetage pour le bricoleur.

Ma main-d'œuvre

Nous avons subi quelques revers, dont lors de l'installation de la clôture, ils ont coulé du béton autour des conduites allant du système de filtration à la piscine.

Inutile de dire que tout ce béton et ces lignes de piscine ont dû être remplacés pour que le projet avance. Presque tout devait disparaître.

Au début, j'avais décidé d'intégrer une certaine automatisation dans le nouveau système de piscine. J'ai opté pour un système de gestion appelé Autopilot. (Ma famille dit que je l'ai choisi parce que je suis pilote et que j'ai aimé le nom ! ) Ce système me permettrait de convertir la piscine en piscine d'eau salée et de gérer une partie de la gestion, principalement le fonctionnement du générateur d'eau salée lorsque cela est nécessaire et le pompage de l'acide pour gérer le pH. Il n'y avait pas d'autre automatisation au-delà de ces choses.

Finalement, nous avons tout compris. Nous avons également récupéré notre cuisine qui a fini par être mon atelier pour le projet.

Tout est fait :

Automatisation - Le début

Maintenant que l'usine physique était installée et opérationnelle, j'ai pensé que ce serait bien de pouvoir remplir la piscine sans avoir à sortir le tuyau tout le temps. J'ai pensé qu'avec un Raspberry Pi et une vanne d'arrosage normale, je serais en affaires ! J'ai acheté un autre Pi (je les utilise partout pour divers projets) et j'ai expliqué ce que je voulais qu'il fasse.

Raspberry Pi3

Au départ, je pensais que je devais être capable de faire deux choses :

J'ai commencé à faire des recherches et je suis tombé sur une entreprise qui fabriquait un ruban à mesurer liquide qui changeait de résistance à mesure que le niveau de l'eau (ou d'un autre liquide) montait ou descendait. Milone serait ravi de créer une unité de taille spécifique pour moi également, car aucune de leurs tailles ne correspondrait à l'endroit où je voulais la placer.

eTape de Milone

MISE À JOUR :Malheureusement, pour une raison quelconque, mon Milone eTape a souffert d'avoir de l'eau à l'intérieur de la veste et a échoué. Après avoir discuté du problème avec Milone, j'ai décidé que le coût pour le remplacer et potentiellement souffrir du même problème, ne valait pas le coût de remplacement. Pour aggraver les choses, j'ai besoin d'une taille spéciale qu'ils doivent faire spécialement pour moi.

L'eau dans le manchon intérieur a causé l'échec de l'eTape….

J'avais donc besoin d'un autre moyen de mesurer le niveau de ma piscine et j'ai décidé d'utiliser l'un de ceux-ci :

Interrupteur à flotteur pour capteur de niveau d'eau du réservoir en acier inoxydable Elecall

Comme la différence entre mon niveau d'eau bas et mon niveau d'eau normal est d'environ trois pouces, cela a parfaitement fonctionné pour moi. J'avais juste besoin de trouver un moyen de le monter et de le faire fonctionner correctement.

Comme je connais plusieurs autres personnes qui utilisent l'eTape avec d'excellents résultats, je vais tout laisser sur l'eTape dans mon projet et y ajouter la façon dont j'ai fait la configuration à double flotteur. De cette façon, les gens peuvent voir plusieurs options différentes.

Comme il allait être situé en face de l'endroit où mon Pi résiderait, il allait être nécessaire de le connecter à son propre appareil pour le signalement. Comme je n'avais pas besoin d'un Pi pour cela, j'ai choisi un clone sans fil Arduino fonctionnant sur batterie et à faible consommation qui transmettrait les informations à un système existant que j'avais déjà en place dans la maison.

Ces unités que j'ai achetées auprès de Low Power Labs. J'ai fini par en utiliser quatre dans mon projet :un pour le niveau d'eau, un pour la température de l'eau et deux dans le système principal pour surveiller une combinaison de la température interne de l'enceinte, de la pression du filtre et de la consommation d'eau.

Moteino R5-USB avec Flash et émetteur-récepteur RFM69HW 433Mhz

Ces clones Arduino utilisent une puissance extrêmement faible - seulement ~7uA en mode veille profonde, ce qui signifie qu'ils dureraient très, très longtemps avec deux piles AA. Mon capteur de température d'eau flotte autour de ma piscine et mon capteur de niveau est loin d'une source d'alimentation, j'ai donc dû utiliser un équipement sans fil alimenté par batterie.

Au départ, je n'avais pas l'intention de faire autre chose que d'ajouter automatiquement de l'eau à la piscine, mais comme ces choses se passent souvent, le projet a grandi avec son propre esprit. Finalement, je serais capable de faire ce qui suit :

Remplir la piscine

Peu importe ce qui déclenche l'acheminement du remplissage de la piscine (manuellement ou automatiquement), je devais avoir un moyen d'amener l'eau dans la piscine. Étant donné que nous devons déjà avoir un casse-vide entre notre irrigation et notre approvisionnement en eau de la ville, j'ai choisi de le relier à mon système d'arrosage existant pour obtenir de l'eau pour la piscine. En gros, je créais une autre « zone » pour mon système d'arrosage, avec une vanne.

Cela présentait un problème en ce sens que si mes arroseurs fonctionnaient et que je décidais de remplir la piscine, je volerais n'importe quelle zone de pelouse qui coulait de l'eau et cela n'arroserait pas la pelouse correctement. J'ai donc dû trouver un moyen de déterminer si les arroseurs fonctionnaient. Au départ, j'ai utilisé un fuseau horaire « d'interdiction » - c'est-à-dire que si je savais que mes arroseurs fonctionnaient de 3 heures du matin à 6 heures du matin, ne remplissez pas la piscine pendant cette période. Mais cela semblait un peu non technique. En recherchant mon système d'arrosage Rachio, j'ai appris qu'ils avaient une API intégrée qui me permettrait d'interroger par programme l'état du système d'arrosage. Dans mon cas, j'avais juste une question simple :Courez-vous ?

Dans mon cas, je viens d'utiliser une simple commande curl pour obtenir ce dont j'avais besoin :

rachio_url ='curl -s -X GET -H "Content-Type:application/json" -H "Authorization:Bearer xxxx-xxxxx-xx-xxxx-xxxxx-xxx" https:/ /api.rach.io/1/public/device/00xx00x-00xxx000-xxx0x000-00x0x0x0/current_schedule' 

Ceci est appelé par ma fonction get_sprinkler_status comme ceci :

output =subprocess.check_output(pooldb.rachio_url, shell=True)if output =="{}":sprinklers_on ="No" 

Mon application principale s'exécute toutes les 60 secondes, donc si mes arroseurs fonctionnent, je ne fais rien pendant 60 secondes et je vérifie à nouveau. Finalement, les arroseurs cesseront de fonctionner et la piscine commencera à se remplir automatiquement.

Afin de remplir réellement la piscine, j'ai utilisé une vanne d'arrosage normale 24 V CA que j'ai récupérée chez Home Depot. J'ai installé ceci avec une valve unidirectionnelle directement dans la tuyauterie de ma piscine allant à ma piscine. Le clapet anti-retour empêche la pression de la pompe de pousser l'eau contre la vanne d'arrosage lorsque la pompe est en fonctionnement.

Conduite d'eau avec valve unidirectionnelle

Comme le panneau électrique de ma piscine est en 240V et que je n'ai pas de neutre dans le panneau, j'ai dû me procurer un transformateur 240VAC à 24VAC. Assez simple. Cependant, je ne voulais pas faire fonctionner le transformateur 24 × 7 sans raison, j'ai donc utilisé un relais pour 1) allumer le transformateur, puis 2) prendre la sortie 24 VCA du transformateur et la connecter à la vanne d'arrosage.

Configuration des relais

J'ai utilisé les relais à semi-conducteurs Sainsmart (très bon marché) en mode optiquement isolé où j'ai une entrée d'alimentation séparée alimentant les relais au lieu d'utiliser le VCC 5v ou 3.3v du Pi. Ceci est censé aider avec les interférences des relais.

Valve d'arrosage et compteur d'eau intelligent

J'ai également ajouté un compteur intelligent que je peux lire en temps réel pour me montrer que l'eau coule et combien d'eau j'ai utilisée au fil du temps. Ces informations sont stockées dans une base de données MySQL et stockées historiquement :

Écran de mon système EmonCMS pour mon compteur d'eau domestique

Puissance, puissance, puissance

Maintenant est venu la prochaine chose que j'avais besoin de comprendre. Pendant que ma pompe fonctionnait, si j'essayais de remplir la piscine, je lutterais contre la pression de la pompe. J'ai déterminé en mesurant le débit d'eau que j'avais perdu environ 50% de mon débit de remplissage pendant que la pompe fonctionnait, alors j'ai pensé qu'il serait préférable de ne pas remplir du tout pendant que la pompe fonctionnait. J'avais donc besoin d'un moyen de surveiller la puissance de ma pompe et de déterminer si elle fonctionnait ou non.

Dans ce cas, j'avais un moyen très simple de le faire. Chaque circuit de ma maison est surveillé par un système de surveillance électrique. Ce système s'appelle le GEM et il est vendu par Brultech.


Ma pompe de piscine est la principale consommatrice d'électricité de ma maison

Avec ce système, je peux surveiller toute la consommation électrique de ma maison et dans le cadre de la surveillance processus, je stocke ces données dans une base de données MySQL. Donc, une fois par minute, j'interroge simplement ma base de données MySQL et je calcule le nombre de watts actuellement utilisés par mon panneau de piscine.

 if pool_pump_running_watts> pooldb.max_wattage:pool_fill_control.led_control(PUMP_RUN_LED, "ON") pool_pump_running ="Yes" logger.debug('PUMP_RUN_LED doit être allumé. C'est la LED JAUNE') si DEBUG :print("PUMP_RUN_LED devrait être allumé. Ceci est la LED JAUNE") sinon :pool_fill_control.led_control(PUMP_RUN_LED, "OFF") pool_pump_running ="No" logger.debug('PUMP_RUN_LED devrait être éteint. Ceci est la LED JAUNE') if DEBUG :print("PUMP_RUN_LED doit être éteint. C'est la LED JAUNE")

J'ai divers boutons, interrupteurs et LED sur l'unité physique qui me permettent de voir si les arroseurs fonctionnent, la pompe fonctionne, la piscine se remplit ou s'il y a une erreur système quelconque . Ci-dessus, vous pouvez voir où j'allume et éteint le voyant de fonctionnement de la pompe si nécessaire.

En plus des voyants système, j'ai un bouton ON/OFF système (en haut à gauche) qui me permet d'utiliser le système MightyHat pour redémarrer ou éteindre mon Pi intelligemment sans avoir à me connecter au Pi pour faites-le à partir de la CLI. J'ai aussi un interrupteur momentané (deuxième à gauche) qui me permet de remplir ma piscine manuellement quand je veux, et enfin sur le côté gauche j'ai un interrupteur DPDT qui interrompt physiquement l'alimentation de mon système vers la vanne d'arrosage et déclenche un GPIO événement pour indiquer au système que nous avons désactivé manuellement le remplissage du pool. Rien ne fonctionne lorsque cet interrupteur a été déclenché et si quelque chose tombait en panne par programmation, aucune alimentation ne pourrait passer du transformateur à la vanne d'arrosage de toute façon.

Contrôleur de piscine – Externe

Gestion de la pompe

Au fil du temps, j'ai ajouté une autre pièce à mon système de contrôle de piscine. La possibilité de gérer ma pompe à vitesse variable Pentair. Entrez Russell Goldin (tageyoureit) et son projet de logiciel de contrôleur de piscine. Le logiciel de Russell m'a permis de communiquer directement avec ma pompe de piscine via une interface RS485. Une fois connecté, je peux interroger directement la pompe pour obtenir des informations système telles que RPM, GPM et Watts en cours d'utilisation :

def get_pump_data(key):verbose_debug("get_pump_data() Started") verbose_debug("get_pump_data() appelé avec '{}' ".format(key)) log("INFO", " get_pump_data() appelé avec '{}' ".format(key)) if pump_control_active:global json try:req =urllib2.Request(pooldb.PUMP_DATA_URL) opener =urllib2.build_opener() f =opener.open(req) data =json.load(f) pump_data =data["pump"]["1"][key] verbose_debug("get_pump_data() a renvoyé {}".format(pump_data)) log("INFO", "get_pump_data() a renvoyé { }".format(pump_data)) verbose_debug("get_pump_data() - Completed") log("INFO", "get_pump_data() - Completed") if key =="gpm":pump_gpm =pump_data update_database("pump_status", " pump_gpm", pump_gpm) log("INFO", "GPM actuel :{}".format(pump_gpm)) log("DEBUG", "get_pump_gpm() Terminé") debug("GPM actuel :{}".format(pump_gpm) )) verbose_debug("get_pump_gpm() Completed") elif key =="rpm":pump_rpm =pump_data update_database("pump_status", "pump_rpm", pump_rpm) log("INFO", "Current RPM :{}".format(pump_rpm)) log("DEBUG", "get_pump_rpm() Completed") debug("Current RPM:{}".format(pump_rpm)) verbose_debug("get_pump_rpm() Completed") else:pump_watts =pump_data update_database("pump_status", "pump_watts", pump_watts) log("INFO", "Current WATTS :{}".format(pump_watts)) log("DEBUG", "get_pump_watts() Completed") debug ("Current WATTS) :{}".format(pump_watts)) verbose_debug("get_pump_watts() Completed") return pump_data except Exception as error:pump_data =0 debug("EXCEPTION:get_pump_data()") log("WARN", "EXCEPTION:get_pump_data( )") log("WARN", erreur) debug(type(error)) debug(error) verbose_debug("get_pump_data() - Terminé avec EXCEPTION") log("DEBUG", "get_pump_data() - Terminé avec EXCEPTION") return pump_data else :pump_data =0 return pump_data 

Maintenant, je peux interroger la pompe et contrôler ma pompe en ajoutant une autre capacité que je n'avais pas auparavant. En modifiant mon interface Web, j'ai ajouté la possibilité de démarrer ou d'arrêter ma pompe ainsi que d'exécuter l'un des quatre programmes de pompe différents que j'avais configurés sur ma pompe :

Panneau de commande de la pompe

Bien sûr, nous pouvons regarder RPM, GPM et Watts en temps réel :

Jauges de pompe sur l'interface Web

Surveillance de la pression du filtre

Une chose que je voulais aussi faire était de surveiller la pression du filtre afin de savoir quand rincer à contre-courant notre filtre. J'ai acheté un capteur de pression de 100 PSI sur ebay et je l'ai attaché à mon filtre à côté de mon manomètre analogique déjà sur le filtre.

J'ai acheté une unité d'envoi bon marché sur ebay (voir le lien ci-dessus) et je l'ai liée à mon fichier comme ceci :

100 PSI Sender unitPressure Sending unitSending Unit Wiring..

Je l'ai ensuite lié à un Moteino-R5 et j'ai lu la pression une fois par minute, puis j'ai envoyé ces informations à ma base de données MySQL, puis j'ai utilisé ces informations pour piloter la sortie de la jauge sur mon site Web.

// Obtenez notre pression de filtre void get_filter_pressure() { sensorVoltage =analogRead(PSI_SENSOR_PIN); // Lisons la tension de notre capteur de pression PSI =((sensorVoltage-146)/204)*25; // Un étalonnage pour convertir la tension en PSI et la mettre à zéro pool_sensors.PSI =PSI; } 

Jauge PSI pour filtre de piscine

Matériel et logiciel supplémentaires

Le système principal est entièrement écrit en Python, mais j'ai utilisé d'autres logiciels et matériels pour faire fonctionner mon système.

Sur mon Raspberry Pi, j'utilise un MightyHat de Low Power Labs qui fournit une alimentation UPS de secours au Pi, un écran d'état LCD et un contrôle intelligent de l'alimentation pour le Pi. Je peux faire fonctionner le Pi pendant environ deux heures sur la petite batterie que j'ai connectée au système et si le courant ne revient pas à l'heure, le MightyHat éteint automatiquement le Pi pour l'empêcher de se bloquer en raison d'un coup panne de courant.

Gros plan de MightyHat sur Pi3 montrant Overfill Alert

Le MightyHat est un clone Arduino, j'ai donc utilisé l'IDE Arduino pour le programmer en fonction des besoins de mon projet.

Pour la détection, j'utilise une variété de capteurs et de méthodes pour obtenir les informations dans un format utilisable. Pour à peu près toutes les données des capteurs, j'utilise la plate-forme EmonCMS gratuite d'OpenEnergyMonitor.org. Cette plateforme me permet de collecter toutes les données de mes capteurs de partout dans ma maison. Il stocke ces informations dans une base de données MySQL où je peux ensuite les récupérer pour les utiliser dans mon système de contrôle de piscine.

Certains des capteurs de suivi pour ma piscineInformations de suivi supplémentaires

Pour le niveau réel de la piscine, j'utilise le ruban de mesure de liquide résistif eTape (http://www.milonetech.com) :

eTape et MoteinoSe moquer de tout

Une de mes cartes contrôleur IO

Carte contrôleur IO, contrôleur LED, carte contrôleur d'interface d'alimentation IO - Retour

Cartes de capteur USB pH et ORP

Cartes d'interface de capteur de pH et de redox Atlas Scientific

Afin d'obtenir des lectures précises de pH et de redox, j'utilise les capteurs de pH et de redox d'Atlas Scientific ainsi que leurs cartes d'interface. Je les ai installés dans une Flow Cell qui surveille également si la pompe fonctionne. J'ai attaché la Flow Cell aux conduites à l'aide de raccords rapides standard John Guest 3/8 ", un du côté pression du filtre et un du côté aspiration de la pompe pour que l'eau continue de s'écouler à travers la Flow Cell.

Flow Cell (extrême gauche) Flow Cell w/SensorsJohn Guest 3/8″ Fileté Quick ConnectsLigne de retour (aspiration)Ligne de sortie (pression) - installée AVANT l'injecteur d'acide

Lecture de notre pH :

def get_ph_reading() : log("DEBUG", "get_ph_reading() démarré") pool_pump_running =read_pool_sensor_status_values("pool_sensor_status", "led_status", "pump_run_led" ) if pool_pump_running ==:if pooldb.temp_probe =="Yes":pool_temp =float(read_pool_sensor_status_values("pool_sensor_status", "system_status", "pool_current_temp" )) ph_value =float(get_ph.get_current_ph_with_temp(pool_temp)) else:ph_value. ()) debug("Le pH actuel est :{}".format(ph_value)) influx_data.write_data("pH", ph_value) influx_data.write_data("pool_temp", pool_temp) if pooldb.emoncms_server1 =="Oui":res =request.get("http://" + pooldb.server1 + "/" + pooldb.emoncmspath1 + "/input/post?&node=" + str( pooldb.ph_node) + "&csv=" + ph_value + "&apikey =" + pooldb.apikey1) log("DEBUG", "Envoyé la valeur de pH actuelle de {} au serveur Emoncms 1".format(ph_value)) debug("Envoyé la valeur de pH actuelle de {} au serveur Emoncms 1".format( ph_value)) si pooldb.emoncms_server2 =="Oui":res =request.get("https://" + pooldb.server2 + "/" + pooldb.emoncmspath2 + "/input/post?&node=" + str( pooldb.ph_node) + "&csv =" + ph_value + "&apikey=" + pooldb.apikey2) log("DEBUG", "Envoyé la valeur pH actuelle de {} au serveur Emoncms 2".format( ph_value)) debug("Envoyé la valeur pH actuelle de {} à Emoncms Server 2".format( ph_value)) update_pool_sensor_status_values("pool_sensor_status", "pool_chemicals", "pool_current_ph", ph_value) log("DEBUG", "get_ph_reading() Completed") else:log("INFO", "Pool Pump n'est PAS en cours d'exécution, ne peut pas obtenir une lecture de pH précise !") debug("La pompe de la piscine ne fonctionne PAS, ne peut pas obtenir une lecture de pH précise !") log("DEBUG", "get_ph_reading() Completed")

Ce code appelle le module "get_ph.py" qui ressemble à ceci :

#!/usr/bin/python## À utiliser avec pool_control_master.py__author__ ='Richard J. Sears'VERSION ="V3.4 (2018-03-16)"# [email protected ]# Ceci est destiné à être utilisé uniquement avec la carte de pH Atlas Scientific.import serialimport sysimport timefrom serial import SerialExceptionusbport ='/dev/PH'try:ser =serial.Serial(usbport, 38400, timeout=0)except serial.SerialException as e:print "Error, ", e sys.exit(0)def read_line():lsl =len('\r') line_buffer =[] while True:next_char =ser.read(1) if next_char =='':break line_buffer.append(next_char) if (len(line_buffer)>=lsl et line_buffer[-lsl:] ==list('\r')):break return ''.join(line_buffer)def read_lines():lines =[ ] try:while True:line =read_line() sinon line:break ser.flush_input() lines.append(line) renvoie les lignes sauf SerialException as e:print "Error, ", e return Nonedef send_cmd(cmd):"" " Envoyer la commande au capteur Atlas. Avant l'envoi, ajoutez un retour chariot à la fin de la commande. :param cmd::return:""" buf =cmd + "\r" # ajouter un retour chariot essayer:ser.write(buf) retourner True sauf SerialException car e:print "Error, ", e return Nonedef get_current_ph_with_temp(current_temp):# send_cmd("RESPONSE,0") send_cmd ("C,0") send_cmd("T,%d" % current_temp) send_cmd("R") time.sleep(1.3) lines =read_line() return linesdef get_current_ph_no_temp():# send_cmd("RESPONSE,0") send_cmd("C,0") send_cmd("R") time.sleep(1.3) lines =read_line() return linesdef main():# send_cmd("RESPONSE,0") send_cmd("C,0") send_cmd( "R") time.sleep(1.3) lines =read_lines() print("Aucun étalonnage de la température effectué :") for i in range(len(lines)):print lines[i]if __name__ =='__main__':main ()

L'ORP se fait de la même manière.

Cette cellule à écoulement dispose également d'un indicateur de débit installé. Si de l'eau s'écoule à travers la cellule, l'anneau monte et ferme un interrupteur magnétique. Le câblage du commutateur est connecté à une broche GPIO sur le pi. Voici mon code pour lire ce commutateur :

def pool_pump_running_chemical() :pool_pump_running_chemical =GPIO.input(pool_pump_running_pin) if pool_pump_running_chemical ==False :debug ("Pool Pump Running via Chemical Sensor Chamber :TRUE - PUMP IS RUNNING") else :debug( "Pompe de piscine fonctionnant via la chambre du capteur chimique :FAUX - LA POMPE EST ÉTEINTE")

Capteur de niveau d'eau - Le faire fonctionner

Comme je l'ai montré ci-dessus, le capteur de niveau d'eau utilise un MoteinoUBS alimenté par batterie par LowPowerLab. C'est un microcontrôleur parfait pour cette application. Fondamentalement, je réveille le Moteino toutes les soixante secondes, prends une lecture de résistance de l'eTape, allume mon émetteur et envoie ces informations à mon système EmonCMS pour qu'elles soient utilisées par mes scripts de piscine. Puis j'éteins à nouveau tout :

{ digitalWrite(ETAPE_POWER, HIGH); // Allumez eTape pool.resistance =analogRead(ETAPE); // lecture de la résistance d'etape digitalWrite(ETAPE_POWER, LOW); // Coupez l'alimentation de la bande eTape take_battery_reading(); // Prend la lecture de la batterie power_spi_enable(); rf12_sleep(RF12_WAKEUP); rf12_sendNow(0, &pool, sizeof pool); rf12_sendWait(2) ; rf12_sleep(RF12_SLEEP); power_spi_disable(); if (débogage){ flash_led (50); } // C'est tout - attendez la prochaine fois :) sleep_until_next_reading(); } 

Je surveille également les tensions de mes batteries afin de savoir quand il est temps de changer mes batteries. Le script a plusieurs mécanismes pour s'assurer que les piles sont bonnes. Premièrement, je surveille activement la tension de la batterie elle-même, et deuxièmement, je surveille la fréquence à laquelle les capteurs me renvoient et le delta de temps de ces rapports. À de nombreuses lectures manquées et je sais que «quelque chose» ne va pas avec ce capteur et je recevrai une notification Pushbullet pour aller voir ce qui ne va pas. De plus, avec la perte d'un capteur, mon système de remplissage de piscine se met en veille et refusera de remplir la piscine car il ne saura pas quand s'arrêter.

J'utilise 2 piles au lithium AA et jusqu'à présent, elles ont fonctionné pendant plus d'un an sans être remplacées.

Pour assurer la sécurité du MoteinoUSB au niveau de la piscine, j'avais besoin d'une sorte d'enceinte étanche. J'ai choisi la boîte étanche Adafruit avec un couvercle transparent.

Boîtier étanche Adafruit

Ensuite, j'ai utilisé un presse-étoupe Adafruit PG-9 et très soigneusement percé à travers le côté de la boîte et installé le presse-étoupe.

Presse-étoupe Adafruit PG-9

À l'aide du câble d'alimentation CC étanche Adafruit, j'ai connecté l'eTape au MoteinoUSB et au boîtier.

Câble d'alimentation CC étanche AdafruitBoîtier de capteur de niveau d'eau complet

Pour un peu plus de sécheresse, j'ai acheté un déshydratant à mettre dans le boîtier pour absorber et l'humidité qui pourrait le faire dans le boîtier. Une chose à surveiller que j'ai apprise à la dure (heureusement, les capteurs sont peu coûteux) est de NE PAS serrer trop fort le dessus ou les presse-étoupes. Cela a pris un peu d'essais et d'erreurs. En fin de compte, après avoir « pensé » avoir raison, je remplis mon évier et je mets l'enceinte sous l'eau et je la maintiens avec une casserole remplie d'eau placée dessus. Je le garde ainsi pendant quelques heures en vérifiant de temps en temps que tout est correct.

Maintenant, je devais trouver un moyen et un endroit pour monter mon capteur de niveau d'eau. Dans ma piscine, nous avons un petit bassin en ciment qui abritait le flotteur qui ajoutait manuellement de l'eau à la piscine. Celui-ci s'est rouillé il y a longtemps et n'a pas pu être réparé sans arracher l'enceinte en ciment. C'est ce qui a initialement démarré mon projet !

Bassin en ciment

Le bassin en ciment est relié à la piscine avec une petite ligne 3/4″ qui me permet de voir le niveau d'eau mais les enfants qui s'éclaboussent ou s'amusent dans la piscine n'affecteront pas le niveau de l'eau du bassin. C'était l'endroit idéal pour monter le capteur eTape. Pour faire le montage proprement dit, j'ai pris un morceau de tuyau en PVC, je l'ai coupé en deux puis je l'ai poncé pour qu'il ait la même forme circulaire que le bassin en ciment. J'ai ensuite époxydé cette pièce en place directement sur le côté du bassin. Une fois cela fait, j'ai utilisé quelques vis à cloison sèche et vissé l'eTape sur le tuyau en PVC.

Capteur eTape monté sur un tuyau en PVC Installation du capteur eTape terminée

MISE À JOUR :Nouvelle méthode pour lire le niveau d'eau !

Si vous lisez ci-dessus, j'ai eu quelques problèmes avec mon installation eTape qui ont empêché mon eTape de fonctionner et de donner des lectures erronées le rendant inutilisable. J'ai parlé avec Chris à Mileone et nous n'avons pas pu trouver une raison pour laquelle la bande a échoué. En fin de compte, cela ne valait pas 80 $ de plus pour moi d'obtenir une autre bande et que la même chose se reproduise, alors j'ai changé de méthode de lecture de mon niveau d'eau.

Comme je n'ai vraiment qu'une différence de 3″ entre mes niveaux bas et plein, j'ai recherché divers capteurs de niveau et j'ai choisi celui-ci :

Interrupteur à flotteur pour capteur de niveau d'eau de réservoir en acier inoxydable Elecall

J'ai donc dû trouver un moyen de monter le nouveau capteur. J'ai décidé d'utiliser un plexiglas 1/4″ pour le faire fonctionner. J'ai mesuré la largeur dont j'avais besoin et j'ai monté le flotteur avec une vis de réglage supplémentaire afin de pouvoir faire des ajustements précis. J'ai également collé un petit niveau dessus, donc quand je l'ai monté, il serait de niveau :

Pour le monter, j'ai juste utilisé de l'époxy et l'ai nivelé à l'aide de mon "niveau intégré :

Pour lire le niveau de la piscine, j'ai besoin de connaître la position des deux flotteurs. J'ai donc programmé mon code pour lire la position des deux flotteurs puis envoyer un 0, 1 ou 2 selon le niveau d'eau.

Si le flotteur supérieur est ouvert et le flotteur inférieur est ouvert (les deux flottent vers le bas), alors nous sommes bas et il envoie un « 0 ». Si le flotteur inférieur est fermé (haut) et le flotteur supérieur est ouvert (bas) alors on est à mi-chemin et on envoie un « 1 ». If both floats are closed (up) the pool is full and we do not need any water. Here is how the code looks:

UPPER_Float =digitalRead(17);LOWER_Float =digitalRead(3); if (UPPER_Float ==LOW) { UPPER_Float_Position ="Closed"; } else { UPPER_Float_Position ="Open"; } if (LOWER_Float ==LOW) { LOWER_Float_Position ="Closed"; } else { LOWER_Float_Position ="Open"; } if ((UPPER_Float ==LOW) &&(LOWER_Float ==LOW)) { pool_level.level =2; // Both closed =Pool is FULL } else if ((UPPER_Float ==HIGH) &&(LOWER_Float ==LOW)) { pool_level.level =1; // Lower closed, Upper open =Pool MIDWAY } else { pool_level.level =0; // Both floats open =Pool LOW add water }

So the value of 0, 1 or 2 is transmitted to EmonCMS and written to my database. Each minute we query that database to see if we need to add water:

get_pool_level_value =read_emoncms_database("data", pooldb.pool_level_table)

and if it is low, we add water:

if get_pool_level_value ==0:get_pool_level ="LOW" pool_fill_valve("OPEN")

And this is the new way we are reading our pool level and managing filling our pool.

Pool Temperature Sensor – Making it work

Following in the footsteps of my eTape sensor, I build the same configuration for my pool temperature sensor. This time however, I added a temp probe inside the enclosure so I could monitor the temperature in the enclosure. It would also let me know what the temperature was just above the surface of the water in the pool. The second temperature sensor was fed through the PG-9 cable gland and into the pool water. I then just tossed the enclosure into the pool and thought I was done. However, my kids had other ideas. They thought it was fun to grab the temperature sensor hanging down from the enclosure and spin it around like a top and throw it at each other. Needless to say the first one didn’t last long.

So I went down to my local pool store and purchased a chlorine floater and installed the enclosure and temp probe into it. We have not had a problem since doing so. Even if they throw it, it won’t bother it at all. Most people leave it alone since they think it is chlorine even though we have a saltwater pool.

Pool temp sensor floaterPool temp sensor floater

Keeping track of our Acid Level

Part of the pool automation system that is not handled by my project is the dispensing of muriatic acid to keep our pH under control. While the Pool Auto Pilot system handles that, we still need to be able to see if we need acid added to the tank. For this I used a $9.00 DFRobot Liquid Level Sensor:

XKC-Y25-T12V Liquid Level Sensor

This particular sensor is weatherproof and works by sensing when there is no longer liquid behind whatever you have it attached to and then sending a signal to the GPIO that you can read. Once you can read it, you can then do your alerting, etc.

I simply connected this to my Pi (it utilizes the 5v rail and one GPIO pin) and then added in a little bit of code to read the state of the sensor:

def acid_level():acid_level_ok =GPIO.input(acid_level_sensor_pin) if acid_level_ok ==True:

I then epoxied the sensor to our acid tank at the level where I wanted to be notified and hooked it all up:

 

This tank has a pretty thick wall and this sensor worked great. I tested it before affixing it just to make sure.

Web Interface

V3.5.0 Web Interface

Once I had all of this pretty much working like I wanted it, I decided that I needed to have a nice interface so we could track all of the data, manually add water to the pool without having to go to the pool room, stop an automatic fill that may be in progress and check the status of the batteries in our temperature sensor and our level sensor.

The main capabilities of the web interface as of right now are:

I am very thankful to Russell Goldin ([email protected]) for his amazing work on the Pentair RS-485 control software needed for my system to be able to talk to and control my pump. You can check out his github HERE.

With Russ’s software I am able to directly control my Pentair pump without having to spend several thousand dollars on their proprietary hardware!

I spent a lot of time programming everything in python but I did not have an experience building a web interface so I asked around and eventually decided on Flask as the web framework that I would use to build the web interface.

Learning Flask was not as hard as I had thought it was going to be and it integrates very well with the python code that I had already written to control the pool. Flask is a mix of python-like code and html like templates and did everything that I needed it to do:

Upper Control PanelSystem GaugesLower Panel

The control part of the interface is very easy. If I want to start a manual fill, I simply click on the “Manual Fill” button and as long as there is not a system problem, we are not running the sprinklers and we are not already “automatically” filling the pool, the system starts a manual fill of the pool. The “Pool Filling” led will turn blue, than “Manual Fill” button will toggle on and the “Fill Timer” will start a countup. Click the “Manual Fill” button again and the system stops filling and reverts back to normal.

If we are filling the pool automatically and I want to stop that process, I simply click the “Pool Filling” button (led reverts to button to show that you can push it to stop the automatic fill) and the system stops filling and sends me notifications based on the configuration of the system (debug, logging, email, pushbullet, sms).

Flask has the ability to process things prior to showing you the html output:

{% if system_error_led =="True" %}  {% elif system_run_led =="True" %}  {% else %}  {% endif %}

In this example, if there is a system error I show a red led, otherwise if the system is running I show a green led and if I am not running and there is no error, then I show a grey led. This statement is processed before the html is rendered and is a very powerful way to interact with a python driven system.

Historical Graphing

As I continue to extend the system and learn more about what I can do, I wanted to start to watch historical trends in my pool system along with a lot of other home automation stuff I have been playing around with lately. After looking around I choose Grafana and InfluxDB.

Basically I already had my data being recorded utilizing EmonCMS so I just needed to have a quick way to get it into InfluxDB so Grafana could do it’s magic. Basically within the mail pool program whenever I get a pH, ORP or temp reading, I write it to the influxdb:

def get_ph_reading():log("DEBUG", "get_ph_reading() Started") pool_pump_running =read_pool_sensor_status_values("pool_sensor_status", "led_status", "pump_run_led" ) if pool_pump_running =="True":if pooldb.temp_probe =="Yes":pool_temp =float(read_pool_sensor_status_values("pool_sensor_status", "system_status", "pool_current_temp" )) ph_value =float(get_ph.get_current_ph_with_temp(pool_temp)) else:ph_value =float(get_ph.get_current_ph_no_temp()) debug("Current pH is:{}".format(ph_value)) influx_data.write_data("pH", ph_value) influx_data.write_data("pool_temp", pool_temp) if pooldb.emoncms_server1 =="Yes":res =requests.get("http://" + pooldb.server1 + "/" + pooldb.emoncmspath1 + "/input/post?&node=" + str( pooldb.ph_node) + "&csv=" + ph_value + "&apikey=" + pooldb.apikey1) log("DEBUG", "Sent current pH Value of {} to Emoncms Server 1".format(ph_value)) debug("Sent current pH Value of {} to Emoncms Server 1".format(ph_value)) if pooldb.emoncms_server2 =="Yes":res =requests.get("https://" + pooldb.server2 + "/" + pooldb.emoncmspath2 + "/input/post?&node=" + str( pooldb.ph_node) + "&csv=" + ph_value + "&apikey=" + pooldb.apikey2) log("DEBUG", "Sent current pH Value of {} to Emoncms Server 2".format( ph_value)) debug("Sent current pH Value of {} to Emoncms Server 2".format( ph_value)) update_pool_sensor_status_values("pool_sensor_status", "pool_chemicals", "pool_current_ph", ph_value) log("DEBUG", "get_ph_reading() Completed") else:log("INFO", "Pool Pump is NOT running, cannot get accurate pH reading!") debug("Pool pump is NOT running, cannot get accurate pH reading!") log("DEBUG", "get_ph_reading() Completed") 

and from influx_data.py:

import syssys.path.append('../')from influxdb import InfluxDBClientimport pooldbdef write_data(measurement, value):client =InfluxDBClient(pooldb.influx_host, pooldb.influx_port, pooldb.influx_user, pooldb.influx_password, pooldb.influx_dbname) json_body =[ { "measurement":measurement, "fields":{ "value":value } } ] client.write_points(json_body)

From there it is a simple matter of setting up Grafana to look at the InfluxDB and make the graphs:

Notifications

My system relies heavily on notifications. Currently the system can provide notifications via logging to a log file, debug messages to stdout allowing for the running of the main program from the command line with valuable, immediate feedback, pushbullet, email and SMS via Twillio. Because of all they types of notifications as well as areas where there can be notifications, I created a system which allows me to fine tune my notifications very easily via my web interface.

By setting up the code in this manner, I can very easily and quickly adjust my notification settings as well as different categories that I want to have those notifications applied to at that time. In future versions of the code, I am going to create an entire “Notifications” panel that allows me the ability to set specific notification types by category. For example I might want an SMS message about filling events, but email notifications about system errors and pushbullet notifications about my pump. In this manner I am able to tweak all of my notification settings to be exactly how I want then to notify me…both the how and the when!

Current Notification Settings Panel
root scruffy:www # ./pool_control_master.pyStarted is_database_online()MightyHat Serial setup completedSystem Reset Status =No Reset RequestedStarted get_pool_temp()get_pool_temp returned 67.30Fpool_temp in C is 19.61Started is_pool_pump_running()pool_pump_running_watts returned 563 watts in use by pump.PUMP_RUN_LED should be ON. This is the YELLOW LEDCurrent unix datetime stamp is:1521835161Pool LEVEL sensor last updated at:1521835044Pool LEVEL sensor battery voltage is:3.2Pool LEVEL sensor battery percentage is 100Pool TEMP sensor last updated at:1521835131Pool TEMP sensor battery voltage is:3.2Pool TEMP sensor battery percentage is 100Pool FILTER PSI is:21Time dfference between last pool LEVEL sensor reading is:117 seconds.Time dfference between last pool TEMP sensor reading is:30 seconds.Everything appears to be OK with the pool sensors!pool_sensors:Pool Resistance is:724pool_sensors:Pool Level Percentage is:85pooldb:Static critical pool level resistance set at (740).pooldb:Static normal pool level resistance set at (710).Our Pool Level is MIDWAY.Total Gallons:22462Acid Level OKTotal Current Power Utilization:2039 wattsTotal Current Power Import:415 wattsTotal Current Solar Production:1624 wattsCurrent GPM:15Current RPM:2225Starting get_ph_reading().Current pH is:7.043Sent Emoncms Server 1 current PH Value:7.043Sent Emoncms Server 2 current PH Value:7.043Completed get_ph_reading()Starting get_orp_reading().Sent Emoncms Server 1 current ORP Value:669.8Sent Emoncms Server 2 current ORP Value:669.8Completed get_orp_reading()

Running from the cli

Alexa Skill and Interface

One of the last things I wanted to tackle was to integrate my pool control system with Alexa. We have Echo Dots and Echo Shows and I wanted to use the visual Echo Show when I could. So I spent a bunch of time learning how to do Alexa skills and then I used the Python microframework Flask-Ask to program the interconnection between my pool control system and the Alexa Skill.

It was a very interesting learning curve, but now I can query Alexa and get all of our pool stats and we can fill (or stop filling) our pool via voice commands:

Alexa Show Interface with pool, electrical and solar stats

Conclusion

I am running V3.5.0 of my code now which seriously changes the way I am checking sensors, and handling error checking. I have also started breaking out my code into separate python functions instead of a monolithic block of 4,000+ lines of code. I will put it up and include all of the Flask programming as well.

This project has taught me a lot about programming, the Pi and Arduinos.

Pool Control System – InternalPool Control System – External

To view all of the code, please visit my Github site HERE! Thank you for reading about my project.

Source: Pool Fill Control


Processus de fabrication

  1. Circuits de contrôle
  2. arroseur de pelouse
  3. Piscine
  4. Lave-vaisselle
  5. Table de billard
  6. Pistolet à eau
  7. Remplir le barrage
  8. Toilettes
  9. pilule contraceptive