Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Sketch to send a Shutter open command via IR to SONY A230 DSLR Camera

This Sketch was developed to allow some time-lapse photography with my Sony A230 DSLR Camera. I found out about the Sony protocol by looking at http://www.sbprojects.com/knowledge/ir/sirc.htm to get the timing. The command was found from a remote I got for my camera and I used http://playground.arduino.cc/Code/InfraredReceivers and IRAnalyzer.pde to analyze the command and get the actual code being sent using my Arduino.

The sketch did not work at first with my camera so I had to fudge the timing of the 40kHz signal to get it to work. It has worked flawlessly since I modified the timing. You may have to fiddle with the timing of the delays in routines burst() and quiet() if it doesn't work with you.

The code SCodeBits is the code I use to fire the shutter on the Camera via IR. The code S2CodeBits gives a shutter speed twice as long as what is set on the camera, I don't use this code.

The TimeBetweenShots variable can be a really big number and is what sets the delay between shutter firings. Just set to what you require.

The circuit is shown in the code header below and is just an IR LED from an old remote control in series with a 150 ohm resistor to protect the LED from overcurrent. You can reduce the resistor value to increase the range of the IR, but be careful you don't burn out the LED or destroy the output pin of the ATmega chip used in the Arduino.

The Begin LED on the Arduino board is flashed to let you know when a code is sent.

When testing use a mobile phone camera or webcam to view the IR LED, it will show up on screen, letting you know it is at least illuminating.


Code

I hope you find this sketch useful, no guarantees though.

/* This works on my Camera but your mileage may vary
* You may have to modify the timings if you have problems
* File....... MyIRController.pde
* Purpose.... To send Shutter open IR command to SONY A230 DSLR Camera
* Author..... Jim Park
* E-mail..... jim(d_o_t)buzz(a_t)gmail(d_o_t)com
* Started.... 17 May 2010
*
*         
*            IR Circuit
*         IR LED     150R
* Pin 2 ----|>|-----VVVVV----GND
*/

// Some Declarations
unsigned long TimeBetweenShots = 60000;    // Time in mS 60000 = 60 Seconds
int IRled = 2;                // IR Output Signal to Anode of IR LED 
// Cathode of IR LED to ground through a 150 Ohm Resistor.
int Begin = 13;               // Indicates Shutter Start on LED

// Code to send Shutter release command B4B8F
int SCodeBits[] = {1,0,1,1,0,1,0,0,1,0,1,1,1,0,0,0,1,1,1,1};

// Code to send 2 X delay Shutter release command ECB8F (Not used)
int S2CodeBits[] = {1,1,1,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,1,1};

void setup()
{
  // Setup IRLed and Begin Led Pins as outputs
  pinMode(IRled, OUTPUT);      // sets the digital pin as output
  pinMode(Begin, OUTPUT);      // sets the digital pin as output
}

// Infinite Loop 
void loop()
{
  digitalWrite(Begin, HIGH);  // Signal Begin LED ON

  for (int i=1; i <= 3; i++)  // Send Command 3 times as per Sony Specs
  {
    header();                    // Send the Start header
    for (int i=0; i <= 19; i++)  // Loop to send the bits
    {
          if(SCodeBits[i] == 1)  // Is Data_is_One to be sent ?
          {
            Data_is_One();              // Yes, send a Data_is_One bit
          }
          else                  // No, Data_is_Zero to be sent
          {
            Data_is_Zero();              // Send a Data_is_Zero bit
          }
    }
    delay(11);                  // Delay Padding to give approx 45mS between command starts
  }
  digitalWrite(Begin, LOW);     // Begin LED OFF
  delay(TimeBetweenShots);      // Hang about wasting time before next shot
}

// Routine to give the 40kHz burst signal
void burst()                   // 40KHz burst
{
  digitalWrite(IRled, HIGH);   // sets the pin on
  delayMicroseconds(10);       // pauses for 13 microseconds  (fudged to 10uS Delay)   
  digitalWrite(IRled, LOW);    // sets the pin off
  delayMicroseconds(8);        // pauses for 12 microseconds   (fudged to 8uS Delay)
}

// Routine to give a quiet period of data
void quiet()                   // Quiet burst
{
  digitalWrite(IRled, LOW);    // sets the pin off
  delayMicroseconds(10);       // pauses for 13 microseconds   (fudged to 10uS Delay)  
  digitalWrite(IRled, LOW);    // sets the pin off
  delayMicroseconds(8);        // pauses for 12 microseconds    (fudged to 8uS Delay)
}

// Routine to send header data burst
// This allows the IR receiver to set its AGC (Gain)
// Header Burst Timing is 96 * 0.025uS = 2.4mS
// Quiet Timing is 24 * 0.025uS = 600uS
void header() 
{
    for (int i=1; i <= 96; i++){
      burst();                // 40kHz burst
    }
    for (int i=1; i <= 24; i++){
      quiet();                // No 40 kHz
    }
}

// Routine to send one data burst
// Burst Timing is 48 * 0.025uS = 1.2mS
// Quiet Timing is 24 * 0.025uS = 600uS
void Data_is_One()
{
    for (int i=1; i <= 48; i++){
      burst();                // 40kHz burst
    }
    for (int i=1; i <= 24; i++){
      quiet();                // No 40 kHz
    }
}

// Routine to send zero data burst
// Burst Timing is 24 * 0.025uS = 600uS
// Quiet Timing is 24 * 0.025uS = 600uS
void Data_is_Zero()
{
    for (int i=1; i <= 24; i++){
      burst();                // 40 kHz burst
    }
    for (int i=1; i <= 24; i++){
      quiet();                // No 40 kHz 
    }
}