Project in progress
 (SAL) Sonar&Alexa Lights

(SAL) Sonar&Alexa Lights © GPL3+

Alexa and Sonar do the heavy lifting of light switches for the home.

  • 826 views
  • 0 comments
  • 0 respects

Components and supplies

Necessary tools and machines

Screwdriver
3drag
3D Printer (generic)

Apps and online services

About this project

I wanted to be able to go from one room to another with out needing to back track to flip the switch in case I failed to turn the lights out before transitioning rooms and getting comfortable. Alexa with the help of Arduino can physically flip the switch without anybody lifting a finger. My place started out with fairly standard residential light switches.

Hardware

Step One:

The light switch panel has 4 screws in it. Using a screwdriver take out the two screws at the top and bottom, and remove the panel. The new panel that was 3D printed can now be attached to the bare switches using the screws that were removed from the original panel. Servos are placed in between the switches to get something like the picture below.

Step Two:

Wire the servos to the Arduino along with a sonar sensor. Connect the Raspberry Pi to the Arduino which will all be held together by a 3D printed dome shaped cover that will fit inside the circular base using a pressure fit. The sonar has its own holder which can be placed in an opening at the top of the dome. A Li-ion battery which is the blue cylinder already in the dome connects to the Pi with a USB cable.

With the hardware fully assembled you get this.

The 3D models were designed in Fusion 360. I have provided the CAD files for the circular base plate, sonar holder, dome cap, and custom servo attachments.

Software

Step one:

Setup the Raspberry Pi using the code titled Pi setup. Download ngrok which allows the Pi to act as a server. https://ngrok.com

Step two:

Setup ngrok by opening a terminal and navigeting to where it was downloaded. I had use cd Downloads, then I executed ngrok by typing ./ngrok http 5000.

Step three:

Create a script made from Python and execute it on the Pi. It's called Pi Code in my code section below. This will allow you to network with Alexa and Arduino.

Step four:

Create an Arduino script that turns the servo's depending on the sonar sensors distance readings. Include a function that will allow Alexa to turn the servos at the user's command. This script is titled Arduino Code, in my code section.

Step five:

Setup Amazon Developer Console by going to this link https://developer.amazon.com/home.html. After signing in, navigate to the tab named Alexa. Next you will click on the Alexa skills kit option and create a new skill.

After setting the skill up, the ngrok server on-line, and the Python code running, now Alexa can flip the switch.

Demonstration

https://drive.google.com/file/d/1X7uDm_i_BaA8EH0zPMqPvfmmQ99hMF1v/view?usp=sharing

Alexa Demonstration part one

https://drive.google.com/file/d/15shB4me1XET_eha4MRCoyhBjMD86TmnS/view?usp=sharing

Alexa Demonstration part two

https://drive.google.com/file/d/1XjWY1Uoqxy_x7AJF74imnSCss0ODhNtf/view?usp=sharing

Sonar Feature Demonstration

Side Notes

* As a possible update on the software side, I would like to have Alexa be able to change the timer settings for how long the lights stay on.

*As a possible update on the hardware side, it would be nice if the sonar was able to rotate.

*My Internet connection speed can be sluggish which is the cause of the delay between command and execution with Alexa in part two of the demonstration.

*The Python code as it's written now only has one chance to make a serial connection with the Arduino. If it fails, you have to restart the Python script. The Arduino also needs to be disconnected and reconnected to the Pi. There should be a way to allow Python to make multiple attempts at a serial connection.

Code

Pi Setupsnippets
Install Raspberry Pi dependencies needed to use Python code along with the ngrok server and allow connection to Alexa through the Amazon Developer Console.
sudo apt-get install python-pip  
pip install flask 
pip install flask-ask 
sudo apt-get install pyserial 
sudo apt-get intall libpython2.7-dev 
Arduino CodeArduino
/* HC-SR04 Sensor

   https://www.dealextreme.com/p/hc-sr04-ultrasonic-sensor-distance-measuring-module-133696

  

   This sketch reads a HC-SR04 ultrasonic rangefinder and returns the

   distance to the closest object in range. To do this, it sends a pulse

   to the sensor to initiate a reading, then listens for a pulse 

   to return.  The length of the returning pulse is proportional to 

   the distance of the object from the sensor.

     

   The circuit:

 * VCC connection of the sensor attached to +5V

  * GND connection of the sensor attached to ground

  * TRIG connection of the sensor attached to digital pin 2

  * ECHO connection of the sensor attached to digital pin 4





   Original code for Ping))) example was created by David A. Mellis

   Adapted for HC-SR04 by Tautvidas Sipavicius



   This example code is in the public domain.

 */


#include <Servo.h>
Servo myservo;  // create servo object to control a servo
Servo myservo2;

const int trigPin = 4;

const int echoPin = 2;
const int servoMin= 7;
const int servo2Min = 2;
const int servoMax = 55;
const int servo2Max = 32;

const long timerOnMax = 50;
const long tol = 1;
const long distMax = 30;
const long distMin = 5;
long timerOn = 0;
long prev = -999;
int pos;
void setup() {

  // initialize serial communication:
  myservo2.attach(10);
  myservo.attach(11);
  Serial.begin(9600);

  myservo.write(servoMax);              
  myservo2.write(servo2Max);
  Serial.println("Start - Off");
}



 
void loop()
{
 int input = Serial.read();
 if (input == 'A') { 
     for (pos = servoMax; pos >= servoMin; pos -= 3) { // goes from 180 degrees to 0 degrees
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(200);
     }                       // waits 15ms for the servo to reach the position 
 } else if(input == 'B') { 
    for (pos = servoMin; pos <= servoMax; pos += 3) { // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
        myservo.write(pos);
        delay(200);
    }
 } else if (input == 'C') { 
     for (pos = servo2Max; pos >= servo2Min; pos -= 3) { // goes from 180 degrees to 0 degrees
        // tell servo to go to position in variable 'pos'
        myservo2.write(pos);
        delay(200);
     }                       // waits 15ms for the servo to reach the position 
 } else if(input == 'D') { 
    for (pos = servo2Min; pos <= servo2Max; pos += 3) { // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
        myservo2.write(pos);
        delay(200);
    }
 }  

  // establish variables for duration of the ping, 

  // and the distance result in inches and centimeters:

  long dist;



  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.

  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:

  pinMode(trigPin, OUTPUT);

  digitalWrite(trigPin, LOW);

  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);

  delayMicroseconds(10);

  digitalWrite(trigPin, LOW);



  // Read the signal from the sensor: a HIGH pulse whose

  // duration is the time (in microseconds) from the sending

  // of the ping to the reception of its echo off of an object.

   pinMode(echoPin, INPUT);

  // convert the time into a distance
  dist = microsecondsToInches(pulseIn(echoPin, HIGH));

  Serial.print(dist);
  Serial.print(" in.  Timer: ");
  Serial.println(timerOn);
  delay(200);



  if((dist > distMax + tol) || (dist < distMin - tol))
    prev = -999;
  else if(abs(dist - prev) > tol)
  {
    if(timerOn == 0)
    {
      //turnLightOn
      Serial.println("Turn On");
      for (pos = servoMax; pos >= servoMin; pos -= 3) { // goes from 180 degrees to 0 degrees
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        //myservo2.write(((servo2Min - servoMin)+pos));
        delay(200);                       // waits 15ms for the servo to reach the position
      }
    }
    timerOn = timerOnMax;
    prev = dist;
  }
  if(timerOn > 0)
  {
    timerOn--;
    if(timerOn == 0)
    {
      //turnLightOff
      Serial.println("Turn Off");
      for (pos = servoMin; pos <= servoMax; pos += 3) { // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        //myservo2.write((servo2Max - pos));
        delay(200);                       // waits 15ms for the servo to reach the position
      }
    }
  }
}



long microsecondsToInches(long microseconds)

{

  // According to Parallax's datasheet for the PING))), there are

  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per

  // second).  This gives the distance travelled by the ping, outbound

  // and return, so we divide by 2 to get the distance of the obstacle.

  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf

  return microseconds / 74 / 2;

}



long microsecondsToCentimeters(long microseconds)

{

  // The speed of sound is 340 m/s or 29 microseconds per centimeter.

  // The ping travels out and back, so to find the distance of the

  // object we take half of the distance travelled.

  return microseconds / 29 / 2;

}
Raspberry Pi CodePython
from flask import Flask 
from flask_ask import Ask, statement 
import requests 
import json 
import serial 
ser = serial.Serial("/dev/ttyACM0", 9600)  # pls change here for your serial
app = Flask(__name__) 
ask = Ask(app, '/') 
@ask.launch 
@ask.intent("LightOn") 
def on(): 
   ser.write(b'A') 
   return statement("Closet light turned on.") 
@ask.intent("LightOff") 
def off(): 
   ser.write(b'B') 
   return statement("Closet light turned off.")
@ask.intent("LightOnTwo") 
def on2(): 
   ser.write(b'C') 
   return statement("Bedroom light turned on.") 
@ask.intent("LightOffTwo") 
def off2(): 
   ser.write(b'D') 
   return statement("Bedroom light turned off.") 
if __name__ == "__main__": 
   app.run(debug=True) 

Custom parts and enclosures

LightSwitchPanel
Light switch cover to replace the old panel and secure the servo motors.
ServoAttachment
Attaches to the servo with the light switch placed in the middle of the fork.
SonarHolder
Holds the sonar sensor at the top of the dome
Capstone
Houses the electronics and fits inside the light switch cover.

Schematics

Making Connections
The Arduino is connected to the Pi. Wired to the Arduino is a sonar sensor with the trig pin going to pin 4 and the echo pin connects with pin 2. Red and black cables on both the servos and sonar are power and ground respectively. Yellow signal pins on the servos are connected to pins 10 and 11.
Connections bb 95sgif2dqm

Comments

Similar projects you might like

Intelligent Door Lock

Project in progress by Md. Khairul Alam

  • 15,961 views
  • 19 comments
  • 95 respects

Where's my stuff?? - Find your misplaced things with Alexa!

Project in progress by Team Crakers

  • 1,630 views
  • 0 comments
  • 6 respects

Rainometer

Project tutorial by King Bros

  • 1,822 views
  • 0 comments
  • 6 respects

Sputnik Spotlight

Project in progress by Joster

  • 1,304 views
  • 0 comments
  • 5 respects

Light Control Using Arduino and Amazon Alexa

Project tutorial by Rajesh

  • 13,814 views
  • 1 comment
  • 16 respects

DIY 3-Axis CNC VMC

Project tutorial by Amit Nandi (BigWiz)

  • 12,163 views
  • 9 comments
  • 46 respects
Add projectSign up / Login