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

RC receiver as joystick

PWMIn class defines your pins which are connected to certain channels on receiver. I suggest you keep the order and just swap pins (since order defines axis identified in computer through USB and generic Joystick driver. You can also calibrate your Joystick.

Tested on mbed boards

  • NUCLEO-F401RE

Initial tests were done with NUCLEO-F401RE and was tested on Chromebook, with PicaSim, Linux PC with CRRCSim and FlightGear. Because it is just Joystick it can be used in any game supporting joysticks (from car simulations to everyday games). No more need for special cables to get your transmitter to the computer.

Requirements, Test Cases and Design

Since this was done before project was started I used a simple notebook to outline the required work. It is still available on https://os.mbed.com/users/Letme/notebook/rc-receiver-as-joystick/

Files at this revision

API Documentation at this revision

Comitter:
Letme
Date:
Thu Oct 18 20:31:36 2018 +0000
Commit message:
Stable version

Changed in this revision

PwmIn.lib Show annotated file Show diff for this revision Revisions of this file
USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
USBJoystick.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r e0d0f401d8a4 PwmIn.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PwmIn.lib	Thu Oct 18 20:31:36 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/simon/code/PwmIn/#6d68eb9b6bbb
diff -r 000000000000 -r e0d0f401d8a4 USBDevice.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Thu Oct 18 20:31:36 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/mbed_official/code/USBDevice/#53949e6131f6
diff -r 000000000000 -r e0d0f401d8a4 USBJoystick.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBJoystick.lib	Thu Oct 18 20:31:36 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/wim/code/USBJoystick/#e086541742c3
diff -r 000000000000 -r e0d0f401d8a4 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Oct 18 20:31:36 2018 +0000
@@ -0,0 +1,97 @@
+#include "mbed.h"
+#include <math.h>
+#include "USBJoystick.h"
+#include "PwmIn.h"
+
+//InterruptIn button(USER_BUTTON);
+//#define DEBUG_PRINTF
+
+DigitalOut led(LED1);
+
+PwmIn a(PB_1); /**< Plug channel 1 from receiver to this pin */
+PwmIn b(PC_4); /**< Plug channel 2 from receiver to this pin */
+PwmIn c(PC_5); /**< Plug channel 3 from receiver to this pin */
+PwmIn d(PC_8); /**< Plug channel 4 from receiver to this pin */
+
+/**@note Do not forget to plug ground pin to GND of the board */
+
+/** Covert PWM output which is in floats in range of 0.000153231 to -127..128 range
+ *
+ * PWM pulse width is in float range which needs to be offset a bit and then
+ * converted to int8_t range for the PC joystick driver to understand
+ *
+ * @param[in] pwm PWM float value produced by PwmIn.pulseWidth function
+ *
+ * @return Converted signed integer value in range of -127..128
+ */
+int16_t covert_PWM_to_PC_range(float pwm)
+{
+    int32_t ipwm = pwm * 1000000;
+    if(ipwm != 0) {
+        ipwm = (((ipwm - 1100) * 255) / 870) - 127;   
+    }
+    
+    return (int16_t) ipwm;
+}
+
+int main(void)
+{
+#ifndef DEBUG_PRINTF
+    USBJoystick joystick; /**< Joystick object from USBJoystick library */
+#else
+    Serial pc(USBTX, USBRX); /**< USB interface through debugger (/dev/ttyACM0) */
+    pc.baud(115200); /** Set USB speed for the PC interface */
+#endif
+    uint16_t i = 0;
+    int16_t throttle = 0;
+    int16_t rudder = 0;
+    int16_t x = 0;
+    int16_t y = 0;
+    uint8_t tmp = 0;
+    uint32_t buttons = 0;
+    uint8_t hat = 0;
+
+    led = 1;
+#ifdef DEBUG_PRINTF
+    pc.printf("Hello World from Joystick!\r\n");
+#endif
+    
+    while (1) {
+        /** Get PWM pulsewidth via PwmIn library and covert that to simple
+         * int8_t range for all 4 channels */
+        x = covert_PWM_to_PC_range(a.pulsewidth());
+        y = covert_PWM_to_PC_range(b.pulsewidth());
+        throttle = covert_PWM_to_PC_range(c.pulsewidth());
+        rudder = covert_PWM_to_PC_range(d.pulsewidth());
+
+/*
+#if (BUTTONS4 == 1)
+        buttons = (i >> 8) & 0x0F;   // value    0 ..  15, one bit per button
+#endif
+#if (BUTTONS8 == 1)
+        buttons = (i >> 8) & 0xFF;   // value    0 .. 255, one bit per button
+#endif
+#if (BUTTONS32 == 1)
+        tmp     = (i >> 8) & 0xFF;   // value    0 .. 255, one bit per button
+        buttons =           (( tmp <<  0) & 0x000000FF);
+        buttons = buttons | ((~tmp <<  8) & 0x0000FF00);
+        buttons = buttons | (( tmp << 16) & 0x00FF0000);
+        buttons = buttons | ((~tmp << 24) & 0xFF000000);
+#endif
+
+#if (HAT4 == 1)
+        hat    = (i >> 8) & 0x03;   // value 0, 1, 2, 3 or 4 for neutral
+#endif
+#if (HAT8 == 1)
+        hat    = (i >> 8) & 0x07;   // value 0..7 or 8 for neutral
+#endif
+*/
+        
+#ifndef DEBUG_PRINTF
+        joystick.update(rudder, throttle, y, x, 0, 0);
+#else
+        pc.printf("x (CH1): %i\t\ty (CH2): %i\t\t throttle: %i\r\n", y, x,throttle);
+#endif
+        wait(0.005);
+    }
+}
diff -r 000000000000 -r e0d0f401d8a4 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Oct 18 20:31:36 2018 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a7c7b631e539
\ No newline at end of file