tekyinblack2
Published © CC BY-SA

Recycled Meter Artwork

Battery powered artwork made from recycled ammeter to hang on your wall

BeginnerShowcase (no instructions)709
Recycled Meter Artwork

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
Replaced with small circuit board to which the Atmel 328 is transferred
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1
5 mm LED: Red
5 mm LED: Red
×2
5 mm LED: Yellow
5 mm LED: Yellow
×2
5 mm LED: Green
5 mm LED: Green
×2
High Brightness LED, White
High Brightness LED, White
×1
Resistor 330 ohm
Resistor 330 ohm
×7
Resistor 10k ohm
Resistor 10k ohm
×2
Resistor 221 ohm
Resistor 221 ohm
×1
LDR, 1 Mohm
LDR, 1 Mohm
×1
1N4007 – High Voltage, High Current Rated Diode
1N4007 – High Voltage, High Current Rated Diode
×1
Capacitor 220 µF
Capacitor 220 µF
×1
Analog Panel Meter, Black Spade Type Pointer
Analog Panel Meter, Black Spade Type Pointer
This was actually a recycled meter which was modified to expose the mechanism
×1

Story

Read more

Schematics

Diagram of breadboarded project

Runs the basic animation of the meter and the light display

Schematic

Code

Wall_Meter_Display.ino

Arduino
Runs a basic light display and is intended to run with very low power consumption for battery operation
#include <Narcoleptic.h>

/*
  WallDisplay - Traffic light
  Creates a basic traffic light display for a wallmount
*/
int voltref = 0;    // hold reference voltage level for low voltage calculations
int demoCount = 0;   // used to run the demo section when first powered up
int Direction = 1;   // sets direction either 0 or 1
int SetDelay = 1; //0=standard delay, 1=NarcoDelay, low power and no serial port usage
unsigned long randInit = 20;  // limits of random number generator, set low for testing
int LDR;          // voltage measured on LDR
int darkLimit = 1000;  // ldr reading for its dark
int lightLimit = 750;  // ldr reading for its light
int timeOfDay = 1;  // time of day set to gloaming so that power on and reset runs full display  0 = night, 1 = gloaming, 2=day
int lightChange = 0;  // count of contiguous light LDR samples
int gloamingChange = 0;   // count of contiguous gloaming LDR samples
int darkChange = 0;   // count of contiguous dark LDR samples
int randLimit = 20;  // limits of random number generator, set low for testing
int delayPeriod = 4000; //inital delay period just in case its needed
int summer = 14970;  // length of longest day in samples
int winter = 7035;  // length of shortest day in samples
int longDayCount = 0;  // approximate length of day in displays
int shortDayCount = 0;  // approximate length of day in displays
int maxDay = 0;  // previous length of light in display cycles
int delayDayCount = 21; // number of display cycles to defer in the morning based on previous days estimated length
int capacitor=2 // pin applying power to capacitor
int LDRpower=3 // pin applying power to ldr
int red1=5;   // 1st red led
int red2=6;   // 2nd red led
int amber1=7;   // 1st amber led
int amber2=8;   // 2nd amber led
int green1=9;   // 1st green led
int green2=10;   // 2nd green led
int whiteled=11; // white led to illuminate meter



// ---------------------------------------------------------------------------------------    
// the setup function runs once when reset it pressed or power the board
void setup() {
  // initialize digital output pins
  //   pin A1
  //   pin A2
  //   pin A3
  pinMode(capacitor, OUTPUT);
  pinMode(LDRpower, OUTPUT);
  pinMode(red1, OUTPUT);
  pinMode(red2, OUTPUT);
  pinMode(amber1, OUTPUT);
  pinMode(amber2, OUTPUT);
  pinMode(green1, OUTPUT);
  pinMode(green2, OUTPUT);
  pinMode(whiteled, OUTPUT);

  longDayCount = (summer - winter) / randLimit;
  shortDayCount = winter / randLimit;
 
  

  randInit = LDRvoltage();
  randomSeed(randInit);          // randomise on light level
  if (SetDelay == 0)     // only run serial output if standard not narco delay
      Serial.begin(9600);
}




// ---------------------------------------------------------------------------------------    
// the loop function runs over and over again forever
void loop() {
int newTimeOfDay;
// only run routine if random comes up otherwise sleep
   
     
    randInit = random(randLimit);
    SerialSub(SetDelay, "Random ", randInit);
// ---------------------------------------------------------------------------------------    
    
    if (delayDayCount < 20)   //  count down non running of display after dawn when no one will be watching
         {
          delayDayCount++;
          randInit=0;    // extend non running after dawn
          SerialSub(SetDelay, "Delay ", demoCount);
         }
// ---------------------------------------------------------------------------------------      
    if (demoCount < 10)   //  demo and test routine runs every time after power on or reset
         {
          demoCount++;
          randInit=1;    // fudge for test functions
          SerialSub(SetDelay, "Demo ", demoCount);
         }
// ---------------------------------------------------------------------------------------   
    if (randInit == 1) 
      {
        voltref = refVoltage();    // get the reference voltage
        LDR = LDRvoltage();   // get light level
        newTimeOfDay = dayOrNight();
        if (timeOfDay != newTimeOfDay)
            timeOfDay = newTimeOfDay;   // swap to new time of day if theres an update
        SerialSub(SetDelay, "timeOfDay", timeOfDay);    
        if (timeOfDay == 0)    // if night then just wait for 4 or 8 seconds
            {
             if (SetDelay == 0)
                 delayPeriod = 4000;   // if standard sleep then fixed to 4 seconds
             else
                 delayPeriod = 8000;  // if narco then sleep extra time
             }
        else
            {    
            Subloop();    // This breakout runs the display
            delayPeriod = 4000;
            }
      }  
    Ndelay(SetDelay, delayPeriod); //  Delay for 'delayPeriod' seconds approximately
}

// ---------------------------------------------------------------------------------------  
int LDRvoltage() {
    digitalWrite(LDRpower, HIGH);     // activate LDR to check light levels
    int LDRread = analogRead(2);
    digitalWrite(LDRpower, LOW);
    SerialSub(SetDelay, "LDRvoltage", LDRread);
    return LDRread;
}


// ---------------------------------------------------------------------------------------  
// Estimate whether it is day, gloaming or night. The unit has to be in one state for at least four iterations before a state change is registered
// the sequence is light, gloaming, dark, light. 
int dayOrNight() {
  int dayLight;
  dayLight = timeOfDay;
  if (lightChange > maxDay)
      maxDay = lightChange;
  if (LDR > darkLimit)   // calulate continuous state
      {
      lightChange = 0;
      gloamingChange = 0;
      darkChange++;
      }   
    else if (LDR < lightLimit) 
      {
      lightChange++;
      gloamingChange = 0;
      darkChange = 0;
      }  
    else 
      {
      lightChange = 0;
      gloamingChange++;
      darkChange = 0;
      }  
  if (lightChange >10)   // after state the same for four iterations return a change
       dayLight = 2;
       else if (gloamingChange > 10)
                dayLight = 1;
       else if (darkChange > 10)
                dayLight = 0;
  if (timeOfDay == 0 and dayLight==1) // do not allow change from dark to gloaming
      dayLight = 0;        
  SerialSub(SetDelay, "DayOrNight", dayLight);
  return dayLight;        
}


// ---------------------------------------------------------------------------------------  
// get reference voltage for low battery compensation
int refVoltage() {
    digitalWrite(red1, HIGH);
    int readVoltage = analogRead(3);
    digitalWrite(red2, LOW);
    SerialSub(SetDelay, "voltref", readVoltage);
    return readVoltage;
}


// ---------------------------------------------------------------------------------------  
// Return capacitor voltage
int capVoltage() {
    int readVoltage = analogRead(1);
 //   SerialSub(SetDelay, "CapVoltage", readVoltage);
    return readVoltage;
}


// ---------------------------------------------------------------------------------------  
// routine to charge capacitor 
void chargeCap() {
  if (timeOfDay == 1)
      digitalWrite(whiteled, HIGH);     // activate meter illumination
     Ndelay(SetDelay, 300); // wait for 300 milliseconds to attract attention    
  do {
   digitalWrite(capacitor, HIGH);  // start to charge capacitor
   Ndelay(SetDelay, 100); // wait for 100 milliseconds for capacitor to charge
  } while (capVoltage()<800);
  Ndelay(SetDelay, 200); // wait for 200 milliseconds for capacitor to display
   digitalWrite(capacitor, LOW);  // stop charging  
}


// ---------------------------------------------------------------------------------------  
// routine to reverse directiion setting
void reverseDirection() {
    if (Direction == 1)    // reverse previous light direction
  {
    Direction = 2;
  }
  else
  {
    Direction = 1;
  }
}
// ---------------------------------------------------------------------------------------  
// Main display loop
void Subloop() {

// Start by charging capacitor
chargeCap();

// Reverse previous direction to keep variations
  reverseDirection();

// run light display until capacitor runs down
// routine only runs LEDs if gloaming when viewers are likely to see it
  do {     
      if (Direction == 1 and timeOfDay == 1)
      {
        Traffic1();    // run forward light run
      }
      if (Direction == 2 and timeOfDay == 1)
      {
        Traffic2();    // run reverse light run
      }
      if (timeOfDay == 2)
          Ndelay(SetDelay, 1000); //add time delay omitted due to not running lights
      if (random(20) == 1) // Add restart to cap voltage to give random extended displays
          { 
          chargeCap();
          reverseDirection();
          }
  }  while (capVoltage() > 50);
      
      digitalWritewhiteled, LOW);      // turn off meter illumination when done
}


// ---------------------------------------------------------------------------------------  
// One of two LED driver routines which switch on LEDs according to the voltage on the capacitor
void Traffic1()
{
  int light = capVoltage();


  if (light > 60)
  {
    digitalWrite(red1, HIGH);   // Turn on red
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 80)
  {
    digitalWrite(red2, HIGH);   // turn on red
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 120)
  {
    digitalWrite(amber1, HIGH); // Turn on anber
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 200)
  {
    digitalWrite(amber2, HIGH);   // Turn on amber
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 320)
  {
    digitalWrite(green1, HIGH);   // turn on green
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 580)
  {
    digitalWrite(green2, HIGH); // Turn on green
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  digitalWrite(red1, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(red2, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(amber1, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(amber2, LOW);
  Ndelay(SetDelay, 100);;
  digitalWrite(green1, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(green2, LOW);

}


// ---------------------------------------------------------------------------------------  
// One of two LED driver routines which switch on LEDs according to the voltage on the capacitor
// This one works in the opposite direction to the first
void Traffic2()
{
  int light = capVoltage();


  if (light > 60)
  {
    digitalWrite(10, HIGH);   // Turn on green
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 80)
  {
    digitalWrite(9, HIGH);   // turn on green
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 120)
  {
    digitalWrite(8, HIGH); // Turn on amber
    Ndelay(SetDelay, 100);; // wait for 100 milliseconds
  }
  if (light > 200)
  {
    digitalWrite(7, HIGH);   // Turn on amber
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 320)
  {
    digitalWrite(6, HIGH);   // turn on red
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  if (light > 580)
  {
    digitalWrite(5, HIGH); // Turn on red
    Ndelay(SetDelay, 100); // wait for 100 milliseconds
  }
  digitalWrite(10, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(9, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(8, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(7, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(6, LOW);
  Ndelay(SetDelay, 100);
  digitalWrite(5, LOW);

}


// ---------------------------------------------------------------------------------------  
// General delay routine which can switch between barco delay and standard for testing
void Ndelay(int delaytype, int period)
{
  if (delaytype == 0)
  {
    delay(period);
  }
  else
  {
    Narcoleptic.delay(period);
  }
}


// ---------------------------------------------------------------------------------------  
// Serial output routine runs during testing
void SerialSub(int delaytype, char stringy[20], int value)
{
  if (delaytype == 0)
  {
    Serial.print(stringy);
    Serial.println(value);
  }
 
}

Credits

tekyinblack2

tekyinblack2

0 projects • 1 follower

Comments