PiedThon/arduino.cpp

207 lines
4.9 KiB
C++

/***
Fuz Piedthon
Pedestrian traffic lights, green and red, controlled over MQTT
Board: ESP8266
*/
#include <Arduino.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
/// Pins configuration
#define GPIO_VERT 14
#define GPIO_ROUGE 16
/// MQTT Config
#define MQTT_SERVER "sonic.fuz.re"
#define MQTT_SERVERPORT 1883
#define ESP_HOSTNAME "piedthon"
#include "WifiCredFuz.cpp" // Wifi and MQTT Credentials
/* with
#define WLAN_SSID ""
#define WLAN_PASS ""
#define MQTT_USERNAME "" //omg no user
#define MQTT_KEY "" //omg no key
*/
/// End of user config
/// Wifi
#include <ESP8266WiFi.h>
WiFiClient client;
void setupWifi() {
// Connect to WiFi access point.
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi connected");
Serial.print(" IP address: ");
Serial.println(WiFi.localIP());
}
void setupOTA() {
ArduinoOTA.setHostname(ESP_HOSTNAME);
ArduinoOTA.onStart([]() { // switch off all the GPIOs during upgrade
digitalWrite(GPIO_ROUGE, HIGH);
digitalWrite(GPIO_VERT, HIGH);
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
/*if (progress % (total / 4) == 0) {
digitalWrite(GPIO_ROUGE, random(2) ? LOW : HIGH);
digitalWrite(GPIO_VERT, random(2) ? LOW : HIGH);
}*/
});
ArduinoOTA.onEnd([]() { // do a fancy thing with our board led at end
for (int i = 0; i < 10; i++) {
int RANDOM_GPIO = GPIO_ROUGE;
if (random(2)) { // random(2) returns 0 or 1 randomly
RANDOM_GPIO = GPIO_VERT;
}
digitalWrite(RANDOM_GPIO, !digitalRead(RANDOM_GPIO));
delay(400);
}
digitalWrite(GPIO_ROUGE, LOW);
digitalWrite(GPIO_VERT, LOW);
});
ArduinoOTA.onError([](ota_error_t error) {
(void)error;
ESP.restart();
});
ArduinoOTA.begin();
Serial.println(F("End of OTA setup"));
}
/// MQTT
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/************ Global State (you don't need to change this!) ******************/
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_KEY);
/****************************** Feeds ***************************************/
// Setup a feed called 'pub_piedthon' for publishing.
Adafruit_MQTT_Publish pub_piedthon = Adafruit_MQTT_Publish(&mqtt, "piedthon/debug");
// Setup a feed called 'sub_piedthon' for subscribing to changes.
Adafruit_MQTT_Subscribe sub_piedthon = Adafruit_MQTT_Subscribe(&mqtt, "piedthon/input");
char *mqtt_message;
// Function to connect and reconnect as necessary to the MQTT server.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
Serial.println("Fail to connect to MQTT after 3 tries ... ");
return; // will recall the function
}
}
Serial.println("MQTT Connected!");
}
/// PiedThon
void messageToPiedthon(char *msg) {
// Clignotement ? deux en même temps ?
switch (msg[0]) {
// LOW active le relay
case '0' : // Rouge et Vert
digitalWrite(GPIO_ROUGE, LOW);
digitalWrite(GPIO_VERT, LOW);
break;
case '1' : // ROUGE
digitalWrite(GPIO_VERT, HIGH);
digitalWrite(GPIO_ROUGE, LOW);
break;
case '2' : // VERT
digitalWrite(GPIO_VERT, LOW);
digitalWrite(GPIO_ROUGE, HIGH);
break;
case '3' : // Rien
digitalWrite(GPIO_ROUGE, HIGH);
digitalWrite(GPIO_VERT, HIGH);
break;
}
}
//// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
//// for some reason (only affects ESP8266, likely an arduino-builder bug).
//void MQTT_connect();
void setup() {
Serial.begin(115200);
delay(10);
Serial.println(F("Adafruit MQTT PiedThon remix"));
pinMode(GPIO_VERT, OUTPUT);
pinMode(GPIO_ROUGE, OUTPUT);
randomSeed(analogRead(0));
setupWifi();
setupOTA();
// Setup MQTT subscription for onoff feed.
mqtt.subscribe(&sub_piedthon);
}
void loop() {
MQTT_connect();
MDNS.update();
ArduinoOTA.handle();
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if (subscription == &sub_piedthon) {
mqtt_message = (char *) sub_piedthon.lastread;
Serial.println("Got: " + String(mqtt_message));
messageToPiedthon(mqtt_message);
}
}
}