Download free music MP3s on genuine quality, the world’s largest online music catalogue, powered by your scrobbles. Free listening, videos, photos, The world’s largest online music catalogue, powered by your scrobbles. Free listening, videos, photos, stats, charts, biographies and concerts. stats, charts, biographies and concerts.
Sunday, July 20, 2025
Arduino with Multiple Displays – Part 2
As I mentioned in my last post on Arduino with Multiple Displays I'm going to look at other microcontrollers too. This post takes a wander through my Waveshare Zero and similar format boards that each support one of the RP2040, ESP32-C3 or ESP32-S…
As I mentioned in my last post on Arduino with Multiple Displays I'm going to look at other microcontrollers too. This post takes a wander through my Waveshare Zero and similar format boards that each support one of the RP2040, ESP32-C3 or ESP32-S3.
Warning! I strongly recommend using old or second hand equipment for your experiments. I am not responsible for any damage to expensive instruments!
These are the key Arduino tutorials for the main concepts used in this project:
If you are new to microcontrollers, see the Getting Started pages.
Parts list
A Waveshare Zero format board or similar
2x 0.96" ST7735 60x180 SPI TFT displays.
Breadboard and jumper wires.
Once again I'm using displays that look like this - note the order of the pins.
The Circuit
All circuits are a variation on the above, requiring the following ideal connections:
Display
Function
RP2040
ESP32-C3
ESP32-S3
BLK
Backlight control (not required)
N/C
N/C
N/C
CS
Chip select One per display.
5 or any SPI0 CS
10
10
DC
Data/Command
8
8
8
RES
Reset
14
9
9
SDA
Data (MOSI)
3 or any SPI0 MOSI
6 or 7
11
SCL
Clock (SCLK)
2 or any SPI0 SCLK
4 or 6
12
VCC
Power
3V3
3V3
3V3
GND
Ground
GND
GND
GND
For the explanations of the pin choices, and what it means for the code, see the following sections.
ESP32-S3 Zero
In the Arduino IDE, using board ESP32-> Waveshare ESP32-S3-Zero.
There are several SPI buses on the ESP32-S3, but they have fixed uses as follows (see the ESP32-S3 Technical Reference Manual Chapter 30 "SPI Controller"):
SPI 0: Reserved for internal use.
SPI 1: Reserved for internal use.
SPI 2: General purpose use - often called FSPI in the documentation.
SPI 3: General purpose use - often called SPI or SPI3.
Sometimes the two SPI buses are called VSPI and HSPI but I think that is really terminology from the original ESP32 rather than the ESP32-S3.
// Mapping based on the ESP32S3 data sheet - alternate for SPI2 static const uint8_t SS = 34; // FSPICS0 static const uint8_t MOSI = 35; // FSPID static const uint8_t MISO = 37; // FSPIQ static const uint8_t SCK = 36; // FSPICLK
By default the Adafruit libraries will use the boards default SPI interface, as defined in the variants.h file - i.e. the above.
When it comes to assigning SPI devices to GPIO there are a few considerations (see the "ESP32-S3 Technical Reference Manual, Chapter 6 "IO MUX and GPIO Matrix"):
In general, any GPIO can be mapped onto any SPI function. However...
Some GPIO have special "strapping" functions so are best avoided.
Some GPIOs have a default SPI function that bypasses the GPIO MUX routing, so allows for better performance (see section 6.6 "Direct Input and Output via IO MUX").
From my reading of the reference manual I believe the following are default "non-MUX" SPI connections:
In the previous table, where SPI3 is mentioned, then the entry for "Direct IO via IO MUX" is set to "no", so I'm guessing that isn't available.
But now we can see why the Arduino core is using GPIO 34-37, but we can also see that GPIO 10-13 would be an alternative (fast) option too.
The problem is that not all of GPIO 34-37 are broken out on a Waveshare ESP32-S3 Zero, so I need to use the alternative pinouts. Aside: this makes no sense to me that these are the defaults in the Waveshare ESP32-S3 Zero's "variant.h" file, but anyway...
In the Arduino IDE, using board ESP32-> ESP32C3 Dev Module.
Again there are several SPI buses on the ESP32-C3, with the same fixed uses as follows (see the ESP32-C3 Technical Reference Manual Chapter 30 "SPI Controller"):
SPI 0: Reserved for internal use.
SPI 1: Reserved for internal use.
SPI 2: General purpose use - sometimes called GP-SPI in the documentation.
The ESP32-C3 also has a very similar SPI arrangement to the ESP32-S3, in that whilst any pin can be configured for SPI usage, there are certain hard-wired optional arrangements that bypass the GPIO routing matrix.
The faster (direct to IO MUX) pins are as follows (more here):
From the Technical Reference manual, we can see that the default Arduino definitions above, do not support the non-routed, direct-to-IO MUX pin mappings, which from the table below do indeed map onto GPIO 2, 6, 7, 10.
In terms of using a Waveshare ESP32-C3 Zero, both combinations would be supported on the broken out GPIO, so from a software point of view, the Adafruit libraries could be used "as is" with the default mapping, or with a custom SPI definition (as shown above) with the more bespoke, but faster, mapping.
The RP2040 has two SPI peripherals and the SPI functions are mapped onto specific sets of GPIO pins. This gives a range of flexibility, but not arbitrary flexibility. The board definition file for the Waveshare RP2040 Zero provides this as a default:
Note that the SPI1 pins for the Waveshare RP2040 Zero are not all on the standard header connections, some are on the additional pin headers across the bottom.
Using a bespoke configuration is possible using a series of calls to set the SPI pins as shown below.
To use pins for SPI1, replace SPI above with SPI1. As long as this happens prior to the call to the Adafruit libraries, everything works fine.
A Common Option
It would be nice to find a set of physical pin connections that I know would always work regardless of the board in use: RP2040, ESP32-S3 or ESP32-C3.
With careful noting of the RP2040 limitations, I think that is largely possible with the following. Even though the GPIO numbers are different, the physical pins are common on all three boards.
Display
Function
WS Pin
RP2040
ESP32-C3
ESP32-S3
BLK
Backlight control (not required)
N/C
N/C
N/C
CS1
Chip select Display 1
H2 P6
GP5
GP9
GP10
DC
Data/Command
H2 P5
GP4
GP10
GP11
RES
Reset
H2 P9
GP8
GP6
GP7
SDA
Data (MOSI)
H2 P8
GP7
GP7
GP8
SCL
Clock (SCLK)
H2 P7
GP6
GP8
GP9
VCC
Power
H1 P3
3V3
3V3
3V3
GND
Ground
H1 P2
GND
GND
GND
CS2
CS Display 2
H1 P9
GP14
GP5
GP6
CS3
CS Display 3
H1 P8
GP15
GP4
GP5
CS4
CS Display 4
H1 P7
GP26
GP3
GP4
A couple of notes:
I've avoided pins 1-4 on header 2, as the ESP32-C3 can't use them for SPI and they support either the UART or USB.
I've had to include a MISO (SPI RX) pin in each configuration too, so I've just picked something that can be ignored. For RP2040 that has to be one of GP0, GP4 or GP16 however, which could clash with either the UART, the above configuration for DC pin, or the onboard WS2812 LED, but there isn't much that can be done.
I've allowed three consecutive pins on the first header for optional additional CS pins for displays 2 to 4.
Here is the full set of configurable code for the above:
No comments:
Post a Comment