This project uses one channel from an RC receiver to control the optical zoom of a Sony FCB EX11D block camera. An Arduino reads the receiver pulse and sends Sony VISCA commands to the camera.
Hardware
- Sony FCB EX11D camera block
- Arduino Pro Mini running at 3.3 V
- Spektrum DX6i transmitter
- Spektrum AR6200 receiver
- Composite video monitor
- Regulated camera and controller power supplies
The FCB EX11D provides 10 times optical zoom and an NTSC composite video output. Sony specifies a camera supply of 6 to 12 V DC. The serial control port uses VISCA at CMOS 5 V signal levels. The camera accepts 9600, 19200 or 38400 bit/s. This example uses 9600 bit/s.
Connections
- RC receiver elevator signal to Arduino digital pin 3
- Arduino serial transmit to camera RxD
- Arduino ground, receiver ground and camera signal ground connected together
- Camera composite video output to the monitor
- Camera power from a regulated 6 to 12 V supply
Check the voltage of the receiver signal before connecting it to a 3.3 V Arduino. Receivers powered from 5 V do not all use the same signal voltage. Add a divider or a proper level shifter if the pulse exceeds the input limit of the controller.
The camera RxD input recognizes a 3.3 V Arduino high level. The camera TxD output is a 5 V CMOS signal, so it must not be connected directly to a 3.3 V input. This simple example sends commands only and leaves camera TxD disconnected. A complete controller should use level conversion and read the VISCA acknowledgement and completion packets.
How the control works
A normal RC channel produces a pulse close to 1000 through 2000 microseconds. The center is normally near 1500 microseconds. The program measures one pulse, applies a dead band around the center and sends one of three VISCA packets: zoom in, zoom out or stop.
The code below reads the pulse once per loop, sends a packet only when the requested state changes and keeps every VISCA packet together.
#include <SoftwareSerial.h>
const byte rcPin = 3;
const byte cameraRxPin = 10; // Not connected in this transmit only example
const byte cameraTxPin = 11; // Connect to camera RxD
SoftwareSerial cameraSerial(cameraRxPin, cameraTxPin);
const byte addressSet[] = {0x88, 0x30, 0x01, 0xFF};
const byte interfaceClear[] = {0x88, 0x01, 0x00, 0x01, 0xFF};
const byte zoomIn[] = {0x81, 0x01, 0x04, 0x07, 0x23, 0xFF};
const byte zoomOut[] = {0x81, 0x01, 0x04, 0x07, 0x33, 0xFF};
const byte zoomStop[] = {0x81, 0x01, 0x04, 0x07, 0x00, 0xFF};
enum ZoomState { STOPPED, TELE, WIDE };
ZoomState lastState = STOPPED;
template <size_t N>
void sendPacket(const byte (&packet)[N]) {
cameraSerial.write(packet, N);
}
void setup() {
pinMode(rcPin, INPUT);
cameraSerial.begin(9600);
delay(500);
sendPacket(addressSet);
delay(100);
sendPacket(interfaceClear);
delay(100);
sendPacket(zoomStop);
}
void loop() {
unsigned long pulse = pulseIn(rcPin, HIGH, 25000UL);
ZoomState nextState = STOPPED;
if (pulse != 0) {
if (pulse > 1550) nextState = TELE;
else if (pulse < 1400) nextState = WIDE;
}
if (nextState != lastState) {
if (nextState == TELE) sendPacket(zoomIn);
else if (nextState == WIDE) sendPacket(zoomOut);
else sendPacket(zoomStop);
lastState = nextState;
}
}
The values 0x23 and 0x33 request variable speed tele and wide movement at speed 3. Sony allows speed values from 0 through 7 in these commands.
Practical improvements
For use on a moving platform, add a signal loss timeout, read VISCA replies, strain relieve every connector and use a separate regulator with enough current for the lens motor. Set the transmitter failsafe so loss of the RC signal stops the zoom. A three position switch gives more predictable control than a spring centered stick.
Sony lists the FCB EX11D at about 95 g before the controller and wiring. Measure the complete installed payload and update the aircraft balance before flight.
Hackaday featured this project in Controlling A Block Camera With An RC Transmitter. The command details and signal levels come from the Sony FCB EX11D technical documentation.
No comments:
Post a Comment