Skip to content

Commit 06a12fe

Browse files
committed
update Changelog and Readme. I2S related to #338
1 parent 83bad6c commit 06a12fe

2 files changed

Lines changed: 115 additions & 38 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ pre-1.0.0:
66
- esp32: new platformio project in extras/Esp32StepperDemo for esp32 stepper configuration
77
- esp32-idf5: implement I2S-module in DIRECT mode to drive one stepper up to 200 kHz (1-3 modules depending on esp32 variant)
88
- esp32-idf5: use I2S-module in MUX mode (16bit/stereo) to drive up to 32 steppers (or less if direction/enable on mux) (#338)
9-
ATTENTION: WORK IN PROGRESS - DIR/ENABLE not yet functional. using Esp32StepperDemo manual dir/enable setting is possible
109

1110
0.34.0:
1211
- Major internal refactoring: reorganize code into subdirectories

README.md

Lines changed: 115 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,23 @@ The stepper motors should be connected via a driver IC (like A4988) with a 1, 2
3434
- avr atmega32u4: only Pin 9, 10 and 11.
3535
- avr atmega2560: only Pin 6, 7 and 8.
3636
On platformio, this can be changed to other triples: 11/12/13 Timer 1, 5/2/3 Timer 3 or 46/45/44 Timer 5 with `FAS_TIMER_MODULE` setting.
37-
- esp32: This can be any output capable port pin.
37+
- esp32: This can be any output capable port pin, or use I2S for additional steppers:
38+
* I2S Mux mode: up to 32 additional steppers via external demultiplexer (IDF ≥5.3)
39+
* I2S Direct mode: 1-3 additional steppers using I2S controllers directly (IDF ≥5.3)
3840
- pico: Any GPIO up to 31
3941
- atmel sam due: This can be one of each group of pins: 34/67/74/35, 17/36/72/37/42, 40/64/69/41, 9, 8/44, 7/45, 6
4042
- Step should be done on transition Low to High. High time will be only a few us.
4143
On esp32 the high time is for slow speed fixed to ~2ms and high speed to 50% duty cycle.
4244
For pico direction delay is recommended
4345
* Direction Signal (optional)
4446
- This can be any output capable port pin.
47+
- esp32: Can also use I2S Mux slots for direction control (IDF ≥5.3)
4548
- pico: Any GPIO up to 31
4649
- Position counting up on direction pin high or low, as per optional parameter to setDirectionPin(). Default is high.
4750
- With external callback on esp32 derivates, even shift register outputs can be used
4851
* Enable Signal (optional)
4952
- This can be any output capable port pin.
53+
- esp32: Can also use I2S Mux slots for enable control (IDF ≥5.3)
5054
- Stepper will be enabled on pin high or low, as per optional parameter to setEnablePin(). Default is low.
5155
- With external callback, even shift register outputs can be used
5256

@@ -142,49 +146,104 @@ Comments to pin sharing:
142146
* Steppers' command queue depth: 16
143147
* This device has four 16 bit timers, so extension up to 12 steppers should be possible (not implemented)
144148

145-
### ESP32
149+
### ESP32 Variants Overview
150+
151+
| Variant | IDF 4.x Driver | IDF 4.x Max | IDF 5.3+ Driver | IDF 5.3+ Max (RMT+I2S) | I2S Ctrl | I2S Mux | I2S Direct |
152+
|-------------|--------------------|-------------|------------------|------------------------|----------|---------|------------|
153+
| ESP32 | MCPWM/PCNT + RMT | 14 (6+8) | RMT + I2S | 8 + 32 | 2 | 32 pins | 2 ch |
154+
| ESP32-S2 | RMT | 4 | RMT + I2S | 4 + 32 | 2 | 32 pins | 2 ch |
155+
| ESP32-S3 | MCPWM/PCNT + RMT | 8 | RMT + I2S | 4 + 32 | 2 | 32 pins | 2 ch |
156+
| ESP32-C3 | RMT | 2 | RMT + I2S | 2 + 32 | 1 | 32 pins | 1 ch |
157+
| ESP32-C6 | - | - | RMT + I2S | 4 + 32 | 1 | 32 pins | 1 ch |
158+
| ESP32-P4 | - | - | RMT + I2S | 4 + 32 | 3 | 32 pins | 3 ch |
159+
160+
**Notes:**
161+
- IDF 5.3+ Max = RMT channels + I2S Mux slots (can be combined)
162+
- I2S Mux requires ESP-IDF ≥5.3 and uses one I2S controller
163+
- I2S Mux slots are shared: if step/dir/enable all use I2S Mux, each stepper consumes 1-3 slots
164+
- Step only: up to 32 steppers
165+
- Step + Dir: up to 16 steppers
166+
- Step + Dir + Enable: up to 10 steppers
167+
- I2S Direct channels = number of I2S controllers (experimental)
168+
- C6 and P4 require IDF ≥5.3 (no IDF 4.x support)
146169

147170
#### ESP-IDF version 4.x.y:
148171
* allows up to 200000 generated steps per second
149172
* supports up to 14 stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
150173
* Steppers' command queue depth: 32
151174

152175
#### ESP-IDF version >=5.3.0:
153-
* allows up to 200000 generated steps per second
154-
* supports up to 8 stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
176+
* allows up to 200000 generated steps per second for RMT. 40kHz for I2S-MUX.
177+
* supports up to 8+32 stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
155178
* Steppers' command queue depth: 32
156179

157-
### ESP32S2
180+
#### ESP32 I2S Mux Driver (ESP-IDF >=5.3.0 only)
158181

159-
* reported to work
160-
* allows up to 200000 generated steps per second ?
161-
* supports up to four stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
162-
* Steppers' command queue depth: 32
182+
The I2S Mux driver provides an alternative approach for driving multiple stepper motors using the ESP32's I2S peripheral. This is especially useful when you need more steppers than RMT channels provide.
163183

164-
### ESP32S3
184+
**Overview:**
185+
The I2S transmitter outputs a 32-bit data word at 250kHz. Each bit corresponds to one output slot (0-31). These signals can be used in two ways:
165186

166-
#### ESP-IDF version 4.x.y:
167-
* allows up to 200000 generated steps per second ?
168-
* supports up to eight stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
169-
* Steppers' command queue depth: 32
187+
1. **With external demultiplexer**: Connect a decoder IC (e.g., 74HC154, 74HC138 cascade, or shift registers like 74HC595) to the I2S data pin to decode the 32-bit stream into individual output pins for step, direction, and enable signals.
170188

171-
#### ESP-IDF version >=5.3.0:
172-
* allows up to 200000 generated steps per second ?
173-
* supports up to four stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
174-
* Steppers' command queue depth: 32
189+
2. **Direct connection**: Use individual I2S output slots directly as stepper driver inputs. Each slot provides one output signal that toggles at the I2S frame rate.
175190

176-
### ESP32C3
191+
**Key Features:**
192+
* Up to 32 output pins from a single I2S transmitter
193+
* I2S runs at 250kHz sample rate (4µs frame time)
194+
* Step, direction, and enable pins can all use I2S outputs
195+
* Suitable for applications requiring many coordinated steppers
177196

178-
* allows up to 200000 generated steps per second ?
179-
* supports up to two stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
180-
* Steppers' command queue depth: 32
197+
**Limitations:**
198+
* Requires ESP-IDF 5.3 or later (I2S driver API changed significantly)
199+
* Minimum speed for I2S Mux is 25µs period (40kHz max step rate)
200+
* Minimum speed for I2S Direct is 5µs period (200kHz max step rate)
201+
* Step pulse width is 2.5us for I2S Direct and 4us for I2S MUX
202+
* I2S Direct: stepper speed adjustable in 1/8us deltas.
203+
* I2S MUX: stepper speed adjustable in 4us deltas e.g. speed 50us will be 52/48/52/48...
181204

182-
### ESP32C6
205+
**I2S Direct vs I2S Mux:**
206+
* **I2S Mux**: Single I2S transmitter drives up to 32 pins. All pins share the same timing.
207+
* **I2S Direct**: Each stepper gets its own I2S channel. Higher precision timing.
208+
209+
**Initialization:**
210+
```cpp
211+
// Initialize I2S Mux with data, bclk, and word select pins
212+
// Not needed, if I2S direct mode is used
213+
engine.initI2sMux(data_pin, bclk_pin, ws_pin);
214+
215+
// Connect stepper to I2S mux slot (0-31)
216+
// PIN_I2S_FLAG automatically selects I2S Mux mode
217+
stepper = engine.stepperConnectToPin(slot | PIN_I2S_FLAG);
218+
219+
// Direction and enable can also use I2S mux slots
220+
stepper->setDirectionPin(dir_slot | PIN_I2S_FLAG, dirHighCountsUp);
221+
stepper->setEnablePin(enable_slot | PIN_I2S_FLAG, activeLow);
222+
```
223+
224+
**Pin Allocation:**
225+
The I2S mux uses slot numbers 0-31, which are output on the I2S data line. These can be used in two ways:
226+
* **With external demultiplexer**: Connect a decoder (e.g., 74HC154, 74HC138 cascade) to the I2S data pin to decode the 32-bit frame into 32 individual output pins for step/direction/enable signals
227+
* **Direct connection**: Use the I2S data pin directly as a step signal
228+
229+
**Testing and Demo Application:**
230+
A comprehensive platformio test application with web interface is available in `extras/Esp32StepperDemo/`.
231+
This demonstrates:
232+
* Configuration of multiple steppers via Web UI
233+
* Real-time position and status monitoring via WebSocket
234+
* Each I2S slot can be toggled individually
235+
* I2S mux pin management
236+
* serial console 115200 asks at startup for Wifi credentials.
237+
* Sequence automation (not tested)
238+
239+
To build and test:
240+
```bash
241+
cd extras/Esp32StepperDemo
242+
pio run -t upload && pio device monitor
243+
```
244+
245+
This test application was AI crafted....
183246

184-
* only from esp-idf >=v5.3.0
185-
* allows up to 200000 generated steps per second ?
186-
* supports up to four stepper motors using Step/Direction/Enable Control (Direction and Enable is optional)
187-
* Steppers' command queue depth: 32
188247

189248
### Raspberry pi pico/pico 2
190249

@@ -316,19 +375,37 @@ For the other stepper motors, the rmt module comes into use.
316375

317376
#### ESP-IDF version >=5.3.0:
318377

319-
Only rmt module is supported.
378+
RMT and I2S Mux/Direct drivers are supported. MCPWM/PCNT is not available in ESP-IDF 5.3+.
379+
380+
#### I2S Mux Driver Implementation
381+
382+
The I2S Mux driver uses the ESP32's I2S transmitter in 16-bit stereo mode at 250kHz sample rate. Each I2S frame (32 bits = 16-bit left + 16-bit right channel) represents one time slot, with each bit corresponding to one output pin.
383+
384+
**Technical Details:**
385+
* Sample rate: 250kHz, giving 4µs per frame (64 ticks at 16MHz reference)
386+
* 32 output slots per frame, each slot is one bit
387+
* Bits are transmitted MSB-first within each byte
388+
* DMA buffers are filled in the I2S TX-done callback
389+
* Direction and enable pins are stored in a 32-bit state word, written to each frame's data
390+
391+
**Timing Considerations:**
392+
* Minimum step period: 25µs for I2S Mux, 5µs for I2S Direct
393+
* Direction/enable changes have up to 4µs latency
394+
* All steppers sharing I2S mux are inherently synchronized (same DMA buffer)
320395

321396
#### Both ESP-IDF versions
322397
A note to `MIN_CMD_TICKS` using mcpwm/pcnt: The current implementation uses one interrupt per command in the command queue. This is much less interrupt rate than for avr. Nevertheless at 200kSteps/s the switch from one command to the next one should be ideally serviced before the next step. This means within 5us. As this cannot be guaranteed, the driver remedies an overrun (at least by design) to deduct the overrun pulses from the next command. The overrun pulses will then be run at the former command's tick rate. For real life stepper application, this should be ok. To be considered for raw access: Do not run many steps at high rate e.g. 200kSteps/s followed by a pause.
323398

324-
What are the differences between mcpwm/pcnt and rmt ?
399+
What are the differences between mcpwm/pcnt, rmt, and i2s mux?
325400

326-
| | mcpwm/pcnt | rmt |
327-
|:---------------------------|:----------------------------------------|:------------------------------------------------------------------------------|
328-
|Interrupt rate/stepper | one interrupt per command | min: one interrupt per command, max: one interrupt per 31 steps at high speed |
329-
|Required interrupt response | at high speed: time between two steps | at high speed: time between 31 steps |
330-
|Module usage | 1 or 2 mcpcms, up to 6 channels of pcnt | rmt |
331-
|esp32 notes | availabe pcnt modules can be connected | no pcnt module used, so can be attached to rmt output as realtime position |
401+
| | mcpwm/pcnt | rmt | i2s mux |
402+
|:---------------------------|:----------------------------------------|:------------------------------------------------------------------------------|:--------------------------------|
403+
|Interrupt rate/stepper | one interrupt per command | min: one interrupt per command, max: one interrupt per 31 steps at high speed | one interrupt per 500µs (all) |
404+
|Required interrupt response | at high speed: time between two steps | at high speed: time between 31 steps | 500µs for all steppers combined |
405+
|Module usage | 1 or 2 mcpcms, up to 6 channels of pcnt | rmt | 1 i2s |
406+
|Max steppers | 6 + 8 rmt | 8 (ESP32), 4 (ESP32S3) | 32 (I2S slots) + rmt |
407+
|esp32 notes | available pcnt modules can be connected | no pcnt module used, so can be attached to rmt output as realtime position | synchronized outputs |
408+
|Min step period | ~5µs | ~5µs | ~25µs |
332409

333410
If the interrupt load is not an issue, then rmt is the better choice. With rmt the below (multi-axis application) mentioned loss of synchonicity at high speeds can be avoided. The rmt driver is - besides some rmt modules perks - less complex and way more straightforward.
334411

@@ -338,7 +415,7 @@ One specific note for the rmt: If a direction pin toggle is needed directly afte
338415

339416
### ESP32S2
340417

341-
This stepper driver uses rmt module.
418+
This stepper driver uses rmt module only.
342419

343420
### ESP32S3
344421

@@ -347,7 +424,8 @@ The ESP32S3's rmt module is similar to esp32c3 with 4 instead of 2 channels and
347424
#### ESP-IDF version 4.x.y:
348425
This stepper driver uses mcpwm/pcnt + rmt modules. Can drive up to 8 motors. Tested with 6 motors (not by me).
349426
#### ESP-IDF version >=5.3.0:
350-
This stepper driver uses rmt modules. Can drive up to 4 motors.
427+
This stepper driver uses rmt modules. Can drive up to 4 motors.
428+
I2S Mux driver is also available with same capabilities as ESP32 (see ESP32 I2S Mux section above).
351429

352430
### ESP32C3
353431

0 commit comments

Comments
 (0)