Thursday, March 31, 2022

Raspberry Pi Pico/MicroPython generate QR Code and display on SSD1306 I2C OLED

Run on Raspberry Pi Pico/MicroPython, to generate QR Code, and display on SSD1306 128x64 I2C OLED.


I2C(0) is used to connect to SSD1306 I2C, scl=9 and sda=8.

For SSD1306 driver, visit https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py to download ssd1306.py, save to Raspberry Pi Pico driver.

For QR Code, JASchilz/uQR is used. Download uQR.py and save to Raspberry Pi Pico driver.


mpyPico_i2c.py, simple verify I2C(0) pins and connection to SSD1306 I2C OLED.
import uos
import usys

print("====================================================")
print(usys.implementation[0],
      str(usys.implementation[1][0]) + "." +
      str(usys.implementation[1][1]) + "." +
      str(usys.implementation[1][2]))
print(uos.uname()[3])
print("run on", uos.uname()[4])
print("====================================================")

i2c0 = machine.I2C(0)
print(i2c0)
print("Available i2c devices: "+ str(i2c0.scan()))

print("~ bye ~")

mpyPico_ssd1306.py, simple test program for SSD1306 I2C OLED.
"""
Run on Raspbery Pi Pico/MicroPython
display on ssd1306 I2C OLED

connec ssd1306 using I2C(0)
scl=9
sda=8

- Libs needed:

ssd1306 library
https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py
"""
import uos 
import usys
from ssd1306 import SSD1306_I2C

print("====================================================")
print(usys.implementation[0],
      str(usys.implementation[1][0]) + "." +
      str(usys.implementation[1][1]) + "." +
      str(usys.implementation[1][2]))
print(uos.uname()[3])
print("run on", uos.uname()[4])
print("====================================================")

i2c0 = machine.I2C(0)
print(i2c0)
print("Available i2c devices: "+ str(i2c0.scan()))

WIDTH = 128
HEIGHT = 64

oled = SSD1306_I2C(WIDTH, HEIGHT, i2c0)
oled.fill(0)

oled.text(usys.implementation[0], 0, 0)

strVersion = str(usys.implementation[1][0]) + "." + \
             str(usys.implementation[1][1]) + "." + \
             str(usys.implementation[1][2])
oled.text(strVersion, 0, 10)
oled.text(uos.uname()[3], 0, 20)
oled.text(uos.uname()[4], 0, 40)
oled.show()

mpyPico_ssd1306_uQR.py, generate QR Code using uQR.py, and display on SSD1306 I2C OLED.
"""
Run on Raspbery Pi Pico/MicroPython
to generate QR code using uQR,
and display on ssd1306 I2C OLED

- Libs needed:

ssd1306 library
https://github.com/micropython/micropython/blob/master/drivers/
display/ssd1306.py

JASchilz/uQR:
https://github.com/JASchilz/uQR

remark:
in the original example on uQR to display on ssd1306, scale of 2 is used.
It's found:
- If the data is too long, the small 128x64 OLED cannot display the whole matrix.
- In my test using my phone, scale of 1 is more easy to recognize.
Such that I use scale of 1 inside the loop to generate  qr code.
"""
from uos import uname
from usys import implementation
from machine import I2C
from time import sleep
from ssd1306 import SSD1306_I2C
from uQR import QRCode

print("====================================================")
print(implementation[0],
      str(implementation[1][0]) + "." +
      str(implementation[1][1]) + "." +
      str(implementation[1][2]))
print(uname()[3])
print("run on", uname()[4])
print("====================================================")

i2c0 = I2C(0)
print(i2c0)
print("Available i2c devices: "+ str(i2c0.scan()))

WIDTH = 128
HEIGHT = 64

oled = SSD1306_I2C(WIDTH, HEIGHT, i2c0)
oled.fill(0)

oled.text("RPi Pico", 0, 0)
oled.text("MicroPython", 0, 10)
oled.text("OLED(ssd1306)", 0, 20)
oled.text("uQR exercise", 0, 40)
oled.show()

sleep(5)
qr = QRCode()

qr.add_data("uQR example")
matrix = qr.get_matrix()
print("version:", qr.version)
print("len of matrix", len(matrix))

oled.fill(1)
for y in range(len(matrix)*2):                   # Scaling the bitmap by 2
    for x in range(len(matrix[0])*2):            # because my screen is tiny.
        value = not matrix[int(y/2)][int(x/2)]   # Inverting the values because
        oled.pixel(x, y, value)                  # black is `True` in the matrix.
oled.show()

while True:
    userinput = input("\nEnter something: ")
    if userinput == "":
        break
    print(userinput)
    qr.clear()
    qr.add_data(userinput)
    matrix = qr.get_matrix()
    print("version:", qr.version)
    print("len of matrix", len(matrix))
    
    oled.fill(1)
    scale = 1
    for y in range(len(matrix)*scale): 
        for x in range(len(matrix[0])*scale): 
            value = not matrix[int(y/scale)][int(x/scale)]
            oled.pixel(x, y, value)
    oled.show()
    
print("~ bye ~")

mpyPico_simpletest_uQR.py, generate QR Code and display on REPL.
"""
Run on Raspbery Pi Pico/MicroPython
to generate QR code using uQR,
and display on screen

- Libs needed:

JASchilz/uQR:
https://github.com/JASchilz/uQR

"""
from uos import uname
from usys import implementation
from usys import stdout

from uQR import QRCode

print("====================================================")
print(implementation[0],
      str(implementation[1][0]) + "." +
      str(implementation[1][1]) + "." +
      str(implementation[1][2]))
print(uname()[3])
print("run on", uname()[4])
print("====================================================")

# For drawing filled rectangles to the console:
stdout = stdout
WHITE = "\x1b[1;47m  \x1b[40m"
BLACK = "  "
NORMAL = '\033[1;37;0m'

def print_QR(uqr):

    qr_matrix = uqr.get_matrix()
    
    print("version:", uqr.version)
    qr_height = len(qr_matrix)
    qr_width = len(qr_matrix[0])
    print("qr_height:  ", qr_height)
    print("qr_width:   ", qr_width)

    for _ in range(4):
        for _ in range(qr_width + 8): #margin on top
            stdout.write(WHITE)
        print()
    for y in range(qr_height):
        stdout.write(WHITE * 4)       #margin on right
        for x in range(len(matrix[0])):
            value = qr_matrix[int(y)][int(x)]
            if value == True:
                stdout.write(BLACK)
            else:
                stdout.write(WHITE)
        stdout.write(WHITE * 4)        #margin on left
        print()
    for _ in range(4):
        for _ in range(qr_width + 8):  #margin on bottom
            stdout.write(WHITE)
        print()
    print(NORMAL)
        
qr = QRCode()

qr.add_data("uQR example")
matrix = qr.get_matrix()

print_QR(qr)

while True:
    userinput = input("\nEnter something: ")
    if userinput == "":
        break
    print(userinput)
    qr.clear()
    qr.add_data(userinput)
    matrix = qr.get_matrix()
    
    print_QR(qr)


print("~ bye ~")
More exercise for Raspberry Pi Pico

Tuesday, March 15, 2022

Raspberry Pi Pico online simulator

Wokwi is an online Electronics simulator. You can use it to simulate Arduino, ESP32, and many other popular boards, parts and sensors.

Here is a Raspberry Pi Pico (SDK) online simulator.