Trigger fotografico portatile v1.0

Ragazzi è con sommo piacere che vi presento il risultato di 3 giorni intensivi di lavoro!
L’ intervallometro\trigger luminoso portatile!
L’oggettino permette di controllare gli scatti di qualsiasi (teoricamente) macchina fotografica che presenta un ingresso per telecomando a filo.
Le modalità di funzionamento sono 2: intervallometro e scatto su rilevazione luminosa.
L’intervallometro permette di far scattare foto ogni tot di secondi, questo permette la creazione di video cosiddetti timelapse.
Il rilevatore luminoso permette, con un po’ di fantasia, svariati utilizzi: è possibile scattare foto con una torcetta, cercare di catturare fulmini ed infine fare foto ad alta velocità con l’ausilio si un laser che viene interrotto dall’oggetto che si vuole scattare.
Il cuore, per ovvi motivi di spazio non è arduino ma un attiny45, ovviamente però è stato programmato con arduino in modalità ISP.
La modalità viene selezionata tramite un potenziometro, alla quale ho associato una scala di valori (vorrei farmi quindi un’etichetta che indica le diverse impostazioni). le prime 3 posizioni servono per indicare la sensibilità della fotoresistenza, mentre le successive aumentano l’intervallo in modalità intervallometro.

Il led rosso è collegato al focus, serve per capire quando viene triggherata la fotocamera.
Il led giallo rimane fisso se si è in modalità fotoresistenza, mentre lampeggia se è in modalità intervallometro.

La batteria è una tonda da 3.3v con piedini presaldati ed è removibile.

queste le foto:
pronto ad essere inscatolato (si lo so, sono artistico nel fare i circuiti):

Inscatolato:

Vista fotoresistenza:

Questo è il codice:

/* Portable photo trigger
created 2011
by Lorenzo Boasso
*/


// pin digitali
int wakePin = 0;
int shotPin = 1;
int ledActivePin = 2;

// pin analogici
int lightPin = 3;
int configPin = 2;

// valori opzionali - più valori si mettono è più sensibile sarà la precisione della selezione
#define LENARRAY 12 // attenzione, questo valore deve corrispondere al numero di elementi dell'array
int confArray[LENARRAY] = {4,30,80,5, 8,15,30,60,180,600,1800,3600};

int ledBlinkWait = 1000; 
int ledState = LOW;

int lightSet = 0;

long prevBlinkMillis = 0;      
long prevShotMillis = 0;       

int prevLight = 0;

int selection = 0;
int wakeInteval = 500; // quanti millisecondi prima dello scatto viene premuti il wake

unsigned long currentMillis = 0;

void setup() {
  
  // CONFIGURAZIONE PIN
  // scatto
  pinMode(wakePin, OUTPUT);
  pinMode(shotPin, OUTPUT); 
  // led
  pinMode(ledActivePin, OUTPUT);
  
  // spengo tutto
  digitalWrite(wakePin, LOW);
  digitalWrite(shotPin, LOW); 
  
  // trigger attivo
  digitalWrite(ledActivePin, HIGH);
  
  currentMillis = millis();
  prevShotMillis = millis();
  prevBlinkMillis = millis();
}

void loop() 
{ 
  selection = analogRead(configPin);
  selection = map(selection,0, 1023, 1, LENARRAY) ;

  currentMillis = millis();

  if (selection <5){ // i primi 4 valori si riferiscono al trigger lumninoso
  
    // modalita fotoresistenza
    digitalWrite(ledActivePin, HIGH);
  
    int lightVal = analogRead(lightPin);
    if ((prevLight - lightVal > confArray[selection]) ||(lightVal - prevLight  > confArray[selection]) ){
      wakeUp();
      delay(100); 
      shot();
      delay(200);
    }
  
    prevLight = analogRead(lightPin);
    
  }else{
    // modalità intervallometro
    blinkLed();
    
    if((currentMillis - prevShotMillis) > ((confArray[selection]*1000)-wakeInteval)) {
       wakeUp();
    }
    
    if((currentMillis - prevShotMillis) > (confArray[selection]*1000)) {
       shot();
    }

  }
  
} 

void wakeUp(){
    digitalWrite(wakePin, HIGH); //turn wakeup/focus on
}

void shot(){
     // save the last time you blinked the LED 
    prevShotMillis = currentMillis;   

    digitalWrite(shotPin, HIGH); //turn wakeup/focus on
    delay(100); //faccio durare qualche istante la pressione del tasto
    
    // rilascrio tutto
    digitalWrite(shotPin, LOW); //turn wakeup/focus on
    digitalWrite(wakePin, LOW); //turn wakeup/focus on
}

void blinkLed(){
  // if the LED is off turn it on and vice-versa:
    unsigned long currentMillis = millis();
    if(currentMillis - prevBlinkMillis > ledBlinkWait) {
      prevBlinkMillis = currentMillis;
      if (ledState == LOW)
        ledState = HIGH;
      else
        ledState = LOW;
        
      // set the LED with the ledState of the variable:
      digitalWrite(ledActivePin, ledState);
    }
}

Ovviamente il codice non è perfetto. Purtroppo non riuscivo più a programmare l’attiny45, quindi mi sono tenuto quello che c’era.

Mi piacerebbe pensare come migliorare ogni aspetto del progetto per farne una versione 2.0 !! Accetto suggerimenti e consigli.

In che senso non riuscivi più a programmare il Tiny? Avevi danneggiato qualche piedino?

leo72: In che senso non riuscivi più a programmare il Tiny? Avevi danneggiato qualche piedino?

L'ha saldato direttamente ai fili, dubito potesse rifare i collegamenti. oppure semplicemente ha cercato di programmarlo lasciando attaccato su almeno uno dei pin MISO, MOSI, SCK qualcosa che li mandava a GND, di fatto ottenendo errore.

leo72: In che senso non riuscivi più a programmare il Tiny? Avevi danneggiato qualche piedino?

Quando tentavo di programmare avevo un errore, diverso dai soliti 2 standard PAGEDEL. Sinceramente non ho indagato ulteriormente e mi sono messo a montare il tutto ! questo comunque è il famoso progetto col piedino di reset che mi faceva impazzire!

Visto sei espertone di attiny, volevo chiederti un parere: se aumentassi a 8khz la frequenza potrei migliorare la risposta ai trigger luminosi?Aumentando la frequenza dovrebbe aumentare le volte che fa girare il main e quindi avere minor margine tra un controllo e l'altro. questo però mi costa anche un aumento di consumo di batteria?

menniti:

leo72: In che senso non riuscivi più a programmare il Tiny? Avevi danneggiato qualche piedino?

L'ha saldato direttamente ai fili, dubito potesse rifare i collegamenti. oppure semplicemente ha cercato di programmarlo lasciando attaccato su almeno uno dei pin MISO, MOSI, SCK qualcosa che li mandava a GND, di fatto ottenendo errore.

No ovviamente mi riferisco ancora alla fase di test, quando ancora non avevo saldato nulla! L'ho programmato e testato diverse volte, poi ad un certo punto non ha più funzionato. Ho provato anche ricaricare anche lo sketch arduinoISP, ma l'errore non cambiava. Magari c'è stato qualche problema con i piedini che ho fatto all'attiny45, perchè effettivamente poi uno si era staccato in fase di saldatura..

Con l'aumento della frequenza aumenta anche leggermente il consumo. Ma alimentandolo a 3,3Vdovresti comunque stare su valori bassi (il datasheet ha delle tabelle di consumo teorico in base al clock ed alla tensione di alimentazione: dagli un'occhiata, ne vale la pena).

lollotek: Magari c'è stato qualche problema con i piedini che ho fatto all'attiny45, perchè effettivamente poi uno si era staccato in fase di saldatura..

Argh.... :cold_sweat: E ti lamenti anche :P :P

leo72: Con l'aumento della frequenza aumenta anche leggermente il consumo. Ma alimentandolo a 3,3Vdovresti comunque stare su valori bassi (il datasheet ha delle tabelle di consumo teorico in base al clock ed alla tensione di alimentazione: dagli un'occhiata, ne vale la pena).

lollotek: Magari c'è stato qualche problema con i piedini che ho fatto all'attiny45, perchè effettivamente poi uno si era staccato in fase di saldatura..

Argh.... :cold_sweat: E ti lamenti anche :P :P

Mica mi lamentavo era solo una constatazione. ancora non sono certo che cosa causava il problema. Comunque appena posso posto anche un video dimostrativo.

lollotek: Mica mi lamentavo era solo una constatazione. ancora non sono certo che cosa causava il problema. Comunque appena posso posto anche un video dimostrativo.

PS: era una battua, la mia, s'intende :)