CHDK Zoom and Shoot - Canon SX260

I'm trying to build a simple way to control the zoom and shoot functions with oversized buttons.

Basically one button zooms in, another zooms out, and a big red one to take the shot.

I've read the CHDK Wiki and realise I need to send different pulses to the camera for different functions -

1 pulse = zoom in one step
2 pulses = zoom out one step
3 pulses = shoot
4 pulses = zoom completely in
5 pulses = zoom completely out

I can get it to zoom in one step at a time with basic commands but struggling a bit now. Hence I'm here…

There's very limited information available for this and an I'm in way over my head. I've used CHDK and Arduino in the past but struggling to get started with this.

Any pointers from would be greatly appreciated.

Thanks.

Have you got the button code working?

Thought I'd come back to that once I made sure the zoom will work.

Your zoomShoot function is making sense but still working out how I can set different pulses. In my head this was going to be easy - it's only 2 switches , right :slight_smile:

I'll need a while to absorb everything I've read today - very long day - but it's all kind of making sense. Implementing it, however…

Just finished a lead-screw timelapse dolly that's taken longer than anticipated - maybe my brain just needs a rest :confused:

I should maybe explain why a total newbie is trying to do this. My Dad is slowly losing the use of his hands through Parkinsons, stroke and arthritis. He's been on at me to get him a new camera but there's just nothing he can hold. Of course I thought - EASY - I can just use CHDK via Arduino to zoom and trigger. Initially I thought I'd be using a CHDK script (I've used it in the past as a remote shutter) but then I need the USB pulsing method so I can also zoom.

So - here I am...

Sorry to hear about your dad. You're doing very good trying to help him.

Back to the project: you should start with the buttons. This is because you need something to trigger the zoom and shoot procedure.

Once you have the buttons code working, you can attach the zoomShoot() code I gave you in the other thread.

You cannot zoom the camera in the loop() function like you did, because that way you'll be calling it indefinitely. You need to control when to call the function. This is why I suggested you start with the code for the buttons.

What components do you have already?

Well - I'm actually just about to send the SX260 back as it's really bad in full auto. Really blown out highlights and washed out colour. Great photos shooting in full manual but totally defeats the purpose of the project.

However, I still fancy doing this as a learning project and it takes the pressure off a bit as I can get a bit obsessive once I get started on something. If it''s successful then will have a look at another Canon in the future. Can still experiment with the lowly A810 in the meantime…

Components - I was thinking of a Momentary (Spring-Return) Action Rotary Switch for zooming in and out - a kind of throttle action. Failing that two micro limit switches attached to a throttle action and a simple momentary switch for the shutter.

I have a CNC machine so everything else can be fabricated...

Right then - in my head (a vacuous, empty space) - all I have to do is define some buttons and call your function. That's the stumbling block… I'm guessing that I define (byte pulses)? Just not sure exactly what byte represents…

rough example:

const byte SHTR_LED_PIN = 6; // Uses PWM
const byte USB_PIN = 4;
const int switch_1 = 5; //button plugged to digital pin 5
int buttonState = 0;
uint8_t CONF_INTENSITY = 40;

void setup (){
pinMode(switch_1, INPUT);
pinMode(USB_PIN, OUTPUT);
digitalWrite(USB_PIN, LOW);

}

void loop(){
buttonState=digitalRead(switch_1);
if(buttonState==HIGH){
zoomShoot(1, 5) what goes in here? ;
}
}

void zoomShoot(byte pulses) {
analogWrite(SHTR_LED_PIN, CONF_INTENSITY); //

for (byte i=1; i<=pulses;i++) {
digitalWrite(USB_PIN, HIGH);
delay(120);
digitalWrite(USB_PIN, LOW);
delay(60);
}

delay(440);

digitalWrite(SHTR_LED_PIN, LOW);
}

"byte" is a data type that represents unsigned integers from 0 to 255 (a single unsigned byte).

My function:

void zoomShoot(byte pulses) {
 analogWrite(SHTR_LED_PIN, CONF_INTENSITY); // 

 for (byte i=1; i<=pulses;i++) {
   digitalWrite(USB_PIN, HIGH);   
   delay(120);
   digitalWrite(USB_PIN, LOW);
   delay(60);
 }

 delay(440);

 digitalWrite(SHTR_LED_PIN, LOW); 
}

receives values from 1 to 5, meaning the amount of pulses it must send to the USB_PIN (where the camera is connected to) according to the table below. If you want to zoom in one step, you send just one pulse, thus: zoomShoot(1). If you want the camera to shoot, you call my function with 3 pulses (see table below), like this: zoomShoot(3):

  • 1 pulse = zoom in one step. Example: zoomShot(1);
  • 2 pulses = zoom out one step. Example: zoomShot(2);
  • 3 pulses = shoot. Example: zoomShot(3);
  • 4 pulses = zoom completely in. Example: zoomShot(4);
  • 5 pulses = zoom completely out. Example: zoomShot(5);

I rewrote your code, adding some code to debounce the button, so it looks like this:

const byte SHTR_LED_PIN = 6;   // Uses PWM
const byte USB_PIN = 4;
const byte switch_1 = 5; //button plugged to digital pin 5
const byte CONF_INTENSITY = 40;
const byte debounceDelay = 30;    // the debounce time; increase if the output flickers


// Variables will change:
byte buttonState;             // the current reading from the input pin
byte lastButtonState = LOW;   // the previous reading from the input pin


long lastDebounceTime = 0;  // the last time the output pin was toggled

void setup() {
   pinMode(switch_1, INPUT);
   pinMode(USB_PIN, OUTPUT);
   digitalWrite(USB_PIN, LOW);
}

void loop() {
  int reading = digitalRead(switch_1 );
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
        zoomShoot(3);   // I used 3 so the camera can shoot. Other values (1..5) will mean different actions
      }
    }
  }
  
  lastButtonState = reading;
}

void zoomShoot(byte pulses) {
 analogWrite(SHTR_LED_PIN, CONF_INTENSITY); // 

 for (byte i=1; i<=pulses;i++) {
   digitalWrite(USB_PIN, HIGH);   
   delay(120);
   digitalWrite(USB_PIN, LOW);
   delay(60);
 }

 delay(440);

 digitalWrite(SHTR_LED_PIN, LOW); 
}

Thanks for all the help. I'm stumped as to why this isn't working though. I can see the pulses via an LED when I press the button but the camera fails to respond. Not the LED from PIN 6 - I put another one in to see the actual pulses.

Update - it was that bloody LED! Thought it was helping me but was really hindering me. Removed and all is good :slight_smile:

Happy days!!

The debounce code has thrown me a bit…

If I take it out I can get it to work zooming in and out. However, I do realise I need it in...

void loop() {
int reading1 = digitalRead(switch_1);
int reading2 = digitalRead(switch_2);

if (reading1 == HIGH) {
zoomShoot(4);
}

else if (reading2 == HIGH) {
zoomShoot(5);
}

}

Since the zoomShoot() procedure takes more than 50ms (it takes at least 620ms), it is ok to remove the debouncing methods, since when the button starts to bounce, the Arduino will be busy doing something else (in zoomShoot()), so it isn't a big deal. It is good practice, 'though.

So, in this specific scenario, not debouncing the button won't do much harm. You can leave the debouncing code out.

Will keep that in mind. Thanks again for you help. Will post back with further hardware developments.