Below is some serial snooping capture from the V303 serial port:
I have not tried to decipher this protocol, but most likely it will be similar to ZeroUAV YS-X4. This could be MAVlink protocol, but customized by ZeroUAV :
YS-X6 serial protocol
20120514
Custom data transmission format
Transmission characteristics: baud rate 115200 8 bits no
parity 1 stop bit no hardware flow controlData Format: without stated are the
least significant bit firstDownlink:Output ports: On the completion of the
power-on initialization, flight control COM1 and COM3 are so agreed
output.Transmission order of the beginning of the frame flag, data, parity bit,
finished a wait 200ms repeat renewal, or 5 frames per second.
共99字节:
1、
the flag at the beginning of frame:(0~3)
$STP
2、
GPS data:
Aircraft Latitude 4
bytes float,单位为度,IEEE浮点格式,低位在前,下同(4~7)
Aircraft longitude 4
bytes float,单位为度 (8~11)
Target point
Longitude 4
bytes float,单位为度 (12~15)
Target point latitude 4 bytes float,单位为度 (16~19)
The heading angle 4
bytes float,radians(20~23)due north to 0, clockwise is positive
Star Search 1 byte uchar,将其直接显示即可,单位为颗 (24)
Year 1 byte uchar (25)
Month 1 byte uchar (26)
Day 1 byte uchar (27)
When 1 byte uchar (28)
Points 1 byte uchar (29)
Seconds 1 byte uchar (30)
Uploaded total number of waypoints 1 byte
uchar,(31),only
for automatic navigation
3、
manual rudder format:
Rudder 1 byte UCHAR, 100 to 200,
unsigned integer, 0 for no input (32)
Aileron 1 byte UCHAR, 100 to 200,
unsigned integer, 0 for no input (33)
Elevator 1 byte UCHAR, 100 to 200,
unsigned integer, 0 for no input (34)
Throttle 1 byte UCHAR, 100 to 200,
unsigned integer, 0 for no input (35)
4、
actual rudder surface state:
Rudder 1 byte uchar, 100 ~ 200,
unsigned integer (36)
Aileron 1 byte uchar, 100 ~ 200,
unsigned integer (37)
Elevator 1 byte uchar, 100 ~ 200,
unsigned integer (38)
Throttle 1 byte uchar, 100 ~ 200,
unsigned integer (39)
5、
Other:
_Y To speed 2 bytes ushort
filtering unit for cm / s (40 to 41)
Boot time 2 bytes ushort (42 to
43), seconds
Reserved 1 byte char (44)
Reserved 1 byte uchar, (45)
Distance from the take-off
point (high) byte UCHAR, (46), in meters * 256;
PTZ around point radius of 1
byte char (47), in meters
Pressure from 2 bytes int
height, the unit decimeter (48 to 49)
GPS velx 2 bytes ushort, unit
cm / s (50 to 51)
Distance from the take-off
point (low) byte UCHAR, (52), in meters;
Receiver status byte char (53) 0
is open, also receive remote control commands, off, automatic state
Shake coefficient 1 byte uchar
(54)
PDOP value of 1 byte uchar,
(55)
Vibration coefficient 1 byte
uchar (56)
Temperature 1 byte uchar, in
degrees, (57)
Right to the acceleration 2
bytes short (58 to 59)
Backward acceleration 2 bytes
short (60 to 61)
Pitch angle 4 bytes int (62 to
65) in degrees, Yang is overlooking the negative
Roll angle 4 bytes int (66 to
69) units for the degree of left-right negative
Flight control voltage value 2
bytes ushort (70 to 71) the value / 4096 * 25 voltage value
The downward acceleration of 2
bytes short (72 to 73)
Current task number (to which
point) 1 byte uchar, from 0 to 255 unsigned integer (74), from 0 to 1 point
Current control status byte
UCHAR, 0x00 manual, 0x01 auto-hover automatic navigation, 0x02, 0x04 to the
point, 0x07 to set state, 0x08 gyro cleared 0x0b return landing (75)
Power consumption 2bytes
ushort, (76 ~ 77), in mA
Alarm flag 1 byte UCHAR (78) is
1, low voltage, the phone should vibrate, is 0, no alarm;Filtered _D the 1 byte
uchar,, velocity (high) units of cm / s * 256 (79)
The rudder position 1 byte
UCHAR, (80)Aileron-bit byte UCHAR, (81)
The flipper bit 1 byte uchar
(82)
After filtering _X 1 byte uchar
speed (high), in units of cm / s * 256 (83)
Set target height 2 bytes, int,
in decimeter, (84 ~ 85)
Reserved 3 bytes ushort (86 to
88)
Filtered _D 1 byte uchar, speed
(low) to cm / s (89)
Reserved 3 bytes ushort (90 to
92)
Filtered _X 1 byte uchar, speed
(low) to cm / s (93)
GPS vely 2 bytes ushort, unit
cm / s (94 to 95)
Version No. 2 byte (96 to 97)
6、
End of the frame checksum:
Cumulative number of bytes from
the header to the previous bytes (98 bytes) unsigned single。uchar (98)
Below is the Arduino code to decode this data transmitted by the quadcopter (copied from ArducamOSD):
#define SERIALBUFFERSIZE 512
static uint8_t serialBuffer[SERIALBUFFERSIZE]; // this hold the imcoming string from serial O string
static uint8_t readIndex;
static uint8_t receiverIndex = 0;
static uint8_t packetStart = 0;
union u_float_ {
byte b[4];
float floatvalue;
} u_float;
union u_int16_ {
byte b[2];
int16_t intvalue;
} u_int16;
union u_uint16_ {
byte b[2];
uint16_t uintvalue;
} u_uint16;
uint32_t read32() {
uint32_t t = read16();
t |= (uint32_t)read16()<<16;
return t;
}
#define abs_(x) ((x) > 0?(x):-(x))
uint16_t read16() {
uint16_t t = read8();
t |= (uint16_t)read8()<<8;
return t;
}
uint8_t read8() {
return serialBuffer[readIndex++];
}
void read_serial(){
//grabing data
while(Serial.available() > 0) {
uint8_t c = Serial.read();
serialBuffer[receiverIndex] = c;
//serialSymb = c;
// Find '$STP' symb
if (c == 'P' && receiverIndex > 4) {
uint8_t c0 = serialBuffer[receiverIndex-3], c1 = serialBuffer[receiverIndex-2], c2 = serialBuffer[receiverIndex-1], c3 = serialBuffer[receiverIndex];
if (c0 == '$' && c1 == 'S' && c2 == 'T' && c3 == 'P') {
if (packetStart == 0) {
// Start gathering frame
packetStart = 1;
receiverIndex = 4; // 0..3 in frame == $STP
continue;
} else
if (packetStart == 1) {
// End frame gathering
serialSymb = receiverIndex;
serialPackets++;
serialReady = 1;
packetStart = 0;
// Parse frame
// 1) Flight mode
base_mode = serialBuffer[75];
// 2) Voltage
u_uint16.b[0] = serialBuffer[70];
u_uint16.b[1] = serialBuffer[71];
//uint16_t battVoltage = serialBuffer[71]*256 + serialBuffer[70];
osd_vbat_A = 10.0f*(float)u_uint16.uintvalue/2048;
// 3) GPS
osd_satellites_visible = serialBuffer[24];
// Latitude
u_float.b[0] = serialBuffer[4];
u_float.b[1] = serialBuffer[5];
u_float.b[2] = serialBuffer[6];
u_float.b[3] = serialBuffer[7];
osd_lat = u_float.floatvalue;
// Longitude
u_float.b[0] = serialBuffer[8];
u_float.b[1] = serialBuffer[9];
u_float.b[2] = serialBuffer[10];
u_float.b[3] = serialBuffer[11];
osd_lon = u_float.floatvalue;
// 4) Altitude, decimeters
u_int16.b[0] = serialBuffer[48];
u_int16.b[1] = serialBuffer[49];
osd_alt = 0.1*(float)u_int16.intvalue;
// 5) Home distance
// Distance from the take-off point (high) byte UCHAR, (46), in meters;
// Distance from the take-off point (low) byte UCHAR, (52), in meters
osd_home_distance = serialBuffer[46]*256 + serialBuffer[52];
// 6) Speed
// GPS velx 2 bytes ushort, unit cm / s (50 to 51)
u_int16.b[0] = serialBuffer[50];
u_int16.b[1] = serialBuffer[51];
float vx = (float)u_int16.intvalue;
u_int16.b[0] = serialBuffer[94];
u_int16.b[1] = serialBuffer[95];
float vy = (float)u_int16.intvalue;
osd_gpsspeed = 0.036*sqrt(sq(vx) + sq(vy));
// 7) Low battery warning
// Alarm flag 1 byte UCHAR (78), 1 - vibrate
}
}
}
receiverIndex++;
if (receiverIndex >= SERIALBUFFERSIZE-1) {
receiverIndex = 0;
packetStart = 0;
}
}
}
static uint8_t serialBuffer[SERIALBUFFERSIZE]; // this hold the imcoming string from serial O string
static uint8_t readIndex;
static uint8_t receiverIndex = 0;
static uint8_t packetStart = 0;
union u_float_ {
byte b[4];
float floatvalue;
} u_float;
union u_int16_ {
byte b[2];
int16_t intvalue;
} u_int16;
union u_uint16_ {
byte b[2];
uint16_t uintvalue;
} u_uint16;
uint32_t read32() {
uint32_t t = read16();
t |= (uint32_t)read16()<<16;
return t;
}
#define abs_(x) ((x) > 0?(x):-(x))
uint16_t read16() {
uint16_t t = read8();
t |= (uint16_t)read8()<<8;
return t;
}
uint8_t read8() {
return serialBuffer[readIndex++];
}
void read_serial(){
//grabing data
while(Serial.available() > 0) {
uint8_t c = Serial.read();
serialBuffer[receiverIndex] = c;
//serialSymb = c;
// Find '$STP' symb
if (c == 'P' && receiverIndex > 4) {
uint8_t c0 = serialBuffer[receiverIndex-3], c1 = serialBuffer[receiverIndex-2], c2 = serialBuffer[receiverIndex-1], c3 = serialBuffer[receiverIndex];
if (c0 == '$' && c1 == 'S' && c2 == 'T' && c3 == 'P') {
if (packetStart == 0) {
// Start gathering frame
packetStart = 1;
receiverIndex = 4; // 0..3 in frame == $STP
continue;
} else
if (packetStart == 1) {
// End frame gathering
serialSymb = receiverIndex;
serialPackets++;
serialReady = 1;
packetStart = 0;
// Parse frame
// 1) Flight mode
base_mode = serialBuffer[75];
// 2) Voltage
u_uint16.b[0] = serialBuffer[70];
u_uint16.b[1] = serialBuffer[71];
//uint16_t battVoltage = serialBuffer[71]*256 + serialBuffer[70];
osd_vbat_A = 10.0f*(float)u_uint16.uintvalue/2048;
// 3) GPS
osd_satellites_visible = serialBuffer[24];
// Latitude
u_float.b[0] = serialBuffer[4];
u_float.b[1] = serialBuffer[5];
u_float.b[2] = serialBuffer[6];
u_float.b[3] = serialBuffer[7];
osd_lat = u_float.floatvalue;
// Longitude
u_float.b[0] = serialBuffer[8];
u_float.b[1] = serialBuffer[9];
u_float.b[2] = serialBuffer[10];
u_float.b[3] = serialBuffer[11];
osd_lon = u_float.floatvalue;
// 4) Altitude, decimeters
u_int16.b[0] = serialBuffer[48];
u_int16.b[1] = serialBuffer[49];
osd_alt = 0.1*(float)u_int16.intvalue;
// 5) Home distance
// Distance from the take-off point (high) byte UCHAR, (46), in meters;
// Distance from the take-off point (low) byte UCHAR, (52), in meters
osd_home_distance = serialBuffer[46]*256 + serialBuffer[52];
// 6) Speed
// GPS velx 2 bytes ushort, unit cm / s (50 to 51)
u_int16.b[0] = serialBuffer[50];
u_int16.b[1] = serialBuffer[51];
float vx = (float)u_int16.intvalue;
u_int16.b[0] = serialBuffer[94];
u_int16.b[1] = serialBuffer[95];
float vy = (float)u_int16.intvalue;
osd_gpsspeed = 0.036*sqrt(sq(vx) + sq(vy));
// 7) Low battery warning
// Alarm flag 1 byte UCHAR (78), 1 - vibrate
}
}
}
receiverIndex++;
if (receiverIndex >= SERIALBUFFERSIZE-1) {
receiverIndex = 0;
packetStart = 0;
}
}
}