Project showcase
Voice Controlled Wooden Edison Lamp - Question Price $5

Voice Controlled Wooden Edison Lamp - Question Price $5 © GPL3+

"I have not failed. I've just found 10'000 ways that won't work. " - Thomas Alva Edison

  • 197 views
  • 0 comments
  • 7 respects

Components and supplies

Apps and online services

About this project

That is how much Wifi Relay SONOFF (From ITEAD company) cost, which is the heart of this device.

"I have not failed. I've just found 10'000 ways that won't work." - Thomas A. Edison

This is incredible, but more recently, people in schools wrote with feathers. And today, there is a magic brick with a picture, that fits in your pocket and provides access to all information in the world. Voice control and, as people say, the threat to mankind from the side of artificial intelligence. More recently, these technologies seemed like inaccessible fantasies. But today, I will show you how absolutely each of you, with basic programming knowledge, can use voice control. So, let's begin.

WARNING!!! Work with high voltage! The author of the article is not responsible for your actions! Or any material, or physical damage that may be as result from the use of this instruction!

The general scheme of the device working algorithm.

Since the phone, at a time, can only be connected to one Wi-Fi access point, we will work through the router. In general, it is convenient when all your smart devices are on the same network and you can easily manage them without having to constantly reconnect to each of them. The disadvantage of this, is that all your devices depend on the performance of a single router.

1 - we need to reprogram Sonoff wi-fi relays.

By default, it is configured to work through a Chinese server. In my understanding, it is not very convenient to turn off the light bulb in the toilet through the Chinese server. For this we need to disassemble it and solder the contacts for reprogramming.

Now we can connect cp2102 module from Silicon Labs to Sonoff wifi. I also used it to program the Arduino mini.

WARNING!!! When you do reprogramming, do not connect the module to the 220/110 volt network!

Reprogram the relay is very simple. This is a regular esp8266 module. I took the standard sketch of the access point server from Arduino IDE and changed it a bit.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
// name and password from WiFi network
const char* ssid = "Your access point (router) name";
const char* password = "router password";
IPAddress ip(192,168,1,112); // enter static ip
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
// Server port 80
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(100);
//preparing GPIO
pinMode(12, OUTPUT);
digitalWrite(12, 1);
pinMode(13, OUTPUT);
digitalWrite(13, 1);
// connecting to WiFi
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
WiFi.config(ip, gateway, subnet);
// waiting for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// run server
server.begin();
Serial.println("Server started");
// show ip
Serial.println(WiFi.localIP());
}
void loop() {
// connection check
WiFiClient client = server.available();
if (!client) {
return;
}
// Waiting for data
Serial.println("new client");
while (!client.available()) {
delay(1);
}
// Reading the first line of the query
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();
// works with GPIO
if (req.indexOf("/12/0") != -1)
digitalWrite(12, 0);
else if (req.indexOf("/12/1") != -1){
digitalWrite(12, 1);
Serial.println("TEST OK");
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nTest OK. Uptime: ";
// UpTime
int Sec = (millis() / 1000UL) % 60;
int Min = ((millis() / 1000UL) / 60UL) % 60;
int Hours = ((millis() / 1000UL) / 3600UL) % 24;
int Day = ((millis() / 1000UL) / 3600UL / 24UL);
s += Day;
s += "d ";
s += Hours;
s += ":";
s += Min;
s += ":";
s += Sec;
s += "</html>\n";
client.print(s);
client.stop();
return;
}
else
// If an invalid query write error
{
Serial.println("invalid request");
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nInvalid request";
s += "</html>\n";
client.print(s);
client.stop();
return;
}
client.flush();
// Response formation
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO set OK";
s += "</html>\n";
// Send the response to the client
client.print(s);
delay(1);
Serial.println("Client disonnected");
}

You will need to specify the name of your access point (router), password and static ip address for the light bulb. Relay control is at pin 12. Be sure to set the Flash size to 1 MB in the IDE.

Press and hold the push button on the Sonoff board. Insert the cp2102 converter USB in your computer (while holding the push button). After 2–3 seconds, release the push button. Now it’s in flash mode. Load the sketch file in Arduino IDE. Click on Verify / Compile. After you flash it, the module should restart and the green LED will start blinking.

2 - let's make some mobile app, to control this wifi relay. (Android)

I will provide only the main code fragments. Then you can use them to implement it on your applications. Google provides a very simple and convenient interface for voice recognition. Here is the code that allows you to convert a voice to text and save it to a regular string.

// Main code to start speech recognition.
// You can put it's execution, on some button in your app.
       Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
       speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
               RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
       speechIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak please");
       startActivityForResult(speechIntent, RESULT_SPEECH_TO_TEXT);
//------------------------------------------------------------------------
// Then on onAcivityResult we will get result
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (requestCode == RESULT_SPEECH_TO_TEXT && resultCode == RESULT_OK) {
           ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
           if (!matches.isEmpty()) {

               String result_recognition_string = matches.get(0);

		// convert to lower case, since google speech recognition
                // returns "different" results. For example: youtube defines //as YouTube
               result_recognition_string = result_recognition_string.toLowerCase(Locale.getDefault());

                 if (result_recognition_string.contains("lamp on") ) {
			// lamp on 
			new LightOn().execute();
               }
            }
   }
}

Then you can compare it with the commands you want to implement.

This is the code to work with WiFi. Sending a message to the server.

public class LightOn extends AsyncTask<Void,Void,Void> {
   private static final String LOG_TAG = "MyLog";
   @Override
   protected Void doInBackground(Void... params) {
       URL url;
       HttpURLConnection urlConnection = null;
       try {
           url = new URL("http://192.168.1.112/12/1"); // "0" to turn off 
           urlConnection = (HttpURLConnection) url
                   .openConnection();
           InputStream in = urlConnection.getInputStream();
           InputStreamReader isw = new InputStreamReader(in);
           int data = isw.read();
           while (data != -1) {
               char current = (char) data;
               data = isw.read();
               System.out.print(current);
               Log.e(LOG_TAG, "Reply from server - " + current);
           }
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           if (urlConnection != null) {
               urlConnection.disconnect();
           }
       }
       return null;
   }
}
// run it
new LightOn().execute();

It is very simple. "1" turn on the light bulb, "0" turn off the light bulb. You can add, at will, any checks, receive a response from the server etc.. I created two programs for myself. The first is the voice control widget, which is located on the desktop and it always at hand. The second is a simple application of turning on / off a light bulb by pressing a button.

And I assume, that you are already tired of reading all sorts of texts and I suggest you watch the video about how it was.

As Albert Einstein said: “your possibilities are limited only by your imagination.”

Enjoy, have fun and be smart !

Regards

Code

Android main code parts, to use voice recognition.Java
You just need to put it in you app. For example - to put on processing the pressing of a button.
// Main code to start speech recognition.
// You can put it's execution, on some button in your app.

        Intent speechIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        speechIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        speechIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Speak please");
        startActivityForResult(speechIntent, RESULT_SPEECH_TO_TEXT);
    

// Then on onAcivityResult we will get result

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RESULT_SPEECH_TO_TEXT && resultCode == RESULT_OK) {

            ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            if (!matches.isEmpty()) {
              
              String result_recognition_string = matches.get(0);

		// convert to lower case, since google speech recognition
                 // returns "different" results. For example: youtube defines //as YouTube
                result_recognition_string = result_recognition_string.toLowerCase(Locale.getDefault());


                  if (result_recognition_string.contains("lamp on") ) {
			// lamp on 
			new LightOn().execute();
                }
             }
    }
}
Sonoff esp8266 codeC/C++
Firmware for SONOFF Wi-Fi relay. To use it through your home router.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
 
// name and password from WiFi network
const char* ssid = "Your access point (router) name";
const char* password = "router password";


IPAddress ip(192,168,1,112); // enter static ip
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

 
// server port 80
 
WiFiServer server(80);
 
void setup() {
 Serial.begin(115200);
 delay(100);
 
 //preparing GPIO

 pinMode(12, OUTPUT);
 digitalWrite(12, 1);

 pinMode(13, OUTPUT);
 digitalWrite(13, 1);


 
 // connecting to WiFi
 Serial.println();
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);
 WiFi.begin(ssid, password);
 WiFi.config(ip, gateway, subnet);
 
 // waiting for connection
 while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
 }
 Serial.println("");
 Serial.println("WiFi connected");
 
 // run server
 server.begin();
 Serial.println("Server started");
 
 // show ip
 Serial.println(WiFi.localIP());
}
 
void loop() {
 
 // connection check
 WiFiClient client = server.available();
 if (!client) {
 return;
 }
 
 // Waiting for data
 Serial.println("new client");
 while (!client.available()) {
 delay(1);
 }
 
 // Reading the first line of the query
 String req = client.readStringUntil('\r');
 Serial.println(req);
 client.flush();

 // works with GPIO
 if (req.indexOf("/12/0") != -1)
 digitalWrite(12, 0);
 else if (req.indexOf("/12/1") != -1){
 digitalWrite(12, 1);
 Serial.println("TEST OK");
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nTest OK. Uptime: ";


 // UpTime
 int Sec = (millis() / 1000UL) % 60;
 int Min = ((millis() / 1000UL) / 60UL) % 60;
 int Hours = ((millis() / 1000UL) / 3600UL) % 24;
 int Day = ((millis() / 1000UL) / 3600UL / 24UL);
 s += Day;
 s += "d ";
 s += Hours;
 s += ":";
 s += Min;
 s += ":";
 s += Sec;
 s += "</html>\n";
 client.print(s);
 client.stop();
 return;
 }
 else
 // If an invalid query write error
 {
 Serial.println("invalid request");
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nInvalid request";
 s += "</html>\n";
 client.print(s);
 client.stop();
 return;
 }
 
 client.flush();
 
 
 // Response formation
 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO set OK";
 s += "</html>\n";
 
 // Send the response to the client
 client.print(s);
 delay(1);
 Serial.println("Client disonnected");
 
}
Android code to work with WiFiJava
This code is responsible for sending commands to the server (our light bulb)
public class LightOn extends AsyncTask<Void,Void,Void> {

    private static final String LOG_TAG = "MyLog";

    @Override
    protected Void doInBackground(Void... params) {

        URL url;
        HttpURLConnection urlConnection = null;
        try {
            url = new URL("http://192.168.1.112/12/1"); // "0" to turn off 

            urlConnection = (HttpURLConnection) url
                    .openConnection();

            InputStream in = urlConnection.getInputStream();

            InputStreamReader isw = new InputStreamReader(in);

            int data = isw.read();
            while (data != -1) {
                char current = (char) data;
                data = isw.read();
                System.out.print(current);
                Log.e(LOG_TAG, "Reply from server - " + current);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }

        return null;
    }
}



// run it
new LightOn().execute();
Android code work with WiFiJava
This code is responsible for sending commands to the server (our light bulb)
public class LightOn extends AsyncTask<Void,Void,Void> {

    private static final String LOG_TAG = "MyLog";

    @Override
    protected Void doInBackground(Void... params) {

        URL url;
        HttpURLConnection urlConnection = null;
        try {
            url = new URL("http://192.168.1.112/12/1"); // "0" to turn off 

            urlConnection = (HttpURLConnection) url
                    .openConnection();

            InputStream in = urlConnection.getInputStream();

            InputStreamReader isw = new InputStreamReader(in);

            int data = isw.read();
            while (data != -1) {
                char current = (char) data;
                data = isw.read();
                System.out.print(current);
                Log.e(LOG_TAG, "Reply from server - " + current);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }

        return null;
    }
}



// run it
new LightOn().execute();

Schematics

Wifi Relay SONOFF pins
Connecting Wi-Fi relay for flashing.
Arduino 6 ci0h661ekn

Comments

Similar projects you might like

DIY Air Humidifier with Backlight Controlled by Alexa

Project tutorial by Andrii Romanenko

  • 1,307 views
  • 0 comments
  • 7 respects

Voice Controlled K'nex Car

Project tutorial by Austin Wilson

  • 10,143 views
  • 4 comments
  • 53 respects

Robot Arm Controlled Through Ethernet

Project tutorial by Balázs Simon

  • 5,577 views
  • 0 comments
  • 34 respects

Voice Controlled RGB Lamp

Project tutorial by Pham Hoang Son

  • 3,029 views
  • 1 comment
  • 13 respects

Alexa Controlled Desk Lamp

Project tutorial by Pop Gheorghe

  • 632 views
  • 0 comments
  • 1 respect

Arduino Controlled Smart Hydroponic Modular System

Project in progress by Luis Antonio Martin Nuez

  • 11,814 views
  • 3 comments
  • 73 respects
Add projectSign up / Login