Looking at code generated by Arduino compiles

March 2, 2009

Most of the time you don’t need to do this.  But, if you are writing real-time code that is time sensitive or if you interested in what the compiler did with your C or C++, then this is for you.

You may have noticed that when you create a new SketchBook you get a new folder that has the name of the Sketch.  Inside of this folder is another folder that is named “applet”.  This applet folder is created by a successful compile of the Sketch AND a successful upload to the Arduino board.  In the applet folder there are several files, but the ones we are interested in are the ones with the “.o” file name suffixs.  These are the individual object files created by the compiler.  Each one of these correspond to an associated C/C++ source.  As you will notice, there are more in the folder than you probably wrote.  These additional files are all of the other arduino associated files that complete your application.

These object files are binary.  Fortunately, there is another program supplied by the Arduino system that permits looking at a textual version of those files.   The “objdump” executable found in the \hardware\tools\avr\avr\bin\ area of your arduino installation folder.  This program reads an object file (.o) and creates a text file.  To make it easy, create a batch file, I called it objdump.bat.  I put the single following line into this batch file:

for %%f in (*.o) do C:\arduino-0012\hardware\tools\avr\avr\bin\objdump -S %%f > %%~nf.txt

(Please ignore the extra spaces created in the blog)   Of course you also need to change the path to the program to match where you have it located (C:\arduino….)

Ok, now after you have uploaded to the arduino, copy the batch file into the applet folder.  The reason for a copy is that this folder is deleted and recreated everytime you do another upload – hence, you have to have the batch file somewhere else and copy eacy time.  Run the batch file and you should see several new files of type .txt.  Each of these new files are then viewable to see both the original source code and the assocated assembly statements.

Enjoy.

The nature of gravity

March 2, 2009

Actually, I’m referring to things dropping and how long it takes for that thing to drop a certain distance.  If you use this information along with controlling a camera then you can capture things that are falling in a repeatable fashion.  For instance, a drop of water as it just hits a pool of water, or maybe just a little later when the water pool splashes back up after reacting to the water droplet.

The favorite equation used for this dropping behavior is

distance, acceleration and time

where “s” is the distance, “a” is the acceleration rate, and “t” is the amount of time.  This equation assumes the object starts at rest and t=0.  The acceleration “a” can be assumed constant with a value of approximately gravity constant

I was able to build a simple setup that allowed me to experiment with Arduino controlling a Laser, a light sensor, and a camera (Canon XSi).  The experiment performed the following steps:

1.   Turn on a laser and insure that the light sensor detected the laser

2.   Drop an object through the laser-sensor beam

3.   Upon sensing the laser-sensor beam broken, start a delay

4.   Once delay has finished, take a picture

5.   Turn off the laser

6.   Look at the picture to evaluate object’s dropped distance

7.   Repeat with different delay amounts

Ok, simple enough.  The problem I had was how to release the object repeatedly from a fixed position and as close to already breaking the laser-sensor beam as possible.  The object I chose was as ruler, permitting me to visually see the distance traveled. 

img_25221

My object (ruler) release was simple – a nail that I pulled back that released the ruler.  I carefully positioned the ruler to just before breaking the light between the laser and sensor.  I then release, recorded what the camera saw and repeated. 

I also changed the amount of delay.  After I had several interesting data points, I plotted the results.  I recorded 6 different results for the same delay, plotting the average/min/max.  I also plotted a curve-fitted line to determine the least-square best fit for the modified equation (instead of “t”, I used “(t + y)”, where “y” is the unknown amount of camera delay).  From this particular experiment, I determined that “y” is about 106msec, which is for some reason, different from other experiments for the same camera.

capture3

Here is an example picture taken:

img_2407

The arduino code is:

#define shutter_close PORTD |= _BV(2);
#define shutter_open PORTD &= ~_BV(2);

#define focus_on PORTD |= _BV(3);
#define focus_off PORTD &= ~_BV(3);

#define laser_on PORTD |= _BV(4);
#define laser_off PORTD &= ~_BV(4);

#define nolight (PINB & 1)  // digital pin #8
#define ledon PORTB |= _BV(1)
#define ledoff PORTB &= ~_BV(1)


void setup() {
  pinMode(2, OUTPUT);  // camera shutter
  pinMode(3, OUTPUT);  // focus control
  pinMode(4, OUTPUT);  // Laser control
  pinMode(8, INPUT);   // light input
  pinMode(9, OUTPUT);  // led indicator
  shutter_open;
  focus_off;
  ledoff;
  laser_off;
  Serial.begin(9600);
}
unsigned long amt = 0;  // 0 = no extra delay … just the inherent delay

void get_delay() {
  unsigned long delay = 0;
  unsigned char len = 0;
  while(1) {
    while(!Serial.available());  // wait for first character
    unsigned char c = Serial.read();
    if (c >= ‘0’ && c <= ‘9’) {
      delay = (delay * 10) + (c – ‘0’);  // add in digit
      len++;
    } else {
      if (len == 0) {
        Serial.println(“Have to enter a delay”);
        return;
      } else {
        amt = delay;
        Serial.print(“new extra delay of “);
        Serial.println(amt);
        return;
      }
    }
  }
}

void loop() {
  while(1) {
    Serial.println(“Command? (D, T, A)”);
    while(!Serial.available());  // wait for command
    unsigned char c = Serial.read();
    switch(c) {
      case ‘A’: case ‘a’:
        laser_on;
        while(!Serial.available()) {
          if (nolight) ledon;
          else ledoff;
        }
        Serial.read();
        laser_off;
        break;
       
      case ‘T’: case ‘t’: {
        Serial.print(“Delay is camera + “);
        Serial.print(amt);
        Serial.println(“ms”);
       
        laser_on;
        while(nolight);  // wait for laser and sensor together
        focus_on;
        delay(1000);  // pre-focus
        while(nolight == 0);  // wait for light trigger

        // turn off laser
        // laser_off;
        delay(amt);  // time to shutter
        shutter_close;  // close the shutter
        ledon;  // flag progresst
        delay(200);  // delay some amount for the shutter/flash to work
        shutter_open; // release shutter
        focus_off;
        ledoff; // flag progress
        laser_off;
      } break;
     
      case ‘D’: case ‘d’:
        get_delay();
        break;
     
      case ‘F’: case ‘f’:
        focus_on;
        delay(1000);
        focus_off;
        break;
       
    }
  }
}
 

 

Characterizing shutter curtain delay of Canon XSi

March 2, 2009
I wanted to know the delay from closing the shutter of my camera to when the actual picture is taken. With this information, then it becomes easier to setup various stop-motion picture captures.
For this experiment, I needed three things:
  • A way of controlling the Canon XSi camera
  • A bright enough LED with a short flash time while the camera was in total darkness
  • An accurate accounting for delay from control of camera to LED flash

The LED I used was a Luxeon I, which was controlled via a simple transistor driver (2N2222 + base resistor). The flash time for the LED was chosen to be only 1msec. To get an accurate delay I found I had to write my own delay routines. The delay routines provided by the Arduino library were not really adequate for my purpose.
My software hardware algorithm was simple. Have the arduino close the camera shutter, have it delay a predetermined (but user variable) amount, and flash the LED at a piece of paper, for which the camera was taking a picture. I then manually looked at the resulting picture to see the amount of light that was exposed in the picture. I recorded the results and changed the amount of delay and repeated. Because the LED flash time was only 1msec, I had to shoot with an ISO of 1600.
 
I did two different sets of pictures. The first picture set was just of an arbitrary piece of paper I had laying around. It had some garbage writing on it, but this was to determine if the setup worked ok. The shutter speed was set at 1/100. I approximated from these pictures the actual shutter speed at 1/100.6, which is within 0.6% of the camera’s setting. Also the delay begins at 84msec through 86msec depending upon the position in the camera’s sensor.
Notice how the sensor is opened from the bottom and the 2nd curtain also starts at the bottom (as it should).
 
The second set of pictures was of a sheet of paper that had printed on it lines labelled from 0 through 10. This ruling would permit me to better estimate the delay time to % position of the shutter open or closed. I carefully positioned the paper and camera zoom so that the “0” line was just at the bottom and the “10” line was just at the top of the camera’s sensor.
 
Here is an example of one of these shots.
 
Lastly, I used the perceived % opening/closing of shutter to plot the delay of the shutter. I posted these as two excel charts, the first for the shutter opening, the second for closing.      
 
 
 
 
 
 
 
 
 
 
 

my_flash program