- Posts: 3
- Joined: Mon Mar 18, 2019 10:13 pm
- Real Name: Martijn Stam
For a video conferencing project I need to get remote control over S.BUS working for the Blackmagic Pocket Cinema Camera 4K with latest firmware 4.7.1.
I wrote code in C++ and I'm using an FTDI FT232 USB to TTL serial converter. All seems to work fine except that the camera doesn't respond to anything I send. It's important I get it working on the x86 architecture and not Arduino because it's not powerful enough.
Who likes to elaborate to get it working please?
serial.cpp:
sbus.h:
I wrote code in C++ and I'm using an FTDI FT232 USB to TTL serial converter. All seems to work fine except that the camera doesn't respond to anything I send. It's important I get it working on the x86 architecture and not Arduino because it's not powerful enough.
Who likes to elaborate to get it working please?
serial.cpp:
- Code: Select all
/*
Camera S.BUS range 44-212, center 128
*/
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <linux/serial_core.h>
#include <iostream>
#include "sbus.h"
#define BAUD_RATE B38400
#define DEVICE "/dev/ttyUSB0"
int sbus_fd, n;
static uint8_t packet[25];
static uint8_t sbusData[25];
static struct termios orig_termios;
void SBUS::create_packet(uint16_t* channels)
{
packet[0] = _sbusHeader;
if (channels) {
packet[1] = (uint8_t) ((channels[0] & 0x07FF));
packet[2] = (uint8_t) ((channels[0] & 0x07FF)>>8 | (channels[1] & 0x07FF)<<3);
packet[3] = (uint8_t) ((channels[1] & 0x07FF)>>5 | (channels[2] & 0x07FF)<<6);
packet[4] = (uint8_t) ((channels[2] & 0x07FF)>>2);
packet[5] = (uint8_t) ((channels[2] & 0x07FF)>>10 | (channels[3] & 0x07FF)<<1);
packet[6] = (uint8_t) ((channels[3] & 0x07FF)>>7 | (channels[4] & 0x07FF)<<4);
packet[7] = (uint8_t) ((channels[4] & 0x07FF)>>4 | (channels[5] & 0x07FF)<<7);
packet[8] = (uint8_t) ((channels[5] & 0x07FF)>>1);
packet[9] = (uint8_t) ((channels[5] & 0x07FF)>>9 | (channels[6] & 0x07FF)<<2);
packet[10] = (uint8_t) ((channels[6] & 0x07FF)>>6 | (channels[7] & 0x07FF)<<5);
packet[11] = (uint8_t) ((channels[7] & 0x07FF)>>3);
packet[12] = (uint8_t) ((channels[8] & 0x07FF));
packet[13] = (uint8_t) ((channels[8] & 0x07FF)>>8 | (channels[9] & 0x07FF)<<3);
packet[14] = (uint8_t) ((channels[9] & 0x07FF)>>5 | (channels[10] & 0x07FF)<<6);
packet[15] = (uint8_t) ((channels[10] & 0x07FF)>>2);
packet[16] = (uint8_t) ((channels[10] & 0x07FF)>>10 | (channels[11] & 0x07FF)<<1);
packet[17] = (uint8_t) ((channels[11] & 0x07FF)>>7 | (channels[12] & 0x07FF)<<4);
packet[18] = (uint8_t) ((channels[12] & 0x07FF)>>4 | (channels[13] & 0x07FF)<<7);
packet[19] = (uint8_t) ((channels[13] & 0x07FF)>>1);
packet[20] = (uint8_t) ((channels[13] & 0x07FF)>>9 | (channels[14] & 0x07FF)<<2);
packet[21] = (uint8_t) ((channels[14] & 0x07FF)>>6 | (channels[15] & 0x07FF)<<5);
packet[22] = (uint8_t) ((channels[15] & 0x07FF)>>3);
}
packet[23] = 0x00;
packet[24] = _sbusFooter;
memcpy(sbusData,packet,25);
//memcpy(servos,loc_servos,18);
/*for(int i = 0; i < 25; i++) {
printf("%x ", packet[i]);
}
printf("\n");*/
//printf("p 5: %x\n", packet[23]);
}
void SBUS::serial_config()
{
struct termios options;
sbus_fd = open(DEVICE, O_RDWR | O_NONBLOCK);
if (tcgetattr(sbus_fd, &options) != 0)
printf("\n Error! in getting attributes \n");
tcflush(sbus_fd, TCIFLUSH);
bzero(&options, sizeof(options));
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
options.c_cflag |= CLOCAL;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_cflag |= CSTOPB;
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
tcflush(sbus_fd, TCIFLUSH);
if ((tcsetattr(sbus_fd, TCSANOW, &options)) != 0)
printf("\n ERROR ! in Setting attributes\n");
int baud = 100000;
struct serial_struct serials;
if ((ioctl(sbus_fd, TIOCGSERIAL, &serials)) < 0)
printf("\n ERROR ! in Setting serial attributes\n");
serials.flags = ASYNC_SPD_CUST;
serials.custom_divisor = serials.baud_base / baud;
if ((ioctl(sbus_fd, TIOCSSERIAL, &serials)) < 0)
printf("\n ERROR ! in Setting custom baudrate\n");
ioctl(sbus_fd, TIOCGSERIAL, &serials);
tcflush(sbus_fd, TCIFLUSH);
}
void SBUS::serial_write()
{
n = write(sbus_fd, sbusData, 25);
//printf("%d\n", n);
if (n != 25)
printf("Write failed, written %i bytes\n", n);
}
void SBUS::serial_close()
{
close(sbus_fd);
}
int main() {
SBUS s;
uint16_t channels[16] = {0};
s.serial_config();
for (uint8_t i = 0; i < 16; i++) {
channels[i] = 128;
}
channels[5] = 200;
channels[6] = 200;
channels[7] = 200;
channels[8] = 200;
for ( uint16_t x = 0; x < 500000; x++) {
//while(true) {
/*if (x == 100) {
for (uint8_t i = 0; i < 16; i++) {
channels[i] = 45;
}
}
if (x == 250) {
for (uint8_t i = 0; i < 16; i++) {
channels[i] = 128;
}
}
if (x == 400) {
for (uint8_t i = 0; i < 16; i++) {
channels[i] = 45;
}
}*/
s.create_packet(channels);
s.serial_write();
usleep(14000);
}
s.serial_close();
return 0;
}
sbus.h:
- Code: Select all
#ifndef SBUS_h
#define SBUS_h
class SBUS{
public:
void create_packet(uint16_t* channels);
void serial_config();
void serial_write();
void serial_close();
private:
const uint32_t _sbusBaud = 100000;
static const uint8_t _numChannels = 16;
const uint8_t _sbusHeader = 0x0F;
const uint8_t _sbusFooter = 0x00;
};
#endif
- My setup
- bmmcpc.jpg (547.02 KiB) Viewed 2163 times