← Home

IoT door sensor part 2 (now with annoying sounds and web view!)

My son asked if we could add a noise to the door sensor [0] we made a while back, and make it log the data instead of sending email. I suppose he’s been getting a lot of email recently.

This is apparently in an effort to prepare for Christmas, where he’s hoping to detect if Father Christmas opens his door. I’ve got a while to decide whether I’m going to take the Web system offline on December 24th or let him discover a blip in the data.

Anyway, it’s really easy to get the ESP8266 to run a piezo. You can connect up a buzzer to any digital pin, set it as an output and use the analog write [1] function. We had a bit of fun choosing the tones to play.

I then suggested we put a switch in to turn the sound off. I had one lying around which was suitable, so we just used it to disconnect the piezo from the ground rather than doing a software switch, which requires a resistor and coding. It was a nice opportunity to talk about the trade-off of using a relatively expensive switch which needed mounting on the box instead of a microswitch and needing to write some software.

Next, I updated the server to store the data in DynamoDB and added a Web view. You can put any day into the day parameter on the querystring, and it will show a plot of the opening and closing of the door, or it displays data from the current day. I added extra data into the DB that might allow for secondary indices to produce per-week, or year summaries later, but I haven’t done anything with it.

Finally, the box itself got a paint job.

The updated code is below:

#include <WiFiServerSecure.h>
#include <WiFiClientSecure.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiUdp.h>
#include <ESP8266WiFiType.h>
#include <ESP8266WiFiAP.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <ESP8266WiFiScan.h>
#include <ESP8266WiFiGeneric.h>
#include <ESP8266WiFiSTA.h>

#include "RestClient.h"

#include "Debounce.h"

// Uses:
//  * https://github.com/wkoch/Debounce
//  * https://github.com/esp8266/Arduino/tree/master/doc/esp8266wifi
//  * https://github.com/csquared/arduino-restclient
// To install libraries:
//  * cd ~/Documents/Arduino/libraries
//  * git clone <repo>
//  *   (For https://github.com/csquared/arduino-restclient, git clone https://github.com/csquared/arduino-restclient RestClient)

const char *ssid = "xxxxxx";
const char *password = "xxxxxxx";

RestClient client = RestClient("xxxxxxx", 443, 1);
const char *eventDoorOpened = "{ \"event\": \"door_opened\" }";
const char *eventDoorClosed = "{ \"event\": \"door_closed\" }";

const int buzzerPin = D0;
const int inPin = D1;

const bool shouldUseBuzzer = true;
const bool shouldSendMessages = true;

void setup()
{
  pinMode(buzzerPin, OUTPUT);
  pinMode(inPin, INPUT);
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.print("Connecting..");
  }
  Serial.println("Connected...");
}

Debounce doorSwitch(inPin); // the number of the input pin, D1 is set for the ESP8266.
int previousState = -1;

void loop()
{
  int newState = doorSwitch.read();
  if (previousState == -1) {
    // On the first iteration, just set it to the latest value and don't trigger an event.
    // This makes the device succeptible to a power outage making it not work.
    previousState = newState;
  }
  if (newState != previousState) {
    if (newState == HIGH) {
      Serial.println("Door was closed");
      if (shouldUseBuzzer) {
        Serial.print("Buzzing closed...");
        buzzClosed();
      }
      if (shouldSendMessages) {
        postSecure(eventDoorClosed);
      }
    } else {
      Serial.println("Door was opened");
      if (shouldUseBuzzer) {
        Serial.print("Buzzing open...");
        buzzOpened();
      }
      if (shouldSendMessages) {
        postSecure(eventDoorOpened);
      }
    }
  }
  previousState = newState;
}

void postSecure(const char *event)
{
  String response = "";
  Serial.println("Posting...");
  int statusCode = client.post("/dev/sensor/detect", event, &response);
  Serial.println("Results (status / response)...");
  Serial.println(statusCode);
  Serial.println(response);
}

void buzz(int pin, int frequency, int duration) {
  analogWriteFreq(frequency);
  analogWrite(pin, 1000);
  delay(duration);
  analogWrite(pin, 0);
}

void buzzOpened() {
  buzz(buzzerPin, 250, 450);
  buzz(buzzerPin, 500, 350);
  buzz(buzzerPin, 750, 350);
}

void buzzClosed() {
  buzz(buzzerPin, 750, 450);
  buzz(buzzerPin, 500, 350);
  buzz(buzzerPin, 250, 350); 
}