Mini oled screen with raspberry-pi

Hardware

For this i’m using an PI3 B+ and 128×32 Monochrome OLED from adafruit.

OS

First install debian from https://www.raspberrypi.com/software/ . It’s the quickest way to get an functional raspberry pi with ssh and network.

Install dependencies

tom@unicorn:~ $ sudo apt install python3 python3-pip python3-pil i2c-tools -y

And install this python package for the whole system

tom@unicorn:~/demo $ sudo pip install adafruit-circuitpython-ssd1306

Enable I2C

tom@unicorn:~ $ sudo raspi-config
# GO to 
 3 Interface Options    Configure connections to peripherals 
# and then 
 I5 I2C           Enable/disable automatic loading of I2C kernel module 
#you should get
 │ The ARM I2C interface is enabled                         │

You need run a cold start of our raspberry pi

Just shutdown and power up with the cable again:

tom@unicorn:~ $ sudo shutdown -h now

Test your access with:

tom@unicorn:~ $ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
tom@unicorn:~ $

The 3c is the address of the oled screen

Run our first test

Adafruit has make an awesome python script to display in real time SE statistics

Download source from Git hub and run it:

tom@unicorn:~/demo $ ./pistats.py

And enjoy!

For more detail: You may read this :

Let’s make a clock

Well first requirement, is to set our raspberry pi to correct time. You can enable NTP, with

sudo timedatectl set-ntp true

And check your settings with:

tom@unicorn:~/clock $ timedatectl timesync-status
       Server: 2001:bc8:255e:200::1 (2.debian.pool.ntp.org)
Poll interval: 34min 8s (min: 32s; max 34min 8s)
         Leap: normal
      Version: 4
      Stratum: 2
    Reference: A18F188D
    Precision: 1us (-22)
Root distance: 46.988ms (max: 5s)
       Offset: -270us
        Delay: 26.407ms
       Jitter: 3.546ms
 Packet count: 14
    Frequency: +3.556ppm

Here a small script (largely inspired by the adafruit’s one) to print both UTC and local timezone

#!/usr/bin/env python3
# Tomswritegarden.com
# Simple 2 clock 
import time
from time import gmtime, strftime
from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306


class Oled:
    def __init__(self) -> None:
        # Create the I2C interface.
        self.i2c = busio.I2C(SCL, SDA)

        # Create the SSD1306 OLED class.
        # The first two parameters are the pixel self.width and pixel self.height.  Change these
        # to the right size for your display!
        self.disp = adafruit_ssd1306.SSD1306_I2C(128, 32, self.i2c)

        # Create blank image for drawing.
        # Make sure to create image with mode '1' for 1-bit color.
        self.width = self.disp.width
        self.height = self.disp.height
        self.image = Image.new("1", (self.width, self.height))

        # Get drawing object to draw on image.
        self.draw = ImageDraw.Draw(self.image)
        # Load default font.
        self.font = ImageFont.load_default()
        mono = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf"
        self.font = ImageFont.truetype(mono, 15)
        self.hard_clear()

    def hard_clear(self):
        # Clear display.
        self.disp.fill(0)
        self.disp.show()
        # Draw a black filled box to clear the image.
        self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)

    def clear(self):
        # Draw a black filled box to clear the image.
        self.draw.rectangle((0, 0, self.width, self.height), outline=0, fill=0)

    def display_date(self):
        utc_time = strftime("%H:%M:%S UTC", gmtime())
        local_time = strftime("%X %z")
        #msg = strftime("%a, %d %b %Y %H:%M:%S UTC", gmtime())
        self.clear()
        self.draw.text((0, -2), utc_time, font=self.font, fill=255)
        self.draw.text((0, 17), local_time, font=self.font, fill=255)
        # Display image.
        self.disp.image(self.image)
        self.disp.show()

def main():
    oled = Oled()
    oled.clear()
    while True:
        oled.display_date()
        time.sleep(0.01)


if __name__ == "__main__":
    main()

And voila !