From 9e0efe321c7fa8104eb695a185848ab10ac914b9 Mon Sep 17 00:00:00 2001 From: MRC3742 Date: Mon, 3 Aug 2026 08:36:17 -0400 Subject: [PATCH] REALACC/WLV8Tx : WLtoys Cars 284019-A and 284191 Protocol: REALACC Sub Proto: WL_V8Tx Ch1: Steering CH2: Throttle CH3: GY TRIM (Rate) CH4: TH TRIM (Rate) CH5: Steering Trim --- Lua_scripts/MultiChan.txt | 3 +- Multiprotocol/Multi.txt | 2 +- Multiprotocol/Multi_Protos.ino | 3 +- Multiprotocol/Multiprotocol.h | 7 +- Multiprotocol/REALACC_nrf24l01.ino | 230 +++++++++++++++++++++++++---- Multiprotocol/Validate.h | 2 +- Protocols_Details.md | 21 ++- 7 files changed, 232 insertions(+), 36 deletions(-) diff --git a/Lua_scripts/MultiChan.txt b/Lua_scripts/MultiChan.txt index 74b9369a..51ee4dc9 100644 --- a/Lua_scripts/MultiChan.txt +++ b/Lua_scripts/MultiChan.txt @@ -166,7 +166,8 @@ 74,2,RadioLink,DumboRC,0,CH5,CH6,CH7,CH8GY,CH9,CH10,n-a,n-a,n-a,n-a,n-a,n-a 74,3,RadioLink,RC4G,0,CH5,FS_CH1,FS_CH2,FS_CH3,FS_CH4 74,4,RadioLink,Dumbo_P,0,CH5,CH6,CH7,CH8GY,CH9,CH10,n-a,n-a,n-a,n-a,n-a,n-a -76,0,Realacc,Std,1,Flip,Light,Calib,HLess,RTH,ThCut,Rotat +76,0,Realacc,R11,1,Flip,Light,Calib,HLess,RTH,ThCut,Rotat +76,1,Realacc,WLV8Tx,0,ST_Tr 50,0,Redpine,Fast,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16 50,1,Redpine,Slow,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16 21,0,Futaba,SFHSS,0,CH5,CH6,CH7,CH8 diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 47ae172c..c9998485 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -73,7 +73,7 @@ 73,Kyosho,FHSS,Hype 74,RadioLink,Surface,Air,DumboRC,RC4G,Dumbo_P 75,--- -76,Realacc +76,Realacc,R11,WL-V8Tx 77,OMP 78,M-Link 79,WFLY,RF20x diff --git a/Multiprotocol/Multi_Protos.ino b/Multiprotocol/Multi_Protos.ino index e9a6ef22..5a67422b 100644 --- a/Multiprotocol/Multi_Protos.ino +++ b/Multiprotocol/Multi_Protos.ino @@ -181,6 +181,7 @@ const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync"; const char STR_SUBTYPE_PELIKAN[] = "\x05""Pro\0 ""Lite\0""SCX24"; const char STR_SUBTYPE_V761[] = "\x05""3ch\0 ""4ch\0 ""TOPRC"; const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC""RC4G\0 ""Dumbo_P"; +const char STR_SUBTYPE_REALACC[] = "\x07""R11\0 ""WL-V8Tx"; const char STR_SUBTYPE_KYOSHO[] = "\x04""FHSS""Hype"; const char STR_SUBTYPE_KYOSHO2[] = "\x05""KT-17"; const char STR_SUBTYPE_KYOSHO3[] = "\x03""ASF"; @@ -463,7 +464,7 @@ const mm_protocol_definition multi_protocols[] = { {PROTO_RLINK, STR_RLINK, STR_SUBTYPE_RLINK, 5, OPTION_RFTUNE, 0, 0, SW_CC2500, RLINK_init, RLINK_callback }, #endif #if defined(REALACC_NRF24L01_INO) - {PROTO_REALACC, STR_REALACC, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback }, + {PROTO_REALACC, STR_REALACC, STR_SUBTYPE_REALACC, 2, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback }, #endif #if defined(REDPINE_CC2500_INO) {PROTO_REDPINE, STR_REDPINE, STR_SUBTYPE_REDPINE, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, REDPINE_init, REDPINE_callback }, diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index cd244323..1bdf7e6d 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 3 #define VERSION_REVISION 4 -#define VERSION_PATCH_LEVEL 58 +#define VERSION_PATCH_LEVEL 59 #define MODE_SERIAL 0 @@ -475,6 +475,11 @@ enum RLINK RLINK_RC4G = 3, RLINK_DUMBORC_P = 4, }; +enum REALACC +{ + REALACC_R11 = 0, + REALACC_WLV8TX = 1, +}; enum MOULDKG { MOULDKG_ANALOG4 = 0, diff --git a/Multiprotocol/REALACC_nrf24l01.ino b/Multiprotocol/REALACC_nrf24l01.ino index 42090716..34ce341d 100644 --- a/Multiprotocol/REALACC_nrf24l01.ino +++ b/Multiprotocol/REALACC_nrf24l01.ino @@ -19,6 +19,7 @@ Multiprotocol is distributed in the hope that it will be useful, #include "iface_xn297.h" //#define FORCE_REALACC_ORIGINAL_ID +//#define FORCE_REALACC_WLV8TX_ID #define REALACC_INITIAL_WAIT 500 #define REALACC_PACKET_PERIOD 2268 @@ -28,30 +29,68 @@ Multiprotocol is distributed in the hope that it will be useful, #define REALACC_BIND_COUNT 50 #define REALACC_RF_NUM_CHANNELS 5 +#ifndef MULTI_AIR +#define WLV8TX_PACKET_PERIOD 16279 +#define WLV8TX_BIND2_PAYLOAD_SIZE 12 +#define WLV8TX_RX_PAYLOAD_SIZE 6 + +enum +{ + REALACC_WLV8TX_BIND_TX = 0, + REALACC_WLV8TX_BIND_RX_SETUP, + REALACC_WLV8TX_BIND_RX_CHECK, + REALACC_WLV8TX_DATA +}; + +static uint8_t realacc_phase; +static bool realacc_wlv8tx_rx_b3; +#endif +static uint8_t realacc_bind_packet[REALACC_BIND_PAYLOAD_SIZE]; + static void __attribute__((unused)) REALACC_send_packet() { - packet[ 0]= 0xDC; // DC/D6/DE - packet[ 1]= convert_channel_8b(AILERON); // 00..80..FF - packet[ 2]= convert_channel_8b(ELEVATOR); // 00..80..FF - packet[ 3]= convert_channel_8b(THROTTLE); // 00..FF - packet[ 4]= convert_channel_8b(RUDDER); // 00..80..FF - packet[ 5]= 0x20; // Trim - packet[ 6]= 0x20; // Trim - packet[ 7]= 0x20; // Trim - packet[ 8]= 0x20; // Trim - packet[ 9]= 0x88; // Change at each power up: C5 A2 77 F0 84 58, fixed for the E017 = 88 - packet[10]= 0x04 // Flag1: R11=04, E017=0C - | 0x02 // Rate1=0, Rate2=1, Rate3=2 - | GET_FLAG(CH8_SW, 0x20); // Headless - packet[11]= 0x00 // Flag2 - | GET_FLAG(CH7_SW, 0x01) // Calib - | GET_FLAG(CH9_SW, 0x20) // Return - | GET_FLAG(CH10_SW,0x80); // Throttle cut - packet[12]= 0x00 // Flag3 - | GET_FLAG(CH5_SW, 0x01) // Flip - | GET_FLAG(CH11_SW,0x02) // Rotating - | GET_FLAG(CH6_SW, 0x80); // Light - + #ifndef MULTI_AIR + if(sub_protocol == REALACC_WLV8TX) + { + packet[ 0]= 0xDC; // DC + packet[ 1]= 0x80; // not used + packet[ 2]= 0x80; // not used + packet[ 3]= convert_channel_16b_limit(CH2,0x0F,0xF1); // Throttle 0F..80..F7 (spring center) + packet[ 4]= convert_channel_16b_limit(CH1,0xE7,0x19); // Steering E7..80..1F (reversed) + packet[ 5]=(convert_channel_8b(CH3) >> 2); // GY Trim (Rate) 02..20..3D + packet[ 6]= 0x20; // Constant? + packet[ 7]= (convert_channel_8b(CH4) >> 2); // TH Trim (Rate) 02..20..3D + packet[ 8]=((convert_channel_8b(CH5) >> 2) ^ 0x3F); // ST Trim (R..C..L) 3F..20..01 (reversed) + packet[ 9]= 0x77; // Change at each power up? 07 0D 25 50 77 82 89 A5 E4 + packet[10]= 0x0C; // WL-V8Tx: fixed value = 0C + packet[11]= 0x00; // Constant? + packet[12]= 0x00; // Constant? + } + else + #endif + { + packet[ 0]= 0xDC; // DC/D6/DE + packet[ 1]= convert_channel_8b(AILERON); // 00..80..FF + packet[ 2]= convert_channel_8b(ELEVATOR); // 00..80..FF + packet[ 3]= convert_channel_8b(THROTTLE); // 00..FF + packet[ 4]= convert_channel_8b(RUDDER); // 00..80..FF + packet[ 5]= 0x20; // Trim + packet[ 6]= 0x20; // Trim + packet[ 7]= 0x20; // Trim + packet[ 8]= 0x20; // Trim + packet[ 9]= 0x88; // Change at each power up: C5 A2 77 F0 84 58, fixed for the E017 = 88 + packet[10]= 0x04 // Flag1: R11=04, E017=0C + | 0x02 // Rate1=0, Rate2=1, Rate3=2 + | GET_FLAG(CH8_SW, 0x20); // Headless + packet[11]= 0x00 // Flag2 + | GET_FLAG(CH7_SW, 0x01) // Calib + | GET_FLAG(CH9_SW, 0x20) // Return + | GET_FLAG(CH10_SW,0x80); // Throttle cut + packet[12]= 0x00 // Flag3 + | GET_FLAG(CH5_SW, 0x01) // Flip + | GET_FLAG(CH11_SW,0x02) // Rotating + | GET_FLAG(CH6_SW, 0x80); // Light + } XN297_Hopping(hopping_frequency_no); hopping_frequency_no++; hopping_frequency_no %= REALACC_RF_NUM_CHANNELS; @@ -60,11 +99,24 @@ static void __attribute__((unused)) REALACC_send_packet() static void __attribute__((unused)) REALACC_send_bind_packet() { - packet[0] = 0xB1; // B0/B1 - memcpy(&packet[1],rx_tx_addr,4); // Address - memcpy(&packet[5],hopping_frequency,5); // RF frequencies - - XN297_WriteEnhancedPayload(packet, REALACC_BIND_PAYLOAD_SIZE,1); + #ifndef MULTI_AIR + if(sub_protocol == REALACC_WLV8TX && realacc_wlv8tx_rx_b3) + { // WLV8TX bind sent after RX packet B3 acknowledged + packet[0] = 0xB4; + packet[1] = rx_id[1]; + packet[2] = rx_id[2]; + memcpy(&packet[3], realacc_bind_packet, 4); // Original TX ID before XOR + memcpy(&packet[7], hopping_frequency, 5); // RF frequencies + XN297_WriteEnhancedPayload(packet, WLV8TX_BIND2_PAYLOAD_SIZE,1); + } + else + #endif + { // initial bind sent for all models + packet[0] = 0xB1; // B0/B1 + memcpy(&packet[1],realacc_bind_packet,4); // Address + memcpy(&packet[5],hopping_frequency,5); // RF frequencies + XN297_WriteEnhancedPayload(packet, REALACC_BIND_PAYLOAD_SIZE,1); + } } static void __attribute__((unused)) REALACC_initialize_txid() @@ -97,13 +149,26 @@ static void __attribute__((unused)) REALACC_initialize_txid() hopping_frequency[4]=0x3F; } #endif + #ifdef FORCE_REALACC_WLV8TX_ID + { + rx_tx_addr[0]=0x32; + rx_tx_addr[1]=0xE9; + rx_tx_addr[2]=0xDE; + rx_tx_addr[3]=0x0A; + hopping_frequency[0]=0x45; + hopping_frequency[1]=0x42; + hopping_frequency[2]=0x38; + hopping_frequency[3]=0x3C; + hopping_frequency[4]=0x4A; + } + #endif + memcpy(realacc_bind_packet, rx_tx_addr, 4); #if 0 debug("ID: %02X %02X %02X %02X, C: ",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3]); for(uint8_t i=0; i TX sends +// P(10)= B1 32 E9 DE 0A 45 42 38 3C 4A +// B1 indicates bind packet +// 32 E9 DE 0A = ID -> address of normal TX packets before bind +// 45 42 38 3C 4A = 69, 66, 56, 60, 74 -> RF channels to be used +// P(12)= B4 D4 E9 32 E9 DE 0A 45 42 38 3C 4A -> B4 designates TX found RX?, P(10) to P(12), TX inserts packet[1] and [2] from RX +// 32 E9 0A E3 = ID -> address of normal TX packets after bind (XOR rx_tx_addr[2],[3] with values from RX) +// ------> RX returns +// 32 E9 DE 8A = -> RX ID address returning bind info, same as TX address except (packet[3]|0x80) +// P(3)= B3 D4 E9 = B3=bind initiates Tx found, D4=XOR with rx_tx_addr[2], E9=XOR with rx_tx_addr[3] +// P(3)= B5 D4 E9 = B5=bind completed +// P(6)= 40 83 00 00 00 00 = RX returns on some hopping channels - unknown? telemetry? not used on this model? // Normal // TX1 // --- @@ -185,3 +346,14 @@ void REALACC_init() // 0C : |0x20=headless, |0x01=rate2, |0x02=rate3 // 00 : |0x01=calib, |0x20=return, |0x80=unknown // 00 : |0x80=light, |0x01=flip, |0x02=Rotating +// WLtoys Car 284019A V8-Tx +// --- +// Address = 32 E9 DE 0A (before bind), 32 E9 0A E3 (after bind and XOR) +// P(13)= DC 80 80 80 80 20 20 20 20 77 0C 00 00 +// Dx = normal packet, why C ? +// 80 80 80 80 : AE=80 TR 00..80..FF +// 20 20 20 20 : Gyro Rate, Constant?, Throttle Rate, Steer Trim +// 77 : changing every time the TX restart +// 0C : Constant? +// 00 : Constant? +// 00 : Constant? diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index fcea14c0..73ab47ec 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -447,7 +447,7 @@ #undef NCC1701_NRF24L01_INO #undef POTENSIC_NRF24L01_INO #undef PROPEL_NRF24L01_INO - #undef REALACC_NRF24L01_INO + //#undef REALACC_NRF24L01_INO // This now contains a WLtoys car sub protocol #undef SGF22_NRF24L01_INO #undef SYMAX_NRF24L01_INO #undef V761_NRF24L01_INO diff --git a/Protocols_Details.md b/Protocols_Details.md index 45c21395..7d700329 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -138,7 +138,7 @@ CFlie|AIR|38|CFlie||||||||NRF24L01| [Q303](Protocols_Details.md#Q303---31)||31|Q303|CX35|CX10D|CX10WD|||||NRF24L01|XN297 [Q90C](Protocols_Details.md#Q90C---72)||72|Q90C*||||||||NRF24L01|XN297 [RadioLink](Protocols_Details.md#RadioLink---74)||74|Surface|Air|DumboRC|RC4G|Dumbo_P||||CC2500| -[Realacc](Protocols_Details.md#Realacc---76)||76|R11||||||||NRF24L01| +[Realacc](Protocols_Details.md#Realacc---76)||76|R11|WL-V8Tx|||||||NRF24L01| [Redpine](Protocols_Details.md#Redpine---50)||50|FAST|SLOW|||||||NRF24L01|XN297 [Scanner](Protocols_Details.md#Scanner---54)||54|||||||||CC2500| [Scorpio](Protocols_Details.md#Scorpio---94)||94|||||||||CYRF6936| @@ -2301,14 +2301,31 @@ A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL Model: JXD 509 is using Q282 with CH12=Start/Stop motors ## Realacc - *76* -Model: Realacc R11, Eachine E017 Autobind protocol +### Sub_protocol R11 - *0* + +Models: Realacc R11, Eachine E017 + CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11 ---|---|---|---|---|---|---|---|---|----|---- A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|THR_CUT|ROTATE +### Sub_protocol WL-V8Tx - *1* + +Models: WLtoys 284019A, 284191, Cars using V8 Transmitter + +CH1|CH2|CH3|CH4|CH5 +---|---|---|---|--- +Steering|Throttle|GY_TRIM|TH_TRIM|ST_TRIM + +GY TRIM: (Rate) -100% Min, +100% Max, variable/set up on a adj. pot. + +TH TRIM: (Rate) -100% Min, +100% Max, variable/set up on a adj. pot. + +ST TRIM: -100% Left, +100% Right, variable/shouldn't be needed? CH1 trim on steering is available on most radios. + ## Redpine - *50* [Link to the forum](https://www.rcgroups.com/forums/showthread.php?3236043-Redpine-Lowest-latency-RC-protocol)