Arduino Timed Relay

I’ve an idea for a project that needs to wait for a certain length of time and then trigger a relay. So whilst this isn’t a specifically musical post at present, this is the detail of how I got that part of the project ready to go.

IMG_5999

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno
  • 2x momentary push switches
  • 1x HT16K33 based I2C 7-Segment Display
  • 1x Relay module
  • Optional: something for the relay to switch (see warnings below)
  • Optional: “proto shield”
  • Breadboard and jumper wires

The Circuit

ArduinoRelayTimer_bb

This circuit can be made on normal solderless breadboard, but I used a mini breadboard on a proto shield, as shown above.

The following pins/connections are being used:

  • D6, D7 to the two switches.
  • D5 to the relay control signal.
  • A4/A5 to the I2C 7-segment display.

The relay and 7-segment display also required power and GND, and the switches are switched to GND, so will be used in INPUT_PULLUP mode in the code.  Note that I’ve seen both relay modules and I2C displays with VCC/GND connections reversed so really check and double check the modules you have.

The functionality I’m aiming for here is:

  • Button 1: resets and starts the timer.
  • Button 2: resets (i.e. arms) the relay – this will close the “NO” contacts; and open the “NC” contacts.

Once the timer starts counting, when it reaches the internal preset time value it will disarm the relay, causing the relay’s “NO” contacts to break.  The relay has three output connections: NO, COM, NC.  NO means “normally open”; NC means “normally closed”.  The “normal” position being the default when no active signal is supplied (and the default when not powered at all).

The relay I have will work with “HIGH” on the signal also being the “normal” state.  Setting the signal “LOW” will switch its state.

A note on powering the relay.  The relay module I’m using has a relay “SRD-05VDC-SL-C”.  Looking this up online will find a datasheet that decodes this as follows:

  • SRD – model of relay.
  • 05VDC – voltage for the relay coils (5V DC).
  • SL-C – sealed, high sensitivity, contacts type “C” (whatever that means).

But most critically, from the datasheet, we can see that a 5V relay of this type has a coil resistance of 70Ω and requires 71.4mA to switch it.  But these relay modules have a little “driver circuit” on them that means this doesn’t need to come from an Arduino IO pin directly.  Which is good as they can only drive up to 40mA.

No, the onboard circuit contains a transistor that will do the actual switching (more details here) so the “signal” connection can come directly from an IO pin.  So we just need to ensure that the power for VCC can provide 71.4mA.  VCC is supposed to be good for up to 200mA so that should be fine.

Switching a Mains Voltage

One thing that should never be done by anyone other than someone who really knows what they are doing, is working with mains voltage.  That means that one of the key features of a relay, to be able to switch a mains voltage on or off, really should never be attempted as a consequence of any of my DIY projects.

But I want to do just that.  So rather than suggest how anyone else might do the same, all I will describe here are the precautions I’ve personally taken for myself to ensure that this remains within my “safe knowledge zone”.  I thus cannot speak of or recommend any specific practice for anyone else working with mains voltage, other than to suggest “don’t”.

So, with regards to what I’ve written below:

DO NOT FOLLOW THIS AS A SET OF INSTRUCTIONS.  Work to your own limits and knowledge.  DO NOT assume that a MAINS VOLTAGE is ever OFF.  UNDER NO CIRCUMSTANCES get in a position where low-voltage microcontroller projects and MAINS CONNECTIONS might get mixed up.  If something goes wrong with home-made equipment you will probably NOT be covered on your insurance.  Fundamentally, I repeat that I personally recommend that you DO NOT WORK ON MAINS VOLTAGES.

So these are the precautions I’ve personally taken to get this back to somewhere I am comfortable to be, given my own level of ignorance:

  • Everything is confirmed to be physically disconnected whilst everything is being put together.
  • I am using a proper UK plug and socket, not bare wires.
  • I’ve double checked the relay I’m using is both listed as rated for switching a mains voltage (it says 250VAC/10A) and that the actual tracks on the PCB look thick enough and with sensible separation to plausibly support that!
  • I’ve used proper DIY mains screw terminals for securing wires.
  • I’ve tinned the ends of the “live” wires that will be plugged into the relay’s screw terminals.
  • I’ve encased the entire thing in a proper UK pattress box with a proper blanking plate.
  • I’ve taken steps to ensure the mains cables won’t pull out of the pattress box by securing them inside.
  • Even though the relay is rated for 10A operating, I’m only using with a 5A fuse in my plug.
  • I’ve verified that the ground connection is complete through the box (and not linked to the other connections).
  • I’ve broken out the low-voltage connections from the pattress box so that the Arduino is well away from the mains wiring.
  • I’ve covered any exposed terminals within the box with insulating tape.
  • I’ve checked and double checked for both continuity and shorts on the mains side and specifically for no continuity between the low-voltage and mains sides.
  • I’ve developed the code and tested it all works by switching a low-voltage signal with the relay.
  • I’ve not gone anywhere near the mains until all the above checks out.
  • When I got that far, I used an “earth leakage” garden circuit breaker on my connection to the mains.
  • The whole thing won’t be left on for any significant length of time.
  • I’ve never left the mains plugged in (whether on or off) when unattended.

IMG_5998

I repeat this is not a set of instructions or recipe for anyone else.  You will have to find your own comfortable level of expertise, knowledge and mitigations, and if in any doubt, don’t do it.

Relay Sticking…

There is still a problem with relays (especially cheap ones).  Although the “steady state” current may be well under the limits for the relay to switch, it is still quite possible to have a significant surge when the relay first turns things on.  This can cause “contact welding” which makes the relay stay on even though you can hear it “clicking”.

This might be temporary – tapping the relay might free it again in many cases.  Or it might be permanent in which case the relay is probably dead.

There are probably things that can be done to prevent this, I haven’t investigated much (it looks like it might involve a “snubber” circuit).  And as this is on the mains side, I don’t want to experiment.  But once again it is worth noting that if you get a stuck relay and want to give it a tap, make sure it is fully and completely isolated from the mains before you do so.

The Code

The main logic for the code in the loop() goes something like this.

IF timer start switch is pressed THEN
  Reset the timer
  Start the timer

IF relay reset switch is pressed THEN
  Turn the relay on

IF timer is running THEN
  Check the current time in milliseconds
  Update the display with the current minute/second count
  IF timer has timed out THEN
    Turn the relay off
    Stop the timer

The “arming” of the relay is independent of the timer so in principle can be done any time.  But as soon as the timer times out, the relay will be disarmed.  The timer won’t start counting though until the start/reset button has been pressed.

The HT16K33 library I’m using has a rather neat displaySeconds() function which will handle the minute/second split and the display of the colon.  I’m using the millisecond timer as my clock, so it is fairly straight forward to check for a timeout and display the current time as follows:

unsigned long time_ms = millis() - starttime;
seg.displaySeconds(time_ms/1000, true, false);
if (time_ms >= STOP_TIME_MS) {
   // Timer has reached the STOP time
}

For more details on how displaySeconds() works, see the HT16K33 library documentation.

The timeout value is set in minutes and seconds and converted to milliseconds as follows:

#define MINS 1
#define SECS 11
#define STOP_TIME_MS ((MINS*60UL+SECS)*1000UL)

Find it on GitHub here.

Closing Thoughts

This is just a “part project” that I’ve documented while it is fresh in my mind.  I appreciate that it isn’t particularly musical in this form!  I do have a musical application in mind though, so watch this space!

Kevin

Leave a comment