Make RC (Radio controlled) Remote Control presentable as Joystick in Linux without any additional cables. Since we know that servos operate on PWM, I have decided that cheapest way (and easiest) to fly a RC model simulator is to translate PWM from receiver to Joystick data on computer. Mbed board was doing the translation. No need for any special cable and no dependency on RC Transmitter or Receiver whatsoever. If it can move the servos it can also move the model in computer simulator. Requirements and design are available on https://os.mbed.com/users/Letme/notebook/rc-receiver-as-joystick/
Dependencies: PwmIn USBDevice USBJoystick mbed
main.cpp
00001 #include "mbed.h" 00002 #include <math.h> 00003 #include "USBJoystick.h" 00004 #include "PwmIn.h" 00005 00006 //InterruptIn button(USER_BUTTON); 00007 //#define DEBUG_PRINTF 00008 00009 DigitalOut led(LED1); 00010 00011 PwmIn a(PB_1); /**< Plug channel 1 from receiver to this pin */ 00012 PwmIn b(PC_4); /**< Plug channel 2 from receiver to this pin */ 00013 PwmIn c(PC_5); /**< Plug channel 3 from receiver to this pin */ 00014 PwmIn d(PC_8); /**< Plug channel 4 from receiver to this pin */ 00015 00016 /**@note Do not forget to plug ground pin to GND of the board */ 00017 00018 /** Covert PWM output which is in floats in range of 0.000153231 to -127..128 range 00019 * 00020 * PWM pulse width is in float range which needs to be offset a bit and then 00021 * converted to int8_t range for the PC joystick driver to understand 00022 * 00023 * @param[in] pwm PWM float value produced by PwmIn.pulseWidth function 00024 * 00025 * @return Converted signed integer value in range of -127..128 00026 */ 00027 int16_t covert_PWM_to_PC_range(float pwm) 00028 { 00029 int32_t ipwm = pwm * 1000000; 00030 if(ipwm != 0) { 00031 ipwm = (((ipwm - 1100) * 255) / 870) - 127; 00032 } 00033 00034 return (int16_t) ipwm; 00035 } 00036 00037 int main(void) 00038 { 00039 #ifndef DEBUG_PRINTF 00040 USBJoystick joystick; /**< Joystick object from USBJoystick library */ 00041 #else 00042 Serial pc(USBTX, USBRX); /**< USB interface through debugger (/dev/ttyACM0) */ 00043 pc.baud(115200); /** Set USB speed for the PC interface */ 00044 #endif 00045 uint16_t i = 0; 00046 int16_t throttle = 0; 00047 int16_t rudder = 0; 00048 int16_t x = 0; 00049 int16_t y = 0; 00050 uint8_t tmp = 0; 00051 uint32_t buttons = 0; 00052 uint8_t hat = 0; 00053 00054 led = 1; 00055 #ifdef DEBUG_PRINTF 00056 pc.printf("Hello World from Joystick!\r\n"); 00057 #endif 00058 00059 while (1) { 00060 /** Get PWM pulsewidth via PwmIn library and covert that to simple 00061 * int8_t range for all 4 channels */ 00062 x = covert_PWM_to_PC_range(a.pulsewidth()); 00063 y = covert_PWM_to_PC_range(b.pulsewidth()); 00064 throttle = covert_PWM_to_PC_range(c.pulsewidth()); 00065 rudder = covert_PWM_to_PC_range(d.pulsewidth()); 00066 00067 /* 00068 #if (BUTTONS4 == 1) 00069 buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button 00070 #endif 00071 #if (BUTTONS8 == 1) 00072 buttons = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button 00073 #endif 00074 #if (BUTTONS32 == 1) 00075 tmp = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button 00076 buttons = (( tmp << 0) & 0x000000FF); 00077 buttons = buttons | ((~tmp << 8) & 0x0000FF00); 00078 buttons = buttons | (( tmp << 16) & 0x00FF0000); 00079 buttons = buttons | ((~tmp << 24) & 0xFF000000); 00080 #endif 00081 00082 #if (HAT4 == 1) 00083 hat = (i >> 8) & 0x03; // value 0, 1, 2, 3 or 4 for neutral 00084 #endif 00085 #if (HAT8 == 1) 00086 hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral 00087 #endif 00088 */ 00089 00090 #ifndef DEBUG_PRINTF 00091 joystick.update(rudder, throttle, y, x, 0, 0); 00092 #else 00093 pc.printf("x (CH1): %i\t\ty (CH2): %i\t\t throttle: %i\r\n", y, x,throttle); 00094 #endif 00095 wait(0.005); 00096 } 00097 }
Generated on Tue Jul 12 2022 21:33:34 by
1.7.2