Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Arduino.h>
- #include <ESP8266WiFi.h>
- #include <ESP8266mDNS.h>
- #include "Adafruit_MQTT.h"
- #include "Adafruit_MQTT_Client.h"
- #include <ArduinoOTA.h>
- #include "/Users/hanpa/Dropbox/Hem/Arduino/common/credentials.h"
- const char* version = "postbox 1.0";
- const char* date_name = "2017-07-28 Hans Palm";
- // Hans Palm 2017
- // http://www.hobbyelektronik.nu/
- //
- // This code checks the lid and door of my post box using a Wemos D1 mini (ESP8266)
- // The post box has a lid and a separate lockable door used when the box is emptied
- //
- // Reed switches are used together with a permanent magnet for detection
- // The D1 pin is connected to the lid switch, 0 = lid closed, 1 = lid open
- // The D2 pin is connected to the door switch, 0 = door closed, 1 = door open
- //
- // MQTT WiFi messages are sent on the event of opening lid or door
- // The lid or door must be closed more than 30 seconds before a new open event can be sent
- //
- // MQTT WiFi messages are also sent continously each second for function monitoring
- // of the complete circuit, switches and MQTT connection to the server
- // The continous messages are not filtered, reflects the current state of the switches
- // Credentials are assumed to be stated in a #include(d) .h file or stated directly below instead
- // of constant names for ssid, password, mqtt_server and mqtt_port
- //
- // OTA support included
- /************************* WiFi Access Point *********************************/
- #define WLAN_SSID ssid
- #define WLAN_PASS password
- /***************************** MQTT settings *********************************/
- #define SERVER mqtt_server
- #define SERVERPORT mqtt_port // use 8883 for SSL
- #define USERNAME "" // Not used, from Adafruit.io Setup
- #define KEY "" // Not used, from Adafruit.io Setup
- /************************* OTA *********************************/
- #define OTA_HOST_NAME "PostBox" // No _ in hostnames!
- const char* host = OTA_HOST_NAME;
- // The follwing parameters are only required for fixed IP, otherwise uncomment, also uncomment WiFi.config(ip, gateway, subnet)
- IPAddress ip(192, 168, 0, 157);
- IPAddress gateway(192, 168, 0, 1);
- IPAddress subnet(255, 255, 255, 0);
- // Input pin settings for post box
- const int LidInputPin = D1;
- const int DoorInputPin = D2;
- // Types and states
- enum openOrClosed {
- Open,
- Closed
- };
- openOrClosed lidState = Closed;
- openOrClosed doorState = Closed;
- int lidBeforeConsideredClosedCounter = 0;
- int doorBeforeConsideredClosedCounter = 0;
- unsigned long lastContinousPublishTime = 0;
- const int SECONDS_BEFORE_CONSIDERED_CLOSED = 30;
- // Create an ESP8266 WiFiClient class to connect to the MQTT server.
- WiFiClient client;
- // or... use WiFiFlientSecure for SSL
- //WiFiClientSecure client;
- // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
- Adafruit_MQTT_Client mqtt(&client, SERVER, SERVERPORT, USERNAME, KEY);
- /****************************** Feeds ***************************************/
- // Setup feeds for publishing.
- // Continous data, unfiltered
- Adafruit_MQTT_Publish postBoxLidOpen = Adafruit_MQTT_Publish(&mqtt, USERNAME "PostBoxLidOpen");
- Adafruit_MQTT_Publish postBoxDoorOpen = Adafruit_MQTT_Publish(&mqtt, USERNAME "PostBoxDoorOpen");
- // Event data, filtered to avoid multiple events when when several post items are delivered
- Adafruit_MQTT_Publish postBoxLidOpened = Adafruit_MQTT_Publish(&mqtt, USERNAME "PostBoxLidOpened");
- Adafruit_MQTT_Publish postBoxDoorOpened = Adafruit_MQTT_Publish(&mqtt, USERNAME "PostBoxDoorOpened");
- void MQTT_connect();
- void OTA_setup() {
- ArduinoOTA.setHostname(host);
- ArduinoOTA.onStart([]() {
- String type;
- // if (ArduinoOTA.getCommand() == U_FLASH)
- type = "sketch";
- // else // U_SPIFFS
- // type = "filesystem";
- // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
- Serial.println("Start updating " + type);
- });
- ArduinoOTA.onEnd([]() {
- Serial.println("\nEnd");
- });
- ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
- Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
- });
- ArduinoOTA.onError([](ota_error_t error) {
- Serial.printf("Error[%u]: ", error);
- if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
- else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
- else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
- else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
- else if (error == OTA_END_ERROR) Serial.println("End Failed");
- });
- ArduinoOTA.begin();
- }
- void setup() {
- Serial.begin(115200);
- delay(10);
- pinMode(LidInputPin, INPUT_PULLUP);
- pinMode(DoorInputPin, INPUT_PULLUP);
- // Connect to WiFi access point.
- Serial.println(); Serial.println();
- Serial.print("Connecting to ");
- Serial.println(WLAN_SSID);
- WiFi.config(ip, gateway, subnet); // Only required for fixed IP
- WiFi.begin(WLAN_SSID, WLAN_PASS);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println();
- Serial.println("WiFi connected");
- Serial.println("IP address: "); Serial.println(WiFi.localIP());
- OTA_setup();
- }
- void loop() {
- ArduinoOTA.handle();
- // Ensure the connection to the MQTT server is alive (this will make the first
- // connection and automatically reconnect when disconnected). See the MQTT_connect
- // function definition further below.
- MQTT_connect();
- const int CYCLE_TIME = 50; // 50ms
- // Process mqtt data
- mqtt.processPackets(CYCLE_TIME);
- int lidSwitch = digitalRead(LidInputPin); // Reed switch normally closed = 0
- int doorSwitch = digitalRead(DoorInputPin); // Reed switch normally closed = 0
- // Check lid switch
- if (lidSwitch == 1) {
- // Open
- if (lidState == Closed) {
- lidState = Open;
- postBoxLidOpened.publish(1); // open lid event data
- }
- lidBeforeConsideredClosedCounter = 0;
- } else {
- // closed
- if (lidState == Open) {
- // Consider closed after a rather long time, to avoid separate events if lid is open/closed many times in a short time
- if (lidBeforeConsideredClosedCounter > SECONDS_BEFORE_CONSIDERED_CLOSED * 1000/CYCLE_TIME) {
- lidState = Closed;
- lidBeforeConsideredClosedCounter = 0;
- }
- lidBeforeConsideredClosedCounter++;
- }
- }
- // Check door switch
- if (doorSwitch == 1) {
- // Open
- if (doorState == Closed) {
- doorState = Open;
- postBoxDoorOpened.publish(1); // open door event data
- }
- doorBeforeConsideredClosedCounter = 0;
- } else {
- // closed
- if (doorState == Open) {
- // Consider closed after a rather long time, to avoid separate events if door is open/closed many times in a short time
- if (doorBeforeConsideredClosedCounter > SECONDS_BEFORE_CONSIDERED_CLOSED * 1000/CYCLE_TIME) {
- doorState = Closed;
- doorBeforeConsideredClosedCounter = 0;
- }
- doorBeforeConsideredClosedCounter++;
- }
- }
- unsigned long now = millis();
- if ( (now - lastContinousPublishTime) > 1000 ) {
- // Send continous unfiltered data about lid and door state each second
- postBoxLidOpen.publish(lidSwitch == 1);
- postBoxDoorOpen.publish(doorSwitch == 1);
- lastContinousPublishTime = now;
- }
- // No delay() is used, mqtt.processPackets consumes 50ms in each cycle
- }
- // Function to connect and reconnect as necessary to the MQTT server.
- // Should be called in the loop function and it will take care if connecting.
- void MQTT_connect() {
- int8_t ret;
- // Stop if already connected.
- if (mqtt.connected()) {
- return;
- }
- Serial.print("Connecting to MQTT... ");
- while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
- Serial.println(mqtt.connectErrorString(ret));
- Serial.println("Retrying MQTT connection in 5 seconds...");
- delay(5000); // wait 5 seconds
- }
- Serial.println("MQTT Connected!");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement