FaceBot 2.0 — Using 2.42" OLEDs over I2C with MicroPython

Our new generation of STEM teaching robots with big displays are easier to connect and more powerful.

Dan McCreary
CodeX

--

2.42" OLED display is driven by a 4-wire I2C interface with one extra wire for RESET. Photo by the author.

In January 2019, our local CoderDojo club published our first low-cost ($40) robots that drew faces on bright OLED displays. However, those robots were hard to set up and program. This blog will show you how our next generation of Python-powered FaceBot works using just a single Grove connector with one extra reset wire.

Background of the FaceBot 1.0

Our students love robots! They are fantastic at getting students to have fun while they accidentally learn computational thinking. Although hundreds of types of robots are on the market, few are powerful enough and low-cost enough to drive a full 128X64 OLED display. Their older Arduino processors are limited by 2K of RAM, and they can’t keep up with the demands of graphics programming.

Although we did get FaceBot 1.0 working, it had several challenges:

  1. Limited RAM — The Arduino Nano had only a measly 2K of RAM, which means the graphics frame buffer took up most of the RAM.
  2. Limited CPU power — Our old Arduinos had just a single-core CPU running at a plodding 16 Mhz.
  3. Old C Programming — Students were required to learn the historically important but now unpopular C language.
  4. Slow Compile/Link/Test Cycles — C program had to be compiled and downloaded each time the students wanted to test their code. This works OK for small programs, but as our programs get larger the development cycles slow down.
  5. Small OLEDs Were Too Hard to Read — The small .96" low-cost ($4) OLEDs were too small to read without getting close up. Display readability is a problem when your robots are on the floor, and you are standing up.
  6. Bigger OLEDs Were Too Hard To Connect — The lovely 2.42" OLEDs that cost around $18 needed seven wires to hook up using SPI connections. These took up a lot of I/O pins on our microcontrollers.

We learned that our students loved these robots and liked drawing faces on the robots despite these drawbacks. We often intentionally gave them very dull faces and challenged them to draw the faces in new creative ways.

Here is a sample of simple robot face images from a 2021 research paper:

Sample face structures for nine emotions. The image is taken from the paper Emotive Response to a Hybrid-Face Robot and Translation to Consumer Social Robots. Our “happy” robots tend to drive forward without collisions. Robots about to collide with a wall might register a “surprise” face.

Goals for FaceBot 2.0

With these limitations in mind, we wanted to design our next-generation kid-friendly low-cost FaceBot to have the following characteristics:

  1. It must be 100% programmed in Python (technical MicroPython for microcontrollers). This is the popular programming language our kids love.
  2. It should limit the amount of soldering and connections.
  3. It should have enough RAM to support a frame buffer for a 128X64 monochrome display.
  4. It should support the lovely OLED displays and minimize the number of wires.

Raspberry Pi Pico and the Cytron Maker Pi RP2040

This photo is Cytron Maker Pi RP2040 with seven Grove connectors without a display. This robot is the foundation of our FaceBot. Our challenge was connecting the SPI displays took up three complete connectors and caused unused connections.

In January of 2021, we were presently surprised that the Raspberry Pi Foundation announced their RP2040 processor and the Pico board. Not only did it have plenty of RAM (264K), but it could be programmed directly in Python. These processors were also much faster (133 MHz than the old 16 MHz Arduino Nano), giving them plenty of power to do complex drawings on the faces. The dual-core also offered the possibility of dedicating an entire core to keep the display up-to-day without interrupting sensor readings. It was a great fit for our FaceBot 2.0.

A few months later, Cytron launched a RP2040-based robot controller board with motor drivers and power management directly on a board that cost only $9.99. I reviewed this board back in August of 2021. It is fantastic to see such a fully-integrated and feature-rich board for under $10. Anyone spending more than $10 on robot controllers needs to look at this board!

Connecting SPI to the Cytron Boards Grove Connectors

We did connect OLEDs to this board, but there was one big problem—the default connectors for our board from DIYMORE.CC required seven wires! One for GND, one for VCC, and five data wires. That caused us to use three of our Grove connectors to be used up. This was inefficient and limited the number of free connectors we had left in our robots. We were frustrated! So close but yet so far from realizing the vision of our FaceBot 2.0!

Failed Ventures into I2C Conversion

The back of the OLED displays had instructions for converting the boards from the default SPI to using the simpler 4-wire I2C interface. But despite my hours of struggling I could NOT get the SPI interfaces to work with our Raspberry Pi Pico or the Cytron Maker Pi RP2040 boards. I would follow the instructions exactly but every time I did this the basic i2c-scanner would come up empty. I tried tying the CS, DC, and RES signals to various positions — but no luck. I didn’t know if my hardware was bad, my wires were not connected correctly or the I2C Python driver was just not compatible with the board. When I hooked up a logic analyzer to the lines I could see both data and clock signals were going into the display, but I could not get anything to display.

A Little Help from A Friend

Then at the beginning of March, I expressed my frustration to a friend who I will just call WP. WP also had a brother that has some good debugging chops. They ordered similar parts and one day I got an email telling me they finally got it to work! Although they couldn't just use the standard 4-wire Grove connector like our other smaller OLED displays, they could get it to work by adding one extra RESET wire to the display.

The Solution: I2C + 1

The problem with the way we were using the device was that we were not resetting the display driver when the display powered up. This is because most other I2C devices only need four wires: GND, VCC, Data, and Clock. When the devices are powered on they are “smart” in that they reset themselves to a known start just a few milliseconds after power-up. The DIYMORE OLED device requires us to always pull the reset pin high just after power-up and just before the display is used. The MicroPython code to do this is shown below.

Sample MicroPython code to startup the OLED display. Lines 6–9 are used to reset the display before it wakes up to receive the I2C data stream. Image by the author.

Although we could use up another Grove connector to do this reset, there is one other option available to us. That is to just wire the RESET pin to the Servo jumper in the corner of the Maker Pi RP2040 board. A simple female-to-female jumper is all we need! As long as your robot is not using all four servo motors we are good to go!

Details on how to move the resistors on the rear of the board

The one challenge about this project is that moving the jumpers on the rear of the DIYMORE board requires a soldering iron, fine motor skills, and a steady hand. Here is a summary of the changes that we need to make:

The three changes we made to the DIYMORE OLED display to convert it from SPI to I2C. This image was taken from the video provided by retrofriends on YouTube.

There is a video of these steps here provided by the user retrofriends on YouTube:

Video showing how to change the jumper settings to convert an OLED from the SPI factory settings to use the I2C interface. Thanks to the YouTube channel retrofriends for providing the instructions.

We have now finally realized our vision of a low-cost and easy-to hookup interface for our FaceBot 2.0.

Closing with Gratitude for Friends

Looking back on this project, I realized that I might have theoretically figured this out myself if I had been more patient and spent the time reading the datasheets for the SSD1309 chip. But perhaps I never would have figured it out! What this taught me is that having a good group of friends in your network with the right skills and experiences to complement your own skills will get you a lot further along in reaching your goals than trying to do everything yourself.

I just want to express my heartfelt thanks and gratitude to both WP and his brother for helping our little CoderDojo club out. I hope everyone else teaching kids how to code can benefit from this work.

More to Explore

You can find more about our Beginning Python, MicroPython, and our new generation of low-cost Robots at the CoderDojoTC microsites. Keep an eye out for our future FaceBot 2.0 lessons by following me on LinkedIn or my Medium blog.

--

--

Dan McCreary
CodeX
Writer for

Distinguished Engineer that loves knowledge graphs, AI, and Systems Thinking. Fan of STEM, microcontrollers, robotics, PKGs, and the AI Racing League.