Driving a 6-colour e-paper display is not like driving a monochrome panel. Seeed Studio’s reTerminal E1002 carries a 7.3-inch ACeP with 800×480 resolution, and a XIAO ESP32-S3 runs underneath it. Mariusz Jurgielewicz has put together a set of Arduino examples tested on exactly this combination, so newcomers don’t have to reinvent pinout, polarity and refresh sequences.
The practical value of the collection lies in the details the official drivers don’t tell you. The GDEP073E01 panel uses the ED2208 controller and is wired to the carrier through an internal FPC. So the pins are not the ones you’d expect from a breakout module: SCK is on GPIO 7, MOSI on GPIO 9, CS on GPIO 10, DC on GPIO 11, RST on GPIO 12 and BUSY on GPIO 13. Logging is also duplicated across two serials, Serial1 on GPIO 43 and GPIO 44 through the USB-UART bridge, plus the XIAO ESP32-S3’s native USB CDC Serial.
BUSY active-low and SPI clock at 2 MHz
Trap number one is the BUSY polarity. On the ED2208 the signal is active-low: 0 means refresh in progress, 1 means ready. Inverting it locks up the driver or corrupts subsequent writes, and the symptom isn’t a clear error but a panel that stays half-drawn.
The second trap is the clock. The SPI bus runs reliably at 2 MHz, and this also applies to the upload speed set in the Arduino IDE, fixed at 115200. The log serial runs at 115200 baud. Higher frequencies on the internal flex risk clock distortion, with pixel dropouts or corrupted command bytes. Finally there’s the watchdog: during a cold refresh the 40-second timeout can fire, so the sequence has to be handled accordingly.
SCK on GPIO 7, MOSI on GPIO 9, CS on GPIO 10
DC on GPIO 11, RST on GPIO 12, BUSY on GPIO 13
BUSY active-low: 0 refresh in progress, 1 ready
Reliable SPI clock at 2 MHz
Serial1 on GPIO 43 (TX) and GPIO 44 (RX), plus native USB CDC
192,000 bytes of frame buffer in OPI PSRAM
A full frame buffer of 800×480 pixels at 4 bits per pixel, two pixels per byte, requires 192,000 bytes. It doesn’t fit in the ESP32-S3’s internal RAM, so it has to be buffered in OPI PSRAM. The panel exposes 6 native solid colour fields: black, white, red, green, blue and yellow. So each pixel is not a grey value but a colour index, and dithering has to be planned accordingly.
On the software side the collection covers three driver stacks. The first is Jean-Marc Zingg’s GxEPD2, the upstream one you get from the Library Manager. The second is the Good Display vendor driver. The third is Waveshare’s GUI_Paint graphics framework, sitting on top of Adafruit_GFX. Watch out for one detail: the Seeed_GxEPD2 fork should not be installed, because it conflicts with the upstream GxEPD2.
Besides the display, the examples cover the carrier board’s onboard peripherals. There’s the PCF8563 real time clock and the SHT4x environmental sensor, so a complete project can show the time plus temperature and humidity data without adding external modules. Anyone who wants to rebuild everything from scratch will find Mariusz Jurgielewicz’s repository with the sketches ready to upload.
To work on it you need the Arduino IDE with XIAO ESP32-S3 support, the GxEPD2 library from the Library Manager, and the panel connected to the carrier.
The 0.96-inch 128×64 OLED display is a compact module widely used in electronics projects. It uses the SSD1306 driver and communicates over I2C, so it connects to Arduino, ESP8266 and ESP32 with just a few wires. It shows text, sensor data, symbols and graphics. AdriRobot tested it with an Arduino UNO and with an ESP32-C3 SuperMini.
128×64 OLED display: technology and colours
OLED stands for Organic Light Emitting Diode. Each pixel emits its own light, so contrast is high and no backlight is needed. Power consumption is lower than that of a backlit LCD, and readability stays good both in the dark and in bright light. The module comes with white, blue or yellow pixels, or in a two-colour version with a yellow top strip and the rest in blue.
supply from 3.3 to 5 V, 0.06 W consumption in normal display mode;
viewing angle greater than 160°;
operating temperature from -30 to +70 °C;
glass screen, lifetime of at least 16,000 hours;
module dimensions: 29.28 × 27.1 mm.
Pins, I2C address and power supply
The connector has four pins: VCC (3.3-5 V), GND, SCL and SDA. The reset circuit is on board, so no extra pin is needed. On the Arduino UNO the I2C pins are A5 for SCL and A4 for SDA, on the Mega they are 21 and 20.
Watch out for the two power pins, because on some modules their order is reversed. Displays marked JMDO.96C.1 let you choose: two pads on the PCB, shorted with 0 Ω SMD resistors or with a blob of solder, swap the two pins. Before connecting, it is therefore worth checking the silkscreen.
On some modules VCC and GND are swapped: read the silkscreen (photo: AdriRobot)
The I2C address is 0x3C, the same as other SSD1306 displays, and it cannot be changed. If other peripherals with that address are on the bus, another solution is needed.
Test with Arduino UNO
For the test, the display is mounted on a small breadboard and connected to an Arduino UNO. First you read the address with the i2c_scanner sketch (File, Examples, Wire): if nothing shows up, try swapping the SDA and SCL wires. Then install the Adafruit SSD1306 library from the Library Manager, accepting the Adafruit GFX dependency as well with Install all.
The test sketch then fills the screen, draws a pixel in each corner and writes a few lines of text. On the two-colour model, in fact, the first line comes out yellow because it sits in the top strip.
The test sketch running on the 128×64 OLED display (photo: AdriRobot)
Test with ESP32-C3 SuperMini
Connecting the display to the ESP32-C3 SuperMini (diagram: AdriRobot)
With the ESP32-C3 SuperMini the display uses 3.3 V, GND, GPIO9 as SCL and GPIO8 as SDA. In the IDE you select ESP32C3 Dev Module and enable USB CDC On Boot and Erase All Flash Before Sketch Upload, as in the other tests. Finally the sketch initialises I2C on pins 8 and 9, starts the display at address 0x3C and writes a few lines of text.
AdriRobot also used it on a board with an ESP8266 12F, to show temperature and humidity from a DHT11, and on a shield with a DFPlayer Mini, to print messages. The white-pixel model is available as a 0.96-inch I2C OLED display.
Source: AdriRobot’s original article includes the circuit diagram, the downloadable sketches and the test video.
Let’s find out how to use the MAX7219 to drive an LED matrix. Wiring, Arduino libraries and sketches will guide us through building custom graphic and numeric displays.
An LED matrix display is one of the most fascinating components for anyone starting to experiment with Arduino: with a small square module we can bring to life numbers, letters, symbols and animations that immediately catch the eye. The problem? An 8×8 matrix means no fewer than 64 LEDs to control individually: an almost impossible task without dedicated support. That is where the MAX7219 chip comes in, an IC designed specifically to simplify the management of matrix and 7-segment displays, reducing the connection to the Arduino board to just a few pins. In this article we will see how to connect the MAX7219 to an 8×8 matrix, how to use the ready-made modules available on the market and how to program everything with the LedControl library.
The MAX7219
Fig. 1 Pinout of the chip and of the display.
The MAX7219 chip has 24 pins. The 8×8 display (Fig. 1) is connected so that the rows are linked to the DIG pins and the columns to the SEG pins of the MAX7219.
Brightness is varied in software after setting the maximum current with an external resistor connected to the Iset pin. Three pins are dedicated to communication with the control board: DIN (to transfer data from the board to the chip), CS (for device selection) and CLK (for the data clock). A further pin, DOUT, is used to connect the DIN of the next chip, in case you want to chain several LED matrices together (for example to build scrolling text).
The complete schematic of the connection between the chip and the display is shown in Fig. 2, with particular emphasis on the links to the Arduino board and to a second chip. Using the MAX7219 is made even simpler by the availability on the market of modules (such as those in Fig. 3) that integrate both the chip and the LED matrix, along with the relevant wiring.
Fig. 2 Schematic of the connection between the chip and the display.
Fig. 3 Schematic of the connection between modules and the Arduino board.
Using a module reduces the wiring to just the connections between the module and the Arduino board, and between modules possibly arranged in a chain. Each module has 5 input pins (VCC, GND, DIN, CS/LOAD and CLK, to be connected to a board such as the Arduino UNO R3) and 5 output pins (VCC, GND, DOUT, CS and CLK, for any subsequent modules in the chain). The Arduino UNO R3 board can be replaced by the more recent Arduino UNO R4 versions, available in the Minima and WIFI models, both fully compatible electrically and in software with the previous R3. Both versions keep the same pin layout and are compatible with most shields and libraries already developed for the R3.
Programming with Arduino
Several libraries make programming the MAX7219 easier; among them, in particular, the LedControl library, which is very widespread and simple to use.
An object of the LedControl class is created, to which an identifying name is assigned (for example, LC). The DIN, CLK and CS parameters will be replaced with the numbers of the Arduino pins (for example: 2, 4, 3) to which the respective signals are connected.
LC.SHUT (module_number, 0/1)
Enables or disables the chip. The value 0 makes it operational, while 1 puts it in standby. On power-up, the chip is in standby mode by default. The module_number parameter identifies the module in a serial chain, numbered starting from 0.
lc.setIntensity (module_number, intensity)
Adjusts the brightness of the LEDs, with a value between 0 (minimum) and 15 (maximum). The value 0 does not turn the LEDs completely off; to do that, you need to use LC.Shutdown(module_number, 1).
lc.clearDisplay (module_number)
Turns off all the LEDs of the specified module, clearing the displayed content.
Turns a single LED on or off. row_number and column_number indicate the position of the LED (numbered from 0 to 7). state = true (or 1) turns the LED on, false (or 0) turns it off. Rows are numbered from 0 (top) to 7 (bottom), columns from 0 (left) to 7 (right).
For example, the top-left LED occupies position (0, 0), the bottom-right one (7, 7).
lc.setRow (module_number, row_number, byte)
Lets you turn all the LEDs of a row on or off, specifying their state with a binary byte. For example, to turn on the first four LEDs of a row you use: B11110000.
lc.setColumn (module_number, column_number, byte)
Works in a similar way to setRow, but acts on a column. The byte defines which LEDs to turn on or off in the specified column.
Let’s now look at some practical examples of use.
Example 1
The first sketch, shown in Listing 1, is meant to display the 8 rows in sequence, one at a time, starting from the top; then the 8 columns, one at a time, starting from the left; then the 8 rows starting from the bottom; then the 8 columns starting from the right. Finally, all the LEDs are turned on gradually in pairs of rows, starting from the two middle rows and following the order: 4-5, 3-6, 2-7, 1-8. In this last phase, the lighting happens at low intensity, with brightness varying progressively from 10 to 2.
The first sketch lights up rows and columns of the matrix in sequence.
Example 2
The purpose of this sketch (Listing 2) is to gradually light up the LEDs of the matrix rows starting from the bottom, as a consequence of a voltage varying between 0 V and 5 V set by a potentiometer connected to pin A5; the comments inside the sketch describe how the gradual lighting works.
The second sketch lights the rows gradually as the potentiometer voltage changes.
Using arrays
The goals of the two previous examples can be achieved in a similar way using arrays. One approach is to define the row structure inside an array of bytes (for example in binary): with 8 elements of 8 bits you describe the LED states of the whole display. The first cell of the array corresponds to the state of the eight LEDs of row 0 (from left to right), the second to that of row 1, and so on up to row 7.
If, for example, you want to turn off all the LEDs of the first four rows and turn on those of the last four, you can use the following array:
The purpose of this sketch (Listing 3) is to display in sequence all the numbers between 0 and 9 using 10 arrays that define the numbers and 10 for loops that call them up.
The third sketch displays the digits 0 to 9 in sequence.
Example 4
The fourth sketch shows temperature and humidity thresholds on the matrix.
Fig. 4 Display of the temperature and humidity thresholds.
The purpose of this sketch (Listing 4) is to show when certain temperature and humidity thresholds (set in the program) are exceeded, as shown in Fig. 4.
In the left half of the display (columns 0-1-2) the temperature data is shown, while in the right half (columns 5-6-7) the humidity data is shown.
In the upper part of the display (rows 0-1-2) the letters T and U appear; in the lower part (rows 4-5-6-7) the lighting of the LEDs indicates that a given temperature or humidity threshold has been reached.
Four thresholds are defined in the code: as the value increases, the corresponding rows light up progressively, starting from row 7. Temperature and humidity are measured with the HTS221 sensor, integrated into the STMicroelectronics IKS01A3 expansion board (Fig. 5), mounted on the Arduino UNO board. Those who do not have this board can use other sensors, such as the DHT11 or DHT22, adapting the data acquisition part of the software accordingly.
Fig. 5 The IKS01A3 expansion board.
Conclusion
The MAX7219 makes LED matrix management accessible to everyone, turning a complex task into a fun, stimulating and creative experience. Once you understand the basic commands, the possibilities become practically endless: custom scrolling text, small animations, graphic indicators, simple light games and real-time data visualisations. All that is left is to experiment, adapt the sketches provided and let yourself be inspired: with a simple LED matrix your Arduino project can finally “speak with light” in a clear, dynamic and original way.
Building a motorized welding turntable solves a common problem: welding around circular or cylindrical objects without walking around the workpiece. Greenhill Forge’s project creates a large motorized lazy Susan with adjustable speed and a modest budget. The table rotates the piece under the torch, so the welder stays still and both hands are free to guide the arc.
The heart of the system is a stepper motor mounted under the table surface. Rotation passes through a gear reducer and a standard spider coupling, which transmits motion to the top plate. The reducer increases torque and lowers speed, so the table moves smoothly even with heavy parts. Everything is controlled by an Arduino UNO Rev3 board, which drives the motor and reads user commands.
Speed control and user interface
The user adjusts rotation speed with a rotary encoder. The knob is comfortable to use even with welding gloves. A small OLED screen shows the set speed, so control is immediate and precise. The firmware on the Arduino UNO reads the encoder, updates the display, and drives the stepper motor with the correct pulse frequency.
For those who want to replicate the project, choosing components is straightforward. A Uno R3 with ATmega328 is the same board used in the original project. A NEMA 17 stepper motor rated at 1.2 A has the right torque for a table of this size, which rotates through a reducer anyway. A 12 mm rotary encoder with knob connects directly to digital pins and can be turned even with welding gloves. Finally, a 128×64 OLED display shows parameters clearly.
Stepper motor with gear reducer for torque
Spider coupling to connect shaft and table
Lazy Susan bearing for rotating support
Rotary encoder for adjustment
OLED display for visual feedback
Grounding through the shaft
An important detail is grounding management. In welding, current must return to the generator through the workpiece. If the turntable is not grounded, current passes through the lazy Susan bearings, causing arcs that damage them quickly. Greenhill Forge solves the problem with a ground strap that runs through the motor shaft.
The strap maintains conductivity between the table surface and the workpiece. This way, welding current has a dedicated path and the bearings stay protected. The strap is a wear item, but with normal use it should last a long time. Also, replacement cost is minimal, so maintenance stays economical.
The project is documented in a Greenhill Forge video, which follows the entire process: cutting and welding the frame, mounting the motor under the table, and grounding. At the end, the table is shown in action during a real weld, with speed adjusted on the fly.
Why build a turntable
This project appeals to both beginners and experienced welders. Construction is simple and requires few tools. Moreover, electronic control with Arduino UNO opens the door to future modifications, such as programmed rotation or foot pedal control. The modest cost makes the project accessible to many makers.
The welding turntable is an example of how a stepper motor, an encoder, and an OLED display can turn a simple support into a professional tool. Well-designed grounding protects components and ensures quality welds. Finally, adjustable speed lets you adapt rotation to any type of work.