DIRECT_INPUT feature to allow wiring own inputs

This commit is contained in:
gbob 2018-02-01 21:22:09 +00:00
parent 4a9d295f1a
commit 6f12d486a0
6 changed files with 172 additions and 10 deletions

View File

@ -146,6 +146,24 @@ uint16_t convert_channel_frsky(uint8_t num)
return ((val*15)>>4)+1290; return ((val*15)>>4)+1290;
} }
uint16_t limit_uint_16_t(uint16_t val, uint16_t min, uint16_t max)
{
if(val > max)
return max;
else
if (val < min)
return min;
return val;
}
uint16_t apply_direct_input_dead_band_center(uint16_t val, uint16_t center, uint16_t dead_band){
uint16_t off_center = abs(center - val);
if(off_center < dead_band){
return center;
}
return val;
}
/******************************/ /******************************/
/** FrSky D and X routines **/ /** FrSky D and X routines **/
/******************************/ /******************************/

View File

@ -261,14 +261,26 @@ void setup()
#else #else
TX_INV_off; TX_INV_off;
RX_INV_off; RX_INV_off;
#endif #endif
#endif #endif
pinMode(BIND_pin,INPUT_PULLUP); pinMode(BIND_pin,INPUT_PULLUP);
pinMode(PPM_pin,INPUT); pinMode(PPM_pin,INPUT);
pinMode(S1_pin,INPUT_PULLUP);//dial switch #ifdef ENABLE_DIRECT_INPUT
pinMode(S2_pin,INPUT_PULLUP); pinMode(S1_pin, INPUT_ANALOG); //joystick pins
pinMode(S3_pin,INPUT_PULLUP); pinMode(S2_pin, INPUT_ANALOG);
pinMode(S4_pin,INPUT_PULLUP); pinMode(S3_pin, INPUT_ANALOG);
pinMode(S4_pin, INPUT_ANALOG);
pinMode(AUX1_pin, INPUT_PULLUP);
pinMode(AUX2_pin, INPUT_PULLUP);
pinMode(AUX3_pin, INPUT_PULLUP);
pinMode(AUX4_pin, INPUT_PULLUP);
#else
pinMode(S1_pin, INPUT_PULLUP); //dial switch
pinMode(S2_pin, INPUT_PULLUP);
pinMode(S3_pin, INPUT_PULLUP);
pinMode(S4_pin ,INPUT_PULLUP);
#endif
//Random pins //Random pins
pinMode(PB0, INPUT_ANALOG); // set up pin for analog input pinMode(PB0, INPUT_ANALOG); // set up pin for analog input
pinMode(PB1, INPUT_ANALOG); // set up pin for analog input pinMode(PB1, INPUT_ANALOG); // set up pin for analog input
@ -339,7 +351,7 @@ void setup()
//Wait for every component to start //Wait for every component to start
delayMilliseconds(100); delayMilliseconds(100);
// Read status of bind button // Read status of bind button
if( IS_BIND_BUTTON_on ) if( IS_BIND_BUTTON_on )
{ {
@ -357,7 +369,7 @@ void setup()
mode_select= 0x0F -(uint8_t)(((GPIOA->regs->IDR)>>4)&0x0F); mode_select= 0x0F -(uint8_t)(((GPIOA->regs->IDR)>>4)&0x0F);
#else #else
mode_select = mode_select =
((PROTO_DIAL1_ipr & _BV(PROTO_DIAL1_pin)) ? 0 : 1) + ((PROTO_DIAL1_ipr & _BV(PROTO_DIAL1_pin)) ? 0 : 1) +
((PROTO_DIAL2_ipr & _BV(PROTO_DIAL2_pin)) ? 0 : 2) + ((PROTO_DIAL2_ipr & _BV(PROTO_DIAL2_pin)) ? 0 : 2) +
((PROTO_DIAL3_ipr & _BV(PROTO_DIAL3_pin)) ? 0 : 4) + ((PROTO_DIAL3_ipr & _BV(PROTO_DIAL3_pin)) ? 0 : 4) +
((PROTO_DIAL4_ipr & _BV(PROTO_DIAL4_pin)) ? 0 : 8); ((PROTO_DIAL4_ipr & _BV(PROTO_DIAL4_pin)) ? 0 : 8);
@ -385,7 +397,7 @@ void setup()
#ifndef ORANGE_TX #ifndef ORANGE_TX
//Init the seed with a random value created from watchdog timer for all protocols requiring random values //Init the seed with a random value created from watchdog timer for all protocols requiring random values
#ifdef STM32_BOARD #ifdef STM32_BOARD
randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1)); randomSeed((uint32_t)analogRead(PB0) << 10 | analogRead(PB1));
#else #else
randomSeed(random_value()); randomSeed(random_value());
#endif #endif
@ -395,7 +407,7 @@ void setup()
MProtocol_id_master=random_id(10,false); MProtocol_id_master=random_id(10,false);
debugln("Module Id: %lx", MProtocol_id_master); debugln("Module Id: %lx", MProtocol_id_master);
#ifdef ENABLE_PPM #ifdef ENABLE_PPM
//Protocol and interrupts initialization //Protocol and interrupts initialization
if(mode_select != MODE_SERIAL) if(mode_select != MODE_SERIAL)
@ -478,6 +490,13 @@ void setup()
#endif //ENABLE_SERIAL #endif //ENABLE_SERIAL
} }
LED2_on; LED2_on;
#ifdef ENABLE_DIRECT_INPUT
for(uint8_t i=0;i<3;i++)
cur_protocol[i]= DIRECT_INPUT_PROTOCOL_SELECT;
protocol = DIRECT_INPUT_PROTOCOL_SELECT;
CHANGE_PROTOCOL_FLAG_on;
#endif //ENABLE_DIRECT_INPUT
debugln("Init complete"); debugln("Init complete");
} }
@ -602,6 +621,12 @@ uint8_t Update_All()
last_signal=millis(); last_signal=millis();
} }
#endif //ENABLE_PPM #endif //ENABLE_PPM
#ifdef ENABLE_DIRECT_INPUT
update_direct_input_data();
update_channels_aux();
INPUT_SIGNAL_on; //valid signal received
last_signal=millis();
#endif //ENABLE_DIRECT_INPUT
update_led_status(); update_led_status();
#if defined(TELEMETRY) #if defined(TELEMETRY)
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) ) #if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
@ -661,6 +686,66 @@ static void update_channels_aux(void)
Channel_AUX|=1<<i; Channel_AUX|=1<<i;
} }
#ifdef ENABLE_DIRECT_INPUT
uint32_t debug_input_interval = 1000;
void update_direct_input_data(){
uint16_t ai_raw = AILERON_read();
uint16_t th_raw = THROTTLE_read();
uint16_t el_raw = ELEVATOR_read();
uint16_t ru_raw = RUDDER_read();
uint8_t aux1_raw = AUX1_read();
uint8_t aux2_raw = AUX2_read();
uint8_t aux3_raw = AUX3_read();
uint8_t aux4_raw = AUX4_read();
uint16_t ai = apply_direct_input_dead_band_center(ai_raw, AILERON_CENTER, DEAD_CENTER);
uint16_t el = apply_direct_input_dead_band_center(el_raw, ELEVATOR_CENTER, DEAD_CENTER);
uint16_t ru = apply_direct_input_dead_band_center(ru_raw, RUDDER_CENTER, DEAD_CENTER);
ai = limit_uint_16_t(ai, AILERON_MIN, AILERON_MAX);
el = limit_uint_16_t(el, ELEVATOR_MIN, ELEVATOR_MAX);
ru = limit_uint_16_t(ru, RUDDER_MIN, RUDDER_MAX);
uint16_t th = limit_uint_16_t(th_raw, THROTTLE_MIN, THROTTLE_MAX);
ai < AILERON_CENTER ? ai = map(ai, AILERON_MIN, AILERON_CENTER, CHANNEL_MIN_125, CHANNEL_MID_125) :
ai = map(ai, AILERON_CENTER, AILERON_MAX, CHANNEL_MID_125, CHANNEL_MAX_125);
el < ELEVATOR_CENTER ? el = map(el, ELEVATOR_MIN, ELEVATOR_CENTER, CHANNEL_MIN_125, CHANNEL_MID_125) :
el = map(el, ELEVATOR_CENTER, ELEVATOR_MAX, CHANNEL_MID_125, CHANNEL_MAX_125);
ru < RUDDER_CENTER ? ru = map(ru, RUDDER_MIN, RUDDER_CENTER, CHANNEL_MIN_125, CHANNEL_MID_125):
ru = map(ru, RUDDER_CENTER, RUDDER_MAX, CHANNEL_MID_125, CHANNEL_MAX_125);
th = map(th, THROTTLE_MIN, THROTTLE_MAX, CHANNEL_MIN_125, CHANNEL_MAX_125);
uint16_t aux1 = aux1_raw? CHANNEL_MIN_125 : CHANNEL_MAX_125;
uint16_t aux2 = aux2_raw? CHANNEL_MIN_125 : CHANNEL_MAX_125;
uint16_t aux3 = aux3_raw? CHANNEL_MIN_125 : CHANNEL_MAX_125;
uint16_t aux4 = aux4_raw? CHANNEL_MIN_125 : CHANNEL_MAX_125 ;
Channel_data[AILERON] = ai;
Channel_data[THROTTLE] = th;
Channel_data[ELEVATOR] = el;
Channel_data[RUDDER] = ru;
Channel_data[CH5] = aux1;
Channel_data[CH6] = aux2;
Channel_data[CH7] = aux3;
Channel_data[CH8] = aux4;
if(debug_input_interval < millis() ){
debugln("AILERON_RAW:%d,AILERON_VAL:%d", ai_raw, ai);
debugln("THROTTLE_RAW:%d,THROTTLE_VAL:%d", th_raw, th);
debugln("ELEVATOR_RAW:%d,ELEVATOR_VAL:%d", el_raw, el);
debugln("RUDDER_RAW:%d,RUDDER_VAL:%d", ru_raw, ru);
debugln("AUX1_RAW:%d,AUX1_VAL:%d", aux1_raw, aux1);
debugln("AUX2_RAW:%d,AUX2_VAL:%d", aux2_raw, aux2);
debugln("AUX3_RAW:%d,AUX3_VAL:%d", aux3_raw, aux3);
debugln("AUX4_RAW:%d,AUX4_VAL:%d", aux4_raw, aux4);
debug_input_interval = millis() + 1000;
}
}
#endif //ENABLE_DIRECT_INPUT
// Update led status based on binding and serial // Update led status based on binding and serial
static void update_led_status(void) static void update_led_status(void)
{ {

View File

@ -214,7 +214,11 @@
#else //STM32_BOARD #else //STM32_BOARD
#define BIND_pin PA0 #define BIND_pin PA0
#define LED_pin PA1 #define LED_pin PA1
#define LED2_pin PA2 #ifdef ENABLE_DIRECT_INPUT
#define LED2_pin PC13
#else
#define LED2_pin PA2
#endif
// //
#define PPM_pin PA8 //PPM 5V tolerant #define PPM_pin PA8 //PPM 5V tolerant
// //
@ -239,6 +243,12 @@
// //
#define TX_INV_pin PB3 #define TX_INV_pin PB3
#define RX_INV_pin PB1 #define RX_INV_pin PB1
//
#define AUX1_pin PB10
#define AUX2_pin PB11
#define AUX3_pin PA2
#define AUX4_pin PA3
// //
#define PE1_on digitalWrite(PE1_pin,HIGH) #define PE1_on digitalWrite(PE1_pin,HIGH)
#define PE1_off digitalWrite(PE1_pin,LOW) #define PE1_off digitalWrite(PE1_pin,LOW)
@ -316,6 +326,15 @@
#define cli() noInterrupts() #define cli() noInterrupts()
#define sei() interrupts() #define sei() interrupts()
#define delayMilliseconds(x) delay(x) #define delayMilliseconds(x) delay(x)
#define AILERON_read() analogRead(S1_pin)
#define ELEVATOR_read() analogRead(S2_pin)
#define THROTTLE_read() analogRead(S3_pin)
#define RUDDER_read() analogRead(S4_pin)
#define AUX1_read() digitalRead(AUX1_pin)
#define AUX2_read() digitalRead(AUX2_pin)
#define AUX3_read() digitalRead(AUX3_pin)
#define AUX4_read() digitalRead(AUX4_pin)
#endif #endif
//******************* //*******************

View File

@ -39,6 +39,7 @@
#define CHANNEL_MIN_100 204 // 100% #define CHANNEL_MIN_100 204 // 100%
#define CHANNEL_MAX_125 2047 // 125% #define CHANNEL_MAX_125 2047 // 125%
#define CHANNEL_MIN_125 0 // 125% #define CHANNEL_MIN_125 0 // 125%
#define CHANNEL_MID_125 CHANNEL_MAX_125/2+1
#define CHANNEL_MIN_COMMAND 784 // 1350us #define CHANNEL_MIN_COMMAND 784 // 1350us
#define CHANNEL_SWITCH 1104 // 1550us #define CHANNEL_SWITCH 1104 // 1550us

View File

@ -239,6 +239,12 @@
#endif #endif
#endif #endif
#if defined(ENABLE_DIRECT_INPUT)
#if defined(NABLE_SERIAL) || defined(ENABLE_PPM)
#error You must disable ENABLE_SERIAL and ENABLE_PPM before using ENABLE_DIRECT_INPUT
#endif
#endif
#if MIN_PPM_CHANNELS>16 #if MIN_PPM_CHANNELS>16
#error MIN_PPM_CHANNELS must be below or equal to 16. The default for this value is 4. #error MIN_PPM_CHANNELS must be below or equal to 16. The default for this value is 4.
#endif #endif

View File

@ -271,6 +271,39 @@
//If you do not plan to use the PPM mode comment this line using "//" to save Flash space, you don't need to configure anything below in this case //If you do not plan to use the PPM mode comment this line using "//" to save Flash space, you don't need to configure anything below in this case
#define ENABLE_PPM #define ENABLE_PPM
/**********************************/
/*** DIRECT INPUT MODE SETTINGS ***/
/**********************************/
//In this section you can configure the direct input mode.
//The direct mode enables controls(analog joystics, buttons) wired directly to the board
//Current mappings are: AILERON-PA4, ELEVATOR-PA5, THROTTLE-PA6, RUDDER-PA7, AUX1-PB10, AUX2-PB11, AUX3-PA2, AUX4-PA3
//If plan to use direct input mode please uncomment lines below and comment out SERIAL and PPM MODE
//#define ENABLE_DIRECT_INPUT
//
//#define DIRECT_INPUT_PROTOCOL_SELECT PROTO_SYMAX
//
//#define DEAD_CENTER 25 //change in raw input value before being reporter as movement
//
////Enable serial debug and update calibration values below based on the output
//
//#define THROTTLE_MIN 500
//#define THROTTLE_MAX 3550
//
//#define AILERON_MIN 500
//#define AILERON_CENTER 1525
//#define AILERON_MAX 3550
//
//#define ELEVATOR_MIN 500
//#define ELEVATOR_CENTER 1525
//#define ELEVATOR_MAX 3550
//
//#define RUDDER_MIN 500
//#define RUDDER_CENTER 1525
//#define RUDDER_MAX 3550
/** TX END POINTS **/ /** TX END POINTS **/
//It is important for the module to know the endpoints of your radio. //It is important for the module to know the endpoints of your radio.
//Below are some standard transmitters already preconfigured. //Below are some standard transmitters already preconfigured.