/* ArduLapse 1.0 by Praz2004 * Ardulapse è il mio primo tentativo di utilizzare un Arduino e una fotocamera digitale per realizzare * scatti a intervalli di tempo predefiniti, allo scopo di creare filmati cosiddetti "in Time Lapse". * La fotocamera è azionata meccanicamente da un servocomando da modellismo che per mezzo di una leva aziona * il pulsante di scatto. Lo sketch gestisce le due azioni di messa a fuoco e di scatto; il tempo fra gli scatti * è impostabile fino a 255h 59' 59" con risoluzione di un secondo. * Lo stato di funzionamento è indicato da un display LCD 16x2 e due LED, uno per la messa a fuoco e uno per * lo scatto. L'impostazione delle posizioni del servo donno impostabili tramite i pulsanti della "shield" * realizzata per fornire l'interfaccia utente. Maggiori dettagli su * http://digilander.libero.it/praz2004 * * SCHEMA SHIELD ARDULAPSE * HD44780 * .---. * ARDUINO BOARD .-------| o |1 * .---. | 2| o-|--+-------. * GND| o-|--------------------------------------------------------------' .--|-o |3 | .-. * 12| o-|-------------------------------------------------------------------' 4| o |--)----->| |10k * 11| o-|-------------------------------------------------------------------. 5| o |--)--. | |POT * 10| o-|-----------------------------------------------------------------. '--| o |6 | | '-' * 9| o-|----------------------------------------------------------. | | o |7 | | | * 8| o-|---------------------------------------------------. | | | o |8 | '----+ * 7| o-|--------------------------------------------. | | | | o |9 | | * 6| o-|-------------------------------------. | | | | | o |10| === * 5| o-|-------------------------------------)------)------)------)------)----|-o |11| GND * 4| o-|-------------------------------------)------)------)------)------)----|-o |12| * 3| o-|-------------------------------------)------)------)------)------)----|-o |13| * 2| o-|-------------------------------------)------)------)------)------)----|-o |14| * | | | | | | | '---' | * | | | | | | | | * | | | | | | | .---. | * | | | | | | '----|-o | | * | | | | | | SERVO | o-|--+ * | | | | | | MOTOR | o | | * | | | | | | '-|-' | * | | | | | | | | * | | ___ 220 | | | | ___ 10K | | * A3| o-|----|___|-----------------. +------)------)------)----|___|----+ | * | | ___ 220 | | | | | ___ 10K | | * A2| o-|----|___|------------. | | +------)------)----|___|----+ | * | | ___ 220 | | | | | | ___ 10K | | * A1| o-|----|___|-------. | | | | +------)----|___|----+ | * | | ___ 220 | | | | | | | ___ 10k | | * A0| o-|----|___|--. | | | | | | +----|___|----+ | * | | |LED1|LED2|LED3|LED4 | o | o | o | o | | * | | V -> V -> V -> V -> |=|> |=|> |=|> |=|> === | * | | - - - - | o | o | o | o GND | * | | | | | | SW2 | SW3 | SW4 | SW1 | | * GND| o-|-----------+----+----+----' | | | | | * +5V| o-|-------------------------------------+------+------+------+------------------' * '---' * *--------------------------------------CODICE SKETCH------------------------------------ */ // include il codice delle librerie: #include #include #include //--------------------------DEFINIZIONI COSTANTI----------------------------------------- const int SW1 = 9; // pin al quale è collegato il pulsante SW1 const int SW2 = 6; // pin al quale è collegato il pulsante SW2 const int SW3 = 7; // pin al quale è collegato il pulsante SW3 const int SW4 = 8; // pin al quale è collegato il pulsante SW4 const int led1 = A0; // pin al quale è collegato il LED1 const int led2 = A1; // pin al quale è collegato il LED2 const int led3 = A2; // pin al quale è collegato il LED3 const int led4 = A3; // pin al quale è collegato il LED4 //--------------------------DEFINIZIONI VARIABILI---------------------------------------- boolean runflag = false; // flag per il timer, 0=stop, 1=run byte lapsemin = 0; // variabile minuti fra uno scatto e il succesivo byte lapsesec = 0; // variabile secondi fra uno scatto e il succesivo byte lapsehrs = 0; // variabile ore fra uno scatto e il succesivo byte focuspos = 0; // memorizza la posizione del servo per la funzione di messa a fuoco byte shutterpos = 0; // memorizza la posizione del servo per la funzione di scatto int framenumber = 0; // numero di immagini acquisite dallo start unsigned long elapsedsecs; // secondi trascorsi dall'accensione unsigned long nextframesecs = 0; // secondi in cui avverrà lo scatto successivo unsigned long prev_millis = 0; // variabile ausiliaria per il timer Servo myservo; // crea l'oggetto servo byte pos = 0; // variable per memorizzare la posizione del servo // initializza la libreria per il controllo del display lcd LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(SW1, INPUT); pinMode(SW2, INPUT); pinMode(SW3, INPUT); pinMode(SW4, INPUT); lcd.begin(16, 2); // inizializza il display LCD lcd.print("ArduLapse 1.0"); longdelay(); lapsehrs = EEPROM.read(1); //Legge il dato dall'indirizzo 1 della EEPROM interna al controller lapsemin = EEPROM.read(2); //Legge il dato dall'indirizzo 2 della EEPROM interna al controller lapsesec = EEPROM.read(3); //Legge il dato dall'indirizzo 3 della EEPROM interna al controller focuspos = EEPROM.read(4); //Legge il dato dall'indirizzo 4 della EEPROM interna al controller shutterpos = EEPROM.read(5); //Legge il dato dall'indirizzo 5 della EEPROM interna al controller } void loop() { if (digitalRead(SW1)) { longdelay(); if (digitalRead(SW1)) settings(); //avvia la funzione alla pressione lunga di SW1 } if (!runflag && digitalRead(SW2)) { lcd.setCursor(0,1); lcd.print(" Single frame "); //in modo stop, premendo SW2 si scatta una foto take_a_frame(); lcd.clear(); } if (!runflag && digitalRead(SW3)) { lcd.setCursor(0,1); lcd.print("Focus pos. test"); longdelay(); myservo.attach(10); digitalWrite(led1,HIGH); myservo.write(focuspos); while(!digitalRead(SW3)); lcd.setCursor(0,1); lcd.print(" Shot pos. test "); longdelay(); digitalWrite(led2,HIGH); //in modo stop, premendo SW3 si verificano le posizioni di messa a fuoco e scatto myservo.write(shutterpos); shortdelay(); while(!digitalRead(SW3)); myservo.write(0); shortdelay(); myservo.detach(); digitalWrite(led1,LOW); digitalWrite(led2,LOW); lcd.clear(); } if (digitalRead(SW4)) { //SW4 avvia/ferma il timer runflag = !runflag; lcd.setCursor(0,0); if(runflag) lcd.print(" RUN "); else { lcd.print(" STOP "); longdelay(); } nextframesecs = elapsedsecs; framenumber = 0; shortdelay(); } if (runflag) { if (elapsedsecs > nextframesecs) take_a_frame(); lcd.setCursor(0,0); lcd.print(" RUN "); lcd.setCursor(0,1); lcd.print("Tr:"); lcd.print(nextframesecs - elapsedsecs); //secondi rimanenti allo scatto successivo lcd.print(" F#:"); lcd.print(framenumber); lcd.print(" "); } else { lcd.setCursor(0,0); lcd.print("ST/st + - Set"); } if ((millis() - prev_millis) > 1000) { //Se è trascorso almeno un secondo dalla elaborazione precedente prev_millis += 1000; //incrementa variabile elapsedsecs++; //incrementa variabile } } void shortdelay() { delay (500); } void longdelay() { delay(1500); } void take_a_frame() { myservo.attach(10); // l'oggetto myservo agisce sul pin 10 al quale è collegato il pin di controllo del servo digitalWrite(led1,HIGH); // accende il LED1 myservo.write(focuspos); // porta il servo in posizione di messa a fuoco longdelay(); // ritardo di 1500ms per la messa a fuoco digitalWrite(led2,HIGH); // accende il LED2 myservo.write(shutterpos); // porta il servo in posizione di scatto shortdelay(); // clic! myservo.write(0); // riporta il servo in posizione di standby shortdelay(); myservo.detach(); // Rilascia il pin 10 per evitare che il servo "scricchioli" durante il tempo di standby digitalWrite(led1,LOW); // spegne il LED1 digitalWrite(led2,LOW); // spegne il LED2 nextframesecs += long(lapsehrs * 3600L + lapsemin * 60L + lapsesec); //calcola il tempo dello scatto successivo framenumber++; // incrementa il contatore degli scatti } void settings() { lcd.clear(); lcd.setCursor(0,0); lcd.print("Focus pos: "); focuspos = setvalue(focuspos,90, true); //imposta la posizione focus EEPROM.write(4,focuspos); //memorizza in EEPROM lcd.setCursor(0,0); lcd.print("Shutter pos:"); shutterpos = setvalue(shutterpos,90,true); //imposta la posizione scatto EEPROM.write(5,shutterpos); //memorizza in EEPROM lcd.setCursor(0,0); lcd.print("TL hours: "); lapsehrs = setvalue(lapsehrs, 255, false); //imposta il tempo fra gli scatti (ore) EEPROM.write(1, lapsehrs); //memorizza in EEPROM lcd.setCursor(0,0); lcd.print("TL minutes: "); lapsemin = setvalue(lapsemin, 59, false); //imposta il tempo fra gli scatti (min) EEPROM.write(2, lapsemin); //memorizza in EEPROM lcd.setCursor(0,0); lcd.print("TL seconds: "); lapsesec = setvalue(lapsesec, 59, false); //imposta il tempo fra gli scatti (sec) EEPROM.write(3, lapsesec); //memorizza in EEPROM } byte setvalue(byte initvalue, byte maxvalue, boolean svpos) { myservo.attach(10); while(digitalRead(SW1)); while(!digitalRead(SW1)) { if (digitalRead(SW2)) initvalue--; if (digitalRead(SW3)) initvalue++; if(initvalue > maxvalue) initvalue = maxvalue; lcd.setCursor(0,1); lcd.print(" + "); lcd.print(initvalue); lcd.print(" - "); if(svpos) myservo.write(initvalue); shortdelay(); } myservo.detach(); return initvalue; }