Tiny ESP-01s smashes Motor, LEDs, buzzer!
I love the idea of a small micro-controller "punching" above it's weight. An anaemic tiny processor bossing around motors when it has no right to is my idea of heaven. OK, so I don't get out much.
AND...if you add a little iOT into the recipe, then I'm there for the "fun".
So it happens that we are looking at a gate opening/closing mechanism for the bottom of the driveway.
You can buy them commercially and that's fine for regular sane people - but what about using a tiny ESP-01S to act as an Access Point, run a web server and turn on and off stuff WAY beyond it's capacity given it's flash memory and GPIO limitations?
Sounds like a little experimentation might be required to tip the balance from BUY to DIY.
Yes please!
This project has some distinct phases:
- run the 3.3V ESP-01s and a heavy inductive motor (24V) from the same power supply
- extend the ESP-01s meagre output capacity to be able to address many GPIOs using a 74HC595N shift register
- use a ULN2803 with it's inbuilt flyback diode to handle the motor and it's current requirement
- make an Access Point to activate the gate from any WiFi capable device
Let's go!
The power issue was solved (as I've done before) with a combination of a buck/boost module (LM2596 based) and LM1117 3.3V linear voltage regulator. The final drop was 20.5V to 7.5V using the switching regulator and then 7.5V to 3.3V using a TO-220 format LM1117 regulator.
I kept calling this an LM117 regulator in the video - apologies!
With this rig the "top" rail is 20.5V (for the motor) and the "bottom" rail is a steady 3.3V. One hilarious event during testing was the destruction of a 16V rated capacitor I forgot to remove which was still sitting in the top rail when I upped the voltage - love that smell of magic smoke!
The 74HC595N shift register part of the project was fairly easily achieved given that I have worked with these units earlier on this blog.
I will post the code below so that you can see just how simple this stuff can be using standard, mostly "borrowed", code.
//Pin connected to latch pin (ST_CP) of 74HC595 const int latchPin = 0; //Pin connected to clock pin (SH_CP) of 74HC595 const int clockPin = 1; ////Pin connected to Data in (DS) of 74HC595 const int dataPin = 2; byte shiftbyte = 0; void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); } void loop() { for (byte countleds = 1; countleds < 5; countleds++) { shiftbyte = 0; updateShiftRegister(); delay(300); bitSet(shiftbyte, countleds); updateShiftRegister(); delay(100); } shiftbyte = 0; updateShiftRegister(); delay(300); shiftbyte = 0b00011110; updateShiftRegister(); delay(300); } void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shiftbyte); digitalWrite(latchPin, HIGH); }
Next up was the ULN2803 component - this is a very handy darlington transistor array that comes complete with a flyback diode (marked in the diagram below with a red arrow and circle) to hopefully prevent damage to the controller of an inductive load - e.g. let's not fry the little ESP8266 with a big nasty kick back from the motor when it stops!
We have also seen this component in action before.
Finally, I coded up the ESP-01S so that it behaved as a WiFi Access Point and could, er, "open the gate" complete with warning lights and buzzers. Very exciting!
/* Using an ESP-01s to turn on a motor, as well as running a few lights and buzzers all via a 74HC595N and ULN28703 OneCircuit Sun 12 Feb 2023 19:52:25 AEDT */ #include <ESP8266WiFi.h> #include <ESP8266WebServer.h> /* Put your SSID & Password */ const char* ssid = "GateControl"; // Enter SSID here const char* password = "1234"; //Enter Password here //Pin connected to latch pin (ST_CP) of 74HC595 const int latchPin = 0; //Pin connected to clock pin (SH_CP) of 74HC595 const int clockPin = 1; ////Pin connected to Data in (DS) of 74HC595 const int dataPin = 2; byte shiftbyte = 0; // the state of the shift register long motor = 0; boolean motorun = false; bool GATEstatus = false; bool openclick = false; long currenttime = 0; int turnoffmotortime = 5000; /* Put IP Address details */ IPAddress local_ip(192, 168, 2, 1); IPAddress gateway(192, 168, 2, 1); IPAddress subnet(255, 255, 255, 0); ESP8266WebServer server(80); void setup() { pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); delay(20); // clear register shiftbyte = 0b00000000; updateShiftRegister(); delay(500); WiFi.softAP(ssid, password); WiFi.softAPConfig(local_ip, gateway, subnet); delay(100); server.on("/", handle_OnConnect); server.on("/gateon", handle_gateon); server.on("/gateoff", handle_gateoff); server.onNotFound(handle_NotFound); server.begin(); } void turnonsequence() { // turn off green shiftbyte = 0b00000000; updateShiftRegister(); // turn on red and buzzer shiftbyte = 0b00100100; updateShiftRegister(); delay(3000); shiftbyte = 0b00000000; updateShiftRegister(); // flashing yellow, buzzer and motor motorun = true; motor = millis(); // start timing while (motorun) { shiftbyte = 0b01001000; updateShiftRegister(); delay(200); shiftbyte = 0b01110000; updateShiftRegister(); delay(200); shiftbyte = 0b01000000; updateShiftRegister(); currenttime = millis(); if (currenttime - motor > turnoffmotortime) { motorun = false; } } shiftbyte = 0b00000000; updateShiftRegister(); GATEstatus = !GATEstatus; } void updateShiftRegister() { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shiftbyte); digitalWrite(latchPin, HIGH); } void loop() { server.handleClient(); // green to start with shiftbyte = 0b00000010; updateShiftRegister(); if (!GATEstatus && openclick) { turnonsequence(); } if (GATEstatus && !openclick) { turnonsequence(); } } void handle_OnConnect() { GATEstatus = false; openclick = false; server.send(200, "text/html", SendHTML(false)); } void handle_gateon() { openclick = true; server.send(200, "text/html", SendHTML(true)); } void handle_gateoff() { openclick = false; server.send(200, "text/html", SendHTML(false)); } void handle_NotFound() { server.send(404, "text/plain", "Not found"); } String SendHTML(uint8_t gate) { String ptr = "<!DOCTYPE html>\n"; ptr += "<html>\n"; ptr += "<head>\n"; ptr += "<title>Gate Control</title>\n"; ptr += "</head>\n"; ptr += "<body>\n"; ptr += "<h1>Gate Control</h1>\n"; ptr += "<p>Press to open and close gate.</p>\n"; ptr += "<form method=\"get\">\n"; if (gate) ptr += "<input type=\"button\" value=\"Gate open\" onclick=\"window.location.href='/gateoff'\">\n"; else ptr += "<input type=\"button\" value=\"Gate closed\" onclick=\"window.location.href='/gateon'\">\n"; ptr += "</form>\n"; ptr += "</body>\n"; ptr += "</html>\n"; return ptr; }
I really enjoyed this project and indeed I think that as part of my continuing learning experience I may repeat the whole project using I2C (two wires!) instead of a shift register in another blog post and video. Watch this space!
In the meantime I hope that you like the result.
No comments:
Post a Comment