Skip to content

Commit 370a026

Browse files
committed
esp32s2 rx/tx/ppm/analog + gamepad mode
1 parent 691be3a commit 370a026

File tree

5 files changed

+240
-43
lines changed

5 files changed

+240
-43
lines changed

.github/workflows/platformio.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-22.04
1313
strategy:
1414
matrix:
15-
target: ['esp32', 'esp8266']
15+
target: ['esp32_tx_ppm', 'esp32s2_rx', 'esp32s2_tx_ppm', 'esp32s2_tx_analog', 'esp32c3_tx_ppm', 'esp32c3_tx_analog', 'esp8266']
1616
steps:
1717
- uses: actions/checkout@v4
1818
- name: Extract Version

platformio.ini

+74-4
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ lib_deps =
1919
build_flags =
2020
-std=gnu++17
2121
-Wall
22+
; -DPRINT_INFO=1 ; print some details to console
23+
; -DMODE_SIM=1 ; enable simulator, overwrite any rx function
2224

2325
build_unflags =
2426
-std=gnu++11
2527
-ggdb
2628

27-
[env:esp32]
29+
[env:esp32_tx_ppm]
2830
platform = espressif32
2931
board = lolin32
3032
framework = arduino
@@ -35,9 +37,74 @@ build_unflags =
3537
${env.build_unflags}
3638
build_flags =
3739
${env.build_flags}
40+
-DMODE_TX=1
3841
-DPIN_PPM=13
3942

40-
[env:esp32c3_ppm]
43+
[env:esp32s2_rx]
44+
board = esp32-s2-saola-1
45+
platform = espressif32
46+
framework = arduino
47+
extra_scripts = merge_firmware.py
48+
lib_deps =
49+
${env.lib_deps}
50+
schnoog/Joystick_ESP32S2@^0.9.4
51+
build_unflags =
52+
${env.build_unflags}
53+
build_flags =
54+
${env.build_flags}
55+
-DESP32S2
56+
-DARDUINO_USB_MODE=0
57+
-DARDUINO_USB_CDC_ON_BOOT=1
58+
-DMODE_RX=1
59+
-DMODE_GAMEPAD=1
60+
61+
[env:esp32s2_tx_ppm]
62+
board = esp32-s2-saola-1
63+
platform = espressif32
64+
framework = arduino
65+
extra_scripts = merge_firmware.py
66+
lib_deps =
67+
${env.lib_deps}
68+
schnoog/Joystick_ESP32S2@^0.9.4
69+
build_unflags =
70+
${env.build_unflags}
71+
build_flags =
72+
${env.build_flags}
73+
-DESP32C3
74+
-DARDUINO_USB_MODE=0
75+
-DARDUINO_USB_CDC_ON_BOOT=1
76+
-DMODE_GAMEPAD=1
77+
-DMODE_TX=1
78+
-DPIN_PPM=13
79+
80+
[env:esp32s2_tx_analog]
81+
board = esp32-s2-saola-1
82+
platform = espressif32
83+
framework = arduino
84+
extra_scripts = merge_firmware.py
85+
lib_deps =
86+
${env.lib_deps}
87+
schnoog/Joystick_ESP32S2@^0.9.4
88+
build_unflags =
89+
${env.build_unflags}
90+
build_flags =
91+
${env.build_flags}
92+
-DESP32C3
93+
-DARDUINO_USB_MODE=0
94+
-DARDUINO_USB_CDC_ON_BOOT=1
95+
-DMODE_GAMEPAD=1
96+
-DMODE_TX=1
97+
-DUSE_ANALOG=1
98+
-DPIN_POT0=1
99+
-DPIN_POT1=2
100+
-DPIN_POT2=3
101+
-DPIN_POT3=4
102+
-DPIN_SW0=6
103+
-DPIN_SW1=7
104+
-DPIN_SW2=8
105+
-DPIN_SW3=9
106+
107+
[env:esp32c3_tx_ppm]
41108
board = esp32-c3-devkitm-1
42109
platform = espressif32
43110
framework = arduino
@@ -51,9 +118,10 @@ build_flags =
51118
-DESP32C3
52119
-DARDUINO_USB_MODE=1
53120
-DARDUINO_USB_CDC_ON_BOOT=1
121+
-DMODE_TX=1
54122
-DPIN_PPM=6
55123

56-
[env:esp32c3_analog]
124+
[env:esp32c3_tx_analog]
57125
board = esp32-c3-devkitm-1
58126
platform = espressif32
59127
framework = arduino
@@ -67,6 +135,7 @@ build_flags =
67135
-DESP32C3
68136
-DARDUINO_USB_MODE=1
69137
-DARDUINO_USB_CDC_ON_BOOT=1
138+
-DMODE_TX=1
70139
-DUSE_ANALOG=1
71140
-DPIN_POT0=0
72141
-DPIN_POT1=1
@@ -75,7 +144,7 @@ build_flags =
75144
-DPIN_SW0=8
76145
-DPIN_SW1=6
77146
-DPIN_SW2=-1
78-
; -DPRINT_INFO=1 ; print some details to console
147+
-DPIN_SW3=-1
79148

80149
[env:esp8266]
81150
platform = espressif8266
@@ -87,4 +156,5 @@ build_unflags =
87156
${env.build_unflags}
88157
build_flags =
89158
${env.build_flags}
159+
-DMODE_TX=1
90160
-DPIN_PPM=13

src/main.cpp

+99-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#include <Arduino.h>
2-
#include "EspNowRcLink/Transmitter.h"
32
#include "tx.hpp"
4-
#include "sim.hpp"
53

64
#if defined(PIN_PPM) && defined(USE_ANALOG)
75
#error "PIN_PPM and USE_ANALOG Cannot be defined at the same time!"
86
#endif
97

8+
#define SIM_INTERVAL_MS 20 // 20ms => 50Hz
9+
10+
#ifdef MODE_SIM
11+
#include "sim.hpp"
12+
Sim rxSim;
13+
#endif
14+
1015
#ifdef PIN_PPM
1116
#include "ppm.h"
1217
PPM rxPpm;
@@ -17,19 +22,49 @@ PPM rxPpm;
1722
Analog rxAnalog;
1823
#endif
1924

20-
// uncomment to activate simultor on channel 3
21-
// #define SIM_INTERVAL_MS 20 // 20ms => 50Hz
25+
#ifdef MODE_RX
26+
#include "EspNowRcLink/Receiver.h"
27+
EspNowRcLink::Receiver rxEspNow;
28+
#endif
2229

23-
Sim rxSim;
24-
Tx txData;
30+
#ifdef MODE_TX
31+
#include "EspNowRcLink/Transmitter.h"
2532
EspNowRcLink::Transmitter txEspNow;
33+
#endif
34+
35+
#ifdef MODE_GAMEPAD
36+
#include <Joystick_ESP32S2.h>
37+
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK, 3, 0,
38+
true , true , true, // axis x,y,z
39+
false, false, false, // rotation x,y,z
40+
true , true, // throttle, rudder
41+
false, false, false // accel, brake, steering
42+
);
43+
44+
#define INPUT_OFFSET -1500
45+
#define INPUT_RANGE_MIN -512
46+
#define INPUT_RANGE_MAX 512
47+
#define AXIS_RANGE_MIN -512
48+
#define AXIS_RANGE_MAX 512
49+
#define BUTTON_THRESHOLD 1650
50+
51+
int16_t gamepadScale(int16_t val)
52+
{
53+
return constrain(val + INPUT_OFFSET, INPUT_RANGE_MIN, INPUT_RANGE_MAX);
54+
}
55+
#endif
56+
57+
Tx txData;
2658

2759
void setup()
2860
{
2961
#ifdef PRINT_INFO
3062
Serial.begin(115200);
3163
#endif
3264

65+
#ifdef MODE_SIM
66+
rxSim.begin();
67+
#else
3368
#ifdef PIN_PPM
3469
rxPpm.begin(PIN_PPM, FALLING);
3570
#endif
@@ -42,9 +77,26 @@ void setup()
4277
rxAnalog.attach(4, Analog::MODE_DIGITAL, PIN_SW0);
4378
rxAnalog.attach(5, Analog::MODE_DIGITAL, PIN_SW1);
4479
rxAnalog.attach(6, Analog::MODE_DIGITAL, PIN_SW2);
80+
rxAnalog.attach(7, Analog::MODE_DIGITAL, PIN_SW3);
4581
#endif
4682

83+
#ifdef MODE_RX
84+
rxEspNow.begin(true);
85+
#endif
86+
#endif
87+
88+
#ifdef MODE_TX
4789
txEspNow.begin(true);
90+
#endif
91+
92+
#ifdef MODE_GAMEPAD
93+
Joystick.setXAxisRange(AXIS_RANGE_MIN, AXIS_RANGE_MAX);
94+
Joystick.setYAxisRange(AXIS_RANGE_MIN, AXIS_RANGE_MAX);
95+
Joystick.setZAxisRange(AXIS_RANGE_MIN, AXIS_RANGE_MAX);
96+
Joystick.setThrottleRange(AXIS_RANGE_MIN, AXIS_RANGE_MAX);
97+
Joystick.setRudderRange(AXIS_RANGE_MIN, AXIS_RANGE_MAX);
98+
Joystick.begin(false);
99+
#endif
48100
}
49101

50102
template<typename Dst, typename Src>
@@ -59,25 +111,24 @@ void update(Dst& dst, const Src& src)
59111
void loop()
60112
{
61113
uint32_t now = micros();
62-
uint32_t rxDelta = 0;
63114

64-
// decode inputs
115+
// receive inputs
65116

66-
#ifdef SIM_INTERVAL_MS
117+
#ifdef MODE_SIM
67118
static uint32_t simNext = 0;
68-
if(now >= simNext)
119+
if(now > simNext)
69120
{
70-
txData.setChannel(2, 1000 + rxSim.get(2));
71-
txData.setAvailable();
121+
rxSim.update();
122+
update(txData, rxSim);
123+
txData.setAvailable(now);
72124
simNext = now + SIM_INTERVAL_MS * 1000;
73125
}
74126
#else
75-
76127
#ifdef PIN_PPM
77128
if(rxPpm.available())
78129
{
79130
update(txData, rxPpm);
80-
txData.setAvailable();
131+
txData.setAvailable(now);
81132
}
82133
#endif
83134

@@ -87,40 +138,65 @@ void loop()
87138
{
88139
rxAnalog.update();
89140
update(txData, rxAnalog);
90-
txData.setAvailable();
141+
txData.setAvailable(now);
91142
analogNext = now + 20000;
92143
}
93144
#endif
94145

146+
#ifdef MODE_RX
147+
rxEspNow.update();
148+
if(rxEspNow.available())
149+
{
150+
for(size_t channel = 0; channel < 8; ++channel)
151+
{
152+
txData.setChannel(channel, rxEspNow.getChannel(channel));
153+
}
154+
txData.setAvailable(now);
155+
}
156+
#endif
95157
#endif
96158

97159
// transmit outputs
98160

161+
#ifdef MODE_TX
162+
99163
static uint32_t sendTimeout = 0;
100164
static uint32_t sendAfter = 0;
101-
static uint32_t sendLast = 0;
102165
if((now > sendAfter && txData.getAvailable()) || now > sendTimeout)
103166
{
104-
for(size_t c = 0; c < 8; c++)
167+
for(size_t channel = 0; channel < 8; channel++)
105168
{
106-
txEspNow.setChannel(c, txData.getChannel(c));
169+
txEspNow.setChannel(channel, txData.getChannel(channel));
107170
}
108171
sendTimeout = now + 50000ul;
109172
sendAfter = now + 10000ul;
110-
rxDelta = now - sendLast;
111-
sendLast = now;
112-
113173
txEspNow.commit();
114174
}
115175
txEspNow.update();
176+
#endif
116177

117-
// print debug info
178+
#ifdef MODE_GAMEPAD
179+
if(txData.getAvailable())
180+
{
181+
Joystick.setXAxis(gamepadScale(txData.getChannel(0)));
182+
Joystick.setYAxis(gamepadScale(txData.getChannel(1)));
183+
Joystick.setThrottle(gamepadScale(txData.getChannel(2)));
184+
Joystick.setRudder(gamepadScale(txData.getChannel(3)));
185+
Joystick.setZAxis(gamepadScale(txData.getChannel(4)));
186+
// channel 6, 7, 8 as buttons
187+
for(size_t i = 0; i < 3; i++)
188+
{
189+
Joystick.setButton(i, txData.getChannel(i + 5) >= BUTTON_THRESHOLD);
190+
}
191+
Joystick.sendState();
192+
}
193+
#endif
118194

119195
#ifdef PRINT_INFO
196+
// print debug info
120197
static uint32_t printNext = 0;
121198
if(now > printNext)
122199
{
123-
//Serial.printf("V: %d, P: %d, D: %d, C: %d\n", v, sim_val, delta / 100, WiFi.channel());
124200
Serial.printf("%d,%d,%d,%d,%d\n",
125201
txData.getChannel(0), txData.getChannel(1), txData.getChannel(2), txData.getChannel(3), txData.getChannel(4)
126202
);

0 commit comments

Comments
 (0)