Serial Communication
The information on this page refers to firmware v2.11e and higher.
Communication with the STorM32 board is possible through the serial interfaces USB, UART, and Bluetooth. Three sets of commands are available for serial communication:
- Simple Commands: This set has a very simple command structure, and is used for major tasks of the GUI.
- RC Commands: This set is targeted at a remote control of the STorM32 gimbal.
- Mavlink Commands: This set is "real" MAVLink.
The simple serial and the RC commands share many similarities, and could be considered the two sides of a coin (they both are in fact processed by the same code part in the firmware). They tend to be more efficient than the MAVLink commands. Any command of any set can be processed through any of the serial interfaces (USB, UART, and Bluetooth). However, when the MAVLink heartbeat is activated, then the UART accepts only MAVLink commands, and also Bluetooth may not be used anymore (USB still accepts all commands).
For understanding all details of the communication, it is generally best to peek into the source code of the GUI (which is included in any firmware package). It's written in Perl, and Perl is sufficiently primitive to understand the code easily.
Serial Communication - Simple Commands
This protocol for the communication via the serial interfaces follows these rules:
- The board responds to incoming commands by sending back a data stream of one or more characters, which is determined by the received command.
- The board is never sending/transmitting anything by itself, that is, a transmission is always started only as a reaction to an incoming command.
- The board is responding to any incoming command, be it valid or not.
Any data stream returned by the board ends with one of these characters:
- 'o': indicates that everything is ok, i.e. that the received command has been identified
- 'e': indicates that an error has occurred, i.e. that an invalid command has been received
- 't': indicates that a timeout has occurred, i.e. that a command which consists of several characters was not completed within a certain time window
- 'c': indicates that a checksum error has occurred
A checksum is invoked whenever data are transmitted, currently these are the 'p','g', and 'd' commands.
Command 't'
This command simply returns the character 'o'. Can be used by the host to check if the board is still connected.
Command 'v'
This command returns information on the installed firmware version, the name of the board, and the type of the board. The data stream is appended by a crc, and closed with the character 'o'.
Command 'g'
This command returns a data stream containing all parameter values. The data stream is appended by a crc, and closed with the character 'o'.
Command 'p'
This command sets all parameter values. The command character 'p' needs to be followed by a data stream containing all parameter values, plus a crc. It returns the character 'o'.
Command 'd'
Upon receipt of the command 'd' a data stream containing the current live data is transmitted. The live data is appended by a crc, and closed with the character 'o'. The respective C code snippet is as follows:
//send 32 data values uart_prepare_transmit(); ((u16*)fbuf)[(*len)++]= STATE; //state ((u16*)fbuf)[(*len)++]= status; //status ((u16*)fbuf)[(*len)++]= status2; //status2 ((u16*)fbuf)[(*len)++]= i2c_geterrorcntofdevice(IMU_I2CDEVNR)+i2c_geterrorcntofdevice(IMU2_I2CDEVNR); ((u16*)fbuf)[(*len)++]= adc_lipovoltage(); //lipo_voltage; ((u16*)fbuf)[(*len)++]= (u16)systicks; //timestamp ((u16*)fbuf)[(*len)++]= (u16)(1.0E6*fdT); //cycle time ((u16*)fbuf)[(*len)++]= (s16)(fImu1.imu.gx); ((u16*)fbuf)[(*len)++]= (s16)(fImu1.imu.gy); ((u16*)fbuf)[(*len)++]= (s16)(fImu1.imu.gz); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1.imu.ax); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1.imu.ay); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1.imu.az); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1AHRS.R.x); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1AHRS.R.y); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1AHRS.R.z); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fImu1Angle.Pitch); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fImu1Angle.Roll); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fImu1Angle.Yaw); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*cPID[PITCH].Cntrl); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*cPID[ROLL].Cntrl); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*cPID[YAW].Cntrl); ((u16*)fbuf)[(*len)++]= InputSrc.Pitch; ((u16*)fbuf)[(*len)++]= InputSrc.Roll; ((u16*)fbuf)[(*len)++]= InputSrc.Yaw; ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fImu2Angle.Pitch); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fImu2Angle.Roll); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fImu2Angle.Yaw); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fMag2Angle.Yaw); ((u16*)fbuf)[(*len)++]= (s16)(100.0f*fMag2Angle.Pitch); ((u16*)fbuf)[(*len)++]= (s16)(10000.0f*fImu1AHRS._imu_acc_confidence); ((u16*)fbuf)[(*len)++] = pack_functioninputvalues(&FunctionInputPulse); (*len)*=2; //add crc uint16_t crc= do_crc( fbuf, fbuf_len ); fbuf[fbuf_len++]= (u8)crc; //low byte fbuf[fbuf_len++]= (u8)(crc>>8); //high byte //end character uart_transmit_ackchar( closewith ); //this sends a 'o'
Command 's'
Upon receipt of the command 's' a data stream containing the current status data is transmitted. The data stream is appended by a crc, and closed with the character 'o'. The command is essentially identical to the 'd' command, except that it transmits only the first five data values.
Checksum
The checksum for protecting some data streams is the x25 16-bit crc used by Mavlink. C code can be found here.
Serial Communication - RC Commands
In addition to the simple serial commands described in the previous section, the o323bgc firmware also understands some messages targeted at remote control of the gimbal. These messages have a stricter data format, and potentially provide a higher level of transmission reliability.
The rules of the communication are exactly as before:
- The STorM32 board emits a message only upon request, but never by itself.
- Any received message is acknowledged by a message send back to the host.
The general structure of a data frame is:
* Startsign: 0xFA for incoming messages, and 0xFB for outgoing messages * Length: length of the payload, i.e. number of bytes of the data packet excluding
Start sign, Length byte, Command byte, and crc word * Command: the command byte * Payload: as many bytes as expected by the command * Checksum: x25 16-bit crc excluding start byte, as used by Mavlink; C code can be found here
The following commands can be send to the STorM32 controller:
CMD_GETVERSION (#1)
0xFA 0x00 0x01 crc-low-byte crc-high-byte
If an error occurred a CMD_ACK message will be emitted. Otherwise a message containing the firmware version, the setup layout version and board capabilities in this format will be emitted:
0xFB 0x06 0x00 data1-low data1-high data2-low data2-high data3-low data3-high crc-low-byte crc-high-byte
Data1 is the firmware version, data2 the setup layout version, and data3 holds the board capabilities value.
CMD_GETVERSIONSTR (#2)
0xFA 0x00 0x02 crc-low-byte crc-high-byte
If an error occurred a CMD_ACK message will be emitted. Otherwise a message containing the version string, name string and board string in this format will be emitted:
0xFB 0x30 0x02 data-stream crc-low-byte crc-high-byte
The data stream contains the 16 bytes version string, the 16 bytes name string and the 16 bytes board string.
CMD_GETPARAMETER (#3)
0xFA 0x02 0x03 data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and represents the number of the parameter which is requested. If an error occurred a CMD_ACK message will be emitted. Otherwise a message containing the parameter value in this format will be emitted:
0xFB 0x04 0x03 data1-low-byte data1-high-byte data2-low-byte data2-high-byte crc-low-byte crc-high-byte
Data1 is the parameter number and data2 holds the parameter value.
CMD_SETPARAMETER (#4)
0xFA 0x04 0x04 data1-low-byte data1-high-byte data2-low-byte data2-high-byte crc-low-byte crc-high-byte
Data1 is the parameter number and data2 holds the parameter value. As response to this command a CMD_ACK message will be emitted.
CMD_GETDATA (#5)
0xFA 0x01 0x05 type-byte crc-low-byte crc-high-byte
Type specifies the type of the requested data stream; currently only type 0 is supported. If an error occurred a CMD_ACK message will be emitted. Otherwise a message containing the data stream in this format will be emitted:
0xFB 0x4A 0x05 type-byte 0x00 data-stream crc-low-byte crc-high-byte
The data stream contains the same data as send by the 'd' command.
CMD_GETDATAFIELDS (#6)
0xFA 0x02 0x06 data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and represents a bitmask to specify which data should be send. If an error occurred a CMD_ACK message will be emitted. Otherwise a message containing the bitmask word and all the requested data in this format will be emitted:
0xFB LEN 0x06 data1-low-byte data1-high-byte data-stream crc-low-byte crc-high-byte
Data1 is the bitmask word, and data-stream holds the data. The following bits can be raised:
0x0001 = LIVEDATA_STATUS 0x0001 = LIVEDATA_TIMES 0x0004 = LIVEDATA_IMU1GYRO 0x0008 = LIVEDATA_IMU1ACC 0x0010 = LIVEDATA_IMU1R 0x0020 = LIVEDATA_IMU1ANGLES 0x0040 = LIVEDATA_PIDCNTRL 0x0080 = LIVEDATA_INPUTS 0x0100 = LIVEDATA_IMU2ANGLES 0x0200 = LIVEDATA_MAGANGLES 0x0400 = LIVEDATA_STORM32LINK 0x0800 = LIVEDATA_IMUACCCONFIDENCE
CMD_SETPITCH (#10)
0xFA 0x02 0x0A data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and can assume the values 700...2300. It represents the pitch input value. If the value 0 is send, then the pitch axis will be recentered. Any other values are ignored. As response to this command a CMD_ACK message will be emitted.
CMD_SETROLL (#11)
0xFA 0x02 0x0B data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and can assume the values 700...2300. It represents the roll input value. If the value 0 is send, then the roll axis will be recentered. Any other values are ignored. As response to this command a CMD_ACK message will be emitted.
CMD_SETYAW (#12)
0xFA 0x02 0x0C data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and can assume the values 700...2300. It represents the yaw input value. If the value 0 is send, then the yaw axis will be recentered. Any other values are ignored. As response to this command a CMD_ACK message will be emitted.
CMD_SETPANMODE (#13)
0xFA 0x01 0x0D data-byte crc-low-byte crc-high-byte
The data is of type uint8_t and can assume these values: 0 = off, 1 = HOLDHOLDPAN, 2 = HOLDHOLDHOLD, 3 = PANPANPAN, 4 = PANHOLDHOLD, 5 = PANHOLDPAN, 6 = HOLDPANPAN. As response to this command a CMD_ACK message will be emitted.
CMD_SETSTANDBY(#14)
0xFA 0x01 0x0E data-byte crc-low-byte crc-high-byte
The data is of type uint8_t and can assume these values: 0 = off, 1 = on. As response to this command a CMD_ACK message will be emitted.
CMD_DOCAMERA(#15)
0xFA 0x06 0x0F dummy-byte data-byte dummy-byte dummy-byte dummy-byte dummy-byte crc-low-byte crc-high-byte
The data is of type uint8_t and can assume these values: 0 = off, 1 = IRSHUTTER, 2 = IRSHUTTERDELAYED, 3 = IRVIDEOON, 4 = IRVIDEOOFF. As response to this command a CMD_ACK message will be emitted.
CMD_SETSCRIPTCONTROL (#16)
0xFA 0x02 0x10 data1-byte data2-byte crc-low-byte crc-high-byte
The data1 and data2 are of type uint8_t. Data1 is the number of the script and data2 can assume these values: 0 = off, 1 = CASE#DEFAULT, 2 = CASE#1, 3 = CASE#2, 4 = CASE#3. As response to this command a CMD_ACK message will be emitted.
CMD_SETANGLE (#17)
0xFA 0x0E 0x11 float1 float2 float3 flags-byte type-byte crc-low-byte crc-high-byte
The float1, float2, float3 fields represent 4 bytes each. They are of type float, and correspond to the pitch, roll, and yaw angles in degree. The flags byte allows to modify the behavior of the angle setting for each axis. They can be in the unlimited or limited mode. In unlimited mode the respective axis can be set to any angle without restriction, bypassing the RcMin and RcMax settings, and working for both “relative” and “absolute”. In limited mode the angle setting is subject to the RcMin and RcMax settings, and works only for “absolute”. The first bit of the flags byte, 0x01, corresponds to pitch, 0x02 to roll, and 0x04 to yaw, and when set the respective axis is in limited mode. The type byte is not used currently and has to be set to zero. As response to this command a CMD_ACK message will be emitted.
CMD_SETPITCHROLLYAW (#18)
0xFA 0x06 0x12 data1-low-byte data1-high-byte data2-low-byte data2-high-byte data3-low-byte data3-high-byte crc-low-byte crc-high-byte
The data1, data2 and data3 are each of type uint16_t and can assume the values 700...2300. They represent the pitch, roll, yaw input values. If a value 0 is send, then the respective axis will be recentered. Any other values are ignored. As response to this command a CMD_ACK message will be emitted.
CMD_SETPWMOUT (#19)
0xFA 0x02 0x13 data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and can assume the values 700...2300. It represents the pwm pass through input value. As response to this command a CMD_ACK message will be emitted.
CMD_RESTOREPARAMETER (#20)
0xFA 0x02 0x14 data-low-byte data-high-byte crc-low-byte crc-high-byte
The data is of type uint16_t and holds the parameter number. This command sets the parameter to the value in the EEPROM. As response to this command a CMD_ACK message will be emitted.
CMD_RESTOREALLPARAMETER (#21)
0xFA 0x00 0x15 crc-low-byte crc-high-byte
This command sets all parameters to the values stored in the EEPROM. As response to this command a CMD_ACK message will be emitted.
CMD_ACTIVEPANMODESETTING (#100)
0xFA 0x01 0x64 data-byte crc-low-byte crc-high-byte
The data is of type uint8_t and is a bit field related to the pan mode setting: default setting = 0x00, setting #1 = 0x01, setting #2 = 0x02, setting #3 = 0x03. As response to this command a CMD_ACK message will be emitted.
CMD_ACK (#150)
0xFB 0x01 0x96 data-byte crc-low-byte crc-high-byte
This command is send by the STorM32 controller to acknowledge execution of a received RC command message (if the message itself doesn't lead to a response, such as e.g. the get parameter command). The data is of type uint8_t and can assume these values:
0 = SERIALRCCMD_ACK_OK 1 = SERIALRCCMD_ACK_ERR_FAIL 2 = SERIALRCCMD_ACK_ERR_ACCESS_DENIED 3 = SERIALRCCMD_ACK_ERR_NOT_SUPPORTED 150 = SERIALRCCMD_ACK_ERR_TIMEOUT 151 = SERIALRCCMD_ACK_ERR_CRC 152 = SERIALRCCMD_ACK_ERR_PAYLOADLEN
Mavlink Communication
In addition to the commands described in the previous sections, the o323bgc firmware also understands MAVLink messages, as defined in the MAVLink standard. Some STorM32 specific MAVLink messages were also added.
The STorM32's system ID and component ID can be freely adjusted in the GUI; the defaults are
- System ID: 'G' (= 71 = 0x47)
- Component ID: 'C' (= 67 = 0x43)
The following commands are supported:
MAVLINK_MSG_ID_HEARTBEAT (#0, 0x00)
See HEARTBEAT. The emission of the heartbeat needs to be activated in the GUI via the Mav Configuration parameter. The heartbeat is emitted at 1 Hz, with the following values:
- type: MAV_TYPE_GIMBAL (= 26)
- autopilot: 'S' (= 83 = 0x53) (may become MAV_AUTOPILOT_STORM32)
- base_mode: either 0 or MAV_MODE_FLAG_SAFETY_ARMED (= 0x80)
- custom_mode: STATE value of the o323firmware
- system_status: either MAV_STATE_BOOT (= 1) or MAV_STATE_ACTIVE (= 4)
MAVLINK_MSG_ID_PARAM_REQUEST_READ (#20, 0x14)
See PARAM_REQUEST_READ.
MAVLINK_MSG_ID_PARAM_REQUEST_LIST (#21, 0x15)
See PARAM_REQUEST_LIST.
MAVLINK_MSG_ID_PARAM_VALUE (#22, 0x16)
See PARAM_VALUE.
MAVLINK_MSG_ID_PARAM_SET (#23, 0x17)
See PARAM_SET.
MAVLINK_MSG_ID_ATTITUDE (#30, 0x1E)
See ATTITUDE. The emission of the attitude message with 2 Hz can be activated in the GUI via the Mav Configuration parameter, or by requesting a data stream with MESSAGE_INTERVAL. The yaw angle is relative to the forward direction.
MAVLINK_MSG_ID_COMMAND_LONG (#76, 0x4C)
See COMMAND_LONG. These commands are supported (parameter fields not mentioned are ignored):
MAV_CMD_DO_SET_PARAMETER (#180, 0xB4) * param1 = parameter index * param2 = parameter value
MAV_CMD_DO_SET_SERVO (#183, 0xB7) * param2 = pwm value (only 700...2300 accepted)
MAV_CMD_DO_DIGICAM_CONFIGURE (#202, 0xCA) Is just there so that a MAVLINK_MSG_ID_COMMAND_ACK with MAV_CMD_ACK_OK is returned
MAV_CMD_DO_DIGICAM_CONTROL (#203, 0xCB) * param5 = shot (0 = off, 1 = IRSHUTTER)
MAV_CMD_DO_MOUNT_CONFIGURE (#204, 0xCC) * param1 = mount_mode (0 = MAV_MOUNT_MODE_RETRACT and 1 = MAV_MOUNT_MODE_NEUTRAL recenter the camera)
MAV_CMD_DO_MOUNT_CONTROL (#205, 0xCD) * param1 = pitch, angle in degree, unlimited * param2 = roll, angle in degree, unlimited * param3 = yaw, angle in degree, unlimited
MAV_CMD_PREFLIGHT_STORAGE (#245, 0xF5) * param1 = parameter storage 0: restore parameter values from EEPROM 1: store parameter values in EEPROM 2: ignored, as it maybe harmful
MAV_CMD_GET_ATTITUDE (#1234, 0x04D2) STorM32 specific command. Deprecated, but still existing for compatibility reasons.
MAV_CMD_TARGET_SPECIFIC (#1235, 0x04D3) STorM32 specific command. Container for target specific messages. See Comments on STorM32 specific Mavlink Messages.
MAVLINK_MSG_ID_COMMAND_ACK (#77, 0x4D)
See COMMAND_ACK.
MAVLINK_MSG_ID_MOUNT_STATUS (#158, 0x9E)
ArduPilot specific message. See MOUNT_STATUS. The emission of the mount status message with 2 Hz can be activated in the GUI via the Mav Configuration parameter, or by requesting a data stream with MESSAGE_INTERVAL. The yaw angle is relative to the forward direction.
* target_system: 0 (uint8_t) * target_component: 0 (uint8_t) * pointing_a: pitch, angle in 0.01° (int32_t) * pointing_b: roll, angle in 0.01° (int32_t) * pointing_c: yaw relative to forward, angle in 0.01° (int32_t)
MAVLINK_MSG_IDs #234 to #240
STorM32 specific messages. Reserved.
MAVLINK_MSG_ID_MESSAGE_INTERVAL (#244, 0xF4)
See MESSAGE_INTERVAL. The attitude and the mount status can be requested, with time intervals in multiples of 0.1 s.
Comments on STorM32 specific Mavlink Messages
COMMAND_LONG - MAV_CMD_GET_ATTITUDE
The command MAV_CMD_GET_ATTITUDE is deprecated, but still existing for compatibility reasons. The command triggered the emission of a ATTITUDE message instead of a COMMAND_ACK message. This allowed to ask for the gimbal attitude whenever it is required. The command should be replaced by using either the MAVLINK_MSG_ID_MESSAGE_INTERVAL message or a corresponding MAV_CMD_TARGET_SPECIFIC command.
COMMAND_LONG - MAV_CMD_TARGET_SPECIFIC
The command MAV_CMD_TARGET_SPECIFIC was added. This command can be viewed as a container to transmit data, those content isn't known to MAVLink. It thus becomes possible to establish a communication between two arbitrary devices, using a MAVLink channel. The command is intended for peer-to-peer communication, but of course is handled like any other COMMAND_LONG message by the MAVLink systems. The working principle is to treat the memory space of the seven param fields as a contiguous data buffer of 28 bytes, which hosts the target specific message. Obviously, only target specific messages of lengths less or equal 28 bytes can be handled.
In the o323bgc firmware, the command is used to embed both the simple serial and RC commands. That is, the param memory space hosts the serial or RC command, with the crc bytes stripped off however since the message is already crc protected by MAVLink.
For instance, the command CMD_SETPITCH with value 1000 (= 0x03E8) can be transmitted in two ways from a MAVLink device (with IDs 0xYY and 0xZZ) to the STorM32 controller (with IDs 0x47 and 0x43):
- It can be transmitted as described in the above, with the 0xFA start sign. The byte stream which is sent to the STorM32 controller is then:
0xFA 0x02 0x0A 0xE8 0x03 CRCLOW CRCHIGH
and the received ACK stream is:
0xFB 0x01 0x96 0x00 0x52 0xE9
- The message can be embedded into the MAV_CMD_TARGET_SPECIFIC command, i.e. the param field space becomes the target specific message, without its crc. The byte stream is then:
0xFE 0x21 0xXX 0xYY 0xZZ 0x4C 0xFA 0x02 0x0A 0xE8 0x03 23*0x00 0xD3 0x04 0x47 0x43 0x00 CRCLOW CRCHIGH
and the received ACK stream is:
0xFE 0x21 0xXX 0x47 0x43 0x4C 0xFB 0x01 0x96 0x00 24*0x00 0xD3 0x04 0xYY 0xZZ 0x00 CRCLOW CRCHIGH
This of course works for all serial and RC commands, and their responses. Thus, the full command set and functionality of the STorM32 controller is available through MAVLink channels.
Code Examples
Arduino Sketches
User digaus has posted an example sketch for Arduino using MAVLink messages here: http://www.rcgroups.com/forums/showpost.php?p=34912538&postcount=8213.