From 01bef23ac91197901944d6c876c882e0c4ca9eaa Mon Sep 17 00:00:00 2001 From: Pascal Langer Date: Wed, 29 Nov 2017 14:13:12 +0100 Subject: [PATCH] CG023 & H8_3D protocols - Removed sub_protcol H8_3D under protocol CG023 - Added protocol H8_3D (36) - Added sub_protocols H8_3D/H8_3D (0) - Added sub_protocols H8_3D/H20H (1) - Added sub_protocols H8_3D/H20Mini (2) - Added sub_protocols H8_3D/H30Mini (3) --- Multiprotocol/CG023_nrf24l01.ino | 196 ++++++----------------- Multiprotocol/H8_3D_nrf24l01.ino | 258 +++++++++++++++++++++++++++++++ Multiprotocol/Multi.txt | 3 +- Multiprotocol/Multiprotocol.h | 18 ++- Multiprotocol/Multiprotocol.ino | 6 + Multiprotocol/_Config.h | 7 +- Protocols_Details.md | 44 ++++-- 7 files changed, 361 insertions(+), 171 deletions(-) create mode 100644 Multiprotocol/H8_3D_nrf24l01.ino diff --git a/Multiprotocol/CG023_nrf24l01.ino b/Multiprotocol/CG023_nrf24l01.ino index 8d8dd77..870fda6 100644 --- a/Multiprotocol/CG023_nrf24l01.ino +++ b/Multiprotocol/CG023_nrf24l01.ino @@ -13,9 +13,6 @@ along with Multiprotocol. If not, see . */ // compatible with EAchine 3D X4, CG023/CG031, Attop YD-822/YD-829/YD-829C and H8_3D/JJRC H20/H22 -// Merged CG023 and H8_3D protocols -// Last sync with hexfet new_protocols/cg023_nrf24l01.c dated 2015-10-03 -// Last sync with hexfet new_protocols/h8_3d_nrf24l01.c dated 2015-11-18 #if defined(CG023_NRF24L01_INO) @@ -27,9 +24,6 @@ #define CG023_RF_BIND_CHANNEL 0x2D #define CG023_BIND_COUNT 500 // 4 seconds #define YD829_PACKET_PERIOD 4100 // Timeout for callback in uSec -#define H8_3D_PACKET_PERIOD 1800 // Timeout for callback in uSec -#define H8_3D_PACKET_SIZE 20 -#define H8_3D_RF_NUM_CHANNELS 4 enum CG023_FLAGS { @@ -55,26 +49,6 @@ enum YD829_FLAGS { YD829_FLAG_STILL = 0x80, }; -enum H8_3D_FLAGS { - // flags going to packet[17] - H8_3D_FLAG_FLIP = 0x01, - H8_3D_FLAG_RATE_MID = 0x02, - H8_3D_FLAG_RATE_HIGH = 0x04, - H8_3D_FLAG_LIGTH = 0x08, // Light on H22 - H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20, RTH on H22 - H8_3D_FLAG_RTH = 0x20, // 360 flip mode on H8 3D and H22, RTH on JJRC H20 -}; - -enum H8_3D_FLAGS_2 { - // flags going to packet[18] - H8_3D_FLAG_VIDEO = 0x80, - H8_3D_FLAG_PICTURE = 0x40, - H8_3D_FLAG_CALIBRATE1 = 0x20, // H8 3D acc calibration, H20 headless calib - H8_3D_FLAG_CALIBRATE2 = 0x10, // H11D and H20 acc calibration - H8_3D_FLAG_CAM_DN = 0x08, - H8_3D_FLAG_CAM_UP = 0x04, -}; - static void __attribute__((unused)) CG023_send_packet(uint8_t bind) { // throttle : 0x00 - 0xFF @@ -88,117 +62,59 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind) // aileron : 0x43 - 0x7F - 0xBB aileron = convert_channel_8b_scale(AILERON, 0x43, 0xBB); + if (bind) + packet[0]= 0xaa; + else + packet[0]= 0x55; + // transmitter id packet[1] = rx_tx_addr[0]; packet[2] = rx_tx_addr[1]; - if(sub_protocol==H8_3D) + // unknown + packet[3] = 0x00; + packet[4] = 0x00; + packet[5] = throttle; + packet[6] = rudder; + packet[7] = elevator; + packet[8] = aileron; + // throttle trim : 0x30 - 0x20 - 0x10 + packet[9] = 0x20; // neutral + // neutral trims + packet[10] = 0x20; + packet[11] = 0x40; + packet[12] = 0x40; + if(sub_protocol==CG023) { - packet[0] = 0x13; - packet[3] = rx_tx_addr[2]; - packet[4] = rx_tx_addr[3]; - packet[8] = rx_tx_addr[0]+rx_tx_addr[1]+rx_tx_addr[2]+rx_tx_addr[3]; // txid checksum - memset(&packet[9], 0, 10); - if (bind) - { - packet[5] = 0x00; - packet[6] = 0x00; - packet[7] = 0x01; - } - else - { - packet[5] = hopping_frequency_no; - packet[6] = 0x08; - packet[7] = 0x03; - packet[9] = throttle; - if(rudder==0x01) rudder=0; // Small deadband - if(rudder==0x81) rudder=0; // Small deadband - packet[10] = rudder; - packet[11] = elevator; - packet[12] = aileron; - // neutral trims - packet[13] = 0x20; - packet[14] = 0x20; - packet[15] = 0x20; - packet[16] = 0x20; - packet[17] = H8_3D_FLAG_RATE_HIGH - | GET_FLAG(Servo_AUX1,H8_3D_FLAG_FLIP) - | GET_FLAG(Servo_AUX2,H8_3D_FLAG_LIGTH) //H22 light - | GET_FLAG(Servo_AUX5,H8_3D_FLAG_HEADLESS) - | GET_FLAG(Servo_AUX6,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D - packet[18] = GET_FLAG(Servo_AUX3,H8_3D_FLAG_PICTURE) - | GET_FLAG(Servo_AUX4,H8_3D_FLAG_VIDEO) - | GET_FLAG(Servo_AUX7,H8_3D_FLAG_CALIBRATE1) - | GET_FLAG(Servo_AUX8,H8_3D_FLAG_CALIBRATE2); - if(Servo_data[AUX9]PPM_MAX_COMMAND) - packet[18] |= H8_3D_FLAG_CAM_UP; - } - uint8_t sum = packet[9]; - for (uint8_t i=10; i < H8_3D_PACKET_SIZE-1; i++) - sum += packet[i]; - packet[19] = sum; // data checksum + // rate + packet[13] = CG023_FLAG_RATE_HIGH + | GET_FLAG(Servo_AUX1,CG023_FLAG_FLIP) + | GET_FLAG(Servo_AUX2,CG023_FLAG_LED_OFF) + | GET_FLAG(Servo_AUX3,CG023_FLAG_STILL) + | GET_FLAG(Servo_AUX4,CG023_FLAG_VIDEO) + | GET_FLAG(Servo_AUX5,CG023_FLAG_EASY); } else - { // CG023 and YD829 - if (bind) - packet[0]= 0xaa; - else - packet[0]= 0x55; - // transmitter id - // unknown - packet[3] = 0x00; - packet[4] = 0x00; - packet[5] = throttle; - packet[6] = rudder; - packet[7] = elevator; - packet[8] = aileron; - // throttle trim : 0x30 - 0x20 - 0x10 - packet[9] = 0x20; // neutral - // neutral trims - packet[10] = 0x20; - packet[11] = 0x40; - packet[12] = 0x40; - if(sub_protocol==CG023) - { - // rate - packet[13] = CG023_FLAG_RATE_HIGH - | GET_FLAG(Servo_AUX1,CG023_FLAG_FLIP) - | GET_FLAG(Servo_AUX2,CG023_FLAG_LED_OFF) - | GET_FLAG(Servo_AUX3,CG023_FLAG_STILL) - | GET_FLAG(Servo_AUX4,CG023_FLAG_VIDEO) - | GET_FLAG(Servo_AUX5,CG023_FLAG_EASY); - } - else - {// YD829 - // rate - packet[13] = YD829_FLAG_RATE_HIGH - | GET_FLAG(Servo_AUX1,YD829_FLAG_FLIP) - | GET_FLAG(Servo_AUX3,YD829_FLAG_STILL) - | GET_FLAG(Servo_AUX4,YD829_FLAG_VIDEO) - | GET_FLAG(Servo_AUX5,YD829_FLAG_HEADLESS); - } - packet[14] = 0; + {// YD829 + // rate + packet[13] = YD829_FLAG_RATE_HIGH + | GET_FLAG(Servo_AUX1,YD829_FLAG_FLIP) + | GET_FLAG(Servo_AUX3,YD829_FLAG_STILL) + | GET_FLAG(Servo_AUX4,YD829_FLAG_VIDEO) + | GET_FLAG(Servo_AUX5,YD829_FLAG_HEADLESS); } + packet[14] = 0; // Power on, TX mode, 2byte CRC // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); if (bind) - NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol==H8_3D?hopping_frequency[0]:CG023_RF_BIND_CHANNEL); + NRF24L01_WriteReg(NRF24L01_05_RF_CH, CG023_RF_BIND_CHANNEL); else - { - if(sub_protocol==H8_3D) - { - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]); - hopping_frequency_no %= H8_3D_RF_NUM_CHANNELS; - } - else // CG023 and YD829 - NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); - } + NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no); + // clear packet status bits and TX FIFO NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); NRF24L01_FlushTx(); - XN297_WritePayload(packet, sub_protocol==H8_3D ? H8_3D_PACKET_SIZE:CG023_PACKET_SIZE); + XN297_WritePayload(packet, CG023_PACKET_SIZE); NRF24L01_SetPower(); // Set tx_power } @@ -207,16 +123,14 @@ static void __attribute__((unused)) CG023_init() { NRF24L01_Initialize(); NRF24L01_SetTxRxMode(TX_EN); - if(sub_protocol==H8_3D) - XN297_SetTXAddr((uint8_t *)"\xC4\x57\x09\x65\x21", 5); - else // CG023 and YD829 - XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5); + XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5); NRF24L01_FlushTx(); NRF24L01_FlushRx(); NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetPower(); } @@ -240,25 +154,10 @@ uint16_t CG023_callback() static void __attribute__((unused)) CG023_initialize_txid() { - if(sub_protocol==H8_3D) - { - rx_tx_addr[0] = 0xa0 + (rx_tx_addr[0] % 0x10); - rx_tx_addr[1] = 0xb0 + (rx_tx_addr[1] % 0x20); - rx_tx_addr[2] = rx_tx_addr[2] % 0x20; - rx_tx_addr[3] = rx_tx_addr[3] % 0x11; - - hopping_frequency[0] = 0x06 + ((rx_tx_addr[0]&0x0f) % 0x0f); - hopping_frequency[1] = 0x15 + ((rx_tx_addr[1]&0x0f) % 0x0f); - hopping_frequency[2] = 0x24 + ((rx_tx_addr[2]&0x0f) % 0x0f); - hopping_frequency[3] = 0x33 + ((rx_tx_addr[3]&0x0f) % 0x0f); - } - else - { // CG023 and YD829 - rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40); - if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel - rx_tx_addr[0] ++; - hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets - } + rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40); + if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel + rx_tx_addr[0] ++; + hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets } uint16_t initCG023(void) @@ -269,11 +168,8 @@ uint16_t initCG023(void) CG023_init(); if(sub_protocol==CG023) packet_period=CG023_PACKET_PERIOD; - else - if(sub_protocol==YD829) - packet_period=YD829_PACKET_PERIOD; - else - packet_period=H8_3D_PACKET_PERIOD; + else // YD829 + packet_period=YD829_PACKET_PERIOD; return CG023_INITIAL_WAIT+YD829_PACKET_PERIOD; } diff --git a/Multiprotocol/H8_3D_nrf24l01.ino b/Multiprotocol/H8_3D_nrf24l01.ino new file mode 100644 index 0000000..5b0afdc --- /dev/null +++ b/Multiprotocol/H8_3D_nrf24l01.ino @@ -0,0 +1,258 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Multiprotocol is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Multiprotocol. If not, see . + */ +// compatible with EAchine 3D X4, CG023/CG031, Attop YD-822/YD-829/YD-829C and H8_3D/JJRC H20/H22 +// Merged CG023 and H8_3D protocols +// Last sync with hexfet new_protocols/cg023_nrf24l01.c dated 2015-10-03 +// Last sync with hexfet new_protocols/h8_3d_nrf24l01.c dated 2015-11-18 + +#if defined(H8_3D_NRF24L01_INO) + +#include "iface_nrf24l01.h" + +#define H8_3D_PACKET_PERIOD 1800 +#define H20H_PACKET_PERIOD 9340 +#define H20MINI_PACKET_PERIOD 3100 +#define H8_3D_INITIAL_WAIT 500 +#define H8_3D_PACKET_SIZE 20 +#define H8_3D_RF_NUM_CHANNELS 4 +#define H20H_BIND_RF 0x49 +#define H8_3D_BIND_COUNT 1000 + +enum H8_3D_FLAGS { + // flags going to packet[17] + H8_3D_FLAG_FLIP = 0x01, + H8_3D_FLAG_RATE_MID = 0x02, + H8_3D_FLAG_RATE_HIGH = 0x04, + H8_3D_FLAG_LIGTH = 0x08, // Light on H22 + H8_3D_FLAG_HEADLESS = 0x10, // RTH + headless on H8, headless on JJRC H20, RTH on H22 + H8_3D_FLAG_RTH = 0x20, // 360 flip mode on H8 3D and H22, RTH on JJRC H20 +}; + +enum H8_3D_FLAGS_2 { + // flags going to packet[18] + H8_3D_FLAG_VIDEO = 0x80, + H8_3D_FLAG_PICTURE = 0x40, + H8_3D_FLAG_CALIBRATE1 = 0x20, // H8 3D acc calibration, H20,H20H headless calib + H8_3D_FLAG_CALIBRATE2 = 0x10, // H11D, H20, H20H acc calibration + H8_3D_FLAG_CAM_DN = 0x08, + H8_3D_FLAG_CAM_UP = 0x04, +}; + +static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind) +{ + if(sub_protocol==H20H) + packet[0] = 0x14; + else // H8_3D, H20MINI, H30MINI + packet[0] = 0x13; + + packet[1] = rx_tx_addr[0]; + packet[2] = rx_tx_addr[1]; + packet[3] = rx_tx_addr[2]; + packet[4] = rx_tx_addr[3]; + packet[8] = rx_tx_addr[0]+rx_tx_addr[1]+rx_tx_addr[2]+rx_tx_addr[3]; // txid checksum + memset(&packet[9], 0, 10); + if (bind) + { + packet[5] = 0x00; + packet[6] = 0x00; + packet[7] = 0x01; + } + else + { + packet[5] = hopping_frequency_no; + packet[7] = 0x03; + + rudder = convert_channel_8b_scale(RUDDER,0x44,0xBC); // yaw right : 0x80 (neutral) - 0xBC (right) + if(sub_protocol!=H20H) + { // H8_3D, H20MINI, H30MINI + packet[6] = 0x08; + packet[9] = convert_channel_8b(THROTTLE); // throttle : 0x00 - 0xFF + packet[15] = 0x20; // trims + packet[16] = 0x20; // trims + if (rudder<=0x80) + rudder=0x80-rudder; // yaw left : 0x00 (neutral) - 0x3C (left) + if(rudder==0x01 || rudder==0x81) + rudder=0x00; // Small deadband + } + else + { //H20H + packet[6] = hopping_frequency_no == 0 ? 8 - packet_count : 16 - packet_count; + packet[9] = convert_channel_8b_scale(THROTTLE, 0x43, 0xBB); // throttle : 0x43 - 0x7F - 0xBB + packet[15]= 0x40; // trims + packet[16]= 0x40; // trims + rudder--; // rudder : 0x43 - 0x7F - 0xBB + if (rudder>=0x7F-1 && rudder<=0x7F+1) + rudder=0x7F; // Small deadband + } + packet[10] = rudder; + packet[11] = convert_channel_8b_scale(ELEVATOR, 0x43, 0xBB); // elevator : 0x43 - 0x7F - 0xBB + packet[12] = convert_channel_8b_scale(AILERON, 0x43, 0xBB); // aileron : 0x43 - 0x7F - 0xBB + // neutral trims + packet[13] = 0x20; + packet[14] = 0x20; + // flags + packet[17] = H8_3D_FLAG_RATE_HIGH + | GET_FLAG(Servo_AUX1,H8_3D_FLAG_FLIP) + | GET_FLAG(Servo_AUX2,H8_3D_FLAG_LIGTH) //H22 light + | GET_FLAG(Servo_AUX5,H8_3D_FLAG_HEADLESS) + | GET_FLAG(Servo_AUX6,H8_3D_FLAG_RTH); // 180/360 flip mode on H8 3D + packet[18] = GET_FLAG(Servo_AUX3,H8_3D_FLAG_PICTURE) + | GET_FLAG(Servo_AUX4,H8_3D_FLAG_VIDEO) + | GET_FLAG(Servo_AUX7,H8_3D_FLAG_CALIBRATE1) + | GET_FLAG(Servo_AUX8,H8_3D_FLAG_CALIBRATE2); + if(Servo_data[AUX9]PPM_MAX_COMMAND) + packet[18] |= H8_3D_FLAG_CAM_UP; + } + uint8_t sum = packet[9]; + for (uint8_t i=10; i < H8_3D_PACKET_SIZE-1; i++) + sum += packet[i]; + packet[19] = sum; // data checksum + + // Power on, TX mode, 2byte CRC + // Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing + XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); + if(sub_protocol!=H20H) + { // H8_3D, H20MINI, H30MINI + NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? hopping_frequency[0] : hopping_frequency[hopping_frequency_no++]); + hopping_frequency_no %= H8_3D_RF_NUM_CHANNELS; + } + else + { //H20H + NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? H20H_BIND_RF : hopping_frequency[packet_count>>3]); + if(!bind) + { + packet_count++; + if(packet_count>15) + { + packet_count = 0; + hopping_frequency_no = 0; + } + else + if(packet_count > 7) + hopping_frequency_no = 1; + } + } + + // clear packet status bits and TX FIFO + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); + NRF24L01_FlushTx(); + XN297_WritePayload(packet, H8_3D_PACKET_SIZE); + + NRF24L01_SetPower(); // Set tx_power +} + +static void __attribute__((unused)) H8_3D_init() +{ + NRF24L01_Initialize(); + NRF24L01_SetTxRxMode(TX_EN); + if(sub_protocol==H20H) + XN297_SetTXAddr((uint8_t *)"\xEE\xDD\xCC\xBB\x11", 5); + else // H8_3D, H20MINI, H30MINI + XN297_SetTXAddr((uint8_t *)"\xC4\x57\x09\x65\x21", 5); + + NRF24L01_FlushTx(); + NRF24L01_FlushRx(); + NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit + NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes + NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only + NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits + NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps + NRF24L01_SetPower(); +} + +uint16_t H8_3D_callback() +{ + if(IS_BIND_DONE_on) + H8_3D_send_packet(0); + else + { + if (bind_counter == 0) + { + BIND_DONE; + packet_count=0; + } + else + { + H8_3D_send_packet(1); + bind_counter--; + } + } + return packet_period; +} + +static void __attribute__((unused)) H8_3D_initialize_txid() +{ + // captured from H20H stock transmitters + const uint8_t PROGMEM h20h_tx_rf_map[3][6] = {{/*ID*/0x83, 0x3c, 0x60, 0x00, /*RF*/0x47, 0x3e}, + {/*ID*/0x5c, 0x2b, 0x60, 0x00, /*RF*/0x4a, 0x3c}, + {/*ID*/0x57, 0x07, 0x00, 0x00, /*RF*/0x41, 0x48} }; + // captured from H20 Mini / H30 Mini stock transmitters + const uint8_t PROGMEM h20mini_tx_rf_map[4][8] = {{/*ID*/0xb4, 0xbb, 0x09, 0x00, /*RF*/0x3e, 0x45, 0x47, 0x4a}, + {/*ID*/0x94, 0x9d, 0x0b, 0x00, /*RF*/0x3e, 0x43, 0x49, 0x4a}, + {/*ID*/0xd1, 0xd0, 0x00, 0x00, /*RF*/0x3f, 0x42, 0x46, 0x4a}, + {/*ID*/0xcb, 0xcd, 0x04, 0x00, /*RF*/0x41, 0x43, 0x46, 0x4a}}; + uint8_t id_num=rx_tx_addr[4]; + switch(sub_protocol) + { + case H8_3D: + for(uint8_t i=0; i<4; i++) + hopping_frequency[i] = 6 + (0x0f*i) + (((rx_tx_addr[i] >> 4) + (rx_tx_addr[i] & 0x0f)) % 0x0f); + break; + case H20H: + id_num%=3; // 3 different IDs + for(uint8_t i=0; i<4; i++) + { + rx_tx_addr[i] = pgm_read_byte_near(&h20h_tx_rf_map[id_num][i]); + if(i<2) + hopping_frequency[i] = pgm_read_byte_near(&h20h_tx_rf_map[id_num][i+4]); + } + break; + case H20MINI: + case H30MINI: + id_num%=4; // 4 different IDs + for(uint8_t i=0; i<4; i++) + { + rx_tx_addr[i] = pgm_read_byte_near(&h20mini_tx_rf_map[id_num][i]); + hopping_frequency[i] = pgm_read_byte_near(&h20mini_tx_rf_map[id_num][i+4]); + } + break; + } +} + +uint16_t initH8_3D(void) +{ + BIND_IN_PROGRESS; // autobind protocol + bind_counter = H8_3D_BIND_COUNT; + H8_3D_initialize_txid(); + H8_3D_init(); + switch(sub_protocol) + { + case H8_3D: + packet_period=H8_3D_PACKET_PERIOD; + break; + case H20H: + packet_period=H20H_PACKET_PERIOD; + break; + case H20MINI: + case H30MINI: + packet_period=H20MINI_PACKET_PERIOD; + break; + } + return H8_3D_INITIAL_WAIT; +} + +#endif diff --git a/Multiprotocol/Multi.txt b/Multiprotocol/Multi.txt index 470896c..e8cec95 100644 --- a/Multiprotocol/Multi.txt +++ b/Multiprotocol/Multi.txt @@ -10,7 +10,7 @@ 10,SymaX,SYMAX,SYMAX5C 11,SLT,SLT,VISTA 12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041 -13,CG023,CG023,YD829,H8_3D +13,CG023,CG023,YD829 14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE 15,FrskyX,CH_16,CH_8,EU_16,EU_8 16,ESky @@ -33,3 +33,4 @@ 33,DM002 34,CABELL,CAB_V3,C_TELEM,-,-,-,-,F_SAFE,UNBIND 35,ESKY150 +36,H8_3D,H8_3D,H20H,H20Mini,H30Mini diff --git a/Multiprotocol/Multiprotocol.h b/Multiprotocol/Multiprotocol.h index 2216e07..5cb7bfd 100644 --- a/Multiprotocol/Multiprotocol.h +++ b/Multiprotocol/Multiprotocol.h @@ -19,7 +19,7 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 1 #define VERSION_REVISION 6 -#define VERSION_PATCH_LEVEL 33 +#define VERSION_PATCH_LEVEL 34 //****************** // Protocols //****************** @@ -61,6 +61,7 @@ enum PROTOCOLS MODE_DM002 = 33, // =>NRF24L01 MODE_CABELL = 34, // =>NRF24L01 MODE_ESKY150 = 35, // =>NRF24L01 + MODE_H8_3D = 36, // =>NRF24L01 }; enum Flysky @@ -133,7 +134,6 @@ enum CG023 { CG023 = 0, YD829 = 1, - H8_3D = 2 }; enum BAYANG { @@ -206,6 +206,13 @@ enum CABELL CABELL_SET_FAIL_SAFE= 6, CABELL_UNBIND = 7, }; +enum H8_3D +{ + H8_3D = 0, + H20H = 1, + H20MINI = 2, + H30MINI = 3, +}; #define NONE 0 #define P_HIGH 1 @@ -535,6 +542,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- DM002 33 CABELL 34 ESKY150 35 + H8_3D 36 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No @@ -586,7 +594,6 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- sub_protocol==CG023 CG023 0 YD829 1 - H8_3D 2 sub_protocol==BAYANG BAYANG 0 H8S3D 1 @@ -643,6 +650,11 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- CABELL_V3_TELEMETRY 1 CABELL_SET_FAIL_SAFE 6 CABELL_UNBIND 7 + sub_protocol==H8_3D + H8_3D 0 + H20H 1 + H20MINI 2 + H30MINI 3 Power value => 0x80 0=High/1=Low Stream[3] = option_protocol; diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 1dd987d..0b1214d 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -1015,6 +1015,12 @@ static void protocol_init() remote_callback = ESKY150_callback; break; #endif + #if defined(H8_3D_NRF24L01_INO) + case MODE_H8_3D: + next_callback=initH8_3D(); + remote_callback = H8_3D_callback; + break; + #endif #endif } } diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 364684c..4a85904 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -141,6 +141,7 @@ #define DM002_NRF24L01_INO #define CABELL_NRF24L01_INO #define ESKY150_NRF24L01_INO +#define H8_3D_NRF24L01_INO /**************************/ /*** FAILSAFE SETTINGS ***/ @@ -348,7 +349,6 @@ const PPM_Parameters PPM_prot[15]= { MODE_CG023 CG023 YD829 - H8_3D MODE_BAYANG BAYANG H8S3D @@ -414,6 +414,11 @@ const PPM_Parameters PPM_prot[15]= { CABELL_SET_FAIL_SAFE CABELL_UNBIND MODE_ESKY150 + MODE_H8_3D + H8_3D + H20H + H20 Mini + H30 Mini */ // RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded... diff --git a/Protocols_Details.md b/Protocols_Details.md index 9922d46..16471b3 100644 --- a/Protocols_Details.md +++ b/Protocols_Details.md @@ -425,22 +425,6 @@ CH5|CH6|CH7|CH8|CH9 ---|---|---|---|--- FLIP||PICTURE|VIDEO|HEADLESS -### Sub_protocol H8_3D - *2* -Models: EAchine H8 mini 3D, JJRC H20/H22/H11D - -CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13 ----|---|---|---|---|---|---|---|--- -FLIP|LIGTH|PICTURE|VIDEO|OPT1|OPT2|CAL1|CAL2|GIMBAL - -JJRC H20: OPT1=Headless, OPT2=RTH - -JJRC H22: OPT1=RTH, OPT2=180/360° flip mode - -H8 3D: OPT1=RTH then press a direction to enter headless mode (like stock TX), OPT2=switch 180/360° flip mode - -CAL1: H8 3D acc calib, H20 headless calib -CAL2: H11D/H20 acc calib - ## CX10 - *12* Autobind protocol @@ -536,6 +520,34 @@ CH1|CH2|CH3|CH4|CH5 ---|---|---|---|--- A|E|T|R|FLIP +## H8_3D - *36* +Autobind protocol + +### Sub_protocol H8_3D - *0* +Models: EAchine H8 mini 3D, JJRC H20/H22/H11D + +CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13 +---|---|---|---|---|---|---|---|--- +FLIP|LIGTH|PICTURE|VIDEO|OPT1|OPT2|CAL1|CAL2|GIMBAL + +JJRC H20: OPT1=Headless, OPT2=RTH + +JJRC H22: OPT1=RTH, OPT2=180/360° flip mode + +H8 3D: OPT1=RTH then press a direction to enter headless mode (like stock TX), OPT2=switch 180/360° flip mode + +CAL1: H8 3D acc calib, H20/H20H headless calib +CAL2: H11D/H20/H20H acc calib + +### Sub_protocol H20H - *1* +CH6=Motors on/off + +### Sub_protocol H20 Mini - *2* +**Only 3 TX IDs available, change RX_Num value 0-1-2 to cycle through them** + +### Sub_protocol H30 Mini - *3* +**Only 4 TX IDs available, change RX_Num value 0-1-2_3 to cycle through them** + ## HISKY - *4* ### Sub_protocol Hisky - *0* CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8