Arduino Duemilanove and shutter speed mettering

Hallo,

I'm trying calibrate shutter speed of my digital camera by Arduino. I have a matrix of 64 LEDs and my problem is time delay between two shining LEDs. I take a foto of matrix and then I count shining LEDs. For Example, shutter speed is 1/45 s = 22 ms, time delay between LEDs is 1ms, but on photograph are only 11 shining LEDs.

My code:

// definovani pinu rady
const int radek[8] = {
  10,12,18,11,14,15,17,16 };

// definovani pinu sloupce
const int sloupec[8] = {
  9,8,7,6,5,4,3,2};
  
// definovani doby svitu diody  
const int svitit = 1;

// pri startu se spusti jen jednou a pak pokracuje nekonecna smycka loop
void setup()   {
  // nastavim piny na vystup:
  for (int pin = 0; pin < 8; pin++) {
    pinMode(radek[pin], OUTPUT);
    pinMode(sloupec[pin], OUTPUT);  
    //vynuluju vstupy aby nic nesvitilo
    digitalWrite(radek[pin], HIGH);    
    digitalWrite(sloupec[pin], LOW);    
  }   
}

void loop()                     
{
    // postupne radky
for (int poradi_radek = 0; poradi_radek < 8; poradi_radek++) 
{
  // p[ch345]ipojení spolecne katody na zem do propustneho smeru
  digitalWrite(radek[poradi_radek], LOW);
  
  // postupne sloupce
  for (int sloup = 0; sloup < 8; sloup++) 
      {
        //rozsvitim a zhasnu diodu ve sloupci
        digitalWrite(sloupec[sloup], HIGH); 
        delay(svitit); 
        digitalWrite(sloupec[sloup], LOW);
      }
  digitalWrite(radek[poradi_radek], HIGH);      
 }
}

Where is mistake in my idea? Why I don't see 22 shing LEDs? Why is time always 2 times longer then number of shining LEDs?

Thanks for every idea..

For Example, shutter speed is 1/45 s = 22 ms, time delay between LEDs is 1ms, but on photograph are only 11 shining LEDs.

You are ignoring the time that it takes for the looping, and the 4 digital writes in the pair of loops.

I expect something like that - but I can't find details about this - do anybody know what time (exactly) take one "for" loop, write function and others?

The time required to execute the for loop depends on what is happening in the loop. I suspect that you mean the time for the conditional and increment operations to be performed. Those depend on the exact nature of the conditional and increment functions, so no single number will be possible.

You can find the object files that are produced, and use some avr command (avrdump?) to see the assembly instructions that your loop evolves to. Count the number of instructions, and multiply by the length of an instruction (62.5 microseconds at 16MHz).

I know that the instruction take some time, but it is a 6 digit places diference between that. f=1/T , so T=1/f=62,5 ns - not microseconds..

It is insignificant time for one instruction in compare with delay time.

I'm not sure - am I right? How the delay() function works in this sense?

It is insignificant time for one instruction in compare with delay time.

You are right. I misspelled nano-seconds. But the digitalWrite() function is not a single instruction, so the time it takes is NOT insignificant.

I think you should avoid delay() and use your own timing based on micros(). Some code fragments :

long unsigned LastToggle ;
int R = 0 ; int C = 0 ;
const unsigned long 1000L ;  // make sure to define it as long
  :

void setup() { .. }
  :

void loop() {
 if ( LastToggle+micros > DelayInterval ) {
    LastToggle = micros() ;
    NextState ( )  ;
  } 
}

void NextState ( ) {
  digitalWrite(sloupec[C], LOW) ;
  if ( C >= 8 ) {
    C = 0 ;
    if ( R >= 8 ) 
      digitalWrite(radek[R]), LOW) ;
      R = 0 ;
      else
      R ++ ;
      digitalWrite(radek[R]), HIGH) ;
  } else {
  C++ ;
  digitalWrite(sloupec[C], HIGH) ;
  }   
}

In other words, the delay is replaced by the logic from http://arduino.cc/en/Tutorial/BlinkWithoutDelay this way it does not matter how long all the other code takes (as long as it is shorter than the delay) and it will be stable when you change the code path (ie. longer time for the LEDs to togle when you need to go back to the outer loop)

The loop has been "inverted" (turned inside out), incrementing when called. Code not tested! and I may have misunderstood your use of the arrays and how to toggle you matrix.

Thank you both for your clue, my solution is little bit diferent because i need turn on and off each LED. After I take picture, there is a Matlab program for postproccesing and I count number of turn on of each LED.

Uff..I'm sorry for my English, thanks a lot both :slight_smile:

unsigned long PosledniPreklopeni = 0; // Last toogle
int R = 0 ; int S = 0 ;
const long Doba_svitu_LED = 500;  // time of luminous LED
//count it 2x - one for luminous LED, second for turning off
const int radek[8] = {
  10,12,18,11,14,15,17,16 };
const int sloupec[8] = {
  9,8,7,6,5,4,3,2};

int ukazatel=0;  // pointer for turning on/off

void setup() {
    for (int pin = 0; pin < 8; pin++) {
    pinMode(radek[pin], OUTPUT);
    pinMode(sloupec[pin], OUTPUT);  
    digitalWrite(radek[pin], HIGH);   
    digitalWrite(sloupec[pin], LOW); 
  }
}
void loop() {
 unsigned long Aktualni_cas = micros();
 if ( Aktualni_cas - PosledniPreklopeni > Doba_svitu_LED ) {
    PosledniPreklopeni = Aktualni_cas;
    vypnout_zapnout_LED();
 }
} 

void vypnout_zapnout_LED() {
 if(ukazatel==0){
   digitalWrite(radek[R], LOW);   
   digitalWrite(sloupec[S], HIGH);
   ukazatel++;
 }else{
   digitalWrite(radek[R], HIGH);   
   digitalWrite(sloupec[S], LOW);
   ukazatel--; 
 }
if(ukazatel==0){ 
    if(S==7){ //check for end of collumn
       S=0;
      if(R==7){ //inceremnet of row pointer
        R=0;
       }else{
       R++;
     }
 }else{
   S++; // increment of column pointer
  } 
}
}