Hello Fellow Yuneec Pilot!
Join our free Yuneec community and remove this annoying banner!
Sign up

Typhoon H 480 PX4 v1.10 (Stability issues ;-)

To don't waste time about the CRC>

#include <stdint.h>
#include <stddef.h>

uint16_t crc16_mcrf4xx(uint16_t crc, uint8_t *data, size_t len)
{
uint8_t t;
uint8_t L;
if (!data || len < 0)
return crc;

while (len--)
{
crc ^= *data++;
L = crc ^ (crc << 4);
t = (L << 3) | (L >> 5);
L ^= (t & 0x07);
t = (t & 0xF8) ^ (((t << 1) | (t >> 7)) & 0x0F) ^ (uint8_t)(crc >> 8);
crc = (L << 8) | t;
}
return crc;
}
 
and a bit more...
uint16_t crc16_mcrf4xx(uint16_t crc, uint8_t *data, size_t len);

struct Mavlink_V1 //https://mavlink.io/en/guide/serialization.html#v1_packet_format
{
uint8_t magic;
// ---
uint8_t len;
uint8_t seq;
uint8_t sysid;
uint8_t compid;
uint8_t msgid;
uint8_t msgTypeH;
uint8_t msgTypeL;
// uint8_t payload[255];
uint16_t checksum; // -
uint8_t crcLow; // |
uint8_t crcHigh; // -
};

uint16_t initCRC = 0xFFFF, calcCRC = 0x0000;
uint8_t magic[] = {0xFE};
uint8_t zero[] = {0x00};
uint8_t crc[] = {0x00, 0x00};

int count;

int receivePacket(uint8_t *read_buffer)
{
struct Mavlink_V1 mavlink;

int
position = 0x00,
receivedBytes = 0x00,
count = 0x00;

do
{
if (uart_gets(&mavlink.magic, 1) == 0)
{
return count;
}
}
while (mavlink.magic != 0xFE);

while (uart_gets(&mavlink.len, 1) == 0);
read_buffer[position++] = mavlink.len;

while (uart_gets(&mavlink.seq, 1) == 0);
read_buffer[position++] = mavlink.seq;

while (uart_gets(&mavlink.sysid, 1) == 0);
read_buffer[position++] = mavlink.sysid;

while (uart_gets(&mavlink.compid, 1) == 0);
read_buffer[position++] = mavlink.compid;

while (uart_gets(&mavlink.msgid, 1) == 0);
read_buffer[position++] = mavlink.msgid;

while (uart_gets(&mavlink.msgTypeH, 1) == 0);
read_buffer[position++] = mavlink.msgTypeH;

while (uart_gets(&mavlink.msgTypeL, 1) == 0);
read_buffer[position++] = mavlink.msgTypeL;

do
{
receivedBytes += uart_gets(&read_buffer[position + receivedBytes], mavlink.len - receivedBytes);
}
while (mavlink.len != receivedBytes);

while (uart_gets(&mavlink.crcLow, 1) == 0);

while (uart_gets(&mavlink.crcHigh, 1) == 0);

count = position + receivedBytes;


calcCRC = (uint16_t) crc16_mcrf4xx(initCRC, read_buffer, count + 1);
 
MAGIC = {0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x7F, 0x00, 0x01};

#define UART_BAUD_RATE 115200

Send the MAGIC to the copter's camera UART every second. Log what the copter sends to you. Without a camera attached. Paste here what you have received. If this is done I'll paste some text too. ;)
Forgot to remember you should not forget to pack the telegram properly.

int sendPacket(uint8_t* send_buffer, int send_buffer_size)
{
...
{
calcCRC = (uint16_t) crc16_mcrf4xx(initCRC, send_buffer, send_buffer_size);
calcCRC = (uint16_t) crc16_mcrf4xx(calcCRC, zero, sizeof(zero));
crc[0] = calcCRC & 0xFF;
crc[1] = (calcCRC >> 8) & 0xFF;

uart_puts_raw(magic, sizeof(magic));
uart_puts_raw(send_buffer, send_buffer_size);
uart_puts_raw(crc, sizeof(crc));
}
...
 
No reason to do that. Focus on ST's APK to ST's FC communication. All the rest can be written in a much better manner.


Well, like I said I don't know anything about android programming and also I just wanted to enable a feature that seemed like it might already be in the code just disabled. I'm all for somebody rewriting the whole thing better, but it is beyond my capabilities and available time.

I think you are right that the key is to figure out the flightmode APK communication to the serial driver used to communicate with the ST24 transmitter. I think (possibly incorrectly) that the problems with my modified flightmode APK was that it didn't have the correct permissions to access the serial driver/port.

There were some messages where somebody said that, unlike the ST10, the ST16 had some sort of custom low level serial driver that was harder to interface with. I think it was that same person who had said he managed to make the ST10 and ST16 control a cheap android drone (@SilentR9), but he has since disappeared. Advice for using/hacking ST16 for Fathom ROV
 
figure out the flight mode APK communication to the serial driver used to communicate with the ST24 transmitter.
It doesn't communicate directly! Between them is an FC! Somewhere, probably in the WTF... documents is a very good diagram of how the mixer works...
 
Check this out guys,
To start I just simply decom the APK for the app. That contains the full java source in the original format. So all the protocol data is below. With this, there is no need even to scope it with a probe and figure it out. Because most Android apps are just Java and not truly compiled they are not in binary format. Now being able to see the guts of how the entire app works either making a custom version of the client or adding features should be a breeze.

If you want to decomp yourself simply download their latest firmware. Then head over to this site below. Run the decomp, download the output as a zip. Use 7Zip on windows to properly open as the structure wont work with the built in client. But this opens up a lot of anyone interested in the inter workings of the client controller side. Now on to interfacing and customization looking. I dont have a ton of time tonight but will keep looking and once I write some more code start sharing with you guys on the GutHub that was setup.

APK decompiler
Question... If you are able to modify the app. Will you be able to overcome the app signing issue noted in another thread?
 
New feature that I would like to have except both above:
* Add a new instance for MAVlink that shall be routed to a serial connection, best would be the RealSense UART. HW: RealSense is connected to PA0 and PA1 on STM32.
Currently we have only one instance routed to ttyAMA0 (USB).
instance #0:
GCS heartbeat: 835008 us ago
mavlink chan: #0
type: USB CDC
flow control: OFF
rates:
tx: 14.106 kB/s
txerr: 0.000 kB/s
tx rate mult: 1.000
tx rate max: 800000 B/s
rx: 0.038 kB/s
FTP enabled: YES, TX enabled: YES
mode: Config
MAVLink version: 1
transport protocol: serial (/dev/ttyACM0 @2000000)

* UART support for gimbal control (tilt, rotate). This will need a lot of research/high effort.


Question, is the difficulty adding UART support for the gimbal tilt and rotate because of trying to add another serial connection (like you show above) or with the data that needs to be sent gimbal?

Controlling the tilt and rotate of the gimbal via a direct serial connection as been figured out. It is in my arduino code. The entire message that is sent to the CGO3 isn't understood (by me), but which bytes control the movement are known. Basically you just have to send the initialization bytes during start up, then modify the movement bytes of a the message, re-calculate the crc and send it out.
 
Today is your day! Here you are! Almost all is commented on because I have used the same parser for different purposes. This one is probably from the CGO3+ (UART) to GB203 (PWM) converter.

// Yuneec Typhoon H480 Mavlink ID's:
const char
to_all = 0x00,
drone = 0x01,
gimbal = 0x02,
camera = 0x03,
remote = 0x04,
_tbd_1 = 0x05,
_tbd_2 = 0x06;

// int i = 0;
// bool _switch = false;

void parser_init(void)
{

}

void parser_show(uint8_t *read_buffer) // int count,
{
uint8_t *ptr = read_buffer;

uint8_t *len = ptr + 0; //&read_buffer[0];
// uint8_t *seq = ptr++; //&read_buffer[1];
uint8_t *sysid = ptr + 2; //&read_buffer[2];
// uint8_t *compid = ptr++; //&read_buffer[3];
uint8_t *msgid = ptr + 4; //&read_buffer[4];
// uint8_t *msgTypeH = ptr++; //&read_buffer[5];
// uint8_t *msgTypeL = ptr++; //&read_buffer[6];

if (*len == 0x1A && *sysid == drone && *msgid == gimbal)
{
// int16_t copterYaw = ((read_buffer[8] << 8) & 0xFF00) | read_buffer[7];
// int16_t copterPitch = ((read_buffer[10] << 8) & 0xFF00) | read_buffer[9];
// int16_t copterRoll = ((read_buffer[12] << 8) & 0xFF00) | read_buffer[11];


// int16_t cameraPan = ((read_buffer[22] << 8) & 0xFF00) | read_buffer[21];
int16_t cameraTilt = ((read_buffer[24] << 8) & 0xFF00) | read_buffer[23];
tt = cameraTilt;
// int16_t cameraPanMode = ((read_buffer[28] << 8) & 0xFF00) | read_buffer[27];
// int16_t cameraTiltMode = ((read_buffer[30] << 8) & 0xFF00) | read_buffer[29];

// int16_t copterVz = ((read_buffer[14] << 8) & 0xFF00) | read_buffer[13];
// int16_t tbd_2 = ((read_buffer[16] << 8) & 0xFF00) | read_buffer[15];
// int16_t copterVy = ((read_buffer[18] << 8) & 0xFF00) | read_buffer[17];
// int16_t copterVx = ((read_buffer[20] << 8) & 0xFF00) | read_buffer[19];
// int16_t tbd_5 = ((read_buffer[32] << 8) & 0xFF00) | read_buffer[31];

// snprintf(str, BUFSIZE, "Yaw: %3.1f Pitch: %2.1f Roll: %2.1f ", (180.0/16000 * copterYaw - 180), (-90.0 / 7650 * copterPitch), (-90.0 / 7750 * copterRoll));
// print_string_horizontal(1, 11, str, sizeof(str), _White, _Black);

// snprintf(str, BUFSIZE, "Pan: %2.0f%% Tilt: %2.0f Pan mode: %4d Tilt mode: %4d ", (100.0/2048 * (cameraPan - 2048)), (90.0/4096 * cameraTilt), cameraPanMode, cameraTiltMode);
// print_string_horizontal(1, 13, str, sizeof(str), _White, _Black);

// snprintf(str, BUFSIZE, "Vx: %4d Vy: %4d Vz: %4d ", copterVx, copterVy, copterVz);
// print_string_horizontal(1, 15, str, sizeof(str), _White, _Black);
}
else if (*len == 0x22 && *sysid == drone && *msgid == camera)
{
// int32_t copterLongitude = (((read_buffer[10] << 24) & 0xFF000000) | ((read_buffer[9] << 16) & 0xFFFF0000) | ((read_buffer[8] << 8) & 0xFFFFFF00) | read_buffer[7]);
// printf("%08X, %f\n", copterLongitude, 0.0001f * copterLongitude);
// int32_t copterLatitude = (((read_buffer[14] << 24) & 0xFF000000) | ((read_buffer[13] << 16) & 0xFFFF0000) | ((read_buffer[12] << 8) & 0xFFFFFF00) | read_buffer[11]);
// printf("%08X, %f\n", copterLatitude, 0.0001f * copterLatitude);


// int32_t copterAltitude = (((read_buffer[18] << 24) & 0xFF000000) | ((read_buffer[17] << 16) & 0xFFFF0000) | ((read_buffer[16] << 8) & 0xFFFFFF00) | read_buffer[15]);
// snprintf(str, BUFSIZE, "Long: %f\n Lat: %f\n Alt: %.2f\n ",0.0001f * copterLongitude, 0.0001f * copterLatitude, 0.01f * copterAltitude);
// print_string_horizontal(1, 17, str, sizeof(str), _White, _Black);
// printf("%08X, %.2f\n", copterAltitude, 0.01f * copterAltitude);




// int32_t remoteLongitude = (((read_buffer[22] << 24) & 0xFF000000) | ((read_buffer[21] << 16) & 0xFFFF0000) | ((read_buffer[20] << 8) & 0xFFFFFF00) | read_buffer[19]);
// printf("%08X, %f\n", remoteLongitude, 0.0001f * remoteLongitude);

/*
uint16_t copterTBD1 = ((read_buffer[20] << 8) & 0xFF00) | read_buffer[19];
uint16_t copterTBD2 = ((read_buffer[22] << 8) & 0xFF00) | read_buffer[21];
uint16_t copterTBD3 = ((read_buffer[24] << 8) & 0xFF00) | read_buffer[23];
uint16_t copterTBD4 = ((read_buffer[26] << 8) & 0xFF00) | read_buffer[25];
uint16_t copterTBD5 = ((read_buffer[28] << 8) & 0xFF00) | read_buffer[27];
uint16_t copterTBD6 = ((read_buffer[30] << 8) & 0xFF00) | read_buffer[29];

snprintf(str, BUFSIZE,"%04X, %04X, %04X, %04X, %04X, %04X\n", copterTBD1, copterTBD2, copterTBD3, copterTBD4, copterTBD5, copterTBD6);
print_string_horizontal(1, 19, str, sizeof(str), _White, _Black);
*/

// int32_t remoteLatitude = (((read_buffer[26] << 24) & 0xFF000000) | ((read_buffer[25] << 16) & 0xFFFF0000) | ((read_buffer[24] << 8) & 0xFFFFFF00) | read_buffer[23]);
// printf("%08X, %f\n", remoteLatitude, 0.0001f * remoteLatitude);
// int32_t copterTBD = (((read_buffer[30] << 24) & 0xFF000000) | ((read_buffer[29] << 16) & 0xFFFF0000) | ((read_buffer[28] << 8) & 0xFFFFFF00) | read_buffer[27]);
// printf("%08X, %.2f\n", copterTBD, 0.01f * copterTBD);

/* i = 31;
while (i < count)
{
printf("%02X", read_buffer[i++]);

}
printf("\n\n");
i = 0;
*/
 
Question, is the difficulty adding UART support for the gimbal tilt and rotate because of trying to add another serial connection (like you show above) or with the data that needs to be sent gimbal?
The camera UART is already activated and is used to tilt the camera via PWM signal. Other messages will be ignored as I understand.
I want to open an additional UART to connect a MAVlink bridge with a second instance of MAVlink. Instance#0 is connected to USB. You can calibrate only with USB cable connected. Especially the compass calibration is a mess with cable. A MAVlink bridge would allow to access the drone via WiFi. This makes it easier to calibrate it, upload missions and read/write parameter. And it would open a way to control the drone with QGroundControl for special features.
A MAVbridge would increase the usability and may allow tu use other cameras like cams from H520/H Plus including infrared cams with full gimbal support (not tested but who knows).
 
I have been working out logic diagams and some other docs to release in the near future specifically for the controller modding. Would it make sense to start a new thread separate for the controller subject to separate from the autopilot firmware side? I will start a github repo as well for modding the controller soon as I get some more work time on it.
 
  • Like
Reactions: Vaklin
I have been working out logic diagams and some other docs to release in the near future specifically for the controller modding. Would it make sense to start a new thread separate for the controller subject to separate from the autopilot firmware side? I will start a github repo as well for modding the controller soon as I get some more work time on it.
That would be a good idea so we can keep the two things separate and avoid confusion.

I will try to place all recent controller related posts from this thread in a new one this weekend.
 
That would be a good idea so we can keep the two things separate and avoid confusion.

I will try to place all recent controller related posts from this thread in a new one this weekend.
Thank you, I will try and upload my diagrams from DrawIO or in PDF this weekend. As far as the controller I was just going to write a new app and release the code for Android. I have the reference needed via the other decompile to not spends hours on signal analysis. Then if someone wants to replace the internal Zigbee with a opentx, FlySky, Spectrum, etc all that will be needed is a small microcontroller to translate between the modules. I probably will write the microcontroller bridge code too. It could go directly in place of the Zigbee transceiver in the ST24 because its simply connected via UART with a JST connector. With a custom android app the output protocol can be done as well without even a translator microcontroller. Or the translator could be dropped in line to take the existing app and translate to use with a generic transceiver module. They honestly make it really easy to mod the controller. Wish I would have found the st24 before I bought a new radiomaster st16. But Ill end up using both no biggie. Having all the features and nice controllers attached in one unit to an android tablet though with all the electronics on separate boards makes modding super easy. Dont take a whole lot of customization and the case is large enough to fit a lot of new items in the controller when the Zigbee mod is removed. Ill post pictures later showing what each circuit board does. The wifi could also be replaced with a LoraWan module later or different higher speed non wifi link for long range video rx with a little more work. Non wifi video would be some work. But making the st24 an open platform would be awesome there less then $100 on ebay and tons available to help the community afford a cheaper radio that is mod’s able.
 
I'm confused now... Are both PWM and UART required to control the camera gimbal tilt and rotate or can UART alone be used without PWM?
PWM is a fallback procedure if UART connection could not established in time. It was implemented in the flight controller FW for backward compatibility to CGO3.
 

New Posts

Members online

No members online now.

Forum statistics

Threads
21,016
Messages
242,433
Members
27,602
Latest member
fundingmove