I decided to make an RGB Arduino powered Wine Bottle Mood Lamp. The lamp uses inexpensive parts and is very easy to make.

The lamp can be controlled via Bluetooth and will cycle through random colors by default.

Components

The lamp uses the following components:

  • Clear wine glass.
  • Small piece of wood.
  • Arduino Nano v3.0 (cheap compatible replica found on ebay).
  • Small plastic box.
  • Cheap RGB LED Strip (from ebay).
  • LM7805 Voltage Regulator.
  • Some small heat sinks and screws.
  • Mosfet transistors.
  • HC-05 Bluetooth module.
  • 12V power supply (2-6 Amp).

Instructions

Instructions for each part of the project can be seen below.

Base

The base construction is fairly simple. I used a wine bottle with the bottom cut off (instructions here). The wine bottle has been secured to the wood with some super glue. Some sticky back Velcro tape (also ebay) is used to secure the electronics box onto the small piece of wood. Using a drill I cut a number of holes in the top of the plasic enclosure in order to allow cooling (the transistors and voltage regulator can get hot).

Electronics

There are many tutorials to control RGB strips with arduino. The RGB strips commonly found on ebay require 9v-12v of power so use of transistors for PWM are required. I also used a voltage regulator as it was easier to add a heat sync too that rather than the arduino. A great instructable can be found here detailing how to control an RGB strip with the arduino. The HC-05 Bluetooth board can be controlled using serial communication. There are plenty of examples of this so I won’t cover it here. I combined the two circuits and then put them on a small breadboard before gluing them in the plastic enclosure.

Android App

I created an android app that allows you to control the lamp and change some settings such as the current color, the amount of time it takes to fade to a new color and the amount of time it will stay on the current color. You can also disable the automatic color switching and keep a steady color. A screenshot of the app can be seen below.

Android Mood Lamp App
Android Mood Lamp App

The android code is rather boring, it uses a very slightly modified version of the Bluetooth example code which can be found here.

Arduino Code

The code I used on the arduino is listed below for reference:

// Required includes.
#include 
// Robot name.
#define ROBOT_NAME "Mood Lamp"
#define VERSION_STRING "V1.3"
// Bluetooth Baud Rate Speed
#define BLUETOOTH_SPEED 57600
#define BLUETOOTH_DELAY_READ 1500
#define INITIAL_DELAY 1500
#define SERIAL_SPEED 9600
// Pins for LED
int redPin = 11;
int greenPin = 10;
int bluePin = 9;
int enableColorChanging = 1;
// RX/TX connections on bluetooth chip 
SoftwareSerial mySerial(5, 6);
/*
The posible baudrates are:
AT+BAUD1-------1200
AT+BAUD2-------2400
AT+BAUD3-------4800
AT+BAUD4-------9600 - Default for hc-06
AT+BAUD5------19200
AT+BAUD6------38400
AT+BAUD7------57600 - Johnny-five speed
AT+BAUD8-----115200
AT+BAUD9-----230400
AT+BAUDA-----460800
AT+BAUDB-----921600
AT+BAUDC----1382400
*/
// Settings for LAMP
// #########################
double currentRed = 0;
double currentGreen = 0;
double currentBlue = 0;
double targetRed = 0;
double targetGreen = 0;
double targetBlue = 0;
double stepRed = 0;
double stepGreen = 0;
double stepBlue = 0;
int steadyGlows = 0;
int changingGlows = 0;
boolean isSetup = false;
boolean isSteady = false;
// #########################
#define SMALL_DELAY 25
// Initial values
#define INITIAL_CHANGE_DURATION 3000
#define INITIAL_GLOW_DURATION 5000
// Speed for a change.
int changeDuration = INITIAL_CHANGE_DURATION;
// Speed for a glow.
int glowDuration = INITIAL_GLOW_DURATION;
// #########################
// Method to set up BlueTooth.
boolean setupBlueToothModule() {
if (!isSetup) {
// Set the Bluetooth Baud Rate.
mySerial.begin(BLUETOOTH_SPEED);
delay(1000);
// Should respond with OK
mySerial.print("AT");
if (!checkResponse("OK")) {
Serial.println("BT Setup: did not get OK responce");
shutdownMethod();
}
// Should respond with its version
mySerial.print("AT+VERSION");
if (!checkResponse("OKlinvorV1.5")) {
Serial.println("BT Setup: did not get expected version responce");
shutdownMethod();
}
// Set pin to 0000
mySerial.print("AT+PIN0000");
if (!checkResponse("OKsetPIN")) {
Serial.println("BT Setup: did not get pin set ok responce");
shutdownMethod();
}
// Set the name to ROBOT_NAME
mySerial.print("AT+NAME");
mySerial.print(ROBOT_NAME);
if (!checkResponse("OKsetname")) {
Serial.println("BT Setup: did not get name set ok responce");
shutdownMethod();
}
// Set baudrate to 57600
mySerial.print("AT+BAUD7");
if (!checkResponse("OK57600")) {
Serial.println("BT Setup: did not get baud rate set responce");
shutdownMethod();
}
}
}
// Set up the LED.
void setupLED() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
// Set a color (DONT CALL DIRECTLY).
void setColor(int red, int green, int blue) {
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
// Set a certain LED colour.
void setColorInstant(int red, int green, int blue) {
currentRed = red;
currentGreen = green;
currentBlue = blue;
targetRed = red;
targetGreen = green;
targetBlue = blue;
stepRed = 0;
stepGreen = 0;
stepBlue = 0;
setColor((int) currentRed, (int) currentGreen, (int) currentBlue);
steadyGlows = 0;
changingGlows = 0;
}
// Set a color gradually.
void setColorGradually(int red, int green, int blue) {
targetRed = red;
targetGreen = green;
targetBlue = blue;
stepRed = ((currentRed - targetRed) / (double) (changeDuration / SMALL_DELAY));
stepGreen = ((currentGreen - targetGreen) / (double) (changeDuration / SMALL_DELAY));
stepBlue = ((currentBlue - targetBlue) / (double) (changeDuration / SMALL_DELAY));
steadyGlows = 0;
changingGlows = 0;
}
// Update a color (This is called after each SMALL_DELAY).
void updateColor() {
setColor((int)currentRed, (int)currentGreen, (int) currentBlue);
if (enableColorChanging) {
if (isSteady) {
steadyGlows++;
if ((steadyGlows * SMALL_DELAY) > glowDuration) {
steadyGlows = 0;
int randomRed = random(256);
int randomGreen = random(256);
int randomBlue = random(256);
setColorGradually(randomRed, randomGreen, randomBlue); 
Serial.println("new random color: " + (String) randomRed + "," + (String) randomGreen + "," + (String) randomBlue);
isSteady = false;
}
} else {
changingGlows++;
if ((changingGlows * SMALL_DELAY) > changeDuration) {
// Done changing.
changingGlows = 0;
steadyGlows = 0;
isSteady = true;
}else {
if ((int) targetRed != (int) currentRed) {
currentRed -= stepRed;
}
if ((int) targetGreen != (int) currentGreen) {
currentGreen -= stepGreen;
}
if ((int) targetBlue != (int) currentBlue) {
currentBlue -= stepBlue; 
}
}
}
}
}
// Shutdown method if all else fails.
void shutdownMethod() {
Serial.print("ERROR: Shutdown loop.");
// Loop and flash red LED.
while(1) {
setColor(255,0,0);
delay(1000);
setColor(0,0,0);
delay(1000);
}
}
// Setup
void setup() {
// Setup the serial (to PC) speed.
Serial.begin(SERIAL_SPEED);
Serial.println("Starting Configuration...");
// Print version.
Serial.println(VERSION_STRING);
// Set up the LED's.
setupLED();
// Try to set up the bluetooth module.
if (!setupBlueToothModule()) {
shutdownMethod();
}
Serial.println("Successfully set up the BT module!");
// Set to blue.
setColorInstant(0, 0, 255);
isSetup = true;
isSteady= true;
delay(INITIAL_DELAY);
}
// Wait for Bluetooth Responce
boolean checkResponse(String expected) {
// Setup and delay.
delay(BLUETOOTH_DELAY_READ);
String readBuff = ""; 
char character;
// Read a string responce.
while (mySerial.available()) {
character = mySerial.read();
readBuff.concat(character);
}
Serial.println("Got: " + readBuff);
// Compare to the expected.
return expected.equals(readBuff);
}
// Get a Bluetooth message
String getMessage() {
// Setup and delay.
String readBuff = ""; 
char character;
// Read a string responce.
while (mySerial.available()) {
character = mySerial.read();
readBuff.concat(character);
}
// Compare to the expected.
return readBuff;
}
// Try to parse a recieved message.
void tryParse(String message) {
int commaIndex = message.indexOf(',');
String command = message.substring(0, commaIndex);
if (command == "set") {
//  Search for the next comma just after the first
int secondCommaIndex = message.indexOf(',', commaIndex+1);
int thirdCommaIndex = message.indexOf(',', secondCommaIndex+1);
String firstValue = message.substring(commaIndex+1, secondCommaIndex);
String secondValue = message.substring(secondCommaIndex+1, thirdCommaIndex);
String thirdValue = message.substring(thirdCommaIndex+1); // To the end of the string
// Get rgb.
int r = firstValue.toInt();
int g = secondValue.toInt();
int b = thirdValue.toInt();
setColorInstant(r, g, b);
Serial.println("set color color: " + (String) r + "," + (String) g + "," + (String) b);
} else if (command == "fade") {
//  Search for the next comma just after the first
int secondCommaIndex = message.indexOf(',', commaIndex+1);
int thirdCommaIndex = message.indexOf(',', secondCommaIndex+1);
String firstValue = message.substring(commaIndex+1, secondCommaIndex);
String secondValue = message.substring(secondCommaIndex+1, thirdCommaIndex);
String thirdValue = message.substring(thirdCommaIndex+1); // To the end of the string
// Get rgb.
int r = firstValue.toInt();
int g = secondValue.toInt();
int b = thirdValue.toInt();
steadyGlows = 0;
changingGlows = 0;
isSteady = false;
setColorGradually(r, g, b);
Serial.println("set fade: " + (String) r + "," + (String) g + "," + (String) b);
} else if (command == "setting") {
//  Search for the next comma just after the first
int secondCommaIndex = message.indexOf(',', commaIndex+1);
int thirdCommaIndex = message.indexOf(',', secondCommaIndex+1);
String firstValue = message.substring(commaIndex+1, secondCommaIndex);
String secondValue = message.substring(secondCommaIndex+1, thirdCommaIndex);
String thirdValue = message.substring(thirdCommaIndex+1);
if (firstValue == "1") {
enableColorChanging = 1;
} else {
enableColorChanging = 0;
}
int speedVal = secondValue.toInt();
int speedValB = thirdValue.toInt();
// Map new values..
changeDuration = map(speedVal, 0, 100, 100, 10000);
glowDuration = map(speedValB, 0, 100, 100, 30000);
steadyGlows = 0;
changingGlows = 0;
isSteady = true;
Serial.println("settings: changeDuration:" + (String) changeDuration + ", glowDuration:" + (String) glowDuration) + ", enabled:" + firstValue;
}
}
void loop() {
if (isSetup) {
delay(SMALL_DELAY);
String readStr = "";
readStr = getMessage();
// Read a string.
if (readStr != "") {
Serial.println(readStr); 
tryParse(readStr);
}
updateColor();
} else {
delay (INITIAL_DELAY); 
}
}

 

Share Button

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *