Tuesday, December 5, 2017

Arduino Project: Sound Alert via Twitter

For my second IoT project using Arduino MKR1000, I'll employ a sound sensor to send out alerts via Twitter when a loud sound is detected. This could have many uses, ranging from informing the inhabitants of a house that there is someone at the door, informing a car owner that their alarm is going off, or residents that a gunshot has gone off in their neighborhood.

See my previous posts to learn about the setup process for the Arduino MKR1000, which is wifi-enabled without any additional extensions.

I will be using the Arduino IDE to compile the code.

For hardware, I'll be using the sound sensor I purchased here, as well as my Arduino, three solder-free wires, a generic breadboard, and a Kindle power cable (this probably isn't the safest way to power Arduino, but it's what I had).

I'll be following this tutorial to set up the sound detector, as well as some code from here to utilize Twitter.

The sound setup tutorial was very simple and one of the clearest wiring guides I've ever seen. It worked so well that I have little to say about it.

My first comment is that my sound sensor has 4 pins, while the tutorial's has only 3 pins (and some I've seen elsewhere have 5!). However, this was easily overcome when I noticed that my pins are labeled A0, G, +, and DO. I'm not sure what the DO stands for, but it was pretty clear that A0 corresponds to AU0 in the tutorial, G corresponds to GND, and + corresponds to VCC.

My second comment is that I'm not sure why there are two separate code snippets given (I didn't take the time to go through the differences), but the top snippet worked for me.

Here's my working setup:





Here's some of my output (when the numbers go high, that's when I clapped my hands):





For some reason there is a delay of several seconds between when I clap my hands and when the numbers go high, but that may be because the sensor is rather cheap. I also notice that the high numbers continue for a relatively long time, as opposed to just measuring one or two high numbers (I believe a reading is being taken once per second), which is interesting.

Now with the sound sensor portion of the project working, time to move on to the Tweeting portion. I used some of the code and guidance from this source, as mentioned previously.

Here is my complete working code:

#include <WiFi101.h>
#include <Twitter.h>
int led = 13;
int threshold = 10; //Change this as desired
int volume;
//String message;
Twitter twitter("934813958439043072-RmWRNCKFCTwSm6aafgHdktL6nbUgqZD");
char ssid[] = "DG1670A92";     //  your network SSID (name)
char pass[] = "DG1670A353A92";  // your network password
int status = WL_IDLE_STATUS;     // the WiFi radio's status
void setup() {               
  /*Setup for DHT sensor*********/
  Serial.begin(1000);
  delay(300);//Let system settle
  Serial.println("Humidity and temperature\n\n");
  delay(1000);//Wait rest of 1000ms recommended delay before

  /*setup for Twitter stuff**********/
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }
  // attempt to connect to WiFi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  printCurrentNet();
  printWiFiData();

  Serial.begin(9600); // Serial port begin
  pinMode(led, OUTPUT);   
}
void loop() {

  volume = analogRead(A0); // Reads the value from the Analog PIN A0

  //Serial print level
  Serial.println(volume);
  delay(1000);
  if(volume>=threshold){
    digitalWrite(led, HIGH); //Turn ON Led
    String message = "The volume is " + String(volume);
    char msg[100];
    message.toCharArray(msg, 100);
   
    //post the temperature and humidity to Twitter
    if (twitter.post(msg)) {
      // Specify &Serial to output received response to Serial.
      // If no output is required, you can just omit the argument, e.g.
      // int status = twitter.wait();
      int status = twitter.wait(&Serial);
      if (status == 200) {
        Serial.println("OK.");
      } else {
        Serial.print("failed : code ");
        Serial.println(status);
      }
    } else {
      Serial.println("connection failed.");
    }
  } 
  else{
    digitalWrite(led, LOW); // Turn OFF Led
  }
}
void printWiFiData() {
  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Serial.println(ip);
  // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC address: ");
  Serial.print(mac[5], HEX);
  Serial.print(":");
  Serial.print(mac[4], HEX);
  Serial.print(":");
  Serial.print(mac[3], HEX);
  Serial.print(":");
  Serial.print(mac[2], HEX);
  Serial.print(":");
  Serial.print(mac[1], HEX);
  Serial.print(":");
  Serial.println(mac[0], HEX);
}
void printCurrentNet() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("BSSID: ");
  Serial.print(bssid[5], HEX);
  Serial.print(":");
  Serial.print(bssid[4], HEX);
  Serial.print(":");
  Serial.print(bssid[3], HEX);
  Serial.print(":");
  Serial.print(bssid[2], HEX);
  Serial.print(":");
  Serial.print(bssid[1], HEX);
  Serial.print(":");
  Serial.println(bssid[0], HEX);
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.println(rssi);
  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  Serial.print("Encryption Type:");
  Serial.println(encryption, HEX);
  Serial.println();
}

Notice I set the threshold to 10, which is quite low. I did this so I could snap instead of clap get results (so I wouldn't wake my roommates!).

After uploading this code to my Arduino and waiting for it to connect to WiFi, here are some Tweets it sent:



And so, this project is complete! It would be simple to have alerts sent to your phone based on these Tweets if desired, and this project could have many useful IoT functions. Thanks for reading!