MOSFET as a Switch and cuircut protection

I am wanting to make a garage door opener hack i.e. if I am locked out I can connect to my home WIFI and open the door. The garage door unit has two contacts (indicated as red and blue dots) that when shorted, cause the door to open or close. I have also noticed that these contacts have a potential difference of approximately 6.4 volts DC.

Will the following configuration work (GarageDoorHack_bb_1)? I am still waiting for my MOSFET to arrive, hence I am asking the question.

And if this works could I do the following (GarageDoorHack_bb_2) to power the circuit? I am thinking that I would need a protection diode in somewhere but cannot work our where.

And here you see the biggest drawback of Fritzing breadboard messes. We have absolutly no clue what each pin of that mosfet is.... Which you btw even draw as a BJT... So no idea...

Also, you can't power something from the same pins you try to short.

Easiest alternative:

  • Use an external power supply
  • Use a relay (module) to short the contacts
  • make NO programming mistakes otherwise it may randomly open your garage door when your not home... ::slight_smile:

It's all a learning curve for me. Will see if I can draw the schematic and get back to you :slight_smile:

Please see attached. This should help. Basically what I am wanting is that when D3 is HIGH then I want the red and blue contacts to short.

GarageDoorHack_schem.png

GarageDoorHack_schem.png

Drop the resistor and don't connect the source to board but just to the neg of the door. Also would add a pull down to the gate. If somehow the board is reset and D3 is floating the mosfet will not start to conduct. Also use a small mosfet/logic level mosfet. Or just switch to a BJT.

Then if you use a isolated powersupply, it should probably work.

Ok so I think this should be it then (that is if I have understood the pull down resistor part correctly).

In this situation a relay is "safer" because a relay is an electrically-isolated electrically-controlled switch.

A transistor or MOSFET can be used as a switch in certain applications but when connecting to an unknown circuit, a relay is usually better and more foolproof. ...It would be a bummer if you fried your garage door opener.

Since the Arduino can only put-out 5V at 40mA or less, you generally need a relay driver circuit (made with a transistor or MOSFET). But if you don't want to build it yourself, you can get "relay boards" with a relay and driver built-in.

Thanks for that I think if will go the relay option then. As an academic exercise, did I put the resister in the correct place above?

Just as an aside, the contacts that I would be connecting to are on the actual motor housing for the garage door; I think there is more chance of that blowing my cuircit then the other way round, but I might be wrong.

I suggest you to go with relay.My final year project was based on switching only.While studying datasheets,i found relay more efficient.Relay will switch faster and also will be more fullproof and safe for your other components.So try relay dqfansurvey

Yep, I agree with the relay being the saver option. That's why I also suggested it.

And yep, that is the right way to connect a pull down :slight_smile: Value isn't all that citral. Everything between 1k and 100k is fine.

Thanks for confirming that. Now to the second part. I have reconfigured using a relay, see below (the LED and resistor represents the external device that I will be switching).

The challenge that I am having is that the relay closes for a brief second when the circuit is powered up which means the door will open after a power failure. I have checked and the relay is configured to be normally open.

Once up and running everything works as it should. It is possible to prevent the brief trigger when switching on?

/*
   ESP8266 Web server with Web Socket to control an LED.

   References:

   https://github.com/Links2004/arduinoWebSockets

   https://gist.github.com/bbx10/667e3d4f5f2c0831d00b

   This has been modified to suit the relay's normally open configuration
   When the button is pressed, the LED comes on for half a second

*/

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

static const char ssid[] = "xxx";
static const char password[] = "vvv";
MDNSResponder mdns;

static void writeLED(bool);

ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);

static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0">
<title>ESP8266 WebSocket Demo</title>
<style>
"body { background-color: #808080; font-family: Arial, Helvetica, Sans-Serif; Color: #000000; }"
</style>
<script>
var websock;
function start() {
  websock = new WebSocket('ws://' + window.location.hostname + ':81/');
  websock.onopen = function(evt) { console.log('websock open'); };
  websock.onclose = function(evt) { console.log('websock close'); };
  websock.onerror = function(evt) { console.log(evt); };
  websock.onmessage = function(evt) {
    console.log(evt);
    var e = document.getElementById('ledstatus');
    if (evt.data === 'ledon') {
      e.style.color = 'black';
    }
    else if (evt.data === 'ledoff') {
      e.style.color = 'black';
    }
    else {
      console.log('unknown event');
    }
  };
}
function buttonclick(e) {
  websock.send(e.id);
}
</script>
</head>
<body onload="javascript:start();">
<!-- <h1>ESP8266 WebSocket Demo</h1> -->
<button id="ledon"  type="button" onclick="buttonclick(this);">Open/Close</button> 
<!-- <button id="ledoff" type="button" onclick="buttonclick(this);">Off</button> -->
</body>
</html>
)rawliteral";

// GPIO#0 is for Adafruit ESP8266 HUZZAH board. Your board LED might be on 13.
const int LEDPIN = 0;
// Current LED status
bool LEDStatus;

// Commands sent through Web Socket
const char LEDON[] = "ledon";
const char LEDOFF[] = "ledoff";

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
  Serial.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
  switch(type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\r\n", num);
      break;
    case WStype_CONNECTED:
      {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        // Send the current LED status
        if (LEDStatus) {
          webSocket.sendTXT(num, LEDON, strlen(LEDON));
        }
        else {
          webSocket.sendTXT(num, LEDOFF, strlen(LEDOFF));
        }
      }
      break;
    case WStype_TEXT:
      Serial.printf("[%u] get Text: %s\r\n", num, payload);

      if (strcmp(LEDON, (const char *)payload) == 0) {
        writeLED(true);
      }
      else if (strcmp(LEDOFF, (const char *)payload) == 0) {
        writeLED(false);
      }
      else {
        Serial.println("Unknown command");
      }
      // send data to all connected clients
      webSocket.broadcastTXT(payload, length);
      break;
    case WStype_BIN:
      Serial.printf("[%u] get binary length: %u\r\n", num, length);
      hexdump(payload, length);

      // echo data back to browser
      webSocket.sendBIN(num, payload, length);
      break;
    default:
      Serial.printf("Invalid WStype [%d]\r\n", type);
      break;
  }
}

void handleRoot()
{
  server.send_P(200, "text/html", INDEX_HTML);
}

void handleNotFound()
{
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}

static void writeLED(bool LEDon)
{
  LEDStatus = LEDon;
  // Note inverted logic for Adafruit HUZZAH board
  if (LEDon) {
    digitalWrite(LEDPIN,  0);
    delay(500);
    digitalWrite(LEDPIN, 1);
    LEDon = false;
  }
  else {
  digitalWrite(LEDPIN, 0);
  }
}

void setup()
{
  pinMode(LEDPIN, OUTPUT);
  digitalWrite(LEDPIN, 1);
  writeLED(true);

  Serial.begin(115200);
  //Serial.setDebugOutput(true);

  Serial.println();
  Serial.println();
  Serial.println();

  for(uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] BOOT WAIT %d...\r\n", t);
    Serial.flush();
    delay(1000);
  }

  WiFiMulti.addAP(ssid, password);

  while(WiFiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (mdns.begin("espWebSock", WiFi.localIP())) {
    Serial.println("MDNS responder started");
    mdns.addService("http", "tcp", 80);
    mdns.addService("ws", "tcp", 81);
  }
  else {
    Serial.println("MDNS.begin failed");
  }
  Serial.print("Connect to http://espWebSock.local or http://");
  Serial.println(WiFi.localIP());

  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);

  server.begin();

  webSocket.begin();
  webSocket.onEvent(webSocketEvent);

}

void loop()
{
  webSocket.loop();
  server.handleClient();
}

I can't begin to describe how Fritzing (barf) is failing both you and us. I will leave it at that.

Your issue is that you clearly can't directly connect your switching solution without taking into account that the NODEMCU will hold some pins in an undesired state until the actual code "starts running".

You will need to add more parts if you insist on use that particular GPIO as it does NOT float on startup. Choosing GPIO4 or GPIO5 on the other hand, you simply need to add a pulldown resistor to the pin and it will not FLOAT on startup... but remain LOW until activated by your code.

See if that helps.

Hi pwillard, thanks for that I will follow take a further look tonight. Regarding your comment in the Fritzing think, I am still not sure what the challenges are. Having basically no really electronics basics i.e. just "learning as I go" I understand why the breadboard image might not be helpful but I thought the "schematic" might be alright. I am really happy to understand I just need some pointers i.e. what is missing from the schematic :slight_smile:

Is there another free/opensource circuit design tool that might be preferable?

My bigges problem between the real circuit and the circuit diagram is that they don't show the same thing. It shows a relay but in reality you use a relay module. It even has an extra pin. And differences between what you draw and what you have always lead to trouble/misunderstanding.

About the problem, there are also multiple types of relay modules. Some are active HIGH, some are active LOW. Which do you have?

And yeah, a ESP8266 has some weirdness with some pins. I still have to Google it twice when I use it. Some pins need to be (or are pulled into) a certain state at boot. So you want to use a pin that at least does not pull it to the active state o the relay.

but I thought the "schematic" might be alright.

Except, when it's NOT. Your selected SYMBOL does not reflect reality and would give us the impression you are attaching a relay coil directly to your GPIO pins... (but you aren't). This is the kind of information we need to see in a schematic.

If you use a module... you draw a BOX for the module and you explain the SIGNALS the MODULE expects or controls.

Ok, will try clean my act up :slight_smile:

@septillion, I am using the normally open pin of the realy. To close it I need to set the pin LOW (the single channel https://www.aliexpress.com/item/1PCS-4-channel-relay-module-4-channel-relay-modules-relay-control-board-with-optocoupler/32274260444.html).

Okay, that's an active LOW. Aka, you need a pin that does NOT go LOW during boot. So not GPIO0, GPIO2 or GPIO15. On a NodeMCU those are 3, 4 and 8 respectively.

Many thanks to all of you for your help. At the end of the day the issue was cause by not using the appropriate GPIO coupled with a bug in my code. I learned heaps in the process i.e.

  • The woes of Frizting diagrams
  • How mosfets work
  • pull up and down resistors
  • active high and low relays
  • Delayed power on circuits

Well not fully leaned but at least I know what these all are and where to look when I need them later.

Thanks again.