Skip to content

Commit 2a6cfbb

Browse files
committed
Initial Release
0 parents  commit 2a6cfbb

34 files changed

+998
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# MicroPython Examples
2+
3+
Examples to accompany the "Pico Python SDK" book.

adc/temperature.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import machine
2+
import utime
3+
4+
sensor_temp = machine.ADC(4)
5+
conversion_factor = 3.3 / (65535)
6+
7+
while True:
8+
reading = sensor_temp.read_u16() * conversion_factor
9+
10+
temperature = 27 - (reading - 0.706)/0.001721
11+
print(temperature)
12+
utime.sleep(2)

blink/blink.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from machine import Pin, Timer
2+
3+
led = Pin(25, Pin.OUT)
4+
tim = Timer()
5+
def tick(timer):
6+
global led
7+
led.toggle()
8+
9+
tim.init(freq=2.5, mode=Timer.PERIODIC, callback=tick)

i2c/1106oled/README.adoc

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
= Using a SH1106-based OLED graphics display
2+
:xrefstyle: short
3+
4+
Display an image and text on I2C driven SH1106-based OLED graphics display
5+
such as the Pimoroni Breakout Garden 1.12" Mono OLED https://shop.pimoroni.com/products/1-12-oled-breakout?variant=29421050757203
6+
.
7+
8+
== Wiring information
9+
10+
See <<oled-wiring-diagram>> for wiring instructions.
11+
12+
[[oled-wiring-diagram]]
13+
[pdfwidth=75%]
14+
.Wiring the OLED to Pico using I2C
15+
image::pico-and-oled.png[]
16+
17+
== List of Files
18+
19+
A list of files with descriptions of their function;
20+
21+
i2c_1106oled_using_defaults.py:: The example code.
22+
i2c_1106oled_with_freq.py:: The example code, explicitly sets a frequency.
23+
sh1106.py:: SH1106 Driver Obtained from https://github.com/robert-hh/SH1106
24+
25+
== Bill of Materials
26+
27+
.A list of materials required for the example
28+
[[oled-bom-table]]
29+
[cols=3]
30+
|===
31+
| *Item* | *Quantity* | Details
32+
| Breadboard | 1 | generic part
33+
| Raspberry Pi Pico | 1 | http://raspberrypi.org/
34+
| Monochrome 128x128 I2C OLED Display | 1 | https://shop.pimoroni.com/products/1-12-oled-breakout?variant=29421050757203
35+
|===
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Display Image & text on I2C driven SH1106 OLED display
2+
from machine import I2C, ADC
3+
from sh1106 import SH1106_I2C
4+
import framebuf
5+
6+
7+
WIDTH = 128 # oled display width
8+
HEIGHT = 128 # oled display height
9+
10+
i2c = I2C(0) # Init I2C using I2C0 defaults, SCL=Pin(GP9), SDA=Pin(GP8), freq=400000
11+
print("I2C Address : "+hex(i2c.scan()[0]).upper()) # Display device address
12+
print("I2C Configuration: "+str(i2c)) # Display I2C config
13+
14+
15+
oled = SH1106_I2C(WIDTH, HEIGHT, i2c) # Init oled display
16+
17+
# Raspberry Pi logo as 32x32 bytearray
18+
buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
19+
20+
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
21+
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
22+
23+
# Clear the oled display in case it has junk on it.
24+
oled.fill(0)
25+
26+
# Blit the image from the framebuffer to the oled display
27+
oled.blit(fb, 96, 0)
28+
29+
# Add some text
30+
oled.text("Raspberry Pi",5,5)
31+
oled.text("Pico",5,15)
32+
33+
# Finally update the oled display so the image & text is displayed
34+
oled.show()
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Display Image & text on I2C driven ssd1306 OLED display
2+
from machine import Pin, I2C
3+
from sh1106 import SH1106_I2C
4+
import framebuf
5+
6+
WIDTH = 128 # oled display width
7+
HEIGHT = 32 # oled display height
8+
9+
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=200000) # Init I2C using pins GP8 & GP9 (default I2C0 pins)
10+
print("I2C Address : "+hex(i2c.scan()[0]).upper()) # Display device address
11+
print("I2C Configuration: "+str(i2c)) # Display I2C config
12+
13+
14+
oled = SH1106_I2C(WIDTH, HEIGHT, i2c) # Init oled display
15+
16+
# Raspberry Pi logo as 32x32 bytearray
17+
buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
18+
19+
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
20+
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
21+
22+
# Clear the oled display in case it has junk on it.
23+
oled.fill(0)
24+
25+
# Blit the image from the framebuffer to the oled display
26+
oled.blit(fb, 96, 0)
27+
28+
# Add some text
29+
oled.text("Raspberry Pi",5,5)
30+
oled.text("Pico",5,15)
31+
32+
# Finally update the oled display so the image & text is displayed
33+
oled.show()

i2c/1106oled/pico-and-oled.fzz

698 KB
Binary file not shown.

i2c/1106oled/pico-and-oled.png

200 KB
Loading

i2c/1106oled/sh1106.py

+227
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#
2+
# MicroPython SH1106 OLED driver, I2C and SPI interfaces
3+
#
4+
# The MIT License (MIT)
5+
#
6+
# Copyright (c) 2016 Radomir Dopieralski (@deshipu),
7+
# 2017 Robert Hammelrath (@robert-hh)
8+
#
9+
# Permission is hereby granted, free of charge, to any person obtaining a copy
10+
# of this software and associated documentation files (the "Software"), to deal
11+
# in the Software without restriction, including without limitation the rights
12+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
# copies of the Software, and to permit persons to whom the Software is
14+
# furnished to do so, subject to the following conditions:
15+
#
16+
# The above copyright notice and this permission notice shall be included in
17+
# all copies or substantial portions of the Software.
18+
#
19+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
# THE SOFTWARE.
26+
#
27+
# Sample code sections
28+
# ------------ SPI ------------------
29+
# Pin Map SPI
30+
# - 3v - xxxxxx - Vcc
31+
# - G - xxxxxx - Gnd
32+
# - D7 - GPIO 13 - Din / MOSI fixed
33+
# - D5 - GPIO 14 - Clk / Sck fixed
34+
# - D8 - GPIO 4 - CS (optional, if the only connected device)
35+
# - D2 - GPIO 5 - D/C
36+
# - D1 - GPIO 2 - Res
37+
#
38+
# for CS, D/C and Res other ports may be chosen.
39+
#
40+
# from machine import Pin, SPI
41+
# import sh1106
42+
43+
# spi = SPI(1, baudrate=1000000)
44+
# display = sh1106.SH1106_SPI(128, 64, spi, Pin(5), Pin(2), Pin(4))
45+
# display.sleep(False)
46+
# display.fill(0)
47+
# display.text('Testing 1', 0, 0, 1)
48+
# display.show()
49+
#
50+
# --------------- I2C ------------------
51+
#
52+
# Pin Map I2C
53+
# - 3v - xxxxxx - Vcc
54+
# - G - xxxxxx - Gnd
55+
# - D2 - GPIO 5 - SCK / SCL
56+
# - D1 - GPIO 4 - DIN / SDA
57+
# - D0 - GPIO 16 - Res
58+
# - G - xxxxxx CS
59+
# - G - xxxxxx D/C
60+
#
61+
# Pin's for I2C can be set almost arbitrary
62+
#
63+
# from machine import Pin, I2C
64+
# import sh1106
65+
#
66+
# i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
67+
# display = sh1106.SH1106_I2C(128, 64, i2c, Pin(16), 0x3c)
68+
# display.sleep(False)
69+
# display.fill(0)
70+
# display.text('Testing 1', 0, 0, 1)
71+
# display.show()
72+
73+
from micropython import const
74+
import utime as time
75+
import framebuf
76+
77+
78+
# a few register definitions
79+
_SET_CONTRAST = const(0x81)
80+
_SET_NORM_INV = const(0xa6)
81+
_SET_DISP = const(0xae)
82+
_SET_SCAN_DIR = const(0xc0)
83+
_SET_SEG_REMAP = const(0xa0)
84+
_LOW_COLUMN_ADDRESS = const(0x00)
85+
_HIGH_COLUMN_ADDRESS = const(0x10)
86+
_SET_PAGE_ADDRESS = const(0xB0)
87+
88+
89+
class SH1106:
90+
def __init__(self, width, height, external_vcc):
91+
self.width = width
92+
self.height = height
93+
self.external_vcc = external_vcc
94+
self.pages = self.height // 8
95+
self.buffer = bytearray(self.pages * self.width)
96+
fb = framebuf.FrameBuffer(self.buffer, self.width, self.height,
97+
framebuf.MVLSB)
98+
self.framebuf = fb
99+
# set shortcuts for the methods of framebuf
100+
self.fill = fb.fill
101+
self.fill_rect = fb.fill_rect
102+
self.hline = fb.hline
103+
self.vline = fb.vline
104+
self.line = fb.line
105+
self.rect = fb.rect
106+
self.pixel = fb.pixel
107+
self.scroll = fb.scroll
108+
self.text = fb.text
109+
self.blit = fb.blit
110+
111+
self.init_display()
112+
113+
def init_display(self):
114+
self.reset()
115+
self.fill(0)
116+
self.poweron()
117+
self.show()
118+
119+
def poweroff(self):
120+
self.write_cmd(_SET_DISP | 0x00)
121+
122+
def poweron(self):
123+
self.write_cmd(_SET_DISP | 0x01)
124+
125+
def rotate(self, flag, update=True):
126+
if flag:
127+
self.write_cmd(_SET_SEG_REMAP | 0x01) # mirror display vertically
128+
self.write_cmd(_SET_SCAN_DIR | 0x08) # mirror display hor.
129+
else:
130+
self.write_cmd(_SET_SEG_REMAP | 0x00)
131+
self.write_cmd(_SET_SCAN_DIR | 0x00)
132+
if update:
133+
self.show()
134+
135+
def sleep(self, value):
136+
self.write_cmd(_SET_DISP | (not value))
137+
138+
def contrast(self, contrast):
139+
self.write_cmd(_SET_CONTRAST)
140+
self.write_cmd(contrast)
141+
142+
def invert(self, invert):
143+
self.write_cmd(_SET_NORM_INV | (invert & 1))
144+
145+
def show(self):
146+
for page in range(self.height // 8):
147+
self.write_cmd(_SET_PAGE_ADDRESS | page)
148+
self.write_cmd(_LOW_COLUMN_ADDRESS | 2)
149+
self.write_cmd(_HIGH_COLUMN_ADDRESS | 0)
150+
self.write_data(self.buffer[
151+
self.width * page:self.width * page + self.width
152+
])
153+
154+
def reset(self, res):
155+
if res is not None:
156+
res(1)
157+
time.sleep_ms(1)
158+
res(0)
159+
time.sleep_ms(20)
160+
res(1)
161+
time.sleep_ms(20)
162+
163+
164+
class SH1106_I2C(SH1106):
165+
def __init__(self, width, height, i2c, res=None, addr=0x3c,
166+
external_vcc=False):
167+
self.i2c = i2c
168+
self.addr = addr
169+
self.res = res
170+
self.temp = bytearray(2)
171+
if res is not None:
172+
res.init(res.OUT, value=1)
173+
super().__init__(width, height, external_vcc)
174+
175+
def write_cmd(self, cmd):
176+
self.temp[0] = 0x80 # Co=1, D/C#=0
177+
self.temp[1] = cmd
178+
self.i2c.writeto(self.addr, self.temp)
179+
180+
def write_data(self, buf):
181+
self.i2c.writeto(self.addr, b'\x40'+buf)
182+
183+
def reset(self):
184+
super().reset(self.res)
185+
186+
187+
class SH1106_SPI(SH1106):
188+
def __init__(self, width, height, spi, dc, res=None, cs=None,
189+
external_vcc=False):
190+
self.rate = 10 * 1000 * 1000
191+
dc.init(dc.OUT, value=0)
192+
if res is not None:
193+
res.init(res.OUT, value=0)
194+
if cs is not None:
195+
cs.init(cs.OUT, value=1)
196+
self.spi = spi
197+
self.dc = dc
198+
self.res = res
199+
self.cs = cs
200+
super().__init__(width, height, external_vcc)
201+
202+
def write_cmd(self, cmd):
203+
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
204+
if self.cs is not None:
205+
self.cs(1)
206+
self.dc(0)
207+
self.cs(0)
208+
self.spi.write(bytearray([cmd]))
209+
self.cs(1)
210+
else:
211+
self.dc(0)
212+
self.spi.write(bytearray([cmd]))
213+
214+
def write_data(self, buf):
215+
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
216+
if self.cs is not None:
217+
self.cs(1)
218+
self.dc(1)
219+
self.cs(0)
220+
self.spi.write(buf)
221+
self.cs(1)
222+
else:
223+
self.dc(1)
224+
self.spi.write(buf)
225+
226+
def reset(self):
227+
super().reset(self.res)

i2c/1306oled/README.adoc

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
= Using a SSD1306-based OLED graphics display
2+
:xrefstyle: short
3+
4+
Display an image and text on I2C driven SSD1306-based OLED graphics display.
5+
6+
== Wiring information
7+
8+
See <<oled-wiring-diagram>> for wiring instructions.
9+
10+
[[oled-wiring-diagram]]
11+
[pdfwidth=75%]
12+
.Wiring the OLED to Pico using I2C
13+
image::pico-and-oled.png[]
14+
15+
== List of Files
16+
17+
A list of files with descriptions of their function;
18+
19+
i2c_1306oled_using_defaults.py:: The example code.
20+
i2c_1306oled_with_freq.py:: The example code, explicitly sets a frequency.
21+
22+
== Bill of Materials
23+
24+
.A list of materials required for the example
25+
[[oled-bom-table]]
26+
[cols=3]
27+
|===
28+
| *Item* | *Quantity* | Details
29+
| Breadboard | 1 | generic part
30+
| Raspberry Pi Pico | 1 | http://raspberrypi.org/
31+
| Monochrome 128x32 I2C OLED Display | 1 | https://www.adafruit.com/product/931
32+
|===

0 commit comments

Comments
 (0)