Hi folks,
First time posting here!
I'm working on a controller for my camera. Purpose is to control rec/stop with a button, and the iris ("aperture") with a rotary encoder. In the attachment you can see the code, my setup and what a 'default' LANC circuit looks like. The code is a combination of two sets of code:
and:
The board I'm using is a Beetle v1.1 by DFrobot. I've connected the rotary encoder to A0 and A1. The rotary encoder is also connected to the Vin and Ground pins of the Beetle.
The setup works somewhat. I have two questions for the community I hope to get answered:
-
When I turn the rotary encoder the iris will open/close most of the times. But sometimes (seemingly random) the iris will suddenly open/close the opposite way, or take multiple steps in one. It seems the 'steps' of the rotary encoder aren't reliably being recognized. Am I doing something wrong coding wise?
-
I would like the iris to open/close slower. At least two 'steps' of the rotary encoder for one iris stop. Is there an easy way to 'slow' this down? Or do I have to work with a counter or something? (Which feels cumbersome.)
More information about the LANC protocol can be found here: http://www.boehmel.de/lanc .
/*
SIMPLE LANC REMOTE
Version 1.0
Sends LANC commands to the LANC port of a video camera.
Tested with a Canon XF300 camcorder
For the interface circuit interface see
http://controlyourcamera.blogspot.com/2011/02/arduino-controlled-video-recording-over.html
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 cmdPin 10
#define lancPin 9
#define recButton 11
#define irisopen A0
#define irisclose A1
int cmdRepeatCount;
int bitDuration = 104; //Duration of one LANC bit in microseconds.
int counter = 0;
int aState;
int aLastState;
//Start-stop video recording
boolean REC[] = {LOW,LOW,LOW,HIGH,HIGH,LOW,LOW,LOW, LOW,LOW,HIGH,HIGH,LOW,LOW,HIGH,HIGH}; //18 33
//IRIS open
boolean IRIS_OPEN[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,HIGH,LOW,HIGH,LOW,HIGH}; //28 55
//IRIS close
boolean IRIS_CLOSE[] = {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW,LOW, LOW,HIGH,LOW,HIGH,LOW,LOW,HIGH,HIGH}; //28 53
void setup() {
pinMode(lancPin, INPUT); //listens to the LANC line
pinMode(cmdPin, OUTPUT); //writes to the LANC line
pinMode(recButton, INPUT); //start-stop recording button
digitalWrite(recButton, HIGH); //turn on an internal pull up resistor
pinMode(irisopen, INPUT);
pinMode(irisclose, INPUT);
digitalWrite(cmdPin, LOW); //set LANC line to +5V
delay(5000); //Wait for camera to power up completly
bitDuration = bitDuration - 8; //Writing to the digital port takes about 8 microseconds so only 96 microseconds are left for each bit
Serial.begin (9600);
aLastState = digitalRead(irisopen);
}
void loop() {
aState = digitalRead(irisopen);
if (aState != aLastState){
if (digitalRead(irisclose) != aState) {
lancCommand(IRIS_OPEN);
} else {
lancCommand(IRIS_CLOSE);
}
}
aLastState = aState;
if (!digitalRead(recButton)) {
lancCommand(REC);
}
}
void lancCommand(boolean lancBit[]) {
cmdRepeatCount = 0;
while (cmdRepeatCount < 5) { //repeat 5 times to make sure the camera accepts the command
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
//Write the 8 bits of byte 0
//Note that the command bits have to be put out in reverse order with the least significant, right-most bit (bit 0) first
for (int i=7; i>-1; i--) {
digitalWrite(cmdPin, lancBit[i]); //Write bits.
delayMicroseconds(bitDuration);
}
//Byte 0 is written now put LANC line back to +5V
digitalWrite(cmdPin, LOW);
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
//Write the 8 bits of Byte 1
//Note that the command bits have to be put out in reverse order with the least significant, right-most bit (bit 0) first
for (int i=15; i>7; i--) {
digitalWrite(cmdPin,lancBit[i]); //Write bits
delayMicroseconds(bitDuration);
}
//Byte 1 is written now put LANC line back to +5V
digitalWrite(cmdPin, LOW);
cmdRepeatCount++; //increase repeat count by 1
/*Control bytes 0 and 1 are written, now don’t care what happens in Bytes 2 to 7
and just wait for the next start bit after a long pause to send the first two command bytes again.*/
}//While cmdRepeatCount < 5
}
lanc_controller_rotary.ino (4.27 KB)