Initial Release
commit
2a6cfbb1d9
|
@ -0,0 +1 @@
|
||||||
|
.DS_Store
|
|
@ -0,0 +1,3 @@
|
||||||
|
# MicroPython Examples
|
||||||
|
|
||||||
|
Examples to accompany the "Pico Python SDK" book.
|
|
@ -0,0 +1,12 @@
|
||||||
|
import machine
|
||||||
|
import utime
|
||||||
|
|
||||||
|
sensor_temp = machine.ADC(4)
|
||||||
|
conversion_factor = 3.3 / (65535)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
reading = sensor_temp.read_u16() * conversion_factor
|
||||||
|
|
||||||
|
temperature = 27 - (reading - 0.706)/0.001721
|
||||||
|
print(temperature)
|
||||||
|
utime.sleep(2)
|
|
@ -0,0 +1,9 @@
|
||||||
|
from machine import Pin, Timer
|
||||||
|
|
||||||
|
led = Pin(25, Pin.OUT)
|
||||||
|
tim = Timer()
|
||||||
|
def tick(timer):
|
||||||
|
global led
|
||||||
|
led.toggle()
|
||||||
|
|
||||||
|
tim.init(freq=2.5, mode=Timer.PERIODIC, callback=tick)
|
|
@ -0,0 +1,35 @@
|
||||||
|
= Using a SH1106-based OLED graphics display
|
||||||
|
:xrefstyle: short
|
||||||
|
|
||||||
|
Display an image and text on I2C driven SH1106-based OLED graphics display
|
||||||
|
such as the Pimoroni Breakout Garden 1.12" Mono OLED https://shop.pimoroni.com/products/1-12-oled-breakout?variant=29421050757203
|
||||||
|
.
|
||||||
|
|
||||||
|
== Wiring information
|
||||||
|
|
||||||
|
See <<oled-wiring-diagram>> for wiring instructions.
|
||||||
|
|
||||||
|
[[oled-wiring-diagram]]
|
||||||
|
[pdfwidth=75%]
|
||||||
|
.Wiring the OLED to Pico using I2C
|
||||||
|
image::pico-and-oled.png[]
|
||||||
|
|
||||||
|
== List of Files
|
||||||
|
|
||||||
|
A list of files with descriptions of their function;
|
||||||
|
|
||||||
|
i2c_1106oled_using_defaults.py:: The example code.
|
||||||
|
i2c_1106oled_with_freq.py:: The example code, explicitly sets a frequency.
|
||||||
|
sh1106.py:: SH1106 Driver Obtained from https://github.com/robert-hh/SH1106
|
||||||
|
|
||||||
|
== Bill of Materials
|
||||||
|
|
||||||
|
.A list of materials required for the example
|
||||||
|
[[oled-bom-table]]
|
||||||
|
[cols=3]
|
||||||
|
|===
|
||||||
|
| *Item* | *Quantity* | Details
|
||||||
|
| Breadboard | 1 | generic part
|
||||||
|
| Raspberry Pi Pico | 1 | http://raspberrypi.org/
|
||||||
|
| Monochrome 128x128 I2C OLED Display | 1 | https://shop.pimoroni.com/products/1-12-oled-breakout?variant=29421050757203
|
||||||
|
|===
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Display Image & text on I2C driven SH1106 OLED display
|
||||||
|
from machine import I2C, ADC
|
||||||
|
from sh1106 import SH1106_I2C
|
||||||
|
import framebuf
|
||||||
|
|
||||||
|
|
||||||
|
WIDTH = 128 # oled display width
|
||||||
|
HEIGHT = 128 # oled display height
|
||||||
|
|
||||||
|
i2c = I2C(0) # Init I2C using I2C0 defaults, SCL=Pin(GP9), SDA=Pin(GP8), freq=400000
|
||||||
|
print("I2C Address : "+hex(i2c.scan()[0]).upper()) # Display device address
|
||||||
|
print("I2C Configuration: "+str(i2c)) # Display I2C config
|
||||||
|
|
||||||
|
|
||||||
|
oled = SH1106_I2C(WIDTH, HEIGHT, i2c) # Init oled display
|
||||||
|
|
||||||
|
# Raspberry Pi logo as 32x32 bytearray
|
||||||
|
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")
|
||||||
|
|
||||||
|
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
|
||||||
|
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
|
||||||
|
|
||||||
|
# Clear the oled display in case it has junk on it.
|
||||||
|
oled.fill(0)
|
||||||
|
|
||||||
|
# Blit the image from the framebuffer to the oled display
|
||||||
|
oled.blit(fb, 96, 0)
|
||||||
|
|
||||||
|
# Add some text
|
||||||
|
oled.text("Raspberry Pi",5,5)
|
||||||
|
oled.text("Pico",5,15)
|
||||||
|
|
||||||
|
# Finally update the oled display so the image & text is displayed
|
||||||
|
oled.show()
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Display Image & text on I2C driven ssd1306 OLED display
|
||||||
|
from machine import Pin, I2C
|
||||||
|
from sh1106 import SH1106_I2C
|
||||||
|
import framebuf
|
||||||
|
|
||||||
|
WIDTH = 128 # oled display width
|
||||||
|
HEIGHT = 32 # oled display height
|
||||||
|
|
||||||
|
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=200000) # Init I2C using pins GP8 & GP9 (default I2C0 pins)
|
||||||
|
print("I2C Address : "+hex(i2c.scan()[0]).upper()) # Display device address
|
||||||
|
print("I2C Configuration: "+str(i2c)) # Display I2C config
|
||||||
|
|
||||||
|
|
||||||
|
oled = SH1106_I2C(WIDTH, HEIGHT, i2c) # Init oled display
|
||||||
|
|
||||||
|
# Raspberry Pi logo as 32x32 bytearray
|
||||||
|
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")
|
||||||
|
|
||||||
|
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
|
||||||
|
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
|
||||||
|
|
||||||
|
# Clear the oled display in case it has junk on it.
|
||||||
|
oled.fill(0)
|
||||||
|
|
||||||
|
# Blit the image from the framebuffer to the oled display
|
||||||
|
oled.blit(fb, 96, 0)
|
||||||
|
|
||||||
|
# Add some text
|
||||||
|
oled.text("Raspberry Pi",5,5)
|
||||||
|
oled.text("Pico",5,15)
|
||||||
|
|
||||||
|
# Finally update the oled display so the image & text is displayed
|
||||||
|
oled.show()
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 200 KiB |
|
@ -0,0 +1,227 @@
|
||||||
|
#
|
||||||
|
# MicroPython SH1106 OLED driver, I2C and SPI interfaces
|
||||||
|
#
|
||||||
|
# The MIT License (MIT)
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016 Radomir Dopieralski (@deshipu),
|
||||||
|
# 2017 Robert Hammelrath (@robert-hh)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# Sample code sections
|
||||||
|
# ------------ SPI ------------------
|
||||||
|
# Pin Map SPI
|
||||||
|
# - 3v - xxxxxx - Vcc
|
||||||
|
# - G - xxxxxx - Gnd
|
||||||
|
# - D7 - GPIO 13 - Din / MOSI fixed
|
||||||
|
# - D5 - GPIO 14 - Clk / Sck fixed
|
||||||
|
# - D8 - GPIO 4 - CS (optional, if the only connected device)
|
||||||
|
# - D2 - GPIO 5 - D/C
|
||||||
|
# - D1 - GPIO 2 - Res
|
||||||
|
#
|
||||||
|
# for CS, D/C and Res other ports may be chosen.
|
||||||
|
#
|
||||||
|
# from machine import Pin, SPI
|
||||||
|
# import sh1106
|
||||||
|
|
||||||
|
# spi = SPI(1, baudrate=1000000)
|
||||||
|
# display = sh1106.SH1106_SPI(128, 64, spi, Pin(5), Pin(2), Pin(4))
|
||||||
|
# display.sleep(False)
|
||||||
|
# display.fill(0)
|
||||||
|
# display.text('Testing 1', 0, 0, 1)
|
||||||
|
# display.show()
|
||||||
|
#
|
||||||
|
# --------------- I2C ------------------
|
||||||
|
#
|
||||||
|
# Pin Map I2C
|
||||||
|
# - 3v - xxxxxx - Vcc
|
||||||
|
# - G - xxxxxx - Gnd
|
||||||
|
# - D2 - GPIO 5 - SCK / SCL
|
||||||
|
# - D1 - GPIO 4 - DIN / SDA
|
||||||
|
# - D0 - GPIO 16 - Res
|
||||||
|
# - G - xxxxxx CS
|
||||||
|
# - G - xxxxxx D/C
|
||||||
|
#
|
||||||
|
# Pin's for I2C can be set almost arbitrary
|
||||||
|
#
|
||||||
|
# from machine import Pin, I2C
|
||||||
|
# import sh1106
|
||||||
|
#
|
||||||
|
# i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
|
||||||
|
# display = sh1106.SH1106_I2C(128, 64, i2c, Pin(16), 0x3c)
|
||||||
|
# display.sleep(False)
|
||||||
|
# display.fill(0)
|
||||||
|
# display.text('Testing 1', 0, 0, 1)
|
||||||
|
# display.show()
|
||||||
|
|
||||||
|
from micropython import const
|
||||||
|
import utime as time
|
||||||
|
import framebuf
|
||||||
|
|
||||||
|
|
||||||
|
# a few register definitions
|
||||||
|
_SET_CONTRAST = const(0x81)
|
||||||
|
_SET_NORM_INV = const(0xa6)
|
||||||
|
_SET_DISP = const(0xae)
|
||||||
|
_SET_SCAN_DIR = const(0xc0)
|
||||||
|
_SET_SEG_REMAP = const(0xa0)
|
||||||
|
_LOW_COLUMN_ADDRESS = const(0x00)
|
||||||
|
_HIGH_COLUMN_ADDRESS = const(0x10)
|
||||||
|
_SET_PAGE_ADDRESS = const(0xB0)
|
||||||
|
|
||||||
|
|
||||||
|
class SH1106:
|
||||||
|
def __init__(self, width, height, external_vcc):
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self.external_vcc = external_vcc
|
||||||
|
self.pages = self.height // 8
|
||||||
|
self.buffer = bytearray(self.pages * self.width)
|
||||||
|
fb = framebuf.FrameBuffer(self.buffer, self.width, self.height,
|
||||||
|
framebuf.MVLSB)
|
||||||
|
self.framebuf = fb
|
||||||
|
# set shortcuts for the methods of framebuf
|
||||||
|
self.fill = fb.fill
|
||||||
|
self.fill_rect = fb.fill_rect
|
||||||
|
self.hline = fb.hline
|
||||||
|
self.vline = fb.vline
|
||||||
|
self.line = fb.line
|
||||||
|
self.rect = fb.rect
|
||||||
|
self.pixel = fb.pixel
|
||||||
|
self.scroll = fb.scroll
|
||||||
|
self.text = fb.text
|
||||||
|
self.blit = fb.blit
|
||||||
|
|
||||||
|
self.init_display()
|
||||||
|
|
||||||
|
def init_display(self):
|
||||||
|
self.reset()
|
||||||
|
self.fill(0)
|
||||||
|
self.poweron()
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def poweroff(self):
|
||||||
|
self.write_cmd(_SET_DISP | 0x00)
|
||||||
|
|
||||||
|
def poweron(self):
|
||||||
|
self.write_cmd(_SET_DISP | 0x01)
|
||||||
|
|
||||||
|
def rotate(self, flag, update=True):
|
||||||
|
if flag:
|
||||||
|
self.write_cmd(_SET_SEG_REMAP | 0x01) # mirror display vertically
|
||||||
|
self.write_cmd(_SET_SCAN_DIR | 0x08) # mirror display hor.
|
||||||
|
else:
|
||||||
|
self.write_cmd(_SET_SEG_REMAP | 0x00)
|
||||||
|
self.write_cmd(_SET_SCAN_DIR | 0x00)
|
||||||
|
if update:
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def sleep(self, value):
|
||||||
|
self.write_cmd(_SET_DISP | (not value))
|
||||||
|
|
||||||
|
def contrast(self, contrast):
|
||||||
|
self.write_cmd(_SET_CONTRAST)
|
||||||
|
self.write_cmd(contrast)
|
||||||
|
|
||||||
|
def invert(self, invert):
|
||||||
|
self.write_cmd(_SET_NORM_INV | (invert & 1))
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
for page in range(self.height // 8):
|
||||||
|
self.write_cmd(_SET_PAGE_ADDRESS | page)
|
||||||
|
self.write_cmd(_LOW_COLUMN_ADDRESS | 2)
|
||||||
|
self.write_cmd(_HIGH_COLUMN_ADDRESS | 0)
|
||||||
|
self.write_data(self.buffer[
|
||||||
|
self.width * page:self.width * page + self.width
|
||||||
|
])
|
||||||
|
|
||||||
|
def reset(self, res):
|
||||||
|
if res is not None:
|
||||||
|
res(1)
|
||||||
|
time.sleep_ms(1)
|
||||||
|
res(0)
|
||||||
|
time.sleep_ms(20)
|
||||||
|
res(1)
|
||||||
|
time.sleep_ms(20)
|
||||||
|
|
||||||
|
|
||||||
|
class SH1106_I2C(SH1106):
|
||||||
|
def __init__(self, width, height, i2c, res=None, addr=0x3c,
|
||||||
|
external_vcc=False):
|
||||||
|
self.i2c = i2c
|
||||||
|
self.addr = addr
|
||||||
|
self.res = res
|
||||||
|
self.temp = bytearray(2)
|
||||||
|
if res is not None:
|
||||||
|
res.init(res.OUT, value=1)
|
||||||
|
super().__init__(width, height, external_vcc)
|
||||||
|
|
||||||
|
def write_cmd(self, cmd):
|
||||||
|
self.temp[0] = 0x80 # Co=1, D/C#=0
|
||||||
|
self.temp[1] = cmd
|
||||||
|
self.i2c.writeto(self.addr, self.temp)
|
||||||
|
|
||||||
|
def write_data(self, buf):
|
||||||
|
self.i2c.writeto(self.addr, b'\x40'+buf)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
super().reset(self.res)
|
||||||
|
|
||||||
|
|
||||||
|
class SH1106_SPI(SH1106):
|
||||||
|
def __init__(self, width, height, spi, dc, res=None, cs=None,
|
||||||
|
external_vcc=False):
|
||||||
|
self.rate = 10 * 1000 * 1000
|
||||||
|
dc.init(dc.OUT, value=0)
|
||||||
|
if res is not None:
|
||||||
|
res.init(res.OUT, value=0)
|
||||||
|
if cs is not None:
|
||||||
|
cs.init(cs.OUT, value=1)
|
||||||
|
self.spi = spi
|
||||||
|
self.dc = dc
|
||||||
|
self.res = res
|
||||||
|
self.cs = cs
|
||||||
|
super().__init__(width, height, external_vcc)
|
||||||
|
|
||||||
|
def write_cmd(self, cmd):
|
||||||
|
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
|
||||||
|
if self.cs is not None:
|
||||||
|
self.cs(1)
|
||||||
|
self.dc(0)
|
||||||
|
self.cs(0)
|
||||||
|
self.spi.write(bytearray([cmd]))
|
||||||
|
self.cs(1)
|
||||||
|
else:
|
||||||
|
self.dc(0)
|
||||||
|
self.spi.write(bytearray([cmd]))
|
||||||
|
|
||||||
|
def write_data(self, buf):
|
||||||
|
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
|
||||||
|
if self.cs is not None:
|
||||||
|
self.cs(1)
|
||||||
|
self.dc(1)
|
||||||
|
self.cs(0)
|
||||||
|
self.spi.write(buf)
|
||||||
|
self.cs(1)
|
||||||
|
else:
|
||||||
|
self.dc(1)
|
||||||
|
self.spi.write(buf)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
super().reset(self.res)
|
|
@ -0,0 +1,32 @@
|
||||||
|
= Using a SSD1306-based OLED graphics display
|
||||||
|
:xrefstyle: short
|
||||||
|
|
||||||
|
Display an image and text on I2C driven SSD1306-based OLED graphics display.
|
||||||
|
|
||||||
|
== Wiring information
|
||||||
|
|
||||||
|
See <<oled-wiring-diagram>> for wiring instructions.
|
||||||
|
|
||||||
|
[[oled-wiring-diagram]]
|
||||||
|
[pdfwidth=75%]
|
||||||
|
.Wiring the OLED to Pico using I2C
|
||||||
|
image::pico-and-oled.png[]
|
||||||
|
|
||||||
|
== List of Files
|
||||||
|
|
||||||
|
A list of files with descriptions of their function;
|
||||||
|
|
||||||
|
i2c_1306oled_using_defaults.py:: The example code.
|
||||||
|
i2c_1306oled_with_freq.py:: The example code, explicitly sets a frequency.
|
||||||
|
|
||||||
|
== Bill of Materials
|
||||||
|
|
||||||
|
.A list of materials required for the example
|
||||||
|
[[oled-bom-table]]
|
||||||
|
[cols=3]
|
||||||
|
|===
|
||||||
|
| *Item* | *Quantity* | Details
|
||||||
|
| Breadboard | 1 | generic part
|
||||||
|
| Raspberry Pi Pico | 1 | http://raspberrypi.org/
|
||||||
|
| Monochrome 128x32 I2C OLED Display | 1 | https://www.adafruit.com/product/931
|
||||||
|
|===
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Display Image & text on I2C driven ssd1306 OLED display
|
||||||
|
from machine import Pin, I2C
|
||||||
|
from ssd1306 import SSD1306_I2C
|
||||||
|
import framebuf
|
||||||
|
|
||||||
|
WIDTH = 128 # oled display width
|
||||||
|
HEIGHT = 32 # oled display height
|
||||||
|
|
||||||
|
i2c = I2C(0) # Init I2C using I2C0 defaults, SCL=Pin(GP9), SDA=Pin(GP8), freq=400000
|
||||||
|
print("I2C Address : "+hex(i2c.scan()[0]).upper()) # Display device address
|
||||||
|
print("I2C Configuration: "+str(i2c)) # Display I2C config
|
||||||
|
|
||||||
|
|
||||||
|
oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) # Init oled display
|
||||||
|
|
||||||
|
# Raspberry Pi logo as 32x32 bytearray
|
||||||
|
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")
|
||||||
|
|
||||||
|
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
|
||||||
|
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
|
||||||
|
|
||||||
|
# Clear the oled display in case it has junk on it.
|
||||||
|
oled.fill(0)
|
||||||
|
|
||||||
|
# Blit the image from the framebuffer to the oled display
|
||||||
|
oled.blit(fb, 96, 0)
|
||||||
|
|
||||||
|
# Add some text
|
||||||
|
oled.text("Raspberry Pi",5,5)
|
||||||
|
oled.text("Pico",5,15)
|
||||||
|
|
||||||
|
# Finally update the oled display so the image & text is displayed
|
||||||
|
oled.show()
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Display Image & text on I2C driven ssd1306 OLED display
|
||||||
|
from machine import Pin, I2C
|
||||||
|
from ssd1306 import SSD1306_I2C
|
||||||
|
import framebuf
|
||||||
|
|
||||||
|
WIDTH = 128 # oled display width
|
||||||
|
HEIGHT = 32 # oled display height
|
||||||
|
|
||||||
|
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=200000) # Init I2C using pins GP8 & GP9 (default I2C0 pins)
|
||||||
|
print("I2C Address : "+hex(i2c.scan()[0]).upper()) # Display device address
|
||||||
|
print("I2C Configuration: "+str(i2c)) # Display I2C config
|
||||||
|
|
||||||
|
|
||||||
|
oled = SSD1306_I2C(WIDTH, HEIGHT, i2c) # Init oled display
|
||||||
|
|
||||||
|
# Raspberry Pi logo as 32x32 bytearray
|
||||||
|
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")
|
||||||
|
|
||||||
|
# Load the raspberry pi logo into the framebuffer (the image is 32x32)
|
||||||
|
fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)
|
||||||
|
|
||||||
|
# Clear the oled display in case it has junk on it.
|
||||||
|
oled.fill(0)
|
||||||
|
|
||||||
|
# Blit the image from the framebuffer to the oled display
|
||||||
|
oled.blit(fb, 96, 0)
|
||||||
|
|
||||||
|
# Add some text
|
||||||
|
oled.text("Raspberry Pi",5,5)
|
||||||
|
oled.text("Pico",5,15)
|
||||||
|
|
||||||
|
# Finally update the oled display so the image & text is displayed
|
||||||
|
oled.show()
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 200 KiB |
|
@ -0,0 +1,11 @@
|
||||||
|
from machine import Pin, I2C
|
||||||
|
|
||||||
|
i2c = I2C(0, scl=Pin(9), sda=Pin(8), freq=100000)
|
||||||
|
i2c.scan()
|
||||||
|
i2c.writeto(76, b'123')
|
||||||
|
i2c.readfrom(76, 4)
|
||||||
|
|
||||||
|
i2c = I2C(1, scl=Pin(7), sda=Pin(6), freq=100000)
|
||||||
|
i2c.scan()
|
||||||
|
i2c.writeto_mem(76, 6, b'456')
|
||||||
|
i2c.readfrom_mem(76, 6, 4)
|
|
@ -0,0 +1,3 @@
|
||||||
|
from machine import I2C
|
||||||
|
|
||||||
|
i2c = I2C(0) # defaults to SCL=Pin(9), SDA=Pin(8), freq=400000
|
|
@ -0,0 +1,5 @@
|
||||||
|
from machine import Pin
|
||||||
|
|
||||||
|
p2 = Pin(2, Pin.IN, Pin.PULL_UP)
|
||||||
|
p2.irq(lambda pin: print("IRQ with flags:", pin.irq().flags()),
|
||||||
|
Pin.IRQ_FALLING)
|
|
@ -0,0 +1,12 @@
|
||||||
|
import time, _thread, machine
|
||||||
|
|
||||||
|
def task(n, delay):
|
||||||
|
led = machine.Pin(25, machine.Pin.OUT)
|
||||||
|
for i in range(n):
|
||||||
|
led.high()
|
||||||
|
time.sleep(delay)
|
||||||
|
led.low()
|
||||||
|
time.sleep(delay)
|
||||||
|
print('done')
|
||||||
|
|
||||||
|
_thread.start_new_thread(task, (10, 0.5))
|
|
@ -0,0 +1,31 @@
|
||||||
|
= Using PIO to drive a set of NeoPixel Ring (WS2812 LEDs)
|
||||||
|
:xrefstyle: short
|
||||||
|
|
||||||
|
Combination of the PIO WS2812 demo with the Adafruit 'essential' NeoPixel example code to show off color fills, chases and of course a rainbow swirl on a 16-LED ring.
|
||||||
|
|
||||||
|
== Wiring information
|
||||||
|
|
||||||
|
See <<neopixel-wiring-diagram>> for wiring instructions.
|
||||||
|
|
||||||
|
[[neopixel-wiring-diagram]]
|
||||||
|
[pdfwidth=75%]
|
||||||
|
.Wiring the 16-LED NeoPixel Ring to Pico
|
||||||
|
image::neopixel_ring.png[]
|
||||||
|
|
||||||
|
== List of Files
|
||||||
|
|
||||||
|
A list of files with descriptions of their function;
|
||||||
|
|
||||||
|
neopixel_ring.py:: The example code.
|
||||||
|
|
||||||
|
== Bill of Materials
|
||||||
|
|
||||||
|
.A list of materials required for the example
|
||||||
|
[[ring-bom-table]]
|
||||||
|
[cols=3]
|
||||||
|
|===
|
||||||
|
| *Item* | *Quantity* | Details
|
||||||
|
| Breadboard | 1 | generic part
|
||||||
|
| Raspberry Pi Pico | 1 | http://raspberrypi.org/
|
||||||
|
| NeoPixel Ring | 1 | https://www.adafruit.com/product/1463
|
||||||
|
|===
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 272 KiB |
|
@ -0,0 +1,104 @@
|
||||||
|
# Example using PIO to drive a set of WS2812 LEDs.
|
||||||
|
|
||||||
|
import array, time
|
||||||
|
from machine import Pin
|
||||||
|
import rp2
|
||||||
|
|
||||||
|
# Configure the number of WS2812 LEDs.
|
||||||
|
NUM_LEDS = 16
|
||||||
|
PIN_NUM = 6
|
||||||
|
brightness = 0.2
|
||||||
|
|
||||||
|
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
|
||||||
|
def ws2812():
|
||||||
|
T1 = 2
|
||||||
|
T2 = 5
|
||||||
|
T3 = 3
|
||||||
|
wrap_target()
|
||||||
|
label("bitloop")
|
||||||
|
out(x, 1) .side(0) [T3 - 1]
|
||||||
|
jmp(not_x, "do_zero") .side(1) [T1 - 1]
|
||||||
|
jmp("bitloop") .side(1) [T2 - 1]
|
||||||
|
label("do_zero")
|
||||||
|
nop() .side(0) [T2 - 1]
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
|
||||||
|
# Create the StateMachine with the ws2812 program, outputting on pin
|
||||||
|
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(PIN_NUM))
|
||||||
|
|
||||||
|
# Start the StateMachine, it will wait for data on its FIFO.
|
||||||
|
sm.active(1)
|
||||||
|
|
||||||
|
# Display a pattern on the LEDs via an array of LED RGB values.
|
||||||
|
ar = array.array("I", [0 for _ in range(NUM_LEDS)])
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
def pixels_show():
|
||||||
|
dimmer_ar = array.array("I", [0 for _ in range(NUM_LEDS)])
|
||||||
|
for i,c in enumerate(ar):
|
||||||
|
r = int(((c >> 8) & 0xFF) * brightness)
|
||||||
|
g = int(((c >> 16) & 0xFF) * brightness)
|
||||||
|
b = int((c & 0xFF) * brightness)
|
||||||
|
dimmer_ar[i] = (g<<16) + (r<<8) + b
|
||||||
|
sm.put(dimmer_ar, 8)
|
||||||
|
time.sleep_ms(10)
|
||||||
|
|
||||||
|
def pixels_set(i, color):
|
||||||
|
ar[i] = (color[1]<<16) + (color[0]<<8) + color[2]
|
||||||
|
|
||||||
|
def pixels_fill(color):
|
||||||
|
for i in range(len(ar)):
|
||||||
|
pixels_set(i, color)
|
||||||
|
|
||||||
|
def color_chase(color, wait):
|
||||||
|
for i in range(NUM_LEDS):
|
||||||
|
pixels_set(i, color)
|
||||||
|
time.sleep(wait)
|
||||||
|
pixels_show()
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
def wheel(pos):
|
||||||
|
# Input a value 0 to 255 to get a color value.
|
||||||
|
# The colours are a transition r - g - b - back to r.
|
||||||
|
if pos < 0 or pos > 255:
|
||||||
|
return (0, 0, 0)
|
||||||
|
if pos < 85:
|
||||||
|
return (255 - pos * 3, pos * 3, 0)
|
||||||
|
if pos < 170:
|
||||||
|
pos -= 85
|
||||||
|
return (0, 255 - pos * 3, pos * 3)
|
||||||
|
pos -= 170
|
||||||
|
return (pos * 3, 0, 255 - pos * 3)
|
||||||
|
|
||||||
|
|
||||||
|
def rainbow_cycle(wait):
|
||||||
|
for j in range(255):
|
||||||
|
for i in range(NUM_LEDS):
|
||||||
|
rc_index = (i * 256 // NUM_LEDS) + j
|
||||||
|
pixels_set(i, wheel(rc_index & 255))
|
||||||
|
pixels_show()
|
||||||
|
time.sleep(wait)
|
||||||
|
|
||||||
|
BLACK = (0, 0, 0)
|
||||||
|
RED = (255, 0, 0)
|
||||||
|
YELLOW = (255, 150, 0)
|
||||||
|
GREEN = (0, 255, 0)
|
||||||
|
CYAN = (0, 255, 255)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
PURPLE = (180, 0, 255)
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
COLORS = (BLACK, RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE)
|
||||||
|
|
||||||
|
print("fills")
|
||||||
|
for color in COLORS:
|
||||||
|
pixels_fill(color)
|
||||||
|
pixels_show()
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
print("chases")
|
||||||
|
for color in COLORS:
|
||||||
|
color_chase(color, 0.01)
|
||||||
|
|
||||||
|
print("rainbow")
|
||||||
|
rainbow_cycle(0)
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Example using PIO to blink an LED and raise an IRQ at 1Hz.
|
||||||
|
|
||||||
|
import time
|
||||||
|
from machine import Pin
|
||||||
|
import rp2
|
||||||
|
|
||||||
|
|
||||||
|
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
|
||||||
|
def blink_1hz():
|
||||||
|
# Cycles: 1 + 1 + 6 + 32 * (30 + 1) = 1000
|
||||||
|
irq(rel(0))
|
||||||
|
set(pins, 1)
|
||||||
|
set(x, 31) [5]
|
||||||
|
label("delay_high")
|
||||||
|
nop() [29]
|
||||||
|
jmp(x_dec, "delay_high")
|
||||||
|
|
||||||
|
# Cycles: 1 + 7 + 32 * (30 + 1) = 1000
|
||||||
|
set(pins, 0)
|
||||||
|
set(x, 31) [6]
|
||||||
|
label("delay_low")
|
||||||
|
nop() [29]
|
||||||
|
jmp(x_dec, "delay_low")
|
||||||
|
|
||||||
|
|
||||||
|
# Create the StateMachine with the blink_1hz program, outputting on Pin(25).
|
||||||
|
sm = rp2.StateMachine(0, blink_1hz, freq=2000, set_base=Pin(25))
|
||||||
|
|
||||||
|
# Set the IRQ handler to print the millisecond timestamp.
|
||||||
|
sm.irq(lambda p: print(time.ticks_ms()))
|
||||||
|
|
||||||
|
# Start the StateMachine.
|
||||||
|
sm.active(1)
|
|
@ -0,0 +1,28 @@
|
||||||
|
import time
|
||||||
|
from rp2 import PIO, asm_pio
|
||||||
|
from machine import Pin
|
||||||
|
|
||||||
|
# Define the blink program. It has one GPIO to bind to on the set instruction, which is an output pin.
|
||||||
|
# Use lots of delays to make the blinking visible by eye.
|
||||||
|
@asm_pio(set_init=rp2.PIO.OUT_LOW)
|
||||||
|
def blink():
|
||||||
|
wrap_target()
|
||||||
|
set(pins, 1) [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
set(pins, 0) [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
# Instantiate a state machine with the blink program, at 1000Hz, with set bound to Pin(25) (LED on the rp2 board)
|
||||||
|
sm = rp2.StateMachine(0, blink, freq=1000, set_base=Pin(25))
|
||||||
|
|
||||||
|
# Run the state machine for 3 seconds. The LED should blink.
|
||||||
|
sm.active(1)
|
||||||
|
time.sleep(3)
|
||||||
|
sm.active(0)
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Example using PIO to turn on an LED via an explicit exec.
|
||||||
|
#
|
||||||
|
# Demonstrates:
|
||||||
|
# - using set_init and set_base
|
||||||
|
# - using StateMachine.exec
|
||||||
|
|
||||||
|
import time
|
||||||
|
from machine import Pin
|
||||||
|
import rp2
|
||||||
|
|
||||||
|
# Define an empty program that uses a single set pin.
|
||||||
|
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
|
||||||
|
def prog():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Construct the StateMachine, binding Pin(25) to the set pin.
|
||||||
|
sm = rp2.StateMachine(0, prog, set_base=Pin(25))
|
||||||
|
|
||||||
|
# Turn on the set pin via an exec instruction.
|
||||||
|
sm.exec("set(pins, 1)")
|
||||||
|
|
||||||
|
# Sleep for 500ms.
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
# Turn off the set pin via an exec instruction.
|
||||||
|
sm.exec("set(pins, 0)")
|
|
@ -0,0 +1,25 @@
|
||||||
|
import time
|
||||||
|
import rp2
|
||||||
|
|
||||||
|
@rp2.asm_pio()
|
||||||
|
def irq_test():
|
||||||
|
wrap_target()
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
irq(0)
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
nop() [31]
|
||||||
|
irq(1)
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
|
||||||
|
rp2.PIO(0).irq(lambda pio: print(pio.irq().flags()))
|
||||||
|
|
||||||
|
sm = rp2.StateMachine(0, irq_test, freq=1000)
|
||||||
|
sm.active(1)
|
||||||
|
time.sleep(1)
|
||||||
|
sm.active(0)
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Example using PIO to wait for a pin change and raise an IRQ.
|
||||||
|
#
|
||||||
|
# Demonstrates:
|
||||||
|
# - PIO wrapping
|
||||||
|
# - PIO wait instruction, waiting on an input pin
|
||||||
|
# - PIO irq instruction, in blocking mode with relative IRQ number
|
||||||
|
# - setting the in_base pin for a StateMachine
|
||||||
|
# - setting an irq handler for a StateMachine
|
||||||
|
# - instantiating 2x StateMachine's with the same program and different pins
|
||||||
|
|
||||||
|
import time
|
||||||
|
from machine import Pin
|
||||||
|
import rp2
|
||||||
|
|
||||||
|
|
||||||
|
@rp2.asm_pio()
|
||||||
|
def wait_pin_low():
|
||||||
|
wrap_target()
|
||||||
|
|
||||||
|
wait(0, pin, 0)
|
||||||
|
irq(block, rel(0))
|
||||||
|
wait(1, pin, 0)
|
||||||
|
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
|
||||||
|
def handler(sm):
|
||||||
|
# Print a (wrapping) timestamp, and the state machine object.
|
||||||
|
print(time.ticks_ms(), sm)
|
||||||
|
|
||||||
|
|
||||||
|
# Instantiate StateMachine(0) with wait_pin_low program on Pin(16).
|
||||||
|
pin16 = Pin(16, Pin.IN, Pin.PULL_UP)
|
||||||
|
sm0 = rp2.StateMachine(0, wait_pin_low, in_base=pin16)
|
||||||
|
sm0.irq(handler)
|
||||||
|
|
||||||
|
# Instantiate StateMachine(1) with wait_pin_low program on Pin(17).
|
||||||
|
pin17 = Pin(17, Pin.IN, Pin.PULL_UP)
|
||||||
|
sm1 = rp2.StateMachine(1, wait_pin_low, in_base=pin17)
|
||||||
|
sm1.irq(handler)
|
||||||
|
|
||||||
|
# Start the StateMachine's running.
|
||||||
|
sm0.active(1)
|
||||||
|
sm1.active(1)
|
||||||
|
|
||||||
|
# Now, when Pin(16) or Pin(17) is pulled low a message will be printed to the REPL.
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Example of using PIO for PWM, and fading the brightness of an LED
|
||||||
|
|
||||||
|
from machine import Pin
|
||||||
|
from rp2 import PIO, StateMachine, asm_pio
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
|
@asm_pio(sideset_init=PIO.OUT_LOW)
|
||||||
|
def pwm_prog():
|
||||||
|
pull(noblock) .side(0)
|
||||||
|
mov(x, osr) # Keep most recent pull data stashed in X, for recycling by noblock
|
||||||
|
mov(y, isr) # ISR must be preloaded with PWM count max
|
||||||
|
label("pwmloop")
|
||||||
|
jmp(x_not_y, "skip")
|
||||||
|
nop() .side(1)
|
||||||
|
label("skip")
|
||||||
|
jmp(y_dec, "pwmloop")
|
||||||
|
|
||||||
|
|
||||||
|
class PIOPWM:
|
||||||
|
def __init__(self, sm_id, pin, max_count, count_freq):
|
||||||
|
self._sm = StateMachine(sm_id, pwm_prog, freq=2 * count_freq, sideset_base=Pin(pin))
|
||||||
|
# Use exec() to load max count into ISR
|
||||||
|
self._sm.put(max_count)
|
||||||
|
self._sm.exec("pull()")
|
||||||
|
self._sm.exec("mov(isr, osr)")
|
||||||
|
self._sm.active(1)
|
||||||
|
self._max_count = max_count
|
||||||
|
|
||||||
|
def set(self, value):
|
||||||
|
# Minimum value is -1 (completely turn off), 0 actually still produces narrow pulse
|
||||||
|
value = max(value, -1)
|
||||||
|
value = min(value, self._max_count)
|
||||||
|
self._sm.put(value)
|
||||||
|
|
||||||
|
|
||||||
|
# Pin 25 is LED on Pico boards
|
||||||
|
pwm = PIOPWM(0, 25, max_count=(1 << 16) - 1, count_freq=10_000_000)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
for i in range(256):
|
||||||
|
pwm.set(i ** 2)
|
||||||
|
sleep(0.01)
|
|
@ -0,0 +1,48 @@
|
||||||
|
from machine import Pin
|
||||||
|
|
||||||
|
@rp2.asm_pio(out_shiftdir=0, autopull=True, pull_thresh=8, autopush=True, push_thresh=8, sideset_init=(rp2.PIO.OUT_LOW, rp2.PIO.OUT_HIGH), out_init=rp2.PIO.OUT_LOW)
|
||||||
|
def spi_cpha0():
|
||||||
|
# Note X must be preinitialised by setup code before first byte, we reload after sending each byte
|
||||||
|
# Would normally do this via exec() but in this case it's in the instruction memory and is only run once
|
||||||
|
set(x, 6)
|
||||||
|
# Actual program body follows
|
||||||
|
wrap_target()
|
||||||
|
pull(ifempty) .side(0x2) [1]
|
||||||
|
label("bitloop")
|
||||||
|
out(pins, 1) .side(0x0) [1]
|
||||||
|
in_(pins, 1) .side(0x1)
|
||||||
|
jmp(x_dec, "bitloop") .side(0x1)
|
||||||
|
|
||||||
|
out(pins, 1) .side(0x0)
|
||||||
|
set(x, 6) .side(0x0) # Note this could be replaced with mov x, y for programmable frame size
|
||||||
|
in_(pins, 1) .side(0x1)
|
||||||
|
jmp(not_osre, "bitloop") .side(0x1) # Fallthru if TXF empties
|
||||||
|
|
||||||
|
nop() .side(0x0) [1] # CSn back porch
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
|
||||||
|
class PIOSPI:
|
||||||
|
|
||||||
|
def __init__(self, sm_id, pin_mosi, pin_miso, pin_sck, cpha=False, cpol=False, freq=1000000):
|
||||||
|
assert(not(cpol or cpha))
|
||||||
|
self._sm = rp2.StateMachine(sm_id, spi_cpha0, freq=4*freq, sideset_base=Pin(pin_sck), out_base=Pin(pin_mosi), in_base=Pin(pin_sck))
|
||||||
|
self._sm.active(1)
|
||||||
|
|
||||||
|
# Note this code will die spectacularly cause we're not draining the RX FIFO
|
||||||
|
def write_blocking(wdata):
|
||||||
|
for b in wdata:
|
||||||
|
self._sm.put(b << 24)
|
||||||
|
|
||||||
|
def read_blocking(n):
|
||||||
|
data = []
|
||||||
|
for i in range(n):
|
||||||
|
data.append(self._sm.get() & 0xff)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def write_read_blocking(wdata):
|
||||||
|
rdata = []
|
||||||
|
for b in wdata:
|
||||||
|
self._sm.put(b << 24)
|
||||||
|
rdata.append(self._sm.get() & 0xff)
|
||||||
|
return rdata
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Example using PIO to create a UART TX interface
|
||||||
|
|
||||||
|
from machine import Pin
|
||||||
|
from rp2 import PIO, StateMachine, asm_pio
|
||||||
|
|
||||||
|
UART_BAUD = 115200
|
||||||
|
PIN_BASE = 10
|
||||||
|
NUM_UARTS = 8
|
||||||
|
|
||||||
|
|
||||||
|
@asm_pio(sideset_init=PIO.OUT_HIGH, out_init=PIO.OUT_HIGH, out_shiftdir=PIO.SHIFT_RIGHT)
|
||||||
|
def uart_tx():
|
||||||
|
# Block with TX deasserted until data available
|
||||||
|
pull()
|
||||||
|
# Initialise bit counter, assert start bit for 8 cycles
|
||||||
|
set(x, 7) .side(0) [7]
|
||||||
|
# Shift out 8 data bits, 8 execution cycles per bit
|
||||||
|
label("bitloop")
|
||||||
|
out(pins, 1) [6]
|
||||||
|
jmp(x_dec, "bitloop")
|
||||||
|
# Assert stop bit for 8 cycles total (incl 1 for pull())
|
||||||
|
nop() .side(1) [6]
|
||||||
|
|
||||||
|
|
||||||
|
# Now we add 8 UART TXs, on pins 10 to 17. Use the same baud rate for all of them.
|
||||||
|
uarts = []
|
||||||
|
for i in range(NUM_UARTS):
|
||||||
|
sm = StateMachine(
|
||||||
|
i, uart_tx, freq=8 * UART_BAUD, sideset_base=Pin(PIN_BASE + i), out_base=Pin(PIN_BASE + i)
|
||||||
|
)
|
||||||
|
sm.active(1)
|
||||||
|
uarts.append(sm)
|
||||||
|
|
||||||
|
# We can print characters from each UART by pushing them to the TX FIFO
|
||||||
|
def pio_uart_print(sm, s):
|
||||||
|
for c in s:
|
||||||
|
sm.put(ord(c))
|
||||||
|
|
||||||
|
|
||||||
|
# Print a different message from each UART
|
||||||
|
for i, u in enumerate(uarts):
|
||||||
|
pio_uart_print(u, "Hello from UART {}!\n".format(i))
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Example using PIO to drive a set of WS2812 LEDs.
|
||||||
|
|
||||||
|
import array, time
|
||||||
|
from machine import Pin
|
||||||
|
import rp2
|
||||||
|
|
||||||
|
# Configure the number of WS2812 LEDs.
|
||||||
|
NUM_LEDS = 8
|
||||||
|
|
||||||
|
|
||||||
|
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
|
||||||
|
def ws2812():
|
||||||
|
T1 = 2
|
||||||
|
T2 = 5
|
||||||
|
T3 = 3
|
||||||
|
wrap_target()
|
||||||
|
label("bitloop")
|
||||||
|
out(x, 1) .side(0) [T3 - 1]
|
||||||
|
jmp(not_x, "do_zero") .side(1) [T1 - 1]
|
||||||
|
jmp("bitloop") .side(1) [T2 - 1]
|
||||||
|
label("do_zero")
|
||||||
|
nop() .side(0) [T2 - 1]
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
|
||||||
|
# Create the StateMachine with the ws2812 program, outputting on Pin(22).
|
||||||
|
sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(22))
|
||||||
|
|
||||||
|
# Start the StateMachine, it will wait for data on its FIFO.
|
||||||
|
sm.active(1)
|
||||||
|
|
||||||
|
# Display a pattern on the LEDs via an array of LED RGB values.
|
||||||
|
ar = array.array("I", [0 for _ in range(NUM_LEDS)])
|
||||||
|
|
||||||
|
# Cycle colours.
|
||||||
|
for i in range(4 * NUM_LEDS):
|
||||||
|
for j in range(NUM_LEDS):
|
||||||
|
r = j * 100 // (NUM_LEDS - 1)
|
||||||
|
b = 100 - j * 100 // (NUM_LEDS - 1)
|
||||||
|
if j != i % NUM_LEDS:
|
||||||
|
r >>= 3
|
||||||
|
b >>= 3
|
||||||
|
ar[j] = r << 16 | b
|
||||||
|
sm.put(ar, 8)
|
||||||
|
time.sleep_ms(50)
|
||||||
|
|
||||||
|
# Fade out.
|
||||||
|
for i in range(24):
|
||||||
|
for j in range(NUM_LEDS):
|
||||||
|
ar[j] >>= 1
|
||||||
|
sm.put(ar, 8)
|
||||||
|
time.sleep_ms(50)
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Example using PWM to fade an LED.
|
||||||
|
|
||||||
|
import time
|
||||||
|
from machine import Pin, PWM
|
||||||
|
|
||||||
|
|
||||||
|
# Construct PWM object, with LED on Pin(25).
|
||||||
|
pwm = PWM(Pin(25))
|
||||||
|
|
||||||
|
# Set the PWM frequency.
|
||||||
|
pwm.freq(1000)
|
||||||
|
|
||||||
|
# Fade the LED in and out a few times.
|
||||||
|
duty = 0
|
||||||
|
direction = 1
|
||||||
|
for _ in range(8 * 256):
|
||||||
|
duty += direction
|
||||||
|
if duty > 255:
|
||||||
|
duty = 255
|
||||||
|
direction = -1
|
||||||
|
elif duty < 0:
|
||||||
|
duty = 0
|
||||||
|
direction = 1
|
||||||
|
pwm.duty_u16(duty * duty)
|
||||||
|
time.sleep(0.001)
|
|
@ -0,0 +1,11 @@
|
||||||
|
from machine import SPI
|
||||||
|
|
||||||
|
spi = SPI(0)
|
||||||
|
spi = SPI(0, 100_000)
|
||||||
|
spi = SPI(0, 100_000, polarity=1, phase=1)
|
||||||
|
|
||||||
|
spi.write('test')
|
||||||
|
spi.read(5)
|
||||||
|
|
||||||
|
buf = bytearray(3)
|
||||||
|
spi.write_readinto('out', buf)
|
Ładowanie…
Reference in New Issue