Speaklight Project

Here is my SpeakLight project, which uses Android speech recognition to control a lamp's color.

The SpeakLight project has two components, an Android app (because iPhones are a closed system) and a remote Arduino-controlled light source.  When you say to the app, for example, "aquamarine", the light and the screen change to that color.  The SpeakLight app also recognizes "brighter", "dimmer", "rainbow", and a few other commands.

                                      

 SpeakLight app screenshots 1-2-3!

The app has a list of 3,214 color names with their RGB color values.  It listens for a spoken color name and sends that color’s value through a Bluetooth connection to the light.  The light source was initially a simple tri-color LED kit, then a brighter I2C-controlled LED kit, and is now a 75 watt DMX-controlled theater light.

 

            

This is the first version of the Arduino lamp and its color pattern on the ceiling -- as you can see, the aquamarine color is there but not uniform. 

BlinkM MaxM I2C-controlled high-brightness LEDsThis is the second SpeakLight output device, a BlinkM MaxM, the brightest LED kit that SparkFun had! 

 

           

Third version, with the PAR64 can light.  This is the color wash I was looking for!  

The SpeakLight app required 398 lines of Java code (and weeks of Android research), and the Arduino sketch merely 79 lines of C++.

The Android built-in onActivityResult function (see below) receives the results of all requested events.  In my case, if it’s a speech event, this function parses all recognized phrases and compares each phrase to each of the known color names.  If there’s a match, that color’s hex value is sent to the Arduino, which magically (using electrons) changes the lamp’s color.


SpeakLight onActivityResult Code

String[] colors = { "Acadia#1B1404", "Acapulco#7CB0A1", "Acid Green#A8BB19", "Acorn#6A5D1B", "Aero Blue#C9FFE5", "African Violet#B284BE", ... };

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        String result ="", firstResult = "", colorName = "";
        boolean colorFound = false;
        int iColor = 0;
        String[] cNameVal;       

        button.setText("Working...");

        if (requestCode == SPEECH_REQUEST_CODE) { 
            if (resultCode == RESULT_OK) {
                ArrayList matches = 
data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

                if (matches.size() == 0) {
                    button.setText("No matches!");
                } else {
                    // most likely matched phrase
                    firstResult = matches.get(0); 

                    for (int j = 0; j < matches.size(); j++) {
                        // each phrase in turn
                        result = matches.get(j).toLowerCase(); 
                        if (result.contains("grey")) {
                            result = result.replace("grey", "gray");
                        }
                        for (int i = 0; i < colors.length; i++) {
                            // color name [0] and value [1]
                            cNameVal = colors[i].split("#");
                            if (result.equals(cNameVal[0].toLowerCase())) {
                                colorFound = true;
                                // prepend octothorpe
                                sColor =  "#" + cNameVal[1]; 
                                iColor = parseColor(sColor);
                                colorName = cNameVal[0];
                                button.setText(colorName);
                                break;
                            }
                        }
                        if (colorFound) {
                            break;
                        }
                    }
                }
            } else {
                button.setText("Please try again");
            }
        }

        if (colorFound) {
            // send color hex value bytes to Arduino through 
            // previously-established Bluetooth connection
            ArduinoSend(sColor);    
        } else {
             button.setText("'" + firstResult + "' is not a color I know!");
             beDoop(errsound);
        }

        super.onActivityResult(requestCode, resultCode, data);
    }