Monday, April 21, 2014

Moody Tubes - Vacuum tubes to set your mood!

This is an ornament made of old vacuum tubes and some basic electronics including LEDs, Arduino and resistors.







Features:

- Three tubes which slowly change colors.
- Integrated battery meter. Right after power up, it measures its own battery level and shows the level by graduating one of the tubes from Green(full) to Red(needs recharging). If at any point battery goes below threshold levels, it will go into "blink-red" mode and will refuse to do its coloring thing.
- Potentiometer for manual adjustments.
- A battery. I used a Lipo 11.1, 2500mAh battery which was almost gone for trash because it couldn't serve my airplanes anymore.


Materials required:

- A suitable box
- Vacuum tubes (don't need to be in working condition, just need to look pretty)
- RGB LEDs (One per tube)
- 330ohm resistors (15 of them or a resistor array as I used)
- Your favorite micro-controller (I went for an ATMEL Atmega 328).
- A 5v regulator
- A potentiometer (may be even buttons or an IR sensor)

Plan for it


Assemble the hardware. 




Leds are hot glued underneath the tubes:



Consider from my design that the three LEDs are in parallel, which means they show the exact same color at all times. The only one that's different is the center one, where I added an orange led for a cleaner orange tone.



Also consider that LEDs can be turned ON or OFF independently, reason why instead of a common ground connection they go to digital output pins. This also means that to power up each LED you need to bring that ground pin to LOW.


Let's take a closer look at the power regulator:



Pick your colors.

I wrote some code to manually change each color so I could visualize the mix I liked the best, and wrote those values down.


Enjoy your relaxing toy.


Use the potentiometer to increase or decrease the speed at which colors change. I went from somewhat fast all the way down to super-super slow. It will take several minutes to change to the next color. This is for a more realistic approach.

Arduino Code



// PIN DEFINITION
int redPin = 9;
int greenPin = 10;
int bluePin = 11;
int orangePin = 6;
int tubesmaPin =5;
int tubelarPin = 4;
int tubemedPin = 3;
int potPin = A2;
int buttonPin = 7;
int battPin = A1;
// OTHER VARIABLES
int maxbattery = 283;  // reading at which the battery is at 12.3V, which we consider full capaciity.
int minbattery = 244;  // reading at which the battery is at 10.8V, level at which we will consider the battery needs urgent recharging.
int boot_check = 1;
long previousMillis = 0;        // will store last time LED was updated
int redvalue = 0;  // Stores the current value of the color
int greenvalue = 0;
int bluevalue = 0;
int orangevalue = 0;
int potenciometro;
int transitfinished =0;
// __________________________________________________________________________________________________________________________________________________________________
void setup()
{
  Serial.begin(9600);
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(orangePin, OUTPUT);
  pinMode(tubesmaPin, OUTPUT);
  pinMode(tubelarPin, OUTPUT);
  pinMode(tubemedPin, OUTPUT);
  pinMode(potPin, INPUT);
  pinMode(buttonPin, INPUT);
  shutdown_tubes();
}
// __________________________________________________________________________________________________________________________________________________________________
void loop()
{
  go_automatic();
  //check_voltage();
  //while(digitalRead(buttonPin)) { go_manual(); }
  //show_dead_battery();
  //delay(1000); // delay after the press of the button
  //while (digitalRead(buttonPin)){ go_automatic();}
  //delay(1000);
}
// __________________________________________________________________________________________________________________________________________________________________
// __________________________________________________________________________________________________________________________________________________________________
/*
System health functions
*/
// __________________________________________________________________________________________________________________________________________________________________
void check_voltage() // blinks one tube with the status of the battery: Green = 12.4v, Red is below 11.1v and needs recharging
{
  int battvalue = 0; // stores the reading on the battery
  battvalue = analogRead(battPin);
  battvalue = map(battvalue,minbattery,maxbattery,0,255);
  if (battvalue<0) battvalue = 0;
  if (battvalue>255) battvalue = 255;
  Serial.print("battvalue:");
  Serial.println(battvalue);
  if (battvalue<1) show_dead_battery();
  if (boot_check == 1)  //Does this only once when booting.
    {
      shutdown_tubes();
      // green = full, red = depleted.
      setColor(255-battvalue,battvalue,0,0);
      digitalWrite(tubesmaPin,LOW); // Activates the small tube
      delay(2000);
      digitalWrite(tubesmaPin,HIGH); // Shuts the tube down
      delay(500);
      setColor(0,0,0,0);
      boot_check = 0;
    }
}
// __________________________________________________________________________________________________________________________________________________________________
void show_dead_battery()  // Breathes red tube FOR EVER, nothing else.
{
  shutdown_tubes(); // Shuts all the tubes down
  setColor(0,0,0,0);
  digitalWrite(tubesmaPin,LOW); // Activates the small tube by bringing the cathode LOW.
  int destination = 255;
  while(1)
  {
      if (redvalue==0) destination = 255;
      transit_color(3,destination,0,0,0);
      if (redvalue==255) destination = 0;
  }
}
// __________________________________________________________________________________________________________________________________________________________________
/*
Functions involving LED activity
*/
// __________________________________________________________________________________________________________________________________________________________________
void setColor(int red, int green, int blue, int orange)
{
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
  analogWrite(orangePin, orange);
  // let's reflect the current values in the variables
  redvalue=red;
  greenvalue=green;
  bluevalue=blue;
  orangevalue=orange;
}
// __________________________________________________________________________________________________________________________________________________________________
void transit_color(int transitspeed, int red, int green, int blue, int orange)
{
  unsigned long currentMillis = millis();
  if((currentMillis - previousMillis) > transitspeed) //If transitspeed = 12 implies approx 3 sec in raising a led from 0 to 255
    {
        // save the last time I adjusted the LEDs
        previousMillis = currentMillis;
        if (redvalue<red) redvalue++;
        if (redvalue>red) redvalue--;
        if (greenvalue<green) greenvalue++;
        if (greenvalue>green) greenvalue--;
        if (bluevalue<blue) bluevalue++;
        if (bluevalue>blue) bluevalue--;
        if (orangevalue<orange) orangevalue++;
        if (orangevalue>orange) orangevalue--;
        setColor(redvalue,greenvalue,bluevalue,orangevalue);
        if (redvalue==red && greenvalue==green && bluevalue==blue && orangevalue==orange) transitfinished = 1;
    }
}
// __________________________________________________________________________________________________________________________________________________________________
void shutdown_tubes() // Shuts the tubes to dark by raising the cathode to high so no current flows regardles of the RGB pins
{
  digitalWrite(tubesmaPin,HIGH);
  digitalWrite(tubemedPin,HIGH);
  digitalWrite(tubelarPin,HIGH);
  setColor(0,0,0,0);
}
/*
Blinking and Color Routines
*/
// __________________________________________________________________________________________________________________________________________________________________
void go_automatic()
{
  breathe(255,0,140,0);
  breathe(0,255,160,0);
  breathe(255,30,0,255);
  breathe(150,10,255,0);
  breathe(0,0,255,0);
  breathe(0,0,0,255);
  breathe(0,0,255,255);
}
// __________________________________________________________________________________________________________________________________________________________________
void go_manual()
{
  while(digitalRead(buttonPin))
    {
      potenciometro = analogRead(potPin);
      redvalue = map(potenciometro, 0, 1023, 0, 255);
      Serial.print("red:");
      Serial.println(redvalue);
      setColor(redvalue, greenvalue, bluevalue, orangevalue);
    }
  delay(500);
  while(digitalRead(buttonPin))
    {
      potenciometro = analogRead(potPin);
      greenvalue = map(potenciometro, 0, 1023, 0, 255);
      Serial.print("green:");
      Serial.println(greenvalue);
      setColor(redvalue, greenvalue, bluevalue, orangevalue);
    }
  delay(500);
  while(digitalRead(buttonPin))
    {
      potenciometro = analogRead(potPin);
      bluevalue = map(potenciometro, 0, 1023, 0, 255);
      Serial.print("blue:");
      Serial.println(bluevalue);
      setColor(redvalue, greenvalue, bluevalue, orangevalue);
    }
  delay(500);
    while(digitalRead(buttonPin))
    {
      potenciometro = analogRead(potPin);
      orangevalue = map(potenciometro, 0, 1023, 0, 255);
      Serial.print("orange:");
      Serial.println(orangevalue);
      setColor(redvalue, greenvalue, bluevalue, orangevalue);
    }
  delay(500);
}
// __________________________________________________________________________________________________________________________________________________________________
void breathe(int red, int green, int blue, int orange)
{
  transitfinished=0;
  while (transitfinished==0)
  {
    potenciometro = analogRead(potPin);
    potenciometro = map(potenciometro,0,1023,6000,10); // Sets the transition speed with the potentiometer
    transit_color(potenciometro,red,green,blue,orange);
    check_voltage();
    digitalWrite(tubesmaPin,LOW);
    digitalWrite(tubemedPin,LOW);
    digitalWrite(tubelarPin,LOW);
  }
}
// __________________________________________________________________________________________________________________________________________________________________