Project tutorial

Paint Your Dimmer Switch on the Wall © Apache-2.0

It's a dimmer switch! Create your own touch interface for controlling your Philips Hue lights using Bare Conductive's conductive paint.

  • 4,646 views
  • 0 comments
  • 9 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)

Apps and online services

About this project


Conductive Paint Dimmer Switch

Motivation

What to do you do when you have some Bare Conductive paint and some Philips Hue lightbulbs laying around? You paint a dimmer switch on your wall using conductive paint!

Getting Started

Some things you'll need to get started:

  • Arduino Due (or Zero)

Hardware

The Bare Conductive Touch Board actually contains an Arduino compatible MCU (the ATmega32u4), so although it's stacked like a shield we're actually using two different Arduino boards which communicate over serial UART with each other. There's a touch interface sketch running on the touch board, and then the hueDino Philips Hue API client runs on the anduinoWiFi Due. Eventually this could all be condensed in size to run on a MKR1000 and a MPR121 breakout if size were a concern.

The touch Board is essentially an Arduino Leonardo with an onboard MPR121 capacitive touch sensor, SD card reader, and mp3 player with 1/8" audio out.

WiFi Connectivity

You can test out a whole bunch of different painted circuits and touch interfaces using just the touch board. But when it comes time to internet connect your new interface slapping a WiFi shield on the ATmega32u4 isn't quite going to cut it. B.C. also makes a touch interface board for the Raspberry Pi which helps make it a bit easier to internet connect your conductive paint designs.

Since the touch board can't support WiFi this is why we've introduced the second Arduino Due paired with the anduinoWiFi This can now handle the Hue API communication between our Arduino and the local Philips Hue Bridge (which in turn controls the lights). It listens on a serial port for dimmer switch values sent by the touch board.

Let's get things connected up!

Soldering and Wiring

Step 1

To connect the three main components I've soldered a stackable header to the power pins of the B.C. touch board. After removing the LCD screen from the anduinoWiFi shield (just spin off the nylon stand offs and pull up) you can stack it right on top. I've also soldered headers for the touch electrodes and for pins 10 and 11 which we'll use for the Software Serial comms between the touch board and the Arduino Due.

Step 2

Once you've soldered the headers stack the touch board on top of the anduinoWiFi shield. Before stacking the shields on to the Due plug two wires into pins 18 and 19 Tx1 and Rx1. Either bend the pins or use a 90* degree header so the shield can still rest on top. At this point your boards should look like this:

Step 3

Lastly it's time to wire up the logic level converter. Since the touch board MCU operates at 5v and the Due at 3.3v we'll need to use a logic level converter to safely UART between the two devices.

Step 4

Just connect 5v and GND to HV and GND as well as 3.3v to LV and GND on the opposite side. Then use any of the pass through pins HV1 <--> LV1, HV2<-->LV2, etc. Connect Rx and Tx (pins 10 and 11) from the touch board to HV1 and HV2, and Rx1 to LV2 and Tx1 to LV1 from the Due. 3.3v logic on the L side 5v logic on the H side.

Step 5

Double check your wiring to make sure you've crossed your Tx <--> Rx connections. Tx on the touch board goes to RX on the Due and vice versa.

It's time to paint!

For the first prototype I grabbed a sheet of card stock and painted on 6 different traces. Then using some tape and a dab of paint I cold soldered some jumper wires to the ends of the traces. This way you can plug those wires directly into the header that we soldered to the touch board's electrode pins.

Now just connect each trace from top to bottom into electrodes 0 - 5 respectively. After flashing the two sketches you should be ready to test! Speaking of sketches, let's check out the code!

The Code

So how does it all work? Well, here's the source code! In order for everything to work you'll need a few libraries to be installed first.

Sketch for Touch Board

This sketch gets flashed to the Bare Conductive touch board.

#include <MPR121.h> 
#include <Wire.h> 
#define MPR121_ADDR 0x5C 
#define MPR121_INT 4 
#include <SoftwareSerial.h> 
SoftwareSerial mySerial(10, 11); // RX, TX 
void setup(){  
 Serial.begin(115200); 
 mySerial.begin(115200);    
 Wire.begin(); 
 if(!MPR121.begin(MPR121_ADDR)){  
   Serial.println("error setting up MPR121");   
   switch(MPR121.getError()){ 
     case NO_ERROR: 
       Serial.println("no error"); 
       break;   
     case ADDRESS_UNKNOWN: 
       Serial.println("incorrect address"); 
       break; 
     case READBACK_FAIL: 
       Serial.println("readback failure"); 
       break; 
     case OVERCURRENT_FLAG: 
       Serial.println("overcurrent on REXT pin"); 
       break;       
     case OUT_OF_RANGE: 
       Serial.println("electrode out of range"); 
       break; 
     case NOT_INITED: 
       Serial.println("not initialised"); 
       break; 
     default: 
       Serial.println("unknown error"); 
       break;       
   } 
   while(1); 
 } 
 MPR121.setInterruptPin(MPR121_INT); 
 MPR121.setTouchThreshold(40);    // lower numbers make the board more sensitive 
 MPR121.setReleaseThreshold(20);  // make sure that the release threshold is always  
                                  // lower than the touch threshold 
 MPR121.updateAll(); 
} 
void loop(){ 
 if(MPR121.touchStatusChanged()){ 
   // update our touch data to ensure it is valid 
   MPR121.updateTouchData();   
     // run through all electrodes 
     for(int i=0; i<=5; i++){ 
       if(MPR121.isNewTouch(i)){ 
         // if we have a new touch on this electrode... 
         digitalWrite(LED_BUILTIN, HIGH); 
         //Keyboard.press(keyMap[i]); 
         Serial.print("Brightness: "); 
         Serial.println(i); 
         char val=5; 
         itoa(i, &val, 10); 
         mySerial.write(val); 
       }  
     } 
   } 
 } 

Sketch for WiFi

This sketch gets flashed to the WiFi enabled Arduino, in this case our Arduino Due with anduinoWiFi shield.

#include "hueDino.h" 
#define hueUser ""      //ex: "Ur80SKqRKO0ojlFInzdjAZEHy0kjYWznakufY60m" 
#define lightId 5 
char ssid[] = "";       // your network SSID (name) 
char pass[] = "";       // your network password 
char hueBridge[] = "";  // hue bridge ip address ex: "192.168.1.3" 
WiFiClient wifi; 
hueDino hue = hueDino(wifi, hueBridge); 
int level = 0; 
void setup() { 
 Serial.begin(115200); 
 Serial1.begin(115200); 
 connectToWiFi(); 
 //Start Hue 
 hue.begin(hueUser); 
 /*Uncomment the section below if you're unsure of the ID of the  
  *light you'd like to control 
  * 
  */ 
 /*//Query bridge for available lights 
 Serial.println(hue.getLightIds()); //most hueDino methods return strings containing the raw json responses 
                                    //just encapsulate your function calls inside Serial.print statements to  
 Serial.println();                  //to print them to the screen 
 Serial.print("hueDino found: "); 
 Serial.print(hue.numLights); 
 Serial.println(" connected lights"); 
 Serial.println(); 
 Serial.println("Available Light IDs: "); 
 for(int i=0; i<hue.numLights; i++) 
 { 
     Serial.print(hue.lightIds[i]); 
     Serial.print(","); 
 }*/ 
 /*Available attributes/states 
  *on,off,brightness,hue,saturation,colorTemp,colorLoop,alert,flash 
  *reference: https://developers.meethue.com/documentation/lights-api 
  *settings are persistent and will not revert after sketch has run 
  */ 
 //On - make surethe light's are on before we try to dimm 
 hue.lightOn(lightId); 
 delay(200); 
} 
void loop() { 
 if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1) 
   level = Serial1.read();   
   Serial.println(level); 
  switch (level) { 
     case 48:  //48 is actually char '0' in dec '1' = 49..other than increased
               //readability interpreting these as chars didn't make sense
     hue.brightness(lightId, 250); 
     break; 
   case 49: 
     hue.brightness(lightId, 200); 
     break; 
   case 50: 
     hue.brightness(lightId, 150); 
     break; 
   case 51: 
     hue.brightness(lightId, 100); 
     break; 
   case 52: 
     hue.brightness(lightId, 50); 
     break; 
   case 53: 
     hue.brightness(lightId, 1); 
     break;     
   default:  
     hue.alert(lightId, "lselect"); 
   break; 
 } 
 } 
} 
void connectToWiFi() 
{ 
 int status = WL_IDLE_STATUS; 
 while(status != WL_CONNECTED) { 
   Serial.print("Attempting to connect to Network named: "); 
   Serial.println(ssid);                   // print the network name (SSID); 
   // Connect to WPA/WPA2 network: 
   status = WiFi.begin(ssid, pass); 
 } 
 // print the SSID of the network you're attached to: 
 Serial.print("SSID: "); 
 Serial.println(WiFi.SSID()); 
 // print your WiFi shield's IP address: 
 IPAddress ip = WiFi.localIP(); 
 Serial.print("IP Address: "); 
 Serial.println(ip); 
}                                                                                                                                                          

Here's the critical piece! If we receive a touch on any of the dimmer switch painted lines:

   if(MPR121.isNewTouch(i)){ 
         // if we have a new touch on this electrode... 
         digitalWrite(LED_BUILTIN, HIGH); 
         //Keyboard.press(keyMap[i]); 
         Serial.print("Brightness: "); 
         Serial.println(i); 
         char val=5; 
         itoa(i, &val, 10); 
         mySerial.write(val); 
       } 

We send a value (0 - 5) over serial to the Arduino Due so it can follow the logic in this switch statement:

  switch (level) { 
     case 48:  //48 is actually char '0' in dec '1' = 49..other than increased
               //readability interpreting these as chars didn't make sense
     hue.brightness(lightId, 250); 
     break; 
   case 49: 
     hue.brightness(lightId, 200); 
     break; 
   case 50: 
     hue.brightness(lightId, 150); 
     break; 
   case 51: 
     hue.brightness(lightId, 100); 
     break; 
   case 52: 
     hue.brightness(lightId, 50); 
     break; 
   case 53: 
     hue.brightness(lightId, 1); 
     break;     
   default:  
     hue.alert(lightId, "lselect"); 
   break; 
}

Then depending on which line is touched we send a message to the Philips Hue Bridge indicating that this "lightId" should be set to a specific brightness (1-254).

If you'd like to use this sketch to adjust a group of lights just substitute each

hue.brightness(lightId, 50);

for an...

hue.groupBrightness(groupId, 50); 

and be sure to define the correct groupId at the top of the sketch.

That's it!

You now have everything you need to start painting your own dimmer switches where ever you see fit! Here are couple quick clips of the switch in action.

Here's the first prototype painted on card stock:

First prototype on card stock

Our dimmer switch we painted on the wall in the office!

Dimmer switch in action!

What's next?

These capacitance sensors are great at detecting touch, but they're also capable of detecting proximity! It requires a slightly different painted shape, but in doing so you could adjust the brightness or color of your lights just by waving your hand near the "switch". Stay tuned for a new post with this type of control!

Code

hueDino
An Arduino library for WiFi101 connected devices implementing the Philips Hue API Edit Add topics
Anduino
An Arduino library for the Andium(Anduino) shield. Transform your Arduino into an AndiumNode. Edit

Comments

Similar projects you might like

Distance Measurement Vehicle via Websocket

Project tutorial by Matthew Lee

  • 3,868 views
  • 1 comment
  • 26 respects

Barbot: Cocktail Mixing Robot

Project tutorial by sidlauskas

  • 4,862 views
  • 4 comments
  • 32 respects

RING PONG

Project showcase by aerodynamics

  • 1,843 views
  • 0 comments
  • 8 respects

An Urban Plant Watering Solution

Project tutorial by James Yu

  • 4,397 views
  • 7 comments
  • 18 respects

Electron Music Box Buzzer App

Project tutorial by Iain

  • 543 views
  • 0 comments
  • 3 respects
Add projectSign up / Login