▌ 01 pyBoard system function
pyBoard provides pyb.micros() to return the time elapsed since the reset of the MCU, in us. Similar to millis(). Use elapsed_micros(start), elapsed_millis(start) to get the length of time elapsed. Using this function can be used for program control and measurement of function execution time.
1. Delay function
(1) Test time.sleep_us()
a. Measurement code
ddim = []
for i in range(100):
start = pyb.micros()
time.sleep_us(i)
delayus = pyb.elapsed_micros(start)
ddim.append(delayus)
b. Measurement results
From the measurement results, the delay generated by using time.sleep_us has a relatively constant constant of about 20us. The accuracy of the delay is still very reliable.
▲ delay_us测量曲线
(2) Measuring time.sleep_ms()
a.Measure one hundred times time.delay_ms(1)
The following shows the value corresponding to 100 times of delay_ms(1) measurement. It can be seen that the actual delay_ms() is actually more advanced than 1ms, and there is an error and sudden change of about 30usd.
▲ 测量结果time.delay_ms(1)
b. Measuring delay_ms(i)
Measure the increasing delay of delay_ms. It can be seen that the accuracy of the delay corresponding to the ms level is still very high.
▲ 测量 time.delay_ms(i);i=1,..100
(3) Measure pyb.delay
The function corresponding to pyb.delay is similar to the function of time.sleep_ms().
▲ pyb.delay()的延时测量
2. Random number
Use pyb.rng() to generate random numbers using MCU hardware.
▲ 第一次运行所产生的随机数
▲ 第二次运行所产生的随机数
3. DAC; ADC
from pyb import ADC,DAC,LED,Pin
dac = DAC(Pin('X5'))
adc = ADC(Pin('X1'))
adcdim = []
for i in range(256):
dac.write(i)
val = adc.read()
adcdim.append(val)
print(adcdim)
▲ 测量不同的DAC与ADC之间的关系
▌ 02 MicroPython grammar
In homemade pyBoard the I2C experiment, application MicroPython given some new MicroPython syntax. The following is a summary.
1. const
Used in MicroPython to define constant variables, which can be used for compiler optimization. According to the test, we can see that const must be integer. Therefore, in the following statement, PI is wrong.
from micropython import const
PI = const(3.1415) # Wrong: constant must be an integer
A = const(1)
print(type(PI))
print(type(A))
There will be an error corresponding to the constant amplitude. When A=2 in the following code, Exception will appear.
from micropython import const
A = const(1)
B = 3
A = 2
B = 4
2.framebuf
framebuf is used to give some memory buffers to the LCD display. See: framebuf — frame buffer manipulation — MicroPython 1.14 documentation .
Use frame.buffer to access the byte corresponding to framebuf.
3. Define tuples
The following code shows that the conditional amplitude process can be used in the process of defining tuples and lists.
b = 1
a = (0, 1 if b > 0 else 2,100)
print(a)
Execution result: (0, 1, 100)
4. Define the class
When defining a class, you can even run functions that will only exist in derived classes in the future in the base class. For example, in the following code, the self.showA() function is used in the base class , and this function is actually defined in its derived class classA. Compared with OO programming in C++, it needs to define virtual functions in the base class so that it can be overloaded by future derived classes.
class basetype():
def __init__(self, value):
self.value = value
def show(self, ):
print(self.value)
self.showA()
def getvalue(self, ):
return self.value
class classA(basetype):
def __init__(self, v):
super().__init__(v)
def show(self, b):
super().show()
print(b)
def showA(self, ):
print('Hello:%d'%super().getvalue())
a = classA(3)
a.show(4)
The result of running the above code:
3
Hello:3
4
▌Appendix
1.OLED SSD1306 code
(1) Main program code
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTOLED.PY -- by Dr. ZhuoQing 2021-03-20
#
# Note:
#============================================================
#------------------------------------------------------------
'''
实验名称:OLED显示屏(I2C总线)
版本:v1.0
日期:2019.4
作者:01Studio
'''
from machine import I2C,Pin #从machine模块导入I2C、Pin子模块
import SSD1306
i2c = I2C(sda=Pin("Y10"), scl=Pin("Y9")) #pyBoard I2C初始化:sda--> Y8, scl --> Y6
oled = SSD1306.SSD1306_I2C(128, 64, i2c, addr=0x3c) #OLED显示屏初始化:128*64分辨率,OLED的I2C地址是0x3c
oled.text("Hello World!", 0, 0) #写入第1行内容
oled.text("MicroPython", 0, 20) #写入第2行内容
oled.text("By 01Studio", 0, 50) #写入第3行内容
oled.show() #OLED执行显示
#------------------------------------------------------------
# END OF FILE : TESTOLED.PY
#============================================================
(2) The underlying code
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# SSD1306.PY -- by Dr. ZhuoQing 2021-03-20
#
# Note:
#============================================================
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
from micropython import const
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
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)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def init_display(self):
for cmd in (
SET_DISP | 0x00, # off
# address setting
SET_MEM_ADDR, 0x00, # horizontal
# resolution and layout
SET_DISP_START_LINE | 0x00,
SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
SET_MUX_RATIO, self.height - 1,
SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
SET_DISP_OFFSET, 0x00,
SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
# timing and driving scheme
SET_DISP_CLK_DIV, 0x80,
SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
SET_VCOM_DESEL, 0x30, # 0.83*Vcc
# display
SET_CONTRAST, 0xff, # maximum
SET_ENTIRE_ON, # output follows RAM contents
SET_NORM_INV, # not inverted
# charge pump
SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
SET_DISP | 0x01): # on
self.write_cmd(cmd)
self.fill(0)
self.show()
def poweroff(self):
self.write_cmd(SET_DISP | 0x00)
def poweron(self):
self.write_cmd(SET_DISP | 0x01)
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):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
class SSD1306_I2C(SSD1306):
def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
self.i2c = i2c
self.addr = addr
self.temp = bytearray(2)
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.temp[0] = self.addr << 1
self.temp[1] = 0x40 # Co=0, D/C#=1
self.i2c.start()
self.i2c.write(self.temp)
self.i2c.write(buf)
self.i2c.stop()
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
self.rate = 10 * 1024 * 1024
dc.init(dc.OUT, value=0)
res.init(res.OUT, value=0)
cs.init(cs.OUT, value=1)
self.spi = spi
self.dc = dc
self.res = res
self.cs = cs
import time
self.res(1)
time.sleep_ms(1)
self.res(0)
time.sleep_ms(10)
self.res(1)
super().__init__(width, height, external_vcc)
def write_cmd(self, cmd):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(0)
self.cs(0)
self.spi.write(bytearray([cmd]))
self.cs(1)
def write_data(self, buf):
self.spi.init(baudrate=self.rate, polarity=0, phase=0)
self.cs(1)
self.dc(1)
self.cs(0)
self.spi.write(buf)
self.cs(1)
#------------------------------------------------------------
# END OF FILE : SSD1306.PY
#============================================================