Skip to content

Instantly share code, notes, and snippets.

@cerebrate
Created January 18, 2017 20:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cerebrate/9f41a185b148109eaff06de781f74bb0 to your computer and use it in GitHub Desktop.
Save cerebrate/9f41a185b148109eaff06de781f74bb0 to your computer and use it in GitHub Desktop.
/*
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