Nu op het Weblog

Nu op het fotoblog

Nu op het Videoblog

Nu op het Muziekblog

Nu op het Kookblog

Nu op het Liveblog

27 mei 2010

Afstandsbediening voor Nikon met interval timer (concept II)





p.s Filmpje heeft een paar buggy overgangen. Geen idee waar die vandaan komen?! Simpel filmpje dus iMovie gebruikt.

Vervolg op dit ->

Heb weer eens mijn soldeerbout en Dremel ter hand genomen.

Op dit moment dus een functioneel kastje in mijn bezit. Nog lang niet tevreden, maar het werkt!

Het ding heb ik uitgerust met twee IR LED's. Ik heb nog niet de ruimte gevonden om het helemaal goed te testen, maar het bereik is mininimaal 15 meter.

Het is redelijk makkelijk in gebruik, heeft in ieder geval alle functie van de originele afstandsbediening van Nikon. Kan nu dus ook s'nacht lange sluitingstijden gebruiken zonder dat ik de ontspanner ingedrukt hoef te houden!

Met de originele Nikon afstandsbediening kun je op de D60, voor andere modellen weet ik het niet, twee seconden ontspanningsvertraging instellen (lijkt mij net te weinig om de afstandsbediening weg te werken als je een foto van je zelf zou willen maken). Met die van mij in principe een oneindige vertraging.

De interval functie heet de originele Nikon afstandsbediening niet.

Het videodoosje is makkelijk aan mijn statief te bevestigen als ik de interval functie wil gebruiken.

De totale prijs tot nu toe:

* Arduino 26,18 euri (De Arduino is te vervangen voor enkel en alleen de ATMega328 chip met een paar andere componenten)
* Een perforatiebordje 1,65 euri
* Vijf weerstanden (drie 220ohm voor de LED's twee 10k voor de schakelaars) a 0.05 cent stuk dus * 0,25 euri (Dick Best ->)
* Drie ledjes a 0.05 cent stuk dus 0,15 euri (Dick Best ->)

Totaal dus rond de 28,23 euri. Ik reken de tin (ooit eens gratis 250 gram ergens gekregen) en draadjes (uit oude VGA kabels etc. gesloopt) ook niet mee.

In vergelijk met de originele Nikon ML13 helemaal niet zo gek. Vooral niet als je kijkt wat voor functies ik extra heb. DIY loont dus in dit geval goed!

De rest van de onderdelen ergens uit kunnen slopen. Weerstanden waren ook niet echt nodig had ik ook nog tweede hands liggen. Maar wie het breed heeft laat het breed hangen! Voor de IR LED's trouwens wel een tweede hands 100k gebruikt.


Detail opname 1


Detail opname 2



Schema (Niet de mooiste. Heb het progsel Fritzing uitgeprobeerd. Het idee ervan is leuk, van breadboard naar PCB, maar de uitwerking?!?!?! Ik had helaas niet genoeg Deutsche scheldwoorden in mijn repetoire om met enige nut het programma te laten doen wat ik wou).

De code tot zover. Het is nog niet van comments voorzien omdat ik nog lang niet tevreden ben. Denk dat ik de helft nog efficienter kan herschrijven, onderstaande is fout op fout stapelen tot het werkt.


#include <NikonRemote.h>

//HARDWARE
const int intervalometerPotmeter = 0;
const int ontspannerSchakelaar = 4;
const int bewegingsensorSchakelaar = 7;
const int intervalometerSchakelaar = 8;
const int powerLed = 9;
const int intervalometerLed = 10;
const int bewegingsensorLed = 11;
const int irLed = 12;

int ontspannerStatus = HIGH;
int bewegingsensorStatus = LOW;
int intervalometerStatus = LOW;

//VARIABELEN
long interval = 0;
long laatsteFoto = 0;

int instellingTimer = 0;

int instelFunctieIntervalometerGeinitieerd = 0;
int instelFunctieIntervalometerBezig = 0;
int intervalometerIngesteld = 0;
int intervalometerReset = 0;

int instelFunctieOntspannerGeinitieerd = 0;
int instelFunctieOntspannerBezig = 0;
int ontspannerIngesteld = 0;
int ontspannerResetSignaal = 0;

long ontspannerSchakelaarTellerWaarde = 0;
long ontspannerSchakelaarTellerLaatsteStaat = 0;
long ontspannerSchakelaarTellerStaat = 0;
long ontspannerSchakelaarTellerGereset = 0;

long ontspannerVertraging = 0;

int instelTimer = 0;

int escapeLoop = 0;

int ontspannerVertragingIntervalometer = 0;

int standaardStaat = 0;
int ontspannerStaat = 0;
int intervalometerStaat = 0;
int bewegingsensorStaat = 0;
int stelOntspannerIn = 0;
int stelIntervalometerIn = 0; 

NikonRemote camera(irLed);

//SETUP
void setup(){
  pinMode (ontspannerSchakelaar, INPUT);
  pinMode (intervalometerSchakelaar, INPUT);
  pinMode (bewegingsensorSchakelaar, INPUT);

  pinMode (powerLed, OUTPUT);
  pinMode (intervalometerLed, OUTPUT);
  pinMode (bewegingsensorLed, OUTPUT);

  pinMode (irLed, OUTPUT);

  ledOpstartSequencie();
  powerLedAan();
}

void loop(){
  ontspannerStatus = !digitalRead(ontspannerSchakelaar);
  intervalometerStatus = !digitalRead(intervalometerSchakelaar);
  bewegingsensorStatus = !digitalRead(bewegingsensorSchakelaar);
  
  initieerSchakelaarStaat();
  long ontspannerVertraging = ontspannerSchakelaarTellerWaarde;
  
  if (intervalometerStaat == 0 && bewegingsensorStaat == 0 && ontspannerStaat == 1){
   zelfontspannerFunctie(ontspannerVertraging);
  }

  if (intervalometerStaat == 1 && instelTimer == 0){
    if (instelFunctieOntspannerBezig == 0 && instelFunctieIntervalometerBezig == 0 && instelTimer == 0){
      optelLedSignaal();
      instelTimer = 1;
      powerLedAan();
      initieerSchakelaarStaat();
    }
  }

  if (stelIntervalometerIn == 1 && instelTimer == 1 && intervalometerIngesteld == 0){

    if (stelIntervalometerIn == 1 && instelFunctieIntervalometerGeinitieerd == 0){
      instelFunctieIntervalometerGeinitieerd = 1;
      initieerSchakelaarStaat();
    }

    if (stelIntervalometerIn == 1 && instelFunctieIntervalometerGeinitieerd == 1){
      instelFunctieIntervalometerBezig = 1;
      initieerSchakelaarStaat();
    }

    if (stelIntervalometerIn == 1 && instelFunctieIntervalometerBezig == 1){
      intervalometerInstelFunctie();
      long x = (analogRead(intervalometerPotmeter));
      if(x != (analogRead(intervalometerPotmeter))){
        intervalometerIngesteld = 1;
      }
    }
  }

  if (intervalometerStaat == 1 && escapeLoop == 0){
    intervalometerStaat = 0;
    escapeLoop = 1;
  }
  if (ontspannerStaat == 0 && intervalometerStaat == 1){
    intervalometerReset = 1;
    intervalometerFunctie(ontspannerVertraging); 
  }

  if (stelOntspannerIn == 1 && instelTimer == 1){

    alleLedsUit();

    if (stelOntspannerIn == 1){
      instelFunctieOntspannerBezig = 1;
      ontspannerTellerInstelFunctie();
    }
  }

  if (stelOntspannerIn == 0 && instelFunctieOntspannerBezig == 1 && ontspannerIngesteld == 0){
    alleLedsUit();
    delay(1000);
    ontspannerIngesteld = 1;
    aftelLedSignaal();
    powerLedAan();
  }

}

void bepaalIntervalFunctie (){
  interval = map(analogRead(intervalometerPotmeter), 1023, 0, 1, 60);
  interval = interval * 1000; 
}

void intervalometerInstelFunctie(){
  bepaalIntervalFunctie();
  if (millis() - laatsteFoto > interval){
    ledFunctie(0, 0, bewegingsensorLed, 0, 0, 1, 10);
    laatsteFoto = millis(); 
  }
}

void intervalometerFunctie(long vertraging){
  if (vertraging == 0){
    bepaalIntervalFunctie();
    if (millis() - laatsteFoto > interval){
      camera.Snap();
      delay(1);
      ledFunctie(0, 0, bewegingsensorLed, 0, 0, 1, 10);
      laatsteFoto = millis();
    }
  }
  else if(vertraging != 0){
    bepaalIntervalFunctie();
    if(ontspannerVertragingIntervalometer == 0){
      ontspannerVertragingIntervalometer = 1;
      delay(vertraging*1000);
    } 
    if (millis() - laatsteFoto > interval){
      camera.Snap();
      delay(1);
      ledFunctie(0, 0, bewegingsensorLed, 0, 0, 1, 10);
      laatsteFoto = millis();
    }
  }
}

//ONTSPANNER

void ontspannerTellerInstelFunctie(){
  powerLedUit();
  ontspannerSchakelaarTellerStaat = !digitalRead(ontspannerSchakelaar);
  if(ontspannerSchakelaarTellerStaat != ontspannerSchakelaarTellerLaatsteStaat){
    if(ontspannerSchakelaarTellerStaat == LOW){
      ontspannerSchakelaarTellerWaarde++;
      instellingenLedSignaal();
    }
    ontspannerSchakelaarTellerLaatsteStaat = ontspannerSchakelaarTellerStaat;
  }
}

void zelfontspannerFunctie(long vertraging){
  if (vertraging == 0){
    powerLedUit();
    camera.Snap();
    ontspannerLedSignaal();
  }
  else if (vertraging <= 5 && vertraging != 0){
    powerLedUit();
    delay(vertraging*1000-500);
    camera.Snap();
    ontspannerLedSignaal();
  }
  else if(vertraging > 5){
    powerLedUit();
    delay(vertraging*1000-4500+500);
    optelLedSignaal();
    camera.Snap();
    ontspannerLedSignaal();
  }
  ontspannerReset();
}

void ontspannerReset(){
  ontspannerSchakelaarTellerLaatsteStaat = 0;
  ontspannerSchakelaarTellerStaat = 0;
  ontspannerSchakelaarTellerWaarde = 0;
}

//LED's
void ledFunctie (char ledId1, char ledId2, char ledId3, int beginStaat, int eindStaat, int aantal, long vertraging) {
  delay (vertraging);
  if (beginStaat == 0) {
    if (ledId1 != 0){
      digitalWrite(ledId1, LOW);
    }
    if (ledId2 != 0){
      digitalWrite(ledId2, LOW);
    }
    if (ledId3 != 0){
      digitalWrite(ledId3, LOW);
    }
  }
  if (beginStaat == 1) {
    if (ledId1 != 0){
      digitalWrite(ledId1, HIGH);
    }
    if (ledId2 != 0){
      digitalWrite(ledId2, HIGH);
    }
    if (ledId3 != 0){
      digitalWrite(ledId3, HIGH);
    }
  }
  for (int i=0; i < aantal; i++) {
    delay (vertraging);
    if (ledId1 != 0){
      digitalWrite(ledId1, HIGH);
    }
    if (ledId2 != 0){
      digitalWrite(ledId2, HIGH);
    }
    if (ledId3 != 0){
      digitalWrite(ledId3, HIGH);
    }
    delay (vertraging);
    if (ledId1 != 0){
      digitalWrite(ledId1, LOW);
    }
    if (ledId2 != 0){
      digitalWrite(ledId2, LOW);
    }
    if (ledId3 != 0){
      digitalWrite(ledId3, LOW);
    }
    delay (vertraging);
  }
  if (eindStaat == 0) {
    if (ledId1 != 0){
      digitalWrite(ledId1, LOW);
    }
    if (ledId2 != 0){
      digitalWrite(ledId2, LOW);
    }
    if (ledId3 != 0){
      digitalWrite(ledId3, LOW);
    }
  }  
  if (eindStaat == 1) {
    if (ledId1 != 0){
      digitalWrite(ledId1, HIGH);
    }
    if (ledId2 != 0){
      digitalWrite(ledId2, HIGH);
    }
    if (ledId3 != 0){
      digitalWrite(ledId3, HIGH);
    }
  }
}

void ledOpstartSequencie() {
  ledFunctie(powerLed, 0, 0, 0, 0, 1, 50);
  delay(500);
  ledFunctie(powerLed, intervalometerLed, 0, 0, 0, 2, 50);
  delay(500);
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 3, 50);
  delay(500);
}

void ontspannerLedSignaal() {
  delay(100);
  ledFunctie(powerLed, 0, 0, 0, 0, 3, 5);
  ledFunctie(powerLed, intervalometerLed, 0, 0, 0, 3, 5);
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 3, 5);
  delay(100);
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 0, 0);
  delay(785);
  ledFunctie(powerLed, 0, 0, 0, 1, 0, 0); 
}

void instellingenLedSignaal() {
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 3, 20);
}

void optelLedSignaal() {
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 0, 0);
  delay(1000);
  ledFunctie(powerLed, 0, 0, 0, 1, 0, 0);
  delay(1000);
  ledFunctie(0, intervalometerLed, 0, 0, 1, 0, 0);
  delay(1000);
  ledFunctie(0, 0, bewegingsensorLed, 0, 1, 0, 0);
  delay(1000);
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 0, 0); 
  delay(500);
  powerLedAan();
}

void aftelLedSignaal() {
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 1, 1, 1, 0);
  delay(1000);
  ledFunctie(0, 0, bewegingsensorLed, 1, 0, 1, 0);
  delay(1000);
  ledFunctie(0, intervalometerLed, 1, 1, 0, 1, 0);
  delay(1000);
  ledFunctie(powerLed, 1, 1, 1, 0, 1, 0);
  delay(1000);
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 0, 0);
  delay(500);
  powerLedAan();  
}

void bevestigingsLedSignaal() {
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 1, 200);
}

void alleLedsUit() {
  ledFunctie(powerLed, intervalometerLed, bewegingsensorLed, 0, 0, 0, 0);
}

void powerLedAan() {
  delay(500);
  ledFunctie(powerLed, 0, 0, 0, 1, 0, 0); 
}

void powerLedUit() {
  delay(500);
  ledFunctie(powerLed, 0, 0, 0, 0, 0, 0); 
}

void intervalometerLedAan() {
  ledFunctie(0, intervalometerLed, 0, 0, 1, 0, 0);
}

void intervalometerLedUit() {
  ledFunctie(0, intervalometerLed, 0, 0, 0, 0, 0);
}

void bewegingsensorLedAan() {
  ledFunctie(0, 0, bewegingsensorLed, 0, 1, 0, 0);
}

void bewegingsensorLedUit() {
  ledFunctie(0, 0, bewegingsensorLed, 0, 0, 0, 0);
}

void initieerSchakelaarStaat() {
  if (ontspannerStatus == HIGH && intervalometerStatus == LOW && bewegingsensorStatus == LOW){
    standaardStaat = 1;
    ontspannerStaat = 0;
    intervalometerStaat = 0;
    bewegingsensorStaat = 0;
    stelOntspannerIn = 0;
    stelIntervalometerIn = 0; 
    powerLedAan();
    intervalometerLedUit();
    bewegingsensorLedUit();
  }
  else if (ontspannerStatus == LOW && intervalometerStatus == LOW && bewegingsensorStatus == LOW){
    standaardStaat = 0;
    ontspannerStaat = 1;
    intervalometerStaat = 0;
    bewegingsensorStaat = 0;
    stelOntspannerIn = 0;
    stelIntervalometerIn = 0;
    alleLedsUit();
  }
  else if (ontspannerStatus == HIGH && intervalometerStatus == HIGH && bewegingsensorStatus == HIGH){
    standaardStaat = 0;
    ontspannerStaat = 0;
    intervalometerStaat = 0;
    bewegingsensorStaat = 0;
    stelOntspannerIn = 1;
    stelIntervalometerIn = 0;
    alleLedsUit();
    }
  else if (ontspannerStatus == LOW && intervalometerStatus == HIGH && bewegingsensorStatus == LOW){
    standaardStaat = 0;
    ontspannerStaat = 0;
    intervalometerStaat = 0;
    bewegingsensorStaat = 0;
    stelOntspannerIn = 0;
    stelIntervalometerIn = 1;
    powerLedAan();
    intervalometerLedAan(); 
    bewegingsensorLedUit();
  }
  else if (ontspannerStatus == HIGH && intervalometerStatus == HIGH && bewegingsensorStatus == LOW){
    if (instelFunctieOntspannerBezig == 1){
      delay(200);
      instelFunctieOntspannerBezig = 0;
    }
    else if(instelFunctieOntspannerBezig == 0){
      standaardStaat = 0;
      ontspannerStaat = 0;
      intervalometerStaat = 1;
      bewegingsensorStaat = 0;
      stelOntspannerIn = 0;
      stelIntervalometerIn = 0;
      powerLedAan();
      intervalometerLedAan(); 
      bewegingsensorLedUit();
    }
  }
  else if (ontspannerStatus == HIGH && intervalometerStatus == LOW && bewegingsensorStatus == HIGH){
    standaardStaat = 0;
    ontspannerStaat = 0;
    intervalometerStaat = 0;
    bewegingsensorStaat = 1;
    stelOntspannerIn = 0;
    stelIntervalometerIn = 0;
    powerLedAan();
    intervalometerLedUit(); 
    bewegingsensorLedAan();
  }
}

Ik wil proberen of ik het ding met losse modules kan gaan uitbreiden. b.v een kastje met een bewegingssensor of met een microfoon. Ook wil ik me gaan verdiepen in flitsbediening op afstand.

Verder wil ik kijken of ik het zo kan maken dat ik via mijn kastje de camera kan laten bracketten.

Ook lijkt me een kastje met aangestuurde motor voor 360 of panorama's me wel handig.

Verder moet er natuurlijk nog een veul mooier kastje komen. Maar dan moet ik eerst weten wat er allemaal aan elektronika in moet. Nu nog niet helemaal duidelijk. En dan moet ik natuurlijk weer eens na het tig jaren niet gedaan te hebben een printplaat gaan maken! Niet met Fritzing dat is in ieder geval duidelijk.

p.s Muziek is van Israel Vibrations nummer heet Try Again

12 mei 2010

Afstandsbediening voor Nikon met interval timer (concept)

Sinds kort een Arduino in bezit. Een soort van Zwitsers zakmes voor de gadget nerd.

Zocht een leuk beginners projectje dat werd een IR afstandsbediening voor mijn Nikon D60. Een UV ledje was snel genoeg in de weelde die grofvuil heet gevonden. Een afstandsbediening voor waarschijnlijk een videorecorder. Vond de zelfde dag ook nog een goedkope elektrische auto zonder de afstandsbediening (sjips geen joysticks) met een potmeter en een schakelaar!

In eerste instantie wou ik alleen dit project in elkaar knutselen. Heb het uitgebreid met de potmeter waarmee ik de interval snelheid kan instellen en een aan en uit schakelaar wat altijd wel handig is om te hebben op een gadget.

Tot zover ziet het monster er ongeveer zo uit:


Wil het nog gaan uitbreiden met een bewegingssensor en het lijkt me ook handig als ik een knopje heb om een enkele foto te maken.

De code tot zover (wel even de nikonIrControl bibliotheek installeren!):



#include <NikonRemote.h>

//De IR LED
const int irLedPin = 12;

//Intervalometer aan/uit
const int intervalometerPauzeWaardePin = 5;

//De potmeter om de intervals mee te setten
const int intervalometerPotmeter = 5;

//Ik verklaar hiebij dat er iets als een IntervaloleterPauzeWaarde bestaat
int intervalometerPauzeWaarde;

// Variabelen om de interval en de laatsteFoto in op te slaan
long interval = 0;
long laatsteFoto = 0;

//Functie uit de nikonIrControl bibliotheek die het allemaal mogelijk maakt aanroepen:
NikonRemote camera(irLedPin);

void setup()
{
  //Vertel hier de Arduino dat er zoiets als een IR LED bestaat
  pinMode(irLedPin, OUTPUT);
  
  //Er bestaat ook zoiets als een potmeter in het universum van deze specifieke Arduino
  pinMode(intervalometerPotmeter, OUTPUT);
}


void loop()
{
  intervalometerPauzeWaarde = !digitalRead(intervalometerPotmeter);
  
  if (intervalometerPauzeWaarde == HIGH) {
    
    //Breng de waarde van de potmeter op de analoge ingang in "kaart"
    interval = map(analogRead(intervalometerPotmeter), 1000, 0, 1, 60);
  
    //Potmeter waarde moet ik nog een beetje beter in kaart brengen moet de waarde
    //op dit moment nog met 1000 vermenigvuldigen om het een beetje werkend te krijgen
    //lelijke hack maar werkt voor nu.
    interval = interval * 1000;
    
    controleerIntervalometer();
  
  Serial.write(interval);
}
  
}

void controleerIntervalometer()
{
  //Reken uit of er alweer een nieuwe foto genomen moet worden 
  if (millis() - laatsteFoto > interval) {
    camera.Snap();
    laatsteFoto = millis();
  }
}
 
//Oude werkende!! code

 //delay(1000);
 //camera.Snap();

Het jongetje op de foto heet Sacha, maar ik noem hem mijn assistent Igor. Was de eerste foto die lukte met de afstandbediening.