Automated Pool Controller

project_pool

(Lance) #61

I think some of this work has been done. I don’t recall exactly where but I have seen a forum where someone deciphered the Jandy messages, which might at least give you a starting point.


(Nick) #62

I’ve seen some of those forums with that info. I just need to replicate it using the particle photon and write the code/modify someone’s code.


(Nick) #63

Found this one. It’s relatively recent and detailed. I’m interested in trying to cut out having to use a proprietary controller and have the pump talk straight to the particle. What I’m seeing so far, is that it is not a send a command and go, but keep sending the command over and over to until you tell it to stop to maintain a particular speed for example. It seems like maybe a photon would have to be dedicated to this sole task, unloading it from running relays/valves, would that be right?

https://www.troublefreepool.com/threads/147438-Aqualink-PDA-automation-using-RS485


(Bscuderi13) #64

you know I’m not sure most microcontrollers work there way from top to bottom only doing one thing at once but with the cloud capabilities and communication I know that particle still talks to the internet separately while running the code so it doesn’t miss cloud commands maybe this communication process could be similar. There’s only one way to find out and that’s to tinker. Unfortunately the communication thing is way above my arduino skill set worst case scenario you run two photons.


(Bscuderi13) #65

Okay so for everyone following this project I finally found some time to tinker and I have incorporated a whole lot more into my project. The changes are as follows.

  1. I cut out the old abandoned water line and plumbed right into my old autoflll line so there is no more hose in the pool but a dedicated line that my photon turns on and off to dispense and measure water directly into the pool. Big improvement getting rid of the eye sore of a hose.

  2. Changed my jandy valve to actually have three way programming now using two relays. This allowed me to shut off all main returns and only send water to the aerator allowing me to run the aerator at a way lower pump speed and consequently save money. Here in phoenix in the summer I have to run my aerator alot to keep the pool cool. Because the aerator line is so small I put some pump speed protections coded in to keep from accidentally putting too much pressure into the small 1/2 inch line. Changed my device handler to show an intuitive three way valve to match my three available positions of main returns floor cleaners and aerator only.

  3. The aerator valve itself, which is the 12 volt 1/2 inch ball valve style valve, I decided after some tinkering that I only needed full open or closed and no intermediate positions. Therefore I freed up a relay by changing my code and wiring the close to the NC position and the open wire to the NO position on a single relay instead of two. Now I’m either full open or close.

  4. The biggest and most exciting change is chemical injections. I have added two 15 gallon chemical drums with stenner peristaltic pumps. One for muriatic acid since my pool ph creeps up and a second for liquid chlorine. I hate flaoting the pucks as they add too much stabilizer to the pool rendering the chlorine useless. I wont get into cynaurics here but I’ve been manually dosing my pool with liquid chlorine daily or every other day or so. If you are interested in why checkout www.troublefreepool.com since following the practices here my pool is always sparkling clear and cheap on the chemicals. Obviously I wanted to get this process automated as work will keep me gone more this summer than normal making it so I cant dose the pool. To set this up I needed two relays and I only had one left on my 8 relay board. Good news is I had a single relay kicking around I used to tinker with projects. So I wired that up to my photon and I was good to go. My wiring method on these was I took out the gfci outlet on my pool sub pannel and instead put a gfci breaker on the circuit. I then took a regular outlet and snipped the brass jumper conncetor thing on the hot side which separates the top outlet from the bottom. Now I hooked up each outlet to my relays. This just allowed me to plug the stenner pumps right into the now controlled outlets instead of modifying the pumps chord and possibly voiding warranty. This also looks cleaner. For the pumps run schedule I figured that I could afford no errors here and therefore did not want to rely on smartthings for scheduling as if a pump failed to shutoff i could pump way way too many chemicals into the pool. SO for the scheduling I handle it locally on the photon. My device handler for the chemical pumps just merely shows which pump is on or not and also allows me to change the daily targets. And I can also set a manual run with a timer that is also internally handled once the request is received.

  5. Running the stenner pumps locally as well as the discussions above where some of you thought that the pump and valve schedule itself would be better run internally rather than relying on webcore for my regular pump schedules got me thinking that I might as well program my pump and valves internally as well. So that is what I did it was easy to do now smartthings shows whats happening and I can manually over ride but I have an automatic mode that internally schedules its own runs then just refreshed the device in smartthings to show its current state. This overall should make the whole thing more reliable. The aerator also is decided locally if it should run based on time of day and water temperature.

I’ll attach a video and some pictures below. As far as looking into the future I’d like to maybe incorporate a variable run rime that automatically adjust seasonally be it by month outside air temperature or pool water temp. This would eliminate any need to change the schedule seasonally making it a truly smart pool controller. Other ideas I’ve tossed out is smartthings sending a high wind warning to the the photon to run a little extra speed or duration on the floor cleaners. I’d still also consider adding chemical sensors if I can find a good reliable and cheap way to do it. It would incorporate nicely with my auto injectors as right now Ill just have to guess and approximate the time and periodically test the pool.





(Lance) #66

Just a warning for those who may not know…be VERY careful with liquid chlorine and muriatic acid. If they mix, they create mustard gas essentially. If the liquid chlorine mixes with any stablized chlorine (i.e. pucks), it will create a violent explosion. I have a liquid chlorine Stenner pump myself and am planning to add acid, but thought I would put that out there as a PSA!

@bscuderi13 have you updated your GitHub code to reflect the on-photon timing? My project is still progressing, but on hold a bit due to work obligations and waiting to get my variable speed pump installed (Pentair, so not as user friendly from a particle hacking perspective unfortunately).

Edit: Just watched the video. I am certainly no expert, but my pool guy told me the acid/chlorine injection points need to be at least 6 inches from each other. In the video it appears yours are closer. I would be careful not to run them at the same time, as you might run into some issues.


(Bscuderi13) #67

Sorry I haven’t updated the github code but I will do so later tonight. I’m very much aware of the dangers of the two chemicals mixing. I wasn’t worried about the distance of the injection points which is about three inches because the pumps are controlled from the photon and do not run anywhere near the same time. I believe there is a half hour or so of pool pump flushing the lines after one of the chemical pumps turns off before the other is allowed to come on. But this is a very good point and I’m glad you brought it up. Maybe I should have put the points themselves further apart but like I say there is zero chance they are on at he same time.


(Bscuderi13) #68

All the github code should be updated now and I’ve made lots of little changes… To make your life a little easier I’ll paste here the code that pertains to the auto scheduling. I realize there are probably about 20 different ways to do this with a photon but this is what made sense to me. I basically call for the checktime(); function in my loop code which basically checks to see if it needs to run a scheduled event. The function checks the hour and minute as well as sees if the minute changed from the previous minute. I do this so that I only run the code once when the minute becomes the minute I scheduled the event to happen. Also to clarify the acid pump relay is on when high and off when low the chlorine relay is opposite thats why the code has the low and high where it does cause they are different kinds of relays…

// Runs when called upon in loop to check for a regularly scheduled event such as pump speed changes valve changes and chemical pump changes at set times of the day
void checktime() {
hour = Time.hour();
minute = Time.minute();
month = Time.month();
day = Time.day();
//check if the minute changed so stuff runs once
if (minute != previousminute){
    minutechange = true;
    previousminute = minute;
}
else {
    minutechange = false;
}

int cursec = Time.local() % 86400;
char Cpumpstate = digitalRead(chlorinerelay);
char Apumpstate = digitalRead(acidrelay);

//
// chlorine pump auto schedule
//

// Addition 1 at 8:05 am
if (Cpumpstate == HIGH && hour == 8 && minute == 5 && automode == true){
    digitalWrite(chlorinerelay, LOW);
    secCoff = (cursec + (((Cdailyruntime * 60)) / 3));    // calculates the time to trigger shutoff assuming 3 additions to hit the daily value
    Particle.publish("chlorineon", "true", PRIVATE);
}
// Addition 2 at 2:30 pm
if (Cpumpstate == HIGH && hour == 14 && minute == 30 && automode == true){
    digitalWrite(chlorinerelay, LOW);
    secCoff = (cursec + (((Cdailyruntime * 60)) / 3));    // calculates the time to trigger shutoff assuming 3 additions to hit the daily value
    Particle.publish("chlorineon", "true", PRIVATE);
}
// Addition 3 at 10:00 pm
if (Cpumpstate == HIGH && hour == 22 && minute == 0 && automode == true){
    digitalWrite(chlorinerelay, LOW);
    secCoff = (cursec + (((Cdailyruntime * 60)) / 3));    // calculates the time to trigger shutoff assuming 3 additions to hit the daily value
    Particle.publish("chlorineon", "true", PRIVATE);
}
// Turns off chlorine relay after set time if it was turned on automatically
if (Cpumpstate == LOW && cursec >= secCoff){
    digitalWrite(chlorinerelay, HIGH);
    Particle.publish("chlorineoff", "true", PRIVATE);
}

//
// acid pump auto schedule
//

// Addition 1 at 9:00 am
if (Apumpstate == LOW && hour == 9 && minute == 0 && automode == true){
    digitalWrite(acidrelay, HIGH);
    secAoff = (cursec + (((Adailyruntime * 60)) / 2));    // calculates the time to trigger shutoff assuming 2 additions per day to hit the daily value
    Particle.publish("acidon", "true", PRIVATE);
}
// Addition 2 at 11:00 pm
if (Apumpstate == LOW && hour == 23 && minute == 0 && automode == true){
    digitalWrite(acidrelay, HIGH);
    secAoff = (cursec + (((Adailyruntime * 60)) / 2));    // calculates the time to trigger shutoff assuming 2 additions per day to hit the daily value
    Particle.publish("acidon", "true", PRIVATE);
}
// Turns off acid relay after set time if it was turned on automatically
if (Apumpstate == HIGH && cursec >= secAoff){
    digitalWrite(acidrelay, LOW);
    Particle.publish("acidoff", "true", PRIVATE);
}


//
// pump and valve auto runs
//


//  6:30 am full speed and floor cleaners
if (hour == 6 && minute == 30 && minutechange == true && automode == true){
    aeratorautorun = false;
    cleanersOn();
    SetSpeed("7");
    Particle.publish("refresh", "true", PRIVATE);
}

// 8 am 1500 rpm main returns
if (hour == 8 && minute == 0 && minutechange == true && automode == true){
    mainsOn();
    SetSpeed("2");
    Particle.publish("refresh", "true", PRIVATE);
}

// 3 pm off for peak
if (hour == 15 && minute == 0 && minutechange == true && automode == true){
    SetSpeed("0");
    Particle.publish("refresh", "true", PRIVATE);
}

// 8 pm 1500 RPM
if (hour == 20 && minute == 0 && minutechange == true && automode == true){
    SetSpeed("2");
    Particle.publish("refresh", "true", PRIVATE);
}

//  11:30 pm full speed and floor cleaners
if (hour == 23 && minute == 30 && minutechange == true && automode == true){
    cleanersOn();
    SetSpeed("7");
    Particle.publish("refresh", "true", PRIVATE);
}

//  1:00 am 1500 rpm or 1750 and aerator depending on pool temp
if (hour == 1 && minute == 0 && minutechange == true && automode == true){
    if (poolTemp < 86){ // dont run aerator if pool is cold
      mainsOn();
      SetSpeed("2");
      Particle.publish("refresh", "true", PRIVATE);
    }
    if (poolTemp >= 86){ // do run aerator if pool is warm
    SetSpeed("3");
    delay(5000); // give pump time to react before valves move
    aeratorOn();
    aeratorautorun = true;
    Particle.publish("refresh", "true", PRIVATE);
    }
}

// pool temp cools below 84 shut aerator off
if (valveposition == 3 && poolTemp <= 84 && aeratorautorun == true){
    mainsOn();
    SetSpeed("2");
    aeratorautorun = false;
    Particle.publish("refresh", "true", PRIVATE);
}

//
// update the clock once a day
//

if (cursec >= 11700 && day != daylasttimesync){ // 3:15 am but only once
Particle.syncTime();
daylasttimesync = day;
}

}



(Ghassanjankeel) #69

Hi, I’m using Linknode R8 instead of Photon, however I’m using a lot of your code (smart things part only) and modifying it to work for my needs after understanding the logic behind it.
Can you please add to the github the device handler code for the chemical pumps, I need to see how photon function are called, I don’t know if I said it before, but I’m very new to coding, I try to collect bits and bytes here and there and get things working.


(Bscuderi13) #70

Sure I can post that part up. I just realized I never put that up there. I do however call particle functions in most the other device handlers as well. Like the pump controller and the water valve controller. Give me about thirty seconds and it should be up on the github.


(Bscuderi13) #71

So I have done alot of updates even though I haven’t been in here to keep up on it. So I thought I would update the main video at the top of the page as well as talk about a couple of things here.

  1. Particle firmware 0.7.0 is riddled with lots of connectivity bugs. This made me think I was having network hang issues etc that lead to several coding changes. I’ve since found out its bugs in 0.7.0 but my changes are still good changes nonetheless. For instance I found that if network is lost it causes the loop to hang long enough I was missing some local events. So now I have taken control of network control in my firmware. if connectivity is lost it will move on and work on regularly scheduled events and checkback every minute or so and try to connect for a few seconds and if it fails it moves on so it doesn’t hang up trying to connect and miss important jobs. I added an RSSI variable so you can see how your connection is. However, mainly either run 0.6.3 or the new prereleases im on 0.8.0 rc.10 and its working great… in fact particle even incorporated a device health feature and disconnect counter in the new pre-releases. But do not run 0.7.0

  2. The automode now runs as a resume function for instance if you make a manual change and then re-engage auto mode it goes back to where it should be locally scheduled. The same happens if you have a power outage or the device gets rebooted it resumes the regular scheduled speeds and valve settings instead of waiting for the next event.

  3. I had the LED for the pool light burn out eventually and I got a new one. I was surprised it didn’t last longer but oh well the new bulb which was the same kind from amazon has had some changes to how it color cycled so I had to incorporate the changes into my coding… I took this time to clean it up and make the color changing code one small function instead of a large function for each color.

  4. Level sensor eventually died to corrosion. I need to either get a case printed to protect it from the elements or go a different direction with the design. The photon and temp sensor portion are fine since they weren’t directly exposed.

Cheers…


(John) #72

I ordered a photon today just to start playing with it…AFTER I saw this awesome project! Your pool is very similar to mine and I am hoping to piggyback off of some of the amazing things you have done. It looks like a lot of fun and a LOT of work! Thanks for posting and updating progress and files.


(Bscuderi13) #73

No problem. Thanks for the love. Glad I could inspire. The photons are super fun to work with. They have been a great learning platform for me. Big changes coming up as I have ordered a multitude of new sensors for the project. So stay tuned. I’m wating on some stuff from a slow boat. But I’m planning to add to the photons.

  1. Non contact liquid level sensors to my chemical tanks for low chemical level alerts.
  2. Inline PH and ORP sensors as well as an inline temp sensor for the accurate ph. (I have stuff mostly Plummed just wating on my thermowell and I can hook it up calibrate and program)
  3. The liquid level sensors laser distance corroded so I’m replacing with a milone etape and it’s going to be a way better level detection system I can tell already based on test trials hooking it up and getting some readings. Soon as I get some stuff from the slow boat version 3 circuit with the etape will be built. It will also feature a larger battery capacity. And complete waterproof seals to protect it from the elements this time.

(John) #74

Thx for the reply…Looking forward to reading more on these updates. In addition to the control aspects of this project, I have been thinking about my need for system monitoring because we travel a lot. Sounds like you are planning that too.

Since I just started yesterday, haha, I know nothing about the capabilitities for these architectures to provide notifications (emails, texts, etc) for possible issues with the pool such as pump “broken”, chlorine “low” (sounds you are tackling this one), etc.


(Bscuderi13) #75

They work great for notification. The possibilities are basically endless.


(John) #76

I’m having a lot going of fun playing with the photon. It’s taking me a quite a while to learn some of this programming and syntax…I did mostly assembly code so things have changed, haha.

As some of the other posters have talked about, I’ve been experimenting with direct motor control of my ecostar by adding a rs485 adapter to the photon. I can fully control the rpm successfully, no problems with that…the pump returns “watts” as status. This is described in some detail on some other sites…particularly this one: http://www.desert-home.com/2014/07/controlling-hayward-ecostar-pump.html

I am not yet confident about emptying the photon’s receive buffer with the information returned from the pump and am still working out some hiccups that occur when I empty it too quickly (I think). The pump requires refresh signals sent about every second. Since the rs485 bus is only half duplex, I think I am running into some collision sequences between transmit and receive data. This causes the pump not to receive its refresh and so it turns off…but I really want reliable “watts reporting” from the pump so I am going to keep at it until I can reliably get it, and fully understand what my current issue is.

I have also been designing my pump/pump rpm/valve schedule database and experimenting with the photon’s eeprom where I plan to store it. It will include either 32 or 64 entries. The main reason I started this project was to have more options for my pump times/rpms than I currently have with my Hayward pool controller.

Anyway, i am just experimenting with small snippets of code and exploring the photon. Hope to have more updates as I get more time. Have you been working on your system updates? My recently installed chlorine tank definitely is going to need a level detect.

By the way…I also recently found the site you did: https://www.hackster.io/user3424878278/pool-fill-control-119ab7

Some great inspiration there to incorporate into a pool controller…eventually. He needs to change the name of that project from “pool filler” to “pool controller”…I think that is one of the reasons I have missed that site in my many searches for ideas.


(Bscuderi13) #77

@Jonpcar
Wow this is awesome and great news. I have the Tristar and I would think / hope that it is the same logic. The pumps and the control pannel on the pump look identical. I’d definitely love to see your code when you get it to a working state. Most that communication stuff and raw data processing from serial communications confuses me. However, once you get it working It might be kind of nice to switch to this level of control and receive realtime power use data from the pool pump as well as percise speed control. It sounds like something that needs a dedicated photon not running valves and other things since it’s that dependent on the timing of data transmission and receiving. Not that buying one more photon would be a big deal. If you can’t get it working I will say the relay control does work great and is a super easy. I have found I use about 4 or so of my 8 options most often anyways since you end up with favorites FWIW. I think that reading real watt data could be a huge development cause you could base other notifications based on that such as maybe even detecting clogged pipes or a dirty filter etc…

one area of thought on your random communication problems might be related to temporarily losing a connection to WiFi or the particle cloud… basically if you are in automatic mode the attempt to connect to WiFi and or the particle cloud to publish or receive data can be a blocking function and will block the loop from continuing until it connects I found this issue when I went local schedule on the photon and noticed an occasional missed event. Cause of this I use semi automatic mode and or manual mode on most of my photons now.

I agree I also wish I had found that hackser post sooner and agree he needs to rename it. He’s got a lot of great info in there. Me and him have been private emailing back and forth for the last month and he has been great to bounce some ideas back and forth. Come to find out he lives just down the street from me and is also a pilot. Sometime in November when we can get our schedules to align we are planning to go get some lunch and nerd out share some design ideas etc. I am planning on putting the non contact liquid level sensors that he used on my chemical tanks. I’m just still waiting for the slow boat to deliver them. I ordered them like a month ago.

I have been working on my project with a couple of respects. I have changed over to hubitat as my home automation controller so I’ve been catering a lot of my code to that and the local control abilities of the hubitat. I also just finished soldering up version 3 and the replacement for my pool temp level sensor a few days ago. For the level sensor part. I am using the same milone etape like the hackster post. So now there will be no holes in the project case so it should be protected from all moisture and fumes. So far it works great and should be a way more robust solution. I’ll have to come update this post soon with some pictures of that build and updated code. I updated the code on that part of the project too. Instead of waking up every 4 hours I’m waking up every 15 minutes for a new reading. I’m using the retained variables option by powering the vbat pin I just learned about to track my readings. In order to save power and get more timely info I only connect to WiFi and send the data if it changed from the last readings. This should give me a more responsive sensor. I may even switch over to once an hour but once every 5 minutes if the pool is filling or something. The possibilities are endless and I’m very excited about this new version.

I also have plumbed in a diy flow cell into my pool plumbing to take sensor readings from an orp and ph sensor that I have purchased. I just received those items the other day and I need to just hook them up to a photon and calibrate / code and install when I get some time. I also need to figure out my logistics on this cause the one main pool photon is getting pretty busy and full… I may need a different dedicated photon for the chemical stuff in order to free up some pins.

Keep the updates coming man. I’m super stoked that someone was not only inspired by some of the work I’ve done but that you are taking it to the next level and making it even better! I’m excited what this project has is store with multiple brains working it.


(John) #78

I figured out my problem…it was a runtime error where one of my indexes was overwriting my pump command, took me hours since I haven’t yet figured out the best debug methods for the photon yet.

I am now able to set the Hayward Ecostar to any rpm (0, 20-100) and get its response which includes the watts. @bscuderi13 you are right, having the watts reading allows you to check if the pump is actually moving water at an expected rate…useful for acid/chlorine injections, pump failure, etc.

As far as dirty filter…at some point I will definitely be getting a digital PSI device as did Richard Sears (hackster pointer) for that kind of check.

Sending and receiving the pump command and status take virtually no overhead…however, the rest of the code in the photon/arduino loop routine really can’t use the delay() function that might interfere with pump updates . That is how I am planning on writing my main routine to control everything (pump, valves, acid/chlorine, status, etc). It will all be based on scheduling and of course temporary manual overrides of those schedules.

Instead of the delay() function, I will need to use flags that allow flow through loop() to always continue. Let me know how you want the code for the serial control of the pump…can I post it here? Not sure how to do that.

It does require a device like this: https://www.amazon.com/DROK-Adapter-Module-Converter-Indicator/dp/B075V2NMV8 …available on Amazon but also much cheaper through EBAY on the slow boat from China. For Photon, I think you need a 3.3V version of this…there are lots of other versions, most of them 5V.

Edit, btw I’m anxious to see how your probes work out…would sure be great to have those work out.


(Lance) #79

Very interesting. I’m anxious to get back on my project. I have a Pentair Intelliflow, and I would love to figure out how to control it from the Photon.


(Bscuderi13) #80

So you can post code in a code block by putting it in like this only without the brackets.
(‘’’cpp)
Your code here
(‘’’)

Just like it’s described here if my post is confusing lol. https://community.particle.io/t/forum-tips-and-tricks/3999/2