Created
January 18, 2017 20:41
-
-
Save cerebrate/9f41a185b148109eaff06de781f74bb0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Dogtector - operating code for the Dogtector | |
Copyright Alistair Young, 2017. All Rights Reserved. | |
*/ | |
#include <ESP8266WiFi.h> | |
#include <Ticker.h> | |
#include <Adafruit_MQTT.h> | |
#include <Adafruit_MQTT_Client.h> | |
// Expose Espressif SDK functionality - wrapped in ifdef so that it still | |
// compiles on other platforms | |
#ifdef ESP8266 | |
extern "C" { | |
#include "user_interface.h" | |
} | |
#endif | |
// WiFi setup | |
const char* ssid = "Arkane Systems"; | |
const char* password = "CeciNEstPasMonPasswordDeWiFi"; | |
// MQTT server | |
const char* mqttserver = "calmirie.arkane-systems.lan"; | |
const char* pubTopic = "sensors/dogtector"; | |
const char* subTopic = "enable/dogtector"; | |
// Create ESP8266 WiFiClient class to connect to the MQTT server | |
WiFiClient wifiClient; | |
Adafruit_MQTT_Client mqtt (&wifiClient, mqttserver, 1883, "", ""); | |
// Set up feeds | |
Adafruit_MQTT_Publish output = Adafruit_MQTT_Publish (&mqtt, pubTopic); | |
// Adafruit_MQTT_Subscribe enable = Adafruit_MQTT_Subscribe (&mqtt, subTopic); | |
// pins | |
int statusPin = 0; | |
int detectPin = 2; | |
int pirPin = 4; | |
int speakerPin = 14; | |
// tickers | |
Ticker statusBlink; | |
Ticker pirScan; | |
Ticker buzzer; | |
// PIR scanner | |
int pirState = LOW; // assume no motion detected on start | |
int reading = 0 ; // temp reading used by scan() | |
int skipFirst = 1; // PIR always active on boot | |
// buzzer | |
int numTones = 2; | |
int tones[] = {440, 300}; | |
int buzzState = 0; | |
void setup() | |
{ | |
// Setup the system. | |
Serial.println("Setup"); | |
// set up the LED pins | |
pinMode(statusPin, OUTPUT); | |
pinMode(detectPin, OUTPUT); | |
setDetectLedDisabled(); | |
// set up the PIR pin | |
pinMode(pirPin, INPUT); | |
// set up the WiFi | |
wifi_station_set_hostname("iot-dogtector"); | |
WiFi.begin(ssid, password); | |
Serial.print("Connecting to WiFi"); | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(500); | |
Serial.print("."); | |
} | |
Serial.println(); | |
Serial.print("Connected, IP: "); | |
Serial.println(WiFi.localIP()); | |
// Setup MQTT subscription for enable feed. | |
// mqtt.subscribe (&enable); | |
buzz(); | |
// Enable detector. | |
enableDetector(); | |
} | |
void loop() | |
{ | |
// 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(); | |
// this is our 'wait for incoming subscription packets' busy subloop | |
// try to spend your time here | |
// mqtt.processPackets(1000); | |
// ping the server to keep the mqtt connection alive | |
// NOT required if you are publishing once every KEEPALIVE seconds | |
// if(! mqtt.ping()) | |
// { | |
// mqtt.disconnect(); | |
// } | |
} | |
// 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... "); | |
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 | |
while (1); | |
} | |
} | |
Serial.println("MQTT Connected!"); | |
} | |
void enableDetector() | |
{ | |
pirScan.attach (1, scan); | |
setStatusEnabled(); | |
} | |
void disableDetector() | |
{ | |
pirScan.detach(); | |
pirState = LOW; | |
reading = 0; | |
setDetectLedDisabled(); | |
setStatusDisabled(); | |
} | |
void scan () | |
{ | |
reading = digitalRead (pirPin); | |
if (reading == HIGH) // motion currently detected | |
{ | |
if (pirState == LOW) // motion not previously detected | |
{ | |
// we have just turned on | |
pirState = HIGH; | |
if (!skipFirst) | |
{ | |
setDetectLedEnabled(); | |
// communicate this to the MQTT server | |
if (! output.publish (pirState)) | |
{ | |
Serial.println("MQTT publish failed"); | |
} | |
buzz(); | |
} | |
} | |
} | |
else // motion not detected | |
{ | |
if (pirState == HIGH) // motion was previously detected | |
{ | |
// we have just turned off | |
pirState = LOW ; | |
setDetectLedDisabled(); | |
skipFirst = 0; | |
} | |
} | |
} | |
void setStatusEnabled () | |
{ | |
statusBlink.attach (0.5, blink); | |
} | |
void setStatusDisabled () | |
{ | |
statusBlink.detach(); | |
digitalWrite(statusPin, LOW); | |
} | |
void setDetectLedEnabled () | |
{ | |
digitalWrite(detectPin, LOW); | |
} | |
void setDetectLedDisabled () | |
{ | |
digitalWrite(detectPin, HIGH); | |
} | |
void blink() | |
{ | |
int state = digitalRead(statusPin); | |
digitalWrite(statusPin, !state); | |
} | |
void buzz() | |
{ | |
if (buzzState != 0) // already buzzing | |
return; | |
buzz_impl(); | |
} | |
void buzz_impl () | |
{ | |
if (buzzState == 0) | |
{ | |
buzzer.attach (0.5, buzz_impl); | |
} | |
if (buzzState < numTones) | |
{ | |
tone (speakerPin, tones[buzzState]); | |
buzzState++; | |
} | |
else | |
{ | |
noTone (speakerPin); | |
buzzer.detach(); | |
buzzState = 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment