Guide ESP32 C3 OLED - amir1387aht/MicroCS GitHub Wiki
ESP32-C3 + OLED with U8g2
From an empty folder to text and graphics on a small I²C OLED, with the display driver and the fonts chosen before the build. Written for an ESP32-C3 with 4 MB flash; every other ESP32 works the same way (change the target in step 2 and the pins in step 5).
U8g2 is optional and not in the release firmware, so this is your own ESP-IDF build. If you have never built MicroCS for an ESP32, skim ESP32 from zero first.
1. What you need
- ESP-IDF 5.x (Espressif's installer or the VS Code ESP-IDF extension), Python 3, git.
- Your OLED's controller and size, and the two GPIOs it is wired to:
| OLED | U8g2 display name |
|---|---|
| 0.96" 128Ć64 (the most common one) | ssd1306_i2c_128x64_noname |
| 1.3" 128Ć64 | sh1106_i2c_128x64_noname |
| 0.91" 128Ć32 | ssd1306_i2c_128x32_univision |
| ESP32-C3 "SuperMini" / "0.42 inch OLED" boards (72Ć40, built in) | ssd1306_i2c_72x40_er ā usually SDA = GPIO5, SCL = GPIO6 |
Wiring: OLED VCC ā 3V3, GND ā GND, SDA / SCL ā two free GPIOs. On the C3, GPIO 4/5
or 5/6 are good choices; avoid GPIO 2, 8 and 9 (strapping pins) and 11ā17 (flash).
2. Create the project
git clone https://github.com/amir1387aht/MicroCS
cp -r MicroCS/ports/esp32/example my_oled && cd my_oled
git clone https://github.com/amir1387aht/MicroCS components/MicroCS
idf.py set-target esp32c3
The example already fits a 4 MB flash: 2 MB for the program (Wi-Fi and TLS included) and ~1.9 MB for your scripts and font files.
3. Get the u8g2 sources (pick one)
- Easiest: let the build download u8g2 2.37.1 once ā
CONFIG_MICROCS_U8G2_DOWNLOAD=yin step 4. - Offline:
python3 components/MicroCS/tools/u8g2.py fetch(found automatically afterwards). - Your own copy:
CONFIG_MICROCS_U8G2_DIR="/full/path/to/u8g2"in step 4.
If none of them is there, the build stops and prints these three options.
4. Turn U8g2 on, choose the display and the fonts
Append to sdkconfig.defaults:
CONFIG_MICROCS_U8G2=y
CONFIG_MICROCS_U8G2_DOWNLOAD=y
CONFIG_MICROCS_U8G2_DISPLAYS="ssd1306_i2c_128x64_noname sh1106_i2c_128x64_noname"
CONFIG_MICROCS_U8G2_FONTS="6x10_tf helvB10_tr logisoso24_tn open_iconic_embedded_1x_t"
CONFIG_MICROCS_U8X8_FONTS="chroma48medium8_r"
- Displays: only the listed ones are compiled in (1ā3 KB of flash each). Without the line you get SSD1306 128Ć64 / 128Ć32 and SH1106 128Ć64.
- Fonts: built into the flash; the first one is the default. Without the line you get six small fonts (~7 KB).
- Names and sizes:
python3 components/MicroCS/tools/u8g2.py displays ssd1306,python3 components/MicroCS/tools/u8g2.py fonts helv. - Delete an existing
sdkconfigāsdkconfig.defaultsis read only when there is none. (The same settings are inidf.py menuconfigā Component config ā MicroCS ā U8g2 displays.)
5. Give I²C its pins
In main/main.c, one line after MCS_ESP32_CFG_DEFAULT:
mcs_esp32_cfg_t pins = MCS_ESP32_CFG_DEFAULT;
pins.i2c[0] = (mcs_esp32_i2c_pins_t){ 5, 6 }; // SDA, SCL - your GPIOs
mcs_esp32_hal_init(&hal, &pins);
Since MicroCS 1.12 you can also skip this step and choose the pins from C#, before the first
I²C call: I2C.Open(0, new I2cConfig(400_000, 5, 6)); (SDA, SCL ā see
peripheral settings).
6. Build and flash
idf.py build flash monitor
Press Enter for the > prompt and check that the display driver is there:
> Console.WriteLine(string.Join(",", U8g2.Displays));
ssd1306_i2c_128x64_noname,sh1106_i2c_128x64_noname
> Console.WriteLine(string.Join(",", I2C.Scan(0)));
60
60 = 0x3C, the OLED. (Ctrl-] leaves the monitor.)
7. The first program
main.cs:
var oled = new U8g2("ssd1306_i2c_128x64_noname"); // I2C bus 0, address 0x3C
oled.Begin();
int n = 0;
while (true) {
oled.ClearBuffer();
oled.SetFont("helvB10_tr");
oled.DrawStr(0, 14, "Hello ESP32-C3");
oled.SetFont("logisoso24_tn");
oled.DrawStr(0, 56, n.ToString());
oled.DrawFrame(0, 0, 128, 64);
oled.SendBuffer();
n++;
Thread.Sleep(500);
}
Upload it as /main.cs (runs at every boot):
python3 components/MicroCS/tools/mcs_remote.py --port /dev/ttyACM0 put main.cs /main.cs + run /main.cs
(--port COM5 on Windows.) Or MicroCS Studio in
Chrome/Edge: Connect ā paste ā Save & Run.
8. More fonts without rebuilding
All 2000+ u8g2 fonts work from files. Extract the ones you want on the PC:
python3 components/MicroCS/tools/u8g2.py extract profont12_tr unifont_t_symbols -o fonts
copy them into /fonts on the board:
python3 components/MicroCS/tools/mcs_remote.py --port /dev/ttyACM0 mkdir /fonts + \
put fonts/u8g2_font_profont12_tr.bin /fonts/u8g2_font_profont12_tr.bin
and use them like a built-in font: oled.SetFont("profont12_tr"); ā the built-in copy if
there is one, otherwise the file is loaded.
9. Next steps
- Text only, almost no RAM:
var t = new U8x8("ssd1306_i2c_128x64_noname"); t.Begin(); t.DrawString(0, 0, "Hi"); - Less RAM for U8g2: add
_1to the name ("ssd1306_i2c_128x64_noname_1") and draw inoled.Draw(() => { ... });(page mode). - Buttons and menus:
oled.Begin(selectPin, nextPin, prevPin)+UserInterfaceSelectionList(...)(examples/u8g2/menu.cs). - Sensor values on the screen:
examples/u8g2/sensor_log.cs. - Ready-made scripts: MicroCS Studio ā Templates ā U8g2 displays (20 examples: shapes, fonts, bitmaps, menus, dashboard, clock, U8x8 ...).
- Try it on the PC first:
make fetch-u8g2 mcs-u8g2 && ./build/mcs_u8g2 --oled main.cs. - The whole API: U8G2.md.
Troubleshooting
| Symptom | Fix |
|---|---|
| black screen, no error | address 0x3D: U8g2.I2C("ssd1306_i2c_128x64_noname", 0, 0x3D); SDA/SCL swapped; no 3V3 |
| picture shifted by 2 pixels / noise on the right | it is an SH1106: use sh1106_i2c_128x64_noname |
I2C.Scan(0) is empty |
wiring, or the wrong GPIOs in step 5 |
I2C.Scan: not supported (or I2C.Write: ā¦) |
step 5 missing ā the bus has no pins (or open it with new I2cConfig(400_000, sda, scl)) |
U8g2 does not exist |
U8g2 is not in the firmware: step 4 (and delete sdkconfig), rebuild |
| build stops: "u8g2 sources not found" | step 3 |
display 'ā¦' is not compiled in |
add it to CONFIG_MICROCS_U8G2_DISPLAYS, rebuild |