I have a digital photocamera mounted on my plane for aerial photography. It's just a simple camera, Fujifilm A170, cheap and provides pretty good quality of photos for this price - about $70, nothing sophisticated. I liked everything but the servo is used to take a photo. I know, it's the simplest way to do aerial photos using an airframe, however this method is so inconvenient. Then I decided, why I use mechanical solution when it's possible and better to use electronical?!
First of all I disassembled the camera. I think, it's interesting for you too to see what's inside:
Then I found out how the shot button works. It has two-position button, first for focus, second for shot. The button has 4 pins. Here is it:
Datasheet helped to define the meaning of the states and pins. Two of them turned out to be common. I soldered wires to have an external connection:When I short circuit two of the wires - focus process happens, when I short circuit the third wire with that couple - shot happens.
Moreover, I decided to make an external wires for the power. Really, why does the plane need to carry standard heavy Ni-Mh batteries when it's possible to power camera from the main LiPo battery?!
Here are them inside:
And a nice compact view from outside:
I've noticed that if the first and the third wires connected together and then short circuit the second with them, focus and shot happens one after another. It allowed me two use one relay instead of two, so I did:
Also, I have soldered pins for ArduPilot Mega relay:Then a few words about soft. Certainly, it's possible to control relay with mission scripting in APM Planner, however I wanted to control it with the switch on my transmitter. I connected a cable from the sixth channel of my transmitter to the sixth channel input of APM. Firstly, I created a simple function, which just turns on and off the relay and added control_camera() execution in the fast_loop, here is the code:
void control_camera(void) {
if (g.rc_6.radio_in < 1500) {
relay_off();
}
if (g.rc_6.radio_in > 1500) {
relay_on();
}
}
It works pretty good, but I had to take a photo "manually", then I decided to modify code to make it "auto". I have calculated the optimal altitude, speed and delay between the shots to cover the area below. After that I add the function, which makes photos every XX seconds. Here is this function:
int camera_flag = 0;
int camera_delay = 0;
int current_camera_timer = 0; // counter (in seconds)
int dds = 3; // how much time the relay is on while making a shot (in seconds)
int dbs = 10; // how much time to wait between shots (in seconds)
void control_camera(void) {
if (g.rc_6.radio_in < 1500) {
// turn the relay of or do nothing while the switch is off
if (camera_flag != 0) {
relay_off();
}
camera_flag = 0;
camera_delay = 0;
current_camera_timer = 0;
}
if (g.rc_6.radio_in > 1500) {
// while the switch is on - make photos
if (camera_delay == 1 && current_camera_timer > dbs) {
current_camera_timer = 0;
camera_delay = 0;
}
if (camera_delay == 0) {
if (current_camera_timer == 0 && camera_flag == 0) {
relay_on();
camera_flag = 1;
}
if (current_camera_timer > dds && camera_flag == 1) {
relay_off();
camera_flag = 0;
current_camera_timer = 0;
camera_delay = 1;
}
}
current_camera_timer++;
}
}
control_camera() execution is added to one_second_loop() function
Here are the calculations of the most optimal flight parametres for aerial photography flight:
h - altitude
v - speed
tetta1 - half angle of horizontal camera lenses view
tetta2 - half angle of vertical camera lenses view
alpha - factor of neighbour photos cover each other (from 0 to 1, I set 0.8)
f - camera lense focus
a/n - size of camera matrix divided by number of pixels in row (a~4mm, n~4000 for 10 mega pixels)
u - exposure time
t - time between shots
s - area of one photo coverage
w - distance between neighbour flight pathes
t = 2*h*(1-alpha)*tan(tetta1)/v
w = 2*h*(1-alpha)*tan(tetta2)
s = 4*(h^2)*((1-alpha)^2)*tan(tetta1)*tan(tetta2)
h = v*f*u*n/a - fly higher than this altitude to get non-blur photos
In the next version of my function I plan to replace constant time between shots by real-time, which will be based on mathematical calculations above.
I also would like to say special thanks to Darren and Yiangos Yiangou for their valuable advice.
Comments
Ritchie, maybe it could be a good idea to let admins of ArduPilot Mega wiki know about the code (because I didn't find any info about it there)? What do you think about it? Moreover, it would be good to modify that page, add new information, it's a little obsolete now.
Very nice article, thanks for sharing!
Can your camera turn on "manual focus" mode? If so, you can set the focus to infinity and eliminate the lag time, power use, and potential error of refocusing each shot.
Nice article, thanks! I have Canon camera, but it's so obsolete and heavy that even no one plane will lift it!
Just wondering, is it possible to use USB not only with Canon cameras? I think, yes, but some external microcontroller might be need.
Yes, I've read about use USB cable to remotely trigger the shutter, but only with Canon cameras using the "CHDK", look:http://chdk.wikia.com/wiki/USB_Remote_Cable
Thanks for posting your great job, Kirill!
Miquel, thanks for the link! It's very good solution and on higher level than mine.
I know, it's also possible to use USB port of the camera to make shots, control zoom, power on/off and etc. However, there is no any detailed description how it's done, that's why it's not so easy to do.
Ritchie, I likely didn't understand your question correctly. Now, I did :)
My camera, Fuji, works the same as yours. It's certainly possible just to click. It doesn't require to be held.
Yes, I added a timer to allow the camera time to finish, however the same result can be achieved using not 3 seconds delay as I set, but even 1 second. I tested and it works fine too, but I didn't like that APM relay turns on and off so fast, that's why I set 3 seconds.
Using one second delay will make the code simplier and shorter, because the period of the function execution is one second (added to one_second_loop() function).
You can read (I'm sorry,only spanish..) and see some pics here:
http://aerobotclubderobticadeaeronuticos.blogspot.com/2011/06/dispa...
I've thrown it in but its not remotely intuitive :D
I've got to check with you though as I've pulled out cameras from around the house and I can click the button which sets off the focus then shoot procedure. I have (about the house) three CyberShots, two sony camcorders, Canon DSLR and the GoPro and they all function with a click rather than hold.
If your timer is just to allow the camera time to finish then thats brilliant if however your Fuji needs to be held I'll need some more time (again).