www.photomacrography.net :: View topic - Using DigiSpark To Implement A Delay Circuit
www.photomacrography.net Forum Index
An online community dedicated to the practices of photomacrography, close-up and macro photography, and photomicrography.
Photomacrography Front Page Amateurmicrography Front Page
Old Forums/Galleries
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
Using DigiSpark To Implement A Delay Circuit

 
Post new topic   Reply to topic    www.photomacrography.net Forum Index -> Equipment Discussions
View previous topic :: View next topic  
Author Message
mjkzz



Joined: 01 Jul 2015
Posts: 973
Location: California/Shenzhen

PostPosted: Tue Feb 27, 2018 10:45 pm    Post subject: Using DigiSpark To Implement A Delay Circuit Reply with quote

Sometimes, it is necessary to trigger flash or turn on the light in the middle of exposure to avoid vibration caused by shutter opening and closing such as front and rear curtain trigger (or some might call it 1st and 2nd curtain trigger). So, a delay circuit is necessary to do this.

While others use classical analog circuit (Mike's), I decided to do it with digital approach. Trying to maintain DIY'ability, it seems that DigiSpark board from fellow Kickstarter project (which I forgot at first) seems to be good choice. DigiSpark is cheap on eBay, but I am not sure if they are licensed from DigiStump and these cheap boards seem to have some flaws (or even the original has them, too)

Nonetheless, it turns out the DigiSpark is the right choice and then some -- I can even shove a OLED display in. Construction of circuit is described in the code (see below), it is rather simple with some exceptions -- pin 1 of the board seems to be tied to the on-board LED, so it must be pulled up with a 10K resistor (1K in my photo as I could not find one). Another exception is that the cheap DigiSpark board is probably a rip-off one, its pin 5, the reset pin is still ENABLED for reset. I do not have genuine DigiSpark board (they stopped selling till May) to test, so if you turn the POT and change voltage to lower than 2.5V, the board resets. Oh well, that is life Very Happy

Output (in the picture) is now an LED instead of a transistor to trigger flash (or other lights), but it should be easy to change.

One key idea is to use the POT to change the voltage on an ADC pin, in this example, the P5 (analog 0). By turning the POT, you are changing the voltage and the DigiSpark can read it and convert that to change amount of delay.




Code:

Code:

#include <DigisparkOLED.h>    // DigiSpark OLED driver
#include <Wire.h>

// OLED I2C Slave address, this is important as different OLED might have different address
#define SSD1306_SA  0x78     

// P0 is used for I2C SDA -- OLED Display
// P2 is used for I2C SCK -- OLED Display
// P1 is used for INPUT from camera or stack controller
// P5 is used as analog pin (analog 0)
// P4 is used as output to trigger flash or light


enum enumMode
{
  mode_idle,
  mode_down,
  mode_wait,
  mode_fire,
 
  mode_last,
};


#define PIN_INPUT         1       // we use P1 as input signal from either camera or stack controller
#define PIN_OUTPUT        4       // use P4 as output to trigger flash/light
#define PIN_ANALOG        5       // Analog 0 is P5
#define PIN_ANALOG_NUM    0       // Analog 0 is P5

#define MAX_FLASH_DUR     200     // this controls how long the flash/lite is ON in milliseconds
// this is used to increase range.
#define MULTIPLIER        1
// this defines how often the POT is read
#define MAX_READ_TICK     30000

byte gv_ucMode  = mode_idle;
long gv_tkRead  = MAX_READ_TICK;

long gv_tkFire  = MAX_FLASH_DUR;
long gv_slTick  = 0;
long gv_tnWait  = 0;
long gv_tkWait  = 0;

// here to implement a digital filter on the ADC
// as ADC is very, very noisy.
#define NUM_FILTER    16

long gv_svRead = 0;
long gv_slRead = 0;
long gv_arRead[NUM_FILTER];
byte gv_ixRead = 0;


// this is a routine that takes a long value
// and fill it up to a buffer, right aligned

#define BUFFER_SIZE 6
byte gv_arBuffer[BUFFER_SIZE];

void fillBuffer(long val)
{
  for(byte i=0; i<BUFFER_SIZE-1; i++)
  {
    gv_arBuffer[i] = ' ';
  }

  byte  ucVal;
  byte  index = BUFFER_SIZE-2;
 
  while(index)
  {
    gv_arBuffer[index] = val - (val / 10) * 10 + '0';
    if (index > 0)
    {
      index--;
    }
    val = val / 10;   
    if (val == 0)
    {
      break;
    }
  }

  // finally, terminate the string with NULL
  gv_arBuffer[BUFFER_SIZE-1] = 0;
}

void setup()

  // for analog read, no need to configure it.
 
  // but for digital read, we need to
  pinMode(PIN_INPUT, INPUT);       
  digitalWrite(PIN_INPUT, HIGH);      // set pullup resistor on INPUT by writing HIGH to it.

  pinMode(PIN_OUTPUT, OUTPUT);        // we use P4 for output to trigger flash
  digitalWrite(PIN_OUTPUT, LOW);      // set initial state

  pinMode(PIN_ANALOG, INPUT);         // make analog pin INPUT pin
 
  oled.begin();
 
  // clear screen
  oled.clear();                     //all black     
  // set OLED fonts
  // oled.setFont(FONT6X8);         // smaller font
  oled.setFont(FONT8X16);           // large font

  oled.setCursor(12, 6);
  oled.print(F("www.mjkzz.com"));
}

void loop()
{   
  switch(gv_ucMode)
  {
    case mode_idle:
      // sense INPUT
      if (digitalRead(PIN_INPUT) == LOW)
      {
        gv_tkWait = gv_tnWait;

        gv_ucMode = mode_wait;          // down edge triggered
        // gv_ucMode = mode_down;       // up edge triggered
      }
      else
      {
        if (gv_tkRead == 0)
        {
          gv_arRead[gv_ixRead] = analogRead(PIN_ANALOG_NUM);
          gv_ixRead++;
          if (gv_ixRead > NUM_FILTER-1)
          {
            gv_ixRead = 0;         
          }

          gv_slRead = 0;
          for(byte i=0; i<NUM_FILTER; i++)
          {
            gv_slRead += gv_arRead[i];
          }
          gv_slRead /=  NUM_FILTER;

          if (gv_slRead != gv_svRead)
          {
            // new reading
            gv_svRead = gv_slRead;
            gv_tnWait = gv_slRead * MULTIPLIER;           
           
            oled.setCursor(5, 2);
            oled.print(F("Delay : "));
            fillBuffer(gv_tnWait);
            oled.print((char *) gv_arBuffer);
            oled.println(F("ms"));
          }
          gv_tkRead = MAX_READ_TICK;
        }
        else
        {
          gv_tkRead--;
        }
      }
      break;
    case mode_down:
      if (digitalRead(PIN_INPUT) == HIGH)
      {
        gv_ucMode = mode_wait;       
      }
      break;
    case mode_wait:
      if (gv_tkWait)
      {
        gv_tkWait--;
        delay(1);       // every tick is 1ms
      }
      else
      {       
        gv_ucMode = mode_fire;
        gv_tkFire = MAX_FLASH_DUR;
        digitalWrite(PIN_OUTPUT, HIGH);   
      }
      break;
    case mode_fire:
      if (gv_tkFire)
      {
        digitalWrite(PIN_OUTPUT, HIGH);
        gv_tkFire--;
        delay(1);       // every tick is 1ms
      }
      else
      {
        // finished job, set flash off
        digitalWrite(PIN_OUTPUT, LOW);
        gv_ucMode = mode_idle;
      }
      break;
    default:
      gv_ucMode = mode_idle;
      break;     
  }
}


[Admin edit, RJL: add code tags]
_________________
https://www.facebook.com/groups/mjkzzfs/
Back to top
View user's profile Send private message Visit poster's website
rjlittlefield
Site Admin


Joined: 01 Aug 2006
Posts: 19395
Location: Richland, Washington State, USA

PostPosted: Tue Feb 27, 2018 11:18 pm    Post subject: Reply with quote

Great info, thanks for posting.

I took the liberty of adding some [code] block tags to your post, to improve the readability.

--Rik
Back to top
View user's profile Send private message Visit poster's website
mjkzz



Joined: 01 Jul 2015
Posts: 973
Location: California/Shenzhen

PostPosted: Wed Feb 28, 2018 3:47 am    Post subject: Reply with quote

oh, wow, thanks Rik. I see there is a code tag here.
_________________
https://www.facebook.com/groups/mjkzzfs/
Back to top
View user's profile Send private message Visit poster's website
Saul



Joined: 31 Jan 2011
Posts: 1252
Location: Naperville, IL USA

PostPosted: Wed Feb 28, 2018 9:25 am    Post subject: Re: Using DigiSpark To Implement A Delay Circuit Reply with quote

mjkzz wrote:
... Output (in the picture) is now an LED instead of a transistor to trigger flash (or other lights), but it should be easy to change.

One key idea is to use the POT to change the voltage on an ADC pin, in this example, the P5 (analog 0). By turning the POT, you are changing the voltage and the DigiSpark can read it and convert that to change amount of delay. ...


Hi Peter,
Very nice & compact design.
"... to trigger flash (or other lights)" - can be output signal length adjusted in order to control continuous light in this configuration ?
_________________
Saul
Studio, horizontal and field setups
Back to top
View user's profile Send private message Send e-mail Visit poster's website
ChrisR
Site Admin


Joined: 14 Mar 2009
Posts: 7953
Location: Near London, UK

PostPosted: Wed Feb 28, 2018 3:42 pm    Post subject: Reply with quote

Peter, did you have a reason to not use the trailing edge of the pulse which triggers the shutter? Then you just set the timing in the set-up (in Stackshot operation at least).
_________________
Chris R
Back to top
View user's profile Send private message
mjkzz



Joined: 01 Jul 2015
Posts: 973
Location: California/Shenzhen

PostPosted: Wed Feb 28, 2018 8:24 pm    Post subject: Reply with quote

Saul: yes, there is a define, MAX_FLASH_DUR, now it is set to 200ms, you can change it. But if you want dynamic ones, you can add another POT for it.

ChrisR: not sure what you mean by trailing edge, if you mean the edge going from low to high (normally, camera or other devices pulls input low and then high when released), then yes there is a reason -- if camera is in bulb mode or long exposure mode, you can not fire a flash in the middle as the camera will continue hold the signal low till it release the shutter.

For other purposes, you can comment out the "down edge triggered" and un-comment the "up edge triggered" to make the circuit respond to the edge when signal going from low to high.

Essentially, the program is a state machine.
_________________
https://www.facebook.com/groups/mjkzzfs/


Last edited by mjkzz on Wed Feb 28, 2018 8:31 pm; edited 2 times in total
Back to top
View user's profile Send private message Visit poster's website
mjkzz



Joined: 01 Jul 2015
Posts: 973
Location: California/Shenzhen

PostPosted: Wed Feb 28, 2018 8:29 pm    Post subject: Reply with quote

To be honest, this is my first time using and programming the board, it took me four hours to finish it, most of the time was to figure out some peculiarity of the board, a lot of googling :-)

For those interested and want to avoid some time consuming part that I encountered, here is my blog on how to get started.. Good luck.
_________________
https://www.facebook.com/groups/mjkzzfs/
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    www.photomacrography.net Forum Index -> Equipment Discussions All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group