ESP32 Traffic Light Changer
I spent quite a few happy hours fiddling around with traffic light changers after my last blog and video which used the PFS154 and a button to make the changes. The crazy part is that there is not one single traffic light on my 35 minute commute to work - so...huh?
Anyway, first I looked at an interrupt driven change on the ATTiny13 version, then a simple loop driven change for an ESP32.
BTW, there are so many incarnations of the ESP32 that the list covers several pages on my Arduino-IDE.
After choosing the appropriate variant in the IDE I coded the following three versions:
1. Button press activated
2. WiFi activated
3. Bluetooth activated
Button Press:
int red = 13; int yellow = 12; int green = 14; int button = 23; int buttonValue = 0; void setup(){ pinMode(button,INPUT); pinMode(red,OUTPUT); pinMode(yellow,OUTPUT); pinMode(green,OUTPUT); pinMode(button,INPUT); digitalWrite(red,HIGH); } void loop(){ buttonValue = digitalRead(button); if (buttonValue == HIGH){ changeLights(); delay(4000); digitalWrite(green, LOW); digitalWrite(yellow, HIGH); delay(1000); digitalWrite(yellow, LOW); digitalWrite(red, HIGH); delay(2000); buttonValue = LOW; } } void changeLights(){ // red off, yellow for 1 seconds digitalWrite(red, LOW); digitalWrite(yellow, HIGH); delay(1000); // turn off yellow, then turn green on digitalWrite(yellow, LOW); digitalWrite(green, HIGH); }
Wifi:
#include "WiFi.h" int red = 13; int yellow = 12; int green = 14; // Replace with your network credentials const char* ssid = "**********"; const char* password = "**********"; WiFiServer server(80); String header; String buttonState = "red"; unsigned long currentTime = millis(); unsigned long previousTime = 0; const long timeoutTime = 2000; void setup() { pinMode(red, OUTPUT); pinMode(yellow, OUTPUT); pinMode(green, OUTPUT); digitalWrite(red, HIGH); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.begin(115200); Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin(); } void changeLights() { digitalWrite(red, LOW); digitalWrite(yellow, HIGH); delay(1000); digitalWrite(yellow, LOW); digitalWrite(green, HIGH); delay(4000); digitalWrite(green, LOW); digitalWrite(yellow, HIGH); delay(1000); digitalWrite(yellow, LOW); digitalWrite(red, HIGH); delay(2000); } void loop() { WiFiClient client = server.available(); if (client) { currentTime = millis(); previousTime = currentTime; String currentLine = ""; while (client.connected() && currentTime - previousTime <= timeoutTime) { currentTime = millis(); if (client.available()) { char c = client.read(); header += c; if (c == '\n') { if (currentLine.length() == 0) { client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println("Connection: close"); client.println(); if (header.indexOf("GET /26/green") >= 0) { buttonState = "green"; } else if (header.indexOf("GET /26/red") >= 0) { buttonState = "red"; changeLights(); } client.println("<!DOCTYPE html><html>"); client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"); client.println("<link rel=\"icon\" href=\"data:,\">"); client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}"); client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;"); client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}"); client.println(".button2 {background-color: #555555;}</style></head>"); client.println("<body><h1>Traffic Light Changer</h1>"); if (buttonState == "red") { client.println("<p><a href=\"/26/red\"><button class=\"button\">GREEN</button></a></p>"); } else { client.println("<p><a href=\"/26/green\"><button class=\"button button2\">RED</button></a></p>"); } client.println("</body></html>"); client.println(); break; } else { currentLine = ""; } } else if (c != '\r') { currentLine += c; } } } header = ""; client.stop(); } }
Bluetooth (on the C3 version - BLE):
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> BLECharacteristic *pCharacteristic; bool deviceConnected = false; float txValue = 0;
// the following are the RGB leds for the C3 const byte red = 3; const byte green = 4; const byte blue = 5; #define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" void changeLights() { digitalWrite(red, HIGH); digitalWrite(green, HIGH); digitalWrite(blue, LOW); delay(2000); digitalWrite(red, LOW); digitalWrite(green, HIGH); digitalWrite(blue, LOW); delay(4000); digitalWrite(red, HIGH); digitalWrite(green, HIGH); digitalWrite(blue, LOW); delay(2000); digitalWrite(red, HIGH); digitalWrite(green, LOW); digitalWrite(blue, LOW); } class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } }; class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue(); if (rxValue.length() > 0) { for (int i = 0; i < rxValue.length(); i++) { } if (rxValue.find("G") != -1) { changeLights(); } } } }; void setup() { pinMode(red, OUTPUT); pinMode(green, OUTPUT); pinMode(blue, OUTPUT); digitalWrite(red, HIGH); digitalWrite(green, LOW); digitalWrite(blue, LOW); BLEDevice::init("Traffic Light Changer"); BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY ); pCharacteristic->addDescriptor(new BLE2902()); BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); pService->start(); pServer->getAdvertising()->start(); } void loop() { if (deviceConnected) { } delay(1000); }
Given the distinct dearth of traffic lights in Tasmania, I'm not sure how directly useful any of these devices will be in shortening my daily commute, but I can say that it opens up some possibilities for monitoring sensors and activating motors/pumps, etc, around the property. So perhaps overall it was a useful exercise!?
I also "enjoyed" the wrestle with the C3-BLE version of the ESP32, which I think may be very interesting to play with in the future.
No comments:
Post a Comment