Sunday, February 13, 2011

Finding out LANC remote commands

To find the commands of a LANC remote you need to solder a LANC extension cable with two additional wires going to the Arduino.

Attention! If your camera works with a LANC voltage of more than 5V this solution can't be used.



All LANC commands of a Canon ZR-1000 LANC remote for use with e.g. the previously mentioned USB to LANC cable.


Arduino sketch that repeatetly prints byte 0 and byte 1 of the LANC packet to the Serial Monitor in the Arduino developing environment. Press a button on the remote and watch the command appear.
/*
LANC SNIFFER
Version 1.0
Finds out LANC commands from a REMOTE
For the interface ciruit see 
Feel free to use this code in any way you want.
2011, Martin Koch

"LANC" is a registered trademark of SONY.
CANON calls their LANC compatible port "REMOTE".
*/

#define lancPin 11

int bitDuration = 104; //Duration of one LANC bit in microseconds. 

int lancBit[16];


void setup() {
        Serial.begin(9600); //open the serial port
 pinMode(lancPin, INPUT); //listens to the LANC line
        delay(5000); //Wait for camera to power up completly
        bitDuration = bitDuration- 8; //Reading the digital port takes about 8 microseconds so only 96 microseconds are left for each bit
}

void loop() {
  readLancCommand();
  delay(1000);
}

void readLancCommand() {
       
     while (pulseIn(lancPin, HIGH) < 5000) {   
      //"pulseIn, HIGH" catches any 0V TO +5V TRANSITION and waits until the LANC line goes back to 0V 
      //"pulseIn" also returns the pulse duration so we can check if the previous +5V duration was long enough (>5ms) to be the pause before a new 8 byte data packet
      //Loop till pulse duration is >5ms
     }

    //LOW after long pause means the START bit of Byte 0 is here
    delayMicroseconds(bitDuration);  //wait START bit duration
    delayMicroseconds(bitDuration/2); //wait until the middle of bit 0 of byte 0

    //Read the 8 bits of byte 0 
    //Note that the command bits come in in reverse order with the least significant, right-most bit (bit 0) first
    for (int i=7; i>-1; i--) {
      lancBit[i] = digitalRead(lancPin);  //read bits. 
      delayMicroseconds(bitDuration); 
    }
   
    //Byte 0 is read
      
     delayMicroseconds(10); //make sure to be in the stop bit before byte 1
      
      while (digitalRead(lancPin)) { 
        //Loop as long as the LANC line is +5V during the stop bit
      }

      //0V after the previous stop bit means the START bit of Byte 1 is here
      delayMicroseconds(bitDuration);  //wait START bit duration
      delayMicroseconds(bitDuration/2); //wait until the middle of bit 0 of byte 1
      
      //Read the 8 bits of Byte 1
      //Note that the command bits have to be read in reverse order with the least significant, right-most bit (bit 0) first
      for (int i=15; i>7; i--) {
        lancBit[i] = digitalRead(lancPin); //read bits 
 delayMicroseconds(bitDuration);
      }
 
      //Byte 1 is read

   
      //Print byte 0 and byte 1 to the Serial Monitor console of the Arduino developing environment
      Serial.println("BITS: ");
      for (int i=0; i<16; i++) {
        Serial.print((lancBit[i]-1)*-1); //invert the bits
        if (i==7) Serial.print(" ");                        
      }  
      Serial.println("");
}
If you try this with other LANC remotes please post your findings (command / hex values) in the comments. I'm especially interested in the additional commands of the Canon ZR-2000 LANC remote.
I found out the useful PUSH AF code of the ZR-2000 by trial and error. It is 2843 and has to be send repeatetly for a second or two in order to have an effect. The camera has to be in manual focus mode and Push AF invokes auto focus temporarily

3 comments:

  1. Quite interesting reading. I'm trying to get the other direction working: I'd like to control an Arduino from a LANC controller (Canon ZR-1000). If I got your articles right, I would need to create the reference frame.

    Any hints or ideas?

    Thanks

    Klaus

    ReplyDelete
  2. Dear Martin,

    First of all great thank you for your work!

    I have problem implementing the PUSH AF code (2843) in my Canon HF S G30 camera.

    I simple replaced the REC (6) binary code for the 2842 bin value but nothing happens...
    Do I make a mistake? Maybe the push AF has a push only behavior and that is the reason?

    Would appreciate your help,


    Best,

    Lajos

    ReplyDelete
  3. Is there a way I can ask a question here?

    ReplyDelete