Sida 1 av 1

mini-projekt: Ljustimer till skytte

Postat: 30 december 2012, 01:55:01
av amfitony
Hej EF!

Har tänkt dela med mig av ett mini-uppdrag jag fick av en kollega som ville ha en timer för att få ett stressmoment när han tränar skytte.

Väldigt enkelt med andra ord men tog ändå lite tid att få till. Tänkte lägga upp det här för allmän beskådan ifall att någon vill hitta nått tok i koden, ha nytta
av den själv eller få inspiration.

Uppbyggt med en arduino och en hemmagjord RGB-shield som också har en potentiometer ombord för tidsinställning.

Bild

Hade lite stift liggandes som användes till att göra ben till RGB-LEDen, experimentplattan håller dom på plats under lödningen.

Bild

Allting ihoplött o klart. Två NPN-transistorer för att driva lysdioden som är på 3x1W.

Bild

Ihopmonterat.

Gjorde en usel video för att visa hur sekvensen ser ut på ett ungefär
Spelade in med webbkamera som autokorrigerade för ljus, är skillnad på orange och röd irl. Visar också hur färgskala används för att(grovt) indikera potentiometer värde.

Kod: Markera allt

/*

Tony Björkman

2012-12-30

Marksmanship Competition Timer v.1

RGB led and potentiometer connected

The program runs a timed sequence with different light-colour and blinking.

Timing is set by turning the potentiometer. When the potentiometer is turned, the LEDs changes instantly to
show a colourscale of the potentiometer value.

The sequence is: green (user selectable) - green blink (3s) - red (2s) - red blink (3s) - orange blink (3sek) - green.
*/



#define GREEN 1                  //this makes the text GREEN represent the value 1.
#define ORANGE 3
#define RED 2
#define BLINK_TIME 3000         //Duration of the blinking in milliseconds
#define NUM_BLINKS 3            //Number of blinks(last blink starts the new colour).

int time;    //time until colour change
int pot;    //value of potentiometer
int prevSensor;  //previous value of the potentiometer (to compare to detect change)
long prevM;      //prev Millis(). a starting point from where we can calculate elapsed time.
byte colour=1,G_int,R_int;  //colour state, Green led intensity, Red led intensity
byte fade;                //fade both LEDs with the same amount to make blinking


/*= SETUP - Always runs first =*/
void setup() {
 
pinMode(3, OUTPUT);               //Set pin 3 (green led) as output
pinMode(5, OUTPUT); 

pot = analogRead(A0);             //initialise with the colour green
changeColour(GREEN); 
}  //goes to the main loop when done.


/*has some one been turning on the potentiometer since the last
time it was checked?*/
boolean sensorChange () {
  int a;
  pot = analogRead(A0);      //reads the voltage on pin A0. pot gets a value between 0 and 1024.
  
      if(prevSensor < 20)    //needed to prevent comparison with a negative number.
      int a = prevSensor;
      else
      a = 20;              
  
      if(pot > prevSensor + 20 || pot < prevSensor - a){       //the change on the potentiometer needs to be +-20
      prevSensor = pot;                                      //else it will detect noise as a change.
      return true;                                          //return the value true to be used in another function.
     
      }                        //if there was no change, return false.
      else
      return false;
}

/*if a change is detected, light up the leds for 0,5s in a colour according to the pot value*/
void sensor() {
 
  if(sensorChange()){        //run the sensorChange function, if it returns true, then:
  
    prevM = millis();        //resets elapsed count
    
         while(millis() - prevM < 500){    //if 500ms has elapsed
         
         analogWrite(3, 255-pot/4);    //sets a new PWM value on the led output.
         analogWrite(5, pot/4);        //this changes the ratio between green and red light.
        
           if(sensorChange())
             prevM = millis();        //resets the elapsed count if another change is made.
        }
    
    colour=GREEN; 
    changeColour(colour); 
    }
    
}


/*updates the PWM output on pin 3 and 5*/
void updateLED(){

  analogWrite(3, (G_int*fade)/255);    //green LED. 
  analogWrite(5, (R_int*fade)/255);    //red LED
  
}


/*== MAIN LOOP==*/
void loop() {

   
     sensor();          //funtion for detecting potentiometer change and changing LED light accordingly
  
     if(millis() - prevM > time) {  //if a color has run out of time, change to next colour.
     
     colour++;
       
       if(colour > 3)            //colors are values 1-3. should loop around these values. 
       colour = 1;
       
     changeColour(colour);  
     prevM = millis();          //saves current system time. used later to count time elapsed since this point.
     }
     
     
     fade = 255;              //normal fade is no fade at all.
     
     if(millis() - prevM > time - BLINK_TIME)    //if the colour has less then 3 sek left, start blinking.
     fade = abs(255*cos(((NUM_BLINKS-0.5)*PI*((millis() - prevM)-time+BLINK_TIME))/BLINK_TIME));    //cos function.
       
     updateLED();  //now when colour and fade is decided, change LEDs accordingly.
}

void changeColour(byte colour2){          //colour2 is a local(temporary) variable that carries the input parameter.
  
  
   if(colour2 == GREEN){
    G_int = 255;              //intensity of LED
    R_int = 0;
    time = pot*15 + 3200;    //time the colour is active. here it is potentiometer value(0-1024ms)*15 + 3200 ms.
    
   }
   else if(colour2 == ORANGE){
    G_int = 80;
    R_int = 255;
    time = 4000;
   }
   else if(colour2 == RED){
    G_int = 0;
    R_int = 255;
    time = 5000;
   }
 
}
Eftersom min gode vän som ska ha detta inte har hållt på nånting med programmering men är intresserad så har jag sett till att kommentera så att han ska frestas att börja.
Mycket möjligt att orange färgen är helt onödig iom att blinkningen visar att färgen är påväg att bytas. Men får se vad "kunden" säger efter semestern :)