Uno R4 · Wire and Qwiic OLEDs
Two independent official Wire controllers draw complementary patterns. The upper OLED uses the shield SDA/SCL pins; the lower OLED uses all four physical Qwiic contacts, including its switched 3.3 V rail.

What's on the bench
- 2× OLED 128×64
- Arduino Uno R4
- Battery
How it's wired
- Battery · pos→Arduino Uno R4 · 5v
- Battery · neg→Arduino Uno R4 · gnd
- Arduino Uno R4 · gnd2→OLED 128×64 · gnd
- Arduino Uno R4 · 5v→OLED 128×64 · vcc
- Arduino Uno R4 · sda→OLED 128×64 · sda
- Arduino Uno R4 · scl→OLED 128×64 · scl
- Arduino Uno R4 · qwiic-gnd→OLED 128×64 · gnd
- Arduino Uno R4 · qwiic-3v3→OLED 128×64 · vcc
- Arduino Uno R4 · qwiic-sda→OLED 128×64 · sda
- Arduino Uno R4 · qwiic-scl→OLED 128×64 · scl
The code
This Arduino C++ sketch lives in the Code tab; sign in and press Compile & upload to build real firmware for the emulated board.
// First-party P5-C acceptance: official Wire/Wire1 drive distinct OLED pixels. #include <Wire.h> #include <FspTimer.h> static FspTimer overlapTimer; static volatile bool qwiicDone = false; static volatile uint8_t qwiicStatus = 9; static uint8_t pattern(TwoWire &bus, bool inverted) { static const uint8_t init[] = { 0xae, 0xd5, 0x80, 0xa8, 0x3f, 0xd3, 0x00, 0x40, 0x8d, 0x14, 0x20, 0x02, 0xa1, 0xc8, 0xda, 0x12, 0x81, 0x7f, 0xd9, 0xf1, 0xdb, 0x40, 0xa4, 0xa6, 0x2e, 0xaf }; bus.beginTransmission(0x3c); bus.write(0x00); bus.write(init, sizeof(init)); uint8_t status = bus.endTransmission(); if (status) return status; for (uint8_t page = 0; page < 8; ++page) { bus.beginTransmission(0x3c); bus.write(0x00); bus.write(0xb0 | page); bus.write(0x00); bus.write(0x10); status = bus.endTransmission(); if (status) return status; bus.beginTransmission(0x3c); bus.write(0x40); for (uint8_t x = 0; x < 128; ++x) { uint8_t value = ((x / 8 + page) & 1) ? 0xaa : 0x55; bus.write(inverted ? (uint8_t)~value : value); } status = bus.endTransmission(); if (status) return status; } return status; } static void drawQwiic(timer_callback_args_t *) { overlapTimer.stop(); qwiicStatus = pattern(Wire1, true); qwiicDone = true; } void setup() { Serial.begin(115200); Wire.begin(); Wire1.begin(); Wire.setClock(400000); Wire1.setClock(400000); uint8_t timerType = GPT_TIMER; int8_t channel = FspTimer::get_available_timer(timerType); // A lower-priority GPT callback starts Wire1 while Wire is transmitting. // Both official IIC ISR sets can preempt it and continue independently. if (channel < 0 || timerType != GPT_TIMER || !overlapTimer.begin(TIMER_MODE_PERIODIC, timerType, channel, (uint32_t)48000, (uint32_t)0, TIMER_SOURCE_DIV_1, drawQwiic) || !overlapTimer.setup_overflow_irq(15) || !overlapTimer.open() || !overlapTimer.start()) { Serial.println("timer-error"); return; } uint8_t wireStatus = pattern(Wire, false); while (!qwiicDone) {} Serial.print("wire-pattern "); Serial.println(wireStatus); Serial.print("qwiic-pattern "); Serial.println(qwiicStatus); // Two PCF8574s may share this address; their solved input bits combine. Wire.beginTransmission(0x20); Wire.write(0xff); Wire.endTransmission(false); uint8_t count = Wire.requestFrom((uint8_t)0x20, (uint8_t)3, (uint8_t)true); Serial.print("and-read "); Serial.print(count); while (Wire.available()) { Serial.print(' '); Serial.print(Wire.read()); } Serial.println(); for (uint8_t address = 8; address < 0x78; ++address) { Wire.beginTransmission(address); Wire.write(0); if (!Wire.endTransmission()) { Serial.print("found "); Serial.println(address); } } Serial.println("scan-done"); } void loop() {}
Firmware licence
Notice: this firmware uses the LGPL-licensed Arduino core library
arduino-unor4wifi-i2c-oled.bin is statically linked with ArduinoCore-renesas 1.6.0, in Breadboard's port of its UNO R4 WiFi variant to Renesas FSP 5.3.0. Parts of that core are licensed under the GNU Lesser General Public License, version 2.1 or (at your option) any later version ("the Library"). Breadboard distributes this firmware under terms that permit you to modify the work for your own use and to reverse engineer it for debugging such modifications.
- Relink package: arduino-unor4wifi-i2c-oled-relink.zip (352 KB)
- Corresponding source: ArduinoCore-renesas-1.6.0-fsp53-source.zip (3.7 MB)
- Licence texts and relink instructions



