Smart Doorbell using Raspberry Pi

About a year ago, I had to do a project titled Smart Home Automation using a Raspberry Pi and Arduino, part of the project  incorporated a doorbell but not just any doorbell but a Smart doorbell.

Why do I call it a Smart Doorbell?

A classic doorbell can be defined as a signalling device typically placed near an entry door to a building. When a visitor presses a button the bell rings inside the building, alerting the occupant to the presence of the visitor.

The smart doorbell, works in that manner however when a visitor presses the doorbell button it notifies the occupant with an images of the visitor and also sends an email, sms and push notification (to an smart device) to the occupant in case they are not able to hear the bell ringing.

If the button is pressed a pre-recorded voice notification is played for the occupant to check the door as there might be someone, this happens concurrently with an sms notification while a picture of the visitor is captured and sent to both email and push notification. Initially there was a feature to enable 2-way real-time video communication but due to network latency and high resource usage the feature was deprecated.

Click For A Demo

Comment if you need the code

See code snippets(Initial Revision): https://mmphego.wordpress.com/2015/01/11/smart-doorbell-using-rpi-with-voice-and-email-notification/

Advertisements

Getting started with Nodemcu in Arduino IDE

On this blog I will introduce and demonstrate how to use NodeMCU in Arduino IDE

What is NodeMCU or ESP8266 ?

The ESP8266 is a low-cost Wi-Fi chip with full TCP/IP stack and MCU (Micro Controller Unit) capability produced by Espressif Systems.

Whereas NodeMCU is an open source firmware and development kit that helps us to create IoT platform. It includes firmware which runs on the ESP8266 WiFi SoC from Espressif Systems and hardware which is based on the ESP-12 module. NodeMCU can be directly programmed using Arduino Software.

300px-nodemcu_devkit_1-0

P.S: With NodeMCU in hand, you do not need to have Arduino Boards. You can simply program NodeMCU board using Arduino Software using USB cable. However, Small changes in Arduino Software needs to be done so that NodeMCU Module can be programmed using Arduino Software. NodeMCU is very cheap and can be bought in less than $5. Only.  This is a very good solution for IoT application in a very cheap price. Buy it here NodeMCU WiFi Development Board.

This assumes you have the latest Arduino IDE.

1. Adding NodeMCU on board management.

Open Arduino IDE, go to Files > Preferences 

Copy URL below and paste it on Additional Boards Manager URLs as per image below.

http://arduino.esp8266.com/stable/package_esp8266com_index.json

screenshot_2017-03-02_14-06-56

More Info can be found on https://github.com/esp8266/Arduino

2. Installing NodeMCU board

This assumes you are connected to the Internet, else how did you even get to this blog post.

Goto Tools > Board > Boards Manager, This will download additional board information from the url you added in step 1.

board-manager

Navigate and select esp8266, and install.

board-manager-open

Close and re-open the Arduino IDE after installation is successful.

Connect NodeMCU and select Tools > port  and select correct port.

3. LED Blinking Program on NodeMCU Board

After following steps given above, now your NodeMCU board can be used like an Arduino board and you can program it using Arduino Software.

This is a very basic program for blinking of an LED.

You can copy and paste program from here.

Compile it and Upload it on NodeMCU Board and observe the output on pin  D1.

// Program starts here
#define LED_PIN D1

void setup() {
// put your setup code here, to run once:
pinMode( LED_PIN, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:
digitalWrite(LED_PIN, HIGH); // Turn on the LED.
delay(1000); // Wait 1 second
digitalWrite(LED_PIN, LOW); // Turn off the LED.
delay(1000);
}
// Program ends here

I will compile a video soon and upload.

Arduino Quad Relays : Webserver

Phase 3: Quad Relays controlled via/on webserver

/*

 4 parallel Relayes and Arduino with Ethernet Shield
 */

#include <SPI.h>
#include <Ethernet.h>

int led = 2, led2 = 3, led3 = 5, led4 = 6;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 172, 18, 30, 197 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 172, 18, 30, 10 };                   // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port     
String readString;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {

  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();
     
        //read char by char HTTP request
        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          //Serial.print(c);
         }

         //if HTTP request has ended
         if (c == '\n') {          
           Serial.println(readString); //print to serial monitor for debuging
     
           client.println("HTTP/1.1 200 OK"); //send new page
           client.println("Content-Type: text/html");
           client.println();    
           client.println("Connection: close");  // the connection will be closed after completion of the response
	   client.println("Refresh: 5");  // refresh the page automatically every 5 sec
           client.println();
           client.println("<!DOCTYPE HTML>"); 
           client.println("<HTML>");
           client.println("<CENTER><HEAD>");
           client.println("<TITLE>Simple Home Automation</TITLE>");
           client.println("</HEAD>");
           client.println("<BODY>");
           client.println("<H1>Simple Home Automation</H1>");
           client.println("<hr />");
           client.println("
");  
           client.println("<H2>Arduino with Ethernet Shield</H2>");
           client.println("
");  
           client.println("<a href=\"/button1on\"\">Turn On LED 1</a>");
           client.println("<a href=\"/button1off\"\">Turn Off LED 1</a>
");   
           client.println("<a href=\"/button2on\"\">Turn On LED 2</a>");
           client.println("<a href=\"/button2off\"\">Turn Off LED 2</a>
");   
           client.println("<a href=\"/button3on\"\">Turn On LED 3</a>");
           client.println("<a href=\"/button3off\"\">Turn Off LED 3</a>
");   
           client.println("<a href=\"/button4on\"\">Turn On LED 4</a>");
           client.println("<a href=\"/button4off\"\">Turn Off LED 4</a>
"); 
           client.println("
");     
           client.println("
"); 
           client.println("<a href=\"/buttonson\"\">All on LED</a>");
           client.println("<a href=\"/buttonsoff\"\">All Off LED</a>
"); 
           client.println("
");     
           client.println("
"); 
           client.println("
</CENTER>"); 
           client.println("</BODY>");
           client.println("</HTML>");
     
           delay(1);
           //stopping client
           client.stop();
           //controls the Arduino if you press the buttons
           if (readString.indexOf("button1on") > 0){
               digitalWrite(led, HIGH);
           }
           if (readString.indexOf("button1off") > 0){
               digitalWrite(led, LOW);
           }
           if (readString.indexOf("button2on") > 0){
               digitalWrite(led2, HIGH);
           }
           if (readString.indexOf("button2off") > 0){
               digitalWrite(led2, LOW);
           }
           if (readString.indexOf("button3on") > 0){
               digitalWrite(led3, HIGH);
           }
           if (readString.indexOf("button3off") > 0){
               digitalWrite(led3, LOW);
           }
           if (readString.indexOf("button4on") > 0){
               digitalWrite(led4, HIGH);
           }
           if (readString.indexOf("button4off") > 0){
               digitalWrite(led4, LOW);
           }
           if (readString.indexOf("buttonson") > 0){
             //int i;
             //for (i = 0; i < 4; i++){
               digitalWrite(led, HIGH);
               digitalWrite(led2, HIGH);
               digitalWrite(led3, HIGH);
               digitalWrite(led4, HIGH);
             //}
           }
           if (readString.indexOf("buttonsoff") > 0){
               digitalWrite(led, LOW);
               digitalWrite(led2, LOW);
               digitalWrite(led3, LOW);
               digitalWrite(led4, LOW);
           }
          //clearing string for next read
           readString="";  
           
         }
       }
    }
}
}

Arduino Temp Monitor : Webserver

Phase 2: Temperature monitoring logged on webserver.

/*
  Web Server
 
 A simple web server that shows the temperature using an Arduino Wiznet Ethernet shield.
 
Parts list:

10k Thermistor
Breadboard/Veroboard
10k resistor
Arduino ( I use UNO)
Arduino Wiznet Ethernet shield

The Thermistor Circuit:
AREF---+3.3V----Therm----A0(Arduino)----10k res---&gt; Gnd

Better Readings:
When doing analog readings, especially with a 'noisy' board like the arduino, we suggest two tricks to improve results.
One is to use the 3.3V voltage pin as an analog reference and the other is to take a bunch of readings in a row and average them.
The first trick relies on the fact that the 5V power supply that comes straight from your computer's USB does a lot of stuff on the Arduino, 
and is almost always much noisier than the 3.3V line (which goes through a secondary filter/regulator stage!) It's easy to use, simply connect 3.3V to AREF and use that as the VCC voltage. 
Because our calcuations don't include the VCC voltage, you don't have to change your equation. You do have to set the analog reference but that's a single line of code
Taking multiple readings to average out the result helps get slightly better results as well, since you may have noise or fluctuations, we suggest about 5 samples.

Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13

 
 */

#include &lt;SPI.h&gt;
#include &lt;Ethernet.h&gt;

#define THERMISTORPIN A0         
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000      
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25   
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000    
 
int samples[NUMSAMPLES];
 
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(172,18,30,197);

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print(&quot;server is at &quot;);
  Serial.println(Ethernet.localIP());
}

void loop() {
  // listen for incoming clients
    uint8_t i;
  float average;
 
  // take N samples in a row, with a slight delay
  for (i=0; i&lt; NUMSAMPLES; i++) {
   samples[i] = analogRead(THERMISTORPIN);
   delay(10);
  }
 
  // average all the samples out
  average = 0;
  for (i=0; i&lt; NUMSAMPLES; i++) {
     average += samples[i];
  }
  average /= NUMSAMPLES;
 
//  Serial.print(&quot;Average analog reading &quot;); 
//  Serial.println(average);
 
  // convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;
//-------------------------------------------
// To display on Serial monitor
//  Serial.print(&quot;Thermistor resistance &quot;); 
//  Serial.println(average);

// Read about the Steinhart–Hart equation
// http://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation

  float steinhart;
  steinhart = average / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C

  EthernetClient client = server.available();
  if (client) {
    Serial.println(&quot;new client&quot;);
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' &amp;&amp; currentLineIsBlank) {
          // send a standard http response header
          client.println(&quot;HTTP/1.1 200 OK&quot;);
          client.println(&quot;Content-Type: text/html&quot;);
          client.println(&quot;Connection: close&quot;);  // the connection will be closed after completion of the response
	  client.println(&quot;Refresh: 5&quot;);  // refresh the page automatically every 5 sec
          client.println();
          client.println(&quot;&lt;!DOCTYPE HTML&gt;&quot;);
          client.println(&quot;&lt;html&gt;&quot;);
          // output the value of each analog input pin
          //int analogChannel = 0;
          //for (int analogChannel = 0; analogChannel &lt; 6; analogChannel++) {
           // int sensorReading = analogRead(analogChannel);
           client.print(&quot;&lt;CENTER&gt;&lt;H1&gt;&quot;);
           client.print(&quot;Temperature &quot;);
            //client.print(analogChannel);
            client.print(&quot; is &quot;);
            client.print(steinhart);
            client.print(&quot; &amp;deg;C&quot;);
            client.print(&quot;&lt;/H1&gt;&lt;/CENTER&gt;&quot;);
            client.println(&quot;
&quot;);       
          //}
          client.println(&quot;&lt;/html&gt;&quot;);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(100);
    // close the connection:
    client.stop();
    Serial.println(&quot;client disonnected&quot;);
  }
}

Arduino Temp monitor : 16×2 LCD

Phase 1:I have been procrastinating on creating a home automation system until I decided to dedicate a few of my hours to this project.
I have decided to use an Arduino and a Raspberry Pi combination.

The idea is to have the Arduino running all ADC calculations and sensors as the Pi is not equipped with an ADC, and use the Pi as logger and dashboard using apache2/graphite or something along those lines.

So first things first I had to re-brush myself with C code after 2 years of not using C.

/*
Arduino thermometer, LCD Display, Thermistor

Its an arduino project, creating a temperature measurer, with a thermistor, and outputs to an lcd display.

Parts list:
16x2 LCD
10k Thermistor
10k Variable Resistor
Breadboard/Veroboard
10k resistor
Arduino ( I use UNO)

How I did it:

The LCD circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

The Thermistor Circuit:
AREF---+3.3V----Therm----A0(Arduino)----10k res---> Gnd

Better Readings:
When doing analog readings, especially with a 'noisy' board like the arduino, we suggest two tricks to improve results. One is to use the 3.3V voltage pin as an analog reference and the other is to take a bunch of readings in a row and average them.
The first trick relies on the fact that the 5V power supply that comes straight from your computer's USB does a lot of stuff on the Arduino, and is almost always much noisier than the 3.3V line (which goes through a secondary filter/regulator stage!) It's easy to use, simply connect 3.3V to AREF and use that as the VCC voltage. Because our calcuations don't include the VCC voltage, you don't have to change your equation. You do have to set the analog reference but that's a single line of code
Taking multiple readings to average out the result helps get slightly better results as well, since you may have noise or fluctuations, we suggest about 5 samples.

Here's the code 
*/
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// which analog pin to connect
#define THERMISTORPIN A0         
// resistance at 25 degrees C
#define THERMISTORNOMINAL 10000      
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25   
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 5
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT 3950
// the value of the 'other' resistor
#define SERIESRESISTOR 10000    
 
int samples[NUMSAMPLES];
 
void setup(void) {
  lcd.begin(16, 2);
  lcd.clear();
  Serial.begin(9600);
  analogReference(EXTERNAL);
}
 
void loop(void) {
  uint8_t i;
  float average;
 
  // take N samples in a row, with a slight delay
  for (i=0; i< NUMSAMPLES; i++) {
   samples[i] = analogRead(THERMISTORPIN);
   delay(10);
  }
 
  // average all the samples out
  average = 0;
  for (i=0; i< NUMSAMPLES; i++) {
     average += samples[i];
  }
  average /= NUMSAMPLES;
 
//  Serial.print("Average analog reading "); 
//  Serial.println(average);
 
  // convert the value to resistance
  average = 1023 / average - 1;
  average = SERIESRESISTOR / average;
//-------------------------------------------
// To display on Serial monitor
//  Serial.print("Thermistor resistance "); 
//  Serial.println(average);

// Read about the Steinhart–Hart equation
// http://en.wikipedia.org/wiki/Steinhart%E2%80%93Hart_equation

  float steinhart;
  steinhart = average / THERMISTORNOMINAL;     // (R/Ro)
  steinhart = log(steinhart);                  // ln(R/Ro)
  steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
  steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
  steinhart = 1.0 / steinhart;                 // Invert
  steinhart -= 273.15;                         // convert to C

//-------------------------------------------
// To display on Serial monitor 
//  Serial.print("Temperature "); 
//  Serial.print(steinhart);
//  Serial.println(" *C");
  //delay(1000);
  lcd.setCursor(0, 0);
  lcd.print("Temp : ");
  lcd.print(steinhart);
  lcd.print("\337C");
  //lcd.print(" *C");
  lcd.setCursor(0, 1);
  lcd.print("SANSA Office");  
  delay(1000);
  lcd.clear();
}