• My project consists of an Espruino Pico, Wiznet5500io and a 2 Relay Module. I am using node-red and mqtt on my raspberry pi 3 to communicate with the Pico. I am using these parts to turn on and shutdown my computer. I mainly use my computer as a media server which is located downstairs in my office. My TV is located upstairs. I normally shut my computer off when it's not in use so I can save on my electric bill. Instead of walking downstairs to turn on/off my computer I figured I can comfortably do that from my cell phone via from my couch :-)

    The pico controls the relay. The relay is connected to my motherboard shutdown header. The relay is triggered for a second to short the header to gnd when it receives the mqtt msg of "shutdown" or if the button on top of the pico is pressed. Triggering the relay will turn my computer on or shutdown my computer if its all ready on.

    With the help of @alldata I was able to use his suggestions to get a working prototype :-)

    Any critiques/suggests are welcomed.

    I eventually want to create a pcb, but first I need to figure out fritzing.

    Guides that I followed:

    1. http://www.espruino.com/WIZnet
    2. http://www.espruino.com/Home+Automation


    1. Create a cleaner fritzing sketch
    2. Add some gauges in node-red to receive feedback
    3. Create a PCB

      var turnedOFF = 1;
      var isConnected = false;
      var MQTT_HOST = "";
      var PATH = "/mydevice/";
      var mqtt;
      var eth;
      function mqttMessage(pub) {
      console.log("pub: " + pub.message);
       "MQTT=> ",pub.topic,pub.message);
      if (pub.topic==PATH+"computer") {
      //var v = pub.message!=0;
      if (pub.message == "shutdown") {
        mqtt.publish(PATH+"onoff/status", 1);
      if (pub.message == "0") {
        mqtt.publish(PATH+"onoff/status", 0);
      //digitalWrite(B3, v);
      function mqttConnect() {
      mqtt = require("MQTT").connect({
      host: MQTT_HOST,
      mqtt.on('connected', function() {
      console.log("MQTT connected");
      // subscribe to wildcard for our name
      mqtt.on('publish', mqttMessage);
      mqtt.on('disconnected', function() {
      console.log("MQTT disconnected... reconnecting.");
      setTimeout(function() {
      }, 1000);
      /*setInterval(function() {
      if (!mqtt) return;
      }, 2*60*1000);*/
      function trigger() {
      turnedOFF = 1;
      digitalWrite(LED1, 0);
      setWatch(function(e) {
      digitalWrite(LED1, e.state);
      }, BTN, { repeat: true });
      function onInit() {
      console.log("Connecting to Ethernet");
      SPI2.setup({ mosi:B15, miso:B14, sck:B13 });
      eth = require("WIZnet").connect(SPI2, B10);
      //console.log("Connect?: " + isConnected);
      isConnected = eth.setIP();
      //console.log("Connect?: " + isConnected);
      if (isConnected == true) {
      /*setWatch(function() {
      if (!mqtt) return;
      }, BTN, {edge:"rising",repeat:true,debounce:50})­;*/

    1 Attachment

    • Untitled Sketch_bb.png
  • fritzing sketch

    1 Attachment

  • That looks great - thanks for posting it up!

    So this is connected to your computer's 'soft' power switch rather than actual mains - so it's nice and safe and is a lot kinder to your computer?

  • I'm assuming I connected the two breadboard wires to my computer's 'soft' power switch.

    I removed the cases shutdown button wires from my motherboard header and replaced them with my circuits gnd lead and the lead coming from the relay.

    The circuit is powered from one of my usb ports located on the front 0f my computer case.

  • @d0773d, thanks for doing the leg work on details about the relays board / module - http://www.espruino.com/Relays you use. It is what I expected when you sent me a pic of it for the first time.

    Optocouplers are used to drive the relay in order to electrically (galvanic) separate the input to the board and the driving of the relay itself (control circuit electrically separate from activation circuitry). The relay type used on the board requires 5V to work reliably. Some mc though operate on 3.3V (or less) and therefore cannot handle or create 5V signals and often also (some or all) pins do not have the strength to source w/ high/1 or sink w/ low/0 enough current (mA) for directly driving a relay. Voltage difference is mentioned in the Espruino Relays page by '...If you must use a non 5v tolerant pin, you can sometimes remove a jumper from the relay and power the relay from 5v while powering the optoisolator [optocoupler] from 3.3v - however this will depend on your relay module.)

    An optocoupler is a device that has two isolated circuits or sides - hence also called optoisolator: the input side is an LED that shines light on a switching transistor that control the output side (sorry for the crappy inline char graphics):

    o-H--------.                   .------H-o
                |                  |
     opto       |    LED          /  opto
     coupler  .---.  light      |/   coupler
     input     \ / ----------> -|    output
     side:      V    switches   |\   side:
     LED      -----  transistor   >. NPN
                |    on            | transistor
                |                  |
    o-L---------'                  '------L-o

    Relays boards / modules solve these power - voltage and current - and protection issues using multiple approaches:

    1. use optocoupler t0 separately powering of input from mc and output to control relay with different voltages
    2. use an optocoupler to drive the relay coil directly or indirectly
      • directly: optocoupler's output is strong enough to drive relay (using Darlington circuitry)
      • indirectly: optocoupler's output is not strong enough to drive relays directly but strong enough to drive an amplifying transistor which then drives the relay (as on board at hand)
    3. wires input side of optocoupler the way that pulling the input of the board to ground activates the relay coil (directly or indirectly).

    Pulling to ground allows to use the open collector type of output circuitry on the mc to driving the board input. Pulling to ground - sinking current - is usually simpler (in a 'n-type silicon/semi-conductor context'), more powerful and more predictable. But with pulling to ground / sinking comes negative 'negative logic' / output 0 / sink. With negative logic, output of logic LOW / 0 means 'on', and output floating (disconnected) / logic HIGH / output 1 - same voltage as input side of optocoupler is sourced - means 'off'.

    Output floating is like output disconnected or tri-state - neither LOW nor HIGH - which works for sinking (or sourcing) of LED, but not controlling the base or gate of a bipolar transistor / FET. To control a bipolar transistor or FET, a pulling resistor - either to Ground or power (VCC 3.3V or 5V) is needed on the Basis or Gate to have a stable condition. Espruino has pin-mode that can provide such a resistor - just very weak: 30k..40k Ohm. If this is sufficient, no external resistor is needed.

    The logic can be reversed (again) how the relay (output) pins are used - when the relay exposes three (3) output pins:

    • normally closed
      • connected to pole when relay coil is not activated / not powered
      • disconnected from pole when relay coil is activated / powered
    • pole
    • normally open
      • disconnected from pole when relay coil is not activated / not powered
      • connected to pole when relay coil is activated / powered

    Which way to use the relay pins depends on the duty cycle of the (regular, non-latching) relays:

    The input side is controlled by the mc with connecting the L(side) of the LED to Ground. The H(igh) side is powered by 5V (or 3.3V). Usually a current limiting resistor is in the circuit either in on the H(igh) or L(low) side.

    The output side is controlled from the (infrared) light of the LED. The H(igh) side is powered by 5V - as the relay in use requires - and does not have a resistor in the circuit, but a Diode in blocking direction (regarding current flow) across the relay coil pins in order to protect the optocoupler from Back EMF spikes on relay coil deactivation.

    Therefore, the trigger code logic with setTimeout(... and digitalWrite(... (or .set() and .reset()) and related initialization has to be negative logic. setTimeout(... with digitalWrite(... (or .set() and .reset()) for controlling the ***pulse end / duration*** is preferred overdigitalWrite(...``` as documented in Espruino reference for digitalPulse():

    digitalPulse is for SHORT pulses that need to be very accurate. If you're doing anything over a few milliseconds, use setTimeout instead.

    The code using setTimeout(... and digitalWrite(... (or .set() and .reset()) looks like as you pointed out (with some changes in the initialization):

    / some defs/inits
    var inProcess =  false;
    var shortPress = 1000; // ms 1  sec
    var longPress = 5000; // ms 5 secs
    var pressPin = B3;
    pinMode(pressPin,"opendrain"); // output like 'open collector' see reference
    pressPin.set(); // output in tree state / float
    // ...other defs/inits as needed
    function press(short) {
      if (inProcess) return; // ignore press function when one is still going on
      inProcess = true;
      // Relays (board) act in an inverse manner
      // reset() will latch the relay
          // Relays (board) act in an inverse manner
          // set() will unlatch the relay
          inProcess = false;
        },(short) ? shortPress : longPress);
    setWatch(function(e) {
      digitalWrite(LED1, e.state);
    }, BTN, { repeat: true });
  • Fri 2018.08.03

    re: sorry for the crappy inline char graphics ):

    @allObjects don't sell yourself short on the effort, I felt the graphic was quite good and detail explanatory. Nicely done!

    re: "but a Diode in blocking direction (regarding current flow) across
    the relay coil pins in order to protect the optocoupler from Back EMF
    spikes on relay coil deactivation."

    I couldn't remember the diode direction, but remembered I had a link to a diagram:


    and for those that might be diode direction impared, the diode polarity:


    All in all I felt the explanation could be used as a separate tutorial, something like:

    Home >> Tutorials >> Driving a relay using an opto-isolator

    Is there a way to block copy from one post to another or would just a link to this thread be sufficient?

  • @allObjects Holy crap thank you for that write up and explanation :-) Robin is correct, don't sell yourself short :-) Your inline char graphics is great. I'm a visual learner so your char graphics made plenty of sense.

  • Some more and accurate details about the 2 relays board and related schema attached as pic.

    The second pic with optocoupler only driven relays shows that there are actually 2 / 3 independent circuits involved I, II and III. 2, if the power is jumpered / shared (I+II are one), 3 if supplied individually. Interesting technologies to bridge the insulation gaps: (infrared) light between circuit I and II, and mechanical 'rod/lever' between II and III.

    Powering the input side of the optocoupler w/ 3.3 Volt may be critical, because the current limiting resistor R could turn out to be too high and not enough current is flowing to reliably switch the optocouplers output transistor, especially when also a on-indicator LED is in series in the input circuitry.

    A relays creates already a great separation between low voltage and household power voltage (100..240V). The optocoupler provides the protection from any back EMF and with the transistor (or built-in dual transistor as Darlington circuit) reduces the number of parts. The board in uses a simple optocoupler and for current the extra transistor externally, and the on-indicator LED in series with the optocoupler LED (personally, I would like the on-indicator LED parallel to the relays to show wether the relays is pulled, especially when powered separately).

    The cheapo version of relays connectivity uses just a simple npn-Transistor, a current limiting resistor, and a flyweel diode (against back EMF), as shown in the last picture. Since Espruino can have "output_pulldown", the 'swtich-off' resistor from transistor's base to Ground is not needed (crossed out) -pic taken from https://www.electronics-tutorials.ws/blo­g/relay-switch-circuit.html as provided by / thanks to @Robin. Note the positive logic! - What I like in this tutorial is the variations shown, even with different than bipolar transistors.

    3 Attachments

    • BoardAndSchema2Relays.png
    • optoOnlyDrivenRelays.png
    • cheapoRelaysDriving.png
  • Sat 2018.08.04

    Now you've done it @allObjects, you have successfully one-up'd yourself!! Another stellar overview.

    re: 'I would like the on-indicator LED parallel to the relays . . . '

    Agree with you on that observation. Or dual indicators, input - output

    re: 'Since Espruino can have "output_pulldown", the 'swtich-off'
    resistor from transistor's base to Ground is not needed (crossed out)'

    From a hardware design perspective, wouldn't it be smart to have the pull down resistor present on the base, as when the input signal is removed, the transistor could take on either state, which might be a terrible thing if say high voltage is used on the relay output and it stayed in an erroneous state, possibly causing injury?

    What would happen if the signal source, microprocessor driven, gets stuck in an endless loop forcing the input high, which engages the relay. Then in panic, the microprocessor is yanked out of the circuit. Relay stays stuck on, which might not be a desired outcome.

    For the cost of a penny, I'd rather err on the side of safety, and keep that pull down in place. At least we would know what state the transistor should be in, and therefore the same for the state of the relay, should the input signal be lost.

    My 0.02 worth. (okay, three pennies)

  • Indeed, saving has its limits!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Turning my computer on and off with a Pico, Wiznet 5500 and a relay.

Posted by Avatar for d0773d @d0773d