Extend contact closure from one site to another


Good morning Travis,

I just had an interesting experience to share:

I un-commented your two lines of code related to PaperTrail, i.e. “// #include <papertrail.h” and “// PapertrailLogHandler paperpapertrailHandler(“logs7.papertrailapp.com”, 45358,“PumpStatus”);” and re-flashed the file to the Electron at the well. It flashed OK. But some time thereafter (maybe immediately; I wasn’t watching) that Electron lost connection to the Particle Cloud. The Electron flashed cyan continuously ever since until this AM (I was thinking that cell service simply sucked and I was waiting to see if things improved on their own).

This morning I decided to revert to the previous version of the app firmware in case there was something in the PaperTrail code that was responsible (maybe hogging the CPU). I couldn’t flash it over the air, of course, so I downloaded a binary version via Particle Build and flashed it to the board via USB. In the process, I got the responses you can see in the attached screenshot (note that I changed the file name). Although I had to ‘force’ the upload to the board, I was told that it was successful.

I then re-installed the Electron at the well and after a minute or two flashing green, the thing went into safe mode, implying that the app firmware would not run or otherwise wasn’t playing nice with the OS (Particle’s own firmware).

Since it was again reconnected to the cloud, I flashed the previous non-PaperTrail version of the app OTA from within Particle Build and now everything is again (finally) back to normal, stable operation.

Any idea what is in the PaperTrail code that hosed everything up?


Hi Brian,

Can you provide a link to the Papertrail enabled code just as it was when you flashed it to the board? The PaperTrail library has pretty high usage on Particle’s Libraries so I don’t know why there would be any problem with it and my usage was pretty standard.



And just to be clear, while the Electron was flashed with the PaperTrail code, it just sat there flashing cyan forever. The safe mode - flashing magenta - was when I flashed the previous version of the app via USB. Once I flashed that same non-PaperTrail version, OTA instead, everything returned to normal.


Good morning Travis. I hope you had a great Turkey Day!

As you will recall, one of the two relay boards I’ve had in production did, on occasion, fail to power the attached Electron or charge the latter’s Li-Po battery. Although the board eventually began functioning properly and did for a week or so, I was concerned that the power problem might re-occur at any time and I asked for a replacement board. DeeAnn sent me one (actually two, in error) and I installed it yesterday. Immediately, it, too, failed to power the Electron or charge the battery. Even with the battery powering the Electron (before it eventually died), it - the Electron - would not turn on the pump when called upon to do so, i.e. there appeared to be no connectivity of any kind between the two boards.

I think I figured out the issue this morning. When I installed the Electron on the new relay board yesterday, the latter was not yet connected to power. This morning, I removed the Electron and plugged it back in with the relay board already powered up. Bingo, the Electron powered up too (no battery yet connected) and when the next call for water arrived from the storage tank a minute or so later, the R1 LED came on and the pump started up.

So it appears that maybe the relay board must be powered up when an Electron is plugged it. That may well have been the issue that I observed with the previous relay board (I had been removing the Electron occasionally during all my testing). I could do more experimenting to positively confirm my suspicion, but I am reluctant to play around too much with the hardware due to concern about potential ESD damage.

Can you confirm this behavior? If you do not know, perhaps someone at NCD can experiment (you clearly have a more suitable testing environment). If I am correct about this, that would be helpful information to include with your product.

One other thing: the RelayState variable you created to query the status of relay #1 is set in your app firmware running on the Electron. It does not actually query there relay board itself (when I installed the new relay board yesterday, that variable returned a ‘1’ since the tank was calling for water, but the relay was not on (no red R1 LED) and the pump was not running. Is there any way for the app to return the relay’s actual status, i.e. not whether it should be on or off, but whether it is on or off?


That is very strange behavior. It’s my understanding that typically, you don’t want to hot-plug a MCU into a motherboard.

You’ve got me wondering. The only spare NCD relay board I have in my office is a PEIO6R2x0, Rev. B, w/ 20 amp relays shown below:

I just installed an electron (Off, no Li-Po) and then powered the NCD Board with 12V 2amp supply.
The Electron booted fine. It also started charging the Li-po once connected. It’s running firmware 0.8.0-rc11.
I cant reproduce the behavior you’re seeing, but I don’t expect that we are using the exact same relay boards.

Just to confirm… Is the RED LED Power indicator Light shining on the Relay board during the times the Electron will not boot (right beside the DC plug)?
One other long shot, is the problem only showing up @ Cold Temperatures?


Create a new Particle Variable that only reads the relayStatus, like this:

You wont need the extra indentation obviously.

relayState = what the Tank wants to happen
relayStatus = what the Well controller is actually doing.


Hi Brian,

Looks like Ryan’s suggestions should correct the variable issue.

I also powered up an electron in a relay board this morning with the same identical power supply circuit that is on your board and it booted up fine when power was connected(did not hot plug the electron).

What this sounds like to me is your electron has a slightly higher than normal initial power draw spike when it’s first powered up. Most electronic devices draw slightly more current on initial power up so when you were hot plugging the electron my suspicion is that all components on the board were already powered and the 5VDC regulator was stabilized so when you added the electron the power supply circuit was able to handle it, but when you power the board up with the electron the initial power supply draw on power up is more than the 5VDC regulator can handle. This really would not be visible in any way since the power LED on the board is not powered through the 5VDC regulator circuit on the board but rather off the 12VDC supply(through a resistor). For experimentation’s sake you could try pulling the electron from the other board and install it to see if it works or not. Another possible experiment is putting the Electron in MANUAL mode so the code controls when the cellular connection turns on, this way the board could power up, then after a few milliseconds it could turn on Cellular, it’s kind of a pain because you have to handle all the connections manually but that would essentially be close to “hot plugging” the module without the worries.

All in all, I agree this is very strange.


Yes, Ryan, the power LED was/is on whenever the power supply is connected. I agree that “hot” plugging is usually not recommended, which is why my first attempt was done with no power connected to the NCD board.

Thanks for the relay status solution. Kowabunga!


Hey Ryan,

Since I didn’t really care about what the Electron’s code thought the relay status was but, rather, only what the actual relay status was, I modified the original ‘relayState’ variable code to reflect your recommended solution rather than add complexity by creating a new ‘relayStatus’ variable as you suggested.

Everything worked like a charm except when I called your ‘Pump_Min’ function to turn the pump on for a specified number of minutes, the ‘relayStatus’ variable did not reflect that the pump was on (due, of course, to that function being in a ‘while’ loop awaiting timer expiration). So I added a ‘relayState = controller.readRelayStatus (1)’ statement after the ‘controller.turnOnRelay(1)’ statement in that loop. That addressed that issue.

I am now thinking of removing your 10-second loop and simply adding the ‘relayState = controller.readRelayStatus (1)’ statement after every appearance of a ‘controller.turnOnRelay(1)’ or ‘controller.turnOffRelay(1)’ statement. Not necessarily more efficient but, in my view, easier to follow/understand. Question though: do I need to enter any kind off pause/delay between an instruction to turn the relay on or off before I read its state (set the ‘relayState’ variable)?


I’m not a Programmer or a Hardware guy, but I’d say YES.
The best way I found to perform a “delay” with an Electron is this line:

  for (uint32_t ms = millis(); millis() - ms < 1000; Particle.process());  // (ms) 1000 = 1 second

It allows the Electron to perform all it’s required Cloud stuff in the background

However, it’s not uncommon to track the Control Request and the Physical Output w/ 2 variables, especially since you’re using a Remote Controller (in respect to the Well Controller).

I was paving the way for you to have the Tank subscribe to the Well’s Pumping Actions (in the future).
Then the Tank would know that the Well isn’t pumping when it’s supposed to be, and thus send an Alarm Publish, Text message, and/or Email from the Tank.

Similar situation at the Well, you can eventually have the Well Publish an Alarm if the Well hasn’t heard from the Tank in an Hour, etc. That’s the beauty of the Publish/Subscribe method that Travis used for your Code.

My only other recommendation (for the future) would be to add a $100 water pressure sensor at the Well Site. Then it could operate independently of the Tank Controller in case of a communication failure of either Electron (as a fail-safe only).

My goals for a remotely operated Well/Tank water system are simple:

  1. Fill the Elevated Tank when water is needed.

  2. Notify the Operator if anything does not go as expected

  3. Try not to Overflow the Tank each pumping cycle.

  4. Log/Graph all Pumping Activity and Water Level in the Tank.

The objective is to make sure nothing in your Code or Comms can “block” or Prevent #1 from happening.

Once you get the base functionality like you want it, I’ll be glad to add the code for ThingSpeak to graph all your data. I’ve never used PaperTrail so I’m much more familiar with ThingSpeak.

Adding a $100 pressure sensor lets you do things like this with ThingSpeak:

Real-Time Tank Level:

Historical Graph of Tank Level:

This would be a great project to document and Share if you and NCD agreed to it.
I’ve seen SCADA systems sell for $20,000+ with much less functionality and flexibility, and much higher monthly fees.

@Travis or @Bhaskar, Can a pair of the GPIO pins of the MPC23008 be used as a 0-5V ADC to read a pressure transducer at the Well, or is the IO expander Digital Only ?


Wow. Lots to digest there. I’ll do so once my daily errands are complete.



Just an FYI: I still haven’t had time to digest all of your suggestions in your last post, but I did modify the app code to check the relay state immediately after it called for the pump to turn off or on and it worked properly every time, i.e. it does not appear necessary to insert a deliberate pause before the status check.

Regarding your suggestion to use a pressure transducer and ThingSpeak to enhance the system’s capabilities: can you point me to an appropriate transducer on Amazon or elsewhere? The tank is 1700 gallons, but I don’t know how deep it is (I’m sure the required pressure range of a transducer is a function of the maximum height of the water above it). I’m guessing no more than 7 or 8 feet but I can check if necessary.



Here’s some sample Code I made for ThingSpeak:
Most of the Code is comments and how to initially create the webhook.

The working code is 7-10 lines.
It’s basically just using
snprintf(msg, sizeof(msg), "{\"1\":\"%.1f\",\"2\":\"%.1f\",\"k\":\"%s\"}", field1, field2, myWriteAPIKey); to create the Publish Payload, and then publish: Particle.publish(eventName, msg, PRIVATE, NO_ACK);

As far as the Pressure Transducer, I’d install it at the Well Site instead, to allow the Well to run as a stand alone controller as a backup to comms failure. Even though your well is several thousand feet away, measuring the pressure in the water main at the well will give you pretty accurate results of the tank’s water level. Dynamic Head Loss is the only thing it wont account for, but you shouldn’t have high demands on a small rural system.

You will need to look at a manual pressure gauge at the well to determine the required pressure rating for the well’s transducer.
You are correct about the Tank Site, the pressure is only a function of water height.
Height / 2.31 = psi.

I use NCD’s AMS5812 sensors and Dwyer Sensors.
The AMS Sensors will require you to protect the water tubing from freezing. The Dwyer Sensors will thread to a 1/4" fitting.

Dwyer Example for the Tank Site:
1% Accuracy, 0-10 psig (g=gauge) range, General Housing, 1/4" Male Threads, 9 ft cable, 0-5V output.
Since the Electron’s Pins are only rated for 3.3V in analog mode, you need to make sure the sensor is over sized for your pressure conditions to prevent an output >3.3V.
This means the 10 psi example sensor can safely be used up to 6.6 psi with an Electron:
10 psi (0 to 5 V output OPTION)
10psi Input / 5V Output = 2psi / V
3.3 max Voltage * 2.0 psi/V = 6.6 PSI max = 15’ of head

Well Site Example:
Assuming your Max pressure at the Well Site was 30 psi, you would select a 50 psi sensor:
50 psi (0 to 5 V output OPTION)
50/5V = 10
3.3 *10 = 33 PSI

In a perfect world, we’d have a 0-3.3V output option…still waiting on that.


Many thanks for the ThingSpeak code. I already got it working in a rudimentary way and achieved the desired ability to capture all published events in an archived log (a little pleased with myself). Because of that, I also added an ‘if’ statement to the well-side app to prevent the retransmission of duplicate events, i.e. if the pump is already off, don’t keep publishing that fact every time another ‘0’ is received from the tank (as happens every 2 minutes). All I care about at this time is knowing when there is a transition from on to off or vice versa.

I’m anxious to try your ThingSpeak code. I’m guessing it’ll be even more useful.

I’m still a little confused with your recommendation to place the pressure transducer at the well rather than the tank, but I’ll stare at that some more after I get ThingSpeak working exactly as desired.


Ryan: while playing around with ThingSpeak I noticed something that I cannot explain. Perhaps you can.

I have tweaked the particle.publish code - e.g. data = “Manual Off”; Particle.publish(“Status”, data, PRIVATE); - to provide an alpha descriptor indicating whether the pump was just turned on or off and by what means. The attached screenshot taken from the Console shows that it is working as intended. The log in ThingSpeak, also attached, misses some of the events.

Any idea as to why?


A Free ThinkSpeak Account can only receive data every 15 seconds. Is that impacting your test ?
I personally send a Pumping Status to ThingSpeak as a 0 or 1; 0=off, 1=on. That makes real-time graphing easy.

The reason is a Pressure Gauge at the Well site allows you to determine the water level in the Elevated Tank remotely. Under normal circumstances, your Code will function as it does right now : The Well Electron subscribes to the Tank’s commands. The Tank’s probes request the remote well to turn on/off.

If the Well’s Electron has a pressure gauge, it allows you to add an additional/backup control scheme, completely independent of the Tank’s Electron/Probe/Cellular Connection.
The Well Site can determine if the Tank is too low without any communication with the Tank, and thus start the Well in an emergency/backup situation if communication is lost between the (2) electrons.

Every 30-60 minutes the Well Electron can read the pressure and send it to ThingSpeak for graphing.
if (pressure< setpoint) and it’s not receiving any data from the Tank, then start the well for 1 hour and publish an Alarm


Ah HA. Didn’t know about the 15-second rule. That obviously explains it. In real life, I seriously doubt that there will ever be two events that occur within 15 seconds of each other, so this should not be an issue at all. Even if it happens, having an event not appear in the archive is not a big deal.

I had been sending just 0s and 1s but at the moment - during all my testing - it is more important to verify/validate what caused the pump to go on or off. Once I am comfortable that the manual- and timer-initiated control functions are rock-solid, I will very likely revert to the os and 1s again for the very purpose you mention: graphing. Of course, if/when I deploy a pressure transducer, then the published parameters will have to be numeric.

Back to the pressure gauge in the well thing: I understand completely the value it might provide in assuring that the tank receives water even if there is a broken link between the tank and the well, but I’m concerned that if the link fails at a time when the tank is full or close thereto, having the Electron at the well turn on the pump for any pre-defined period of time could cause the tank to overflow. I think it more practical to receive notification of a link failure so that one of those of us responsible for managing the water system can visually inspect the tank’s water level and, if necessary, turn on the pump with a manual switch that I have included in the system design. I am going to try to determine if ThingSpeak can be made to send a text or email if communications between endpoints is lost (do you know?).

Graphing the water level in the tank, on the other hand, seems like a very valuable tool to have.


The Well’s Electron would only start the Pump in an emergency situation when 2 things happen together:
It hasn’t received an update from the Tank, and it measures Low water Pressure in the main.
There’s no harm in overflowing the Tank. If you don’t want the emergency sequence to pump for 1 hour, you can always check the pressure every 10 minutes during the emergency event. Or like you say, just send the Operator an Alarm Notice instead of Pumping.

I don’t have a clean/easy way to automatically determine if either Electron’s Cloud connectivity is lost.
I use ThingSpeak’s API to see the age of the last data update to any specific field… since I always have a scheduled Pressure Update publish.

For Alarm notifications I use IFTTT.com. It can send texts or emails…Or notifications straight to an IPhone.
It works by watching for a specific Publish from your devices. You set that up in your IFTTT Applet.
I have a couple of Clients that want to know how often their wells pump and for how long. So they get a IPhone Notification when the well starts, and another one when the well stops that adds the Pump Runtime to the message. In the Electron Code that’s just a Publish, then IFTTT handles the rest.



Regarding IFTTT.com: that’s exactly what I want to do, notify via SMS when pump comes on and for how long. All users of this system have iPhones. So I’m off to learn how to create the appropriate applet.


I got the IFTTT app and got it working easily with the applet “Get iOS Push Notification with Particle Photon” to notify me when the pump comes on. Apparently an applet can only have a single trigger, though, so that’s a bit of a bummer.

You mentioned that you have clients that can receive separate notifications for start and for stop, but how can you do that with any single applet? Is there a better applet that you’d recommend?

Ignore previous paragraph. I just discovered that I can keep on using any applet any number of times. Life is good!


Dang this stuff is cool! Found an IFTTT applet that automatically posts Particle events to a Google Sheets spreadsheet. There seems to be no end to the potential capabilities and features. Thanks for steering me to IFTTT Ryan!