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 :
- Adafruit ssd1306 doc on https://docs.circuitpython.org/projects/ssd1306/en/latest/
- Pillow doc on https://pillow.readthedocs.io/en/stable/
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 !