Outdoor Lighting Relay Control

I have a SainSmart 4-Channel Relay Module that I’ve been using with 4 rocker switches and a 5v cell phone charger to turn the relays on and off. It controls some deck lights, patio lights, and umbrella lights, plus one extra outlet for whatever else (usually big box fans). While the setup with the rocker switches has been okay for the most part, I didn’t like the ethernet cable running from the weatherproof outdoor enclosure into the house where the rocker switches are “mounted”. So, naturally, I needed to get rid of the wires and control the outlets using a Spark Core!

I am not going to cover wiring of the A/C outlets as I am far from being electrically certified to do it. DO THIS AT YOUR OWN RISK. THERE IS A RISK OF FIRE, PROPERTY LOSS, PERSONAL HARM, OR EVEN DEATH.

The wiring is simple:

  • Spark VIN → SainSmart VCC
  • Spark GND → SainSmart GND
  • Spark D1 → SainSmart IN1
  • Spark D2 → SainSmart IN2
  • Spark D3 → SainSmart IN3
  • Spark D4 → SainSmart IN4

I am powering the Core using USB, so I am pulling the ~5v from the VIN pin to power the relay (it needs more than 3.3v). This particular SainSmart relay controller does things a little backward, so you have to digitalWrite the pin HIGH to turn it off, and digitalWrite LOW to turn it on. However, in the code, I use 0 to signify OFF and 1 to signify ON. I simply perform digitalWrite(pin, !state) to invert the on/off logic for the relay board.

Also, since I have a bunch of 10K NTC thermistors on-hand, I also decided to use it to monitor the outdoor temperature near the enclosure. I have it connected to pin A0.

This project makes use of some additional functions and libraries made possible by the community:

On the web side, I use my own Simple Spark PHP Proxy (the mod_rewrite version), jQuery, jQuery Mobile, and Google Hosted Libraries for the jQuery and jQuery Mobile JS/CSS hosting.

I have posted the web code as well as my firmware to my spark-deck-lights GitHub repository. The web code is in index.html whereas all the firmware files are in the /firmware directory.

Now, for a few pictures!

This is the original setup using a 5v cell phone charger and ethernet (you can see the ethernet and coupler in the bottom left).

The new setup using the Spark Core. The blue and white twisted pair is part of my thermistor temperature probe.

A screenshot of the web app on my iPhone 4s.


This is very cool! I really like the way you handled the web side of things.

How did you power the relay? Was it just powered through USB power? I am looking to purchase a small relay to experiment with an automatic watering project (solenoid valve).

I am powering the Core using USB power. I then use the 5V coming from the Vin pin (the top left pin of the Core) to power the relay. I don’t remember where I learned that trick with the Vin pin, but it’s really, really handy!

Nice project. I’m trying to get it working so I can show it off to my Arduino group meeting tomorrow. (I have bigger plans for it later as well).

I have 4 LEDs connected to D0-D3 and can control them using Tinker so I know the h/w works. The Spark code is working and flashed to the Core. I know this is working because I can turn LEDs on/off using digitalWrite commands. I uploaded your web app to my GoDaddy hosted site and replaced the core id with mine. I can see the web app from my phone or from a browser but none of the buttons work.

Can you give me some ideas what to check? I’m not web savvy…yet. :smile:

Thanks, Bruster.

The code on GitHub relies on the Simple Spark PHP Proxy that I built a while back. To get around using, it you will need to change some of the code in index.html:

Line 73: $.post('https://api.spark.io/v1/devices/'+CORE_ID+'/toggleRelay?access_token=YOUR_ACCESS_TOKEN_HERE', {'args':'relay'+i+relayState}, function(resp) {

Line 122: $.get('https://api.spark.io/v1/devices/'+CORE_ID+'/tempF?access_token=YOUR_ACCESS_TOKEN_HERE', function(resp) {

Line 137: $.get('https://api.spark.io/v1/devices/'+CORE_ID+'/relayStates?access_token=YOUR_ACCESS_TOKEN_HERE', function(resp) {

It’s a quick (untested) fix but should work. Be sure to replace YOUR_ACCESS_TOKEN_HERE in the fixes above with your account’s access token. Please note that this is considered a security risk to put your access token in plain text in the HTML source, which is why I created the PHP proxy.

Let me know how it goes!

That worked perfectly! For later projects I’ll look into getting the proxy working.

I finally decided to try and learn to program for my Pebble watch. I can’t say that I “learned” it, but I do have a basic watch app working. It is capable of toggling all of the relays and updates the temperature from the thermistor by tapping on the watch and triggering the accelerometer. The updated code is in my spark-deck-lights GitHub repository.

Many, many, many thanks to @ChrisLewis for his helpful guides to get me bootstrapped!


Glad my stuff helped!

Great app! I think the full potential of Pebble is in a remote control capacity - made easier by Spark.

1 Like

Now that I’ve built my first app (sans some error-checking), I have a basic understanding of how to build more apps. I have a feeling that I’ll be building apps within apps so that I’m not constrained by the app limit.

app app app app app :wink:

1 Like

You seem very app-y!


Great app but it gives me this error:

In file included from …/inc/spark_wiring.h:30:0,
from …/inc/application.h:29,
from /Thermistor/Thermistor.cpp:1:
…/…/core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning “Defaulting to Release Build” [-Wcpp]
#warning “Defaulting to Release Build”
In file included from …/inc/spark_wiring.h:37:0,
from …/inc/application.h:29,
from /Thermistor/Thermistor.cpp:1:
…/inc/spark_wiring_ipaddress.h: In member function ‘IPAddress::operator uint32_t()’:
…/inc/spark_wiring_ipaddress.h:53:52: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
operator uint32_t() { return ((uint32_t)_address); };
…/inc/spark_wiring_ipaddress.h: In member function ‘bool IPAddress::operator==(const IPAddress&)’:
…/inc/spark_wiring_ipaddress.h:54:72: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
bool operator==(const IPAddress& addr) { return (((uint32_t)_address)) == (((uint32_t)addr._address)); };
…/inc/spark_wiring_ipaddress.h:54:105: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
bool operator==(const IPAddress& addr) { return (((uint32_t)_address)) == (((uint32_t)addr._address)); };
In file included from …/inc/spark_wiring.h:30:0,
from …/inc/application.h:29,
from /Thermistor/Thermistor.h:1,
from /spark_deck_lights.cpp:2:
…/…/core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning “Defaulting to Release Build” [-Wcpp]
#warning “Defaulting to Release Build”
/spark_deck_lights.cpp:13:24: fatal error: Thermistor.h: No such file or directory
void setup();
compilation terminated.
make: *** [/spark_deck_lights.o] Error 1

Error: Could not compile. Please review your code.

And i can’t solve that errors i’ve died using the other thermistor lib but the error keeps popping up, any hints?