TPYBoard Document

TPYBoard快速参考手册

下面是tPYBv10x的针脚图。你也可以查看其他版本的tpyboard的针脚图:.

PYBv1.0 pinout

开发板基础控制

参考 pyb.

import pyb

pyb.repl_uart(pyb.UART(1, 9600)) # duplicate REPL on UART(1)
pyb.wfi() # pause CPU, waiting for interrupt
pyb.freq() # get CPU and bus frequencies
pyb.freq(60000000) # set CPU freq to 60MHz
pyb.stop() # stop CPU, waiting for external interrupt

延时和定时

使用 time 模块:

import time

time.sleep(1)           # sleep for 1 second
time.sleep_ms(500)      # sleep for 500 milliseconds
time.sleep_us(10)       # sleep for 10 microseconds
start = time.ticks_ms() # get value of millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference

LED发光二极管

参考 pyb.LED.

from pyb import LED

led = LED(1) # red led
led.toggle()
led.on()
led.off()

引脚和通用输入输出接口

参考 pyb.Pin.

from pyb import Pin

p_out = Pin('X1', Pin.OUT_PP)
p_out.high()
p_out.low()

p_in = Pin('X2', Pin.IN, Pin.PULL_UP)
p_in.value() # get value, 0 or 1

伺服控制

参考 pyb.Servo.

from pyb import Servo

s1 = Servo(1) # servo on position 1 (X1, VIN, GND)
s1.angle(45) # move to 45 degrees
s1.angle(-60, 1500) # move to -60 degrees in 1500ms
s1.speed(50) # for continuous rotation servos

外部中断

参考 pyb.ExtInt.

from pyb import Pin, ExtInt

callback = lambda e: print("intr")
ext = ExtInt(Pin('Y1'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback)

定时器

参考 pyb.Timer.

from pyb import Timer

tim = Timer(1, freq=1000)
tim.counter() # get counter value
tim.freq(0.5) # 0.5 Hz
tim.callback(lambda t: pyb.LED(1).toggle())

脉宽调制(PWM)

参考 pyb.Pinpyb.Timer.

from pyb import Pin, Timer

p = Pin('X1') # X1 has TIM2, CH1
tim = Timer(2, freq=1000)
ch = tim.channel(1, Timer.PWM, pin=p)
ch.pulse_width_percent(50)

模数转换(ADC)

参考 pyb.Pinpyb.ADC.

from pyb import Pin, ADC

adc = ADC(Pin('X19'))
adc.read() # read value, 0-4095

数模转换(DAC)

参考 pyb.Pinpyb.DAC.

from pyb import Pin, DAC

dac = DAC(Pin('X5'))
dac.write(120) # output between 0 and 255

UART(串行总线)

参考 pyb.UART.

from pyb import UART

uart = UART(1, 9600)
uart.write('hello')
uart.read(5) # read up to 5 bytes

SPI总线

参考 pyb.SPI.

from pyb import SPI

spi = SPI(1, SPI.MASTER, baudrate=200000, polarity=1, phase=0)
spi.send('hello')
spi.recv(5) # receive 5 bytes on the bus
spi.send_recv('hello') # send and receive 5 bytes

I2C总线

参考 pyb.I2C.

from pyb import I2C

i2c = I2C(1, I2C.MASTER, baudrate=100000)
i2c.scan() # returns list of slave addresses
i2c.send('hello', 0x42) # send 5 bytes to slave with address 0x42
i2c.recv(5, 0x42) # receive 5 bytes from slave
i2c.mem_read(2, 0x42, 0x10) # read 2 bytes from slave 0x42, slave memory 0x10
i2c.mem_write('xy', 0x42, 0x10) # write 2 bytes to slave 0x42, slave memory 0x10

TPYBoard概述

本地文件系统和SD卡

TPYBoard有小型内部文件系统,存储在微控制器的闪存,路径是 /flash。 如果将SD卡插入卡槽,路径是 /sd

TPYBoard需要选择一个文件系统来引导,优先使用 /sd,如果没有SD卡,它会使用内部文件系统 /flash``做为引导文件系统。 也可以根据需要在SD卡上创建空文件/flash/SKIPSD``,TPYBoard将会始终使用内部文件系统启动(在这种情况下你可以使用 ``os.mount``来调用SD卡的应用程序)。

(注意:在一些旧版本上, /flash 也称 0://sd 也称 1:/).

启动文件系统主要做两件事情:检测是否通过usb线正确连接pc,再就是搜索查找 boot.pymain.py 文件。

内部文件系统将作为你PC的一个usb驱动器,可直接将文件保存到驱动器,可直接编辑 boot.pymain.py

记着重置TPYBoard前要弹出(linux要unmount) usb驱动器

启动模式

正常通电或者按复位键,TPYBoard会进入标准模式: 首先执行 boot.py 文件,然后配置usb,再运行 main.py 文件。

当TPYBoard启动时,通过按住用户开关,您可以重写此启动顺序。 按住用户开关和按复位键,然后继续按用户键,LED将以二进制计数。 当灯的状态到了你想要的模式,你就可以松开用户键,选定模式的LED将迅速闪烁,TPYBoard将启动。

模式是:

  1. 绿灯, 标准启动: 运行 boot.py 并调用 main.py
  2. 黄灯, 安全启动: 开机,不运行任何脚本。
  3. 绿灯与黄灯同时亮, 文件系统重置:将闪存文件系统重置为出厂状态,然后在安全模式下启动。

如果文件系统损坏,请使用启动模式3(文件系统重置)来修复。 重置系统后,使用损坏前可运行版本的程序,插入您的计算机不运行,你可以尝试将TPYBoard直接插到usb充电器上,或其他USB电源没有数据连接。

错误:闪烁LED

目前你可能会看到有2种错误: 1。如果红色和绿色LED交替闪烁,则为Python脚本(例如,main.py )有错误。使用REPL来调试。 2。如果所有4个LED循环和关闭缓慢,然后有一个硬故障。这不能恢复,你需要做一个硬复位。

MicroPython 教程

本教程的目的是让我们开始您的TPYBoard的使用。 我们需要一块TPYBoard和一根USB线并连接到电脑上。 如果你是第一次,建议按照教程让我们开始编程吧。

TPYBoard简介

为了最大使用好你的TPYBoard 开发板,工作前的一些注意事项是需要知道的。

小心你的TPYBoard开发板

因为 TPYBoard 开发板没有防护罩的缘故,故需要注意的一些事项:

  • 轻力插拔 USB 线。尽管 USB 接头是焊接在电路板上且十分牢固的,一旦有所损坏将非常难以修理。
  • 静电能够损坏开发板上的元器件。如果你在你的工作范围积累了许多的静电(例如干冷的环境下),需要额外小心注意不要击穿开发板。

如果开发板是装在静电袋里边的,这个袋子将是保存和携带该开发板的最好的抗静电工具(其由传导性泡沫的塑料组成)。

如果在硬件层面你能够注意到这些事项,开发板使用起来不会有大问题。软件层面造成开发板损坏几乎是不可能的,所以大可随心所欲敲写你的代码。 如果文件系统损坏,可以在接下来的内容中了解如何修复它。最糟糕的情况乃是需要重刷新MicroPython固件,但这可以轻易地通过一条USB线实现。

TPYBoard的布局

USB 接头在板子的右上方,SD 卡槽在其左上方。 有4个LED在SD插槽的下方。从LED1到LED4颜色分别是:红色,黄色,绿色,蓝色。 有2个开关:RST是复位开关,USR是用户开关。

插入式供电

TPYBoard 是通过 USB 线供电的。通过USB线连接PC是唯一适合的方法。如果连接成功,4个LED依次流水灯闪烁。

由外部电源供电

pyboard可以通过电池或外部电源供电。

连接电源时需要特别注意其正极负极,TPYBoard 开发板上没有极性保护,所以任何东西连接其正极时都要非常小心。

输入电压应该在3.6V和10V之间。

运行第一个脚本

从这篇教程开始将动手在 TPYboard 板上运行 Python 脚本,毕竟这是我们的目标!

连接开发板

通过 USB 线连接你的 PC 机(windows,mac,linux皆可)。 你不可能搞错因为仅有这么一种连接方式。

当连接成功后开发板将上电和进入开机程序,绿色的 LED 灯应该在半秒或更少的时间内亮起,当其熄灭时意味着开机程序已完成。

安装USB驱动

你的电脑现在应该认识到TPYboard开发板。这也取决于你的电脑类型。 关于接下来会发生什么:

  • Windows: 开发板将作为可移动磁盘出现。Window 将自动弹出窗口界面,或者你需要使用资源管理器自己寻找进入。
Windows系统同时会将开发板视为串口驱动,且设备将会自动连接。 如果是这样,取消这样的连接,我们将在下一篇教程中展示串口驱动如何工作。
  • Mac: 你的TPYboard开发板将作为一个可移动磁盘出现在桌面。 其可能为“NONAME”,请点击打开里边的文件夹。
  • Linux: 开发版将作为可移动的多媒体设备出现。

在 Ubuntu 下其将自动挂载并弹出开发板的文件夹。在其他的 Linux 系统下,开发板自动挂载或者需要手动实现。 在命令行下敲入 lsblk 参看连接设备,然后敲入 mount /dev/sdb1(用对应的设备名替换sbd1)。 或许你需要 boot 权限实现这一过程。 至此开发板以移动磁盘的形式存在了,且有一个开发板驱动的窗口(或者命令行)显示出来。

你所见到的设备是由开发板里边的 /flash实现的,其由以下四个文件关联组成:

  • boot.py – 这个脚本执行时TPYboard开发板启动。
    它设置了开发板的多个选项参数。
  • main.py – 这是包含Python程序的主要脚本。
    在 boot.py 运行后被执行
  • README.txt – 包含开启Python的必要基础信息。
  • pybcdc.inf – 这是一个Windows驱动文件,配置串行USB装置,

之后的教程中有更多的介绍。

编辑mian.py

现在我们可以开始编写自己的 python 程序了。 用文本编辑器打开 main.py 文件。Windows 环境下可以使用记事本或者其他编辑器。 Mac 和 linux 下使用你喜欢的文本编辑器即可。 打开文件后你将看到如下的一行:

# main.py – put your code here!

该行以 # 字符开始,意味着只是一个注释。 这样的命令行不会被执行,仅为代码提供信息用在这个 main.py 加多两行,如下所示:

# main.py – put your code here! import pyb pyb.LED(4).on()

第一行表明使用 pyb 模块,这个模块包含了控制开发板的所有函数和类。

第二行打开了蓝色的 LED:先是在 pyb 模块中使用了 LED 类,创建了 LED 4 的实例,然后将其点亮。

重置开发板

为运行这个小小的脚本,我们需要保存并关闭 main.py文件, 然后在 USB 设备中退出(或者卸载),就像退出移动磁盘一样。

当设备安全退出或解除挂载后就来到了实现功能的地方: 按下板上的复位键将重置开发板并运行写好的程序。 RST复位按键位于右边,USB 接口下。

当按下复位键后绿色的 LED 将快速闪烁,然后蓝色的 LED 保持长亮。

至此编写和运行第一个 MicroPython 程序就完成了,加油!You Can Do It !

获取MicroPython REPL提示

REPL(交互式解释器)全称是 Read Evaluate Print Loop,TPYBoard 允许用户和 MicorPython 的交互式连接。 使用repl是迄今为止来测试你的代码和运行命令的最简单的方法。 使用 REPL 可以往 “main.py” 中增添脚本内容。

使用 REPL 需要用 USB 串口连接 TPYBoard。如何做到这一点取决于开发环境。

Windows

你需要安装TPYBoard驱动使用串行USB设备。 该驱动在TPYBoard的USB闪存驱动中,名为 “pybcdc.inf”。

安装该驱动用户需要在电脑的设备管理器列表中中找到 TPYBoard 设备(尚未工作的设备,旁边应该有黄色的警告图标) 在该设备上鼠标右键,选择工具(properties)然后安装驱动。 你需要手动选择选项找到驱动(不要通过 Windows 自动升级的方式),导航到TPYBoard的USB驱动器并安装。 安装完毕后回到设备管理器找到安装后的TPYBoard,查看其使用了那个端口(例如 COM4)。 更多内容可以查看 `Windows TPYBoard指南<http://micropython.org/resources/Micro-Python-Windows-setup.pdf>`_. 如果安装驱动程序有问题,请咨询本指南。

您现在需要运行您的终端程序。 你可以使用超级终端,如果你没有安装,或者下载免费程序putty: putty.exe. 串口程序通过上一步找到的 COM 端口运行。 对于PuTTY , 点击其左边界面的“Session”,点击右边的“Serial”按钮 然后在串口行中选择COM端口(例如COM4),最后,点击“Open”按钮。

Mac OS X

打开一个终端并运行:

“screen /dev/tty.usbmodem”

当想要终止退出界面时,使用快捷键 CTPL-A CTRL-

Linux

打开终端并运行:

“screen /dev/ttyACM0”

你也可以尝试 piocom 或者 minicom 的连接方式而非终端界面。 你需要使用 /dev/ttyACM1或者更高的ttyACM数字。 而且,用户需要给自己正确的权限连接该设备(例如组 uucp 或者 dialout,或者权限 sudo)

使用交互式选择器

现在让我们试着在TPYBoard直接运行一些micropython代码。

打开串口程序(例如Putty,终端界面,piocom等等)可以看到一个光标闪烁着的空屏幕。 按下任意按键进入MicroPython 解释器,显示为 “>>>“。可以通过下面的程序确认是否进入:

“ >>> print(“hello pyboard!”)“ “hello pyboard!“

在上面的例程中用户不需要敲入 >>> 字符,而是应该在解释器中写入内容。 在最后,一旦输入 ``print(“hello pyboard!”)``文本并按下回车键,输出结果将在屏幕上如上呈现。

如果你已经知道一些Python,你可以尝试一些基本的命令在这里。

如果打印不成功,尝试下边的硬件复位或者软件复位的方法。可以继续打入其他指令如:

“>>> pyb.LED(1).on()“ “>>> pyb.LED(2).on()“ “>>> 1 + 2“ “3“ “>>> 1 / 2“ “0.5“ “>>> 20 * ‘py’“ “’pypypypypypypypypypypypypypypypypypypypy’“

复位

如果出错可以通过两种方式复位开发板。 其一是在 MicroPython 解释器中打入 CTRL-D 进行软件复位。出现的消息如下所示:

“>>>“ “PYB: sync filesystems“ “PYB: soft reboot“ “Micro Python v1.0 on 2014-05-03; PYBv1.0 with STM32F405RG“ “Type “help()” for more information.“ “>>>“

如果这是行不通的,你可以执行一个硬复位(关闭和再次打开)按RST按键硬件复位(开发板上USB接线下的黑色按键)。 这将断开与 TPYBoard的任何端口连接 如果你想准备进行硬件复位,建议你先关闭串口程序和与退出/卸载TPYBoard设备。

点亮LED和基本Python概念

对TPYboard 板上最容易实现的事情莫过于点亮板上附带的小灯,连接开发板,按照上篇教程中提到的登录方法, 就可与在解释器中开始点亮 LED 灯了,代码如下:

>>> myled = pyb.LED(1)
>>> myled.on()
>>> myled.off()

这些命令将控制 LED 的亮和灭。

这种方式不错,不过我们将尝试让其更智能化。在你擅长的文本编辑器里打开 TPYboard 里边的 MAIN.PY 文件,写入或粘贴如下的代码。

如果你是 python 新手,那么希望从现在开始你能对 python 有正确的认识。

led = pyb.LED(2) while True:

led.toggle() pyb.delay(1000)

当你保存了文件后,TPYboard 上的红色 LED 将在约一秒后亮起。为运行脚本程序,先以 CTRL -D 进行软件复位。TPYboard 将被重启且能够看到绿色的 LED 持续闪烁。 至此先恭喜你在“the army of evil robot”的路途上迈出了重要的一步!当需要关闭闪灯时,直接在终端界面按下 CLRT -C 即可。

那么这些代码做了什么呢?首先我们需要引用一些术语。Python 是一门面向对象语言(object-oriented), Python中几乎所有的东西都是一个类(class),当你创建一个类的实例时,你得到一个对象(object)。类有与它们相关的方法(methods,也称为成员函数)。方法用于与对象进行交互或控制。

程序的第一行我们通过实例化了LED对象并命名为led, 当我们创建对象时, 它需要一个单一的参数,必须介于1和4之间,与开发板上四颗LED相呼应。 pyb.LED这个类有三个我们使用的重要成员函数:on( ), off( ) 以及 toggle( )。 另一个使用到的函数pyb.delay( ) 仅是一个简单的毫秒级别的延时。一旦我们创建了 LED 对象,while True 这个声明将创建一个无限循环等待一秒时间的 led亮灭翻转。

练习:尝试改变切换LED和打开其他LED之间的时间。

练习:直接连接到TPYboard,创建一个pyb.LED对象,并使用on()方法打开它。

在 TPYboard 板上的Disco

到目前我们使用了板上的单颗 LED 灯而实际上总共有四颗可供使用。我们可以为每颗 LED 灯创建一个对象并分别控制它们。我们将声明一个便于理解的列表(list)形式:

leds = [pyb.LED(i) for i in range(1,5)]

如果没有用 1,2,3,4 的数字作为 pyb.LED( ) 的形参,我们将会得到错误的信息。 接下来我们将添加每个 LED 亮灭的无限循环:

n = 0 while True:

n = (n + 1) % 4 leds[n].toggle() pyb.delay(50)

在这里,n 代表了当前的 LED 且每次循环执行后我们可以得到下一个 n 的值(求余符号%保证了 n 的值在0和3之间)。 然后我们就可以控制第 n 颗 led 灯的翻转亮灭了。执行该程序将可见一排的 led 同时亮和灭。

您可能会发现的一个问题是,如果您停止脚本,然后重新启动, 开发板上的 LED 灯将从之前运行的状态突然进入到我们精心设计的Disco。 可以通过在脚本初始化时关闭所有的 LED 灯并使用 try/finally 块的方式解决这个问题。 当打入 CTRL-C,MicroPython 将产生一个 VCP 中断异常。 异常通常意味着某事出了问题,所以你可以通过 try:command 指令“抓取”一个异常。 这种情况属于用户打断了脚本的运行,所以我们不需要抓取错误而是简单告诉 MicroPython 当我们退出时要做些什么。 最终的程序块如下所示,且我们确保了所有的 LED灯 熄灭。完整的代码如下所示:

leds = [pyb.LED(i) for i in range(1,5)] for l in leds:

l.off()

n = 0 try:

while True:
n = (n + 1) % 4 leds[n].toggle() pyb.delay(50)
finally:
for l in leds:
l.off()

特殊的第四颗灯

蓝色的LED 灯比较特别。可以在让其亮灭的同时通过 iniensity( ) 的方法控制其亮度。 其亮度值在 0 到 255 的值间决定。以下的脚本实现了蓝色的LED循环渐亮然后熄灭的功能。

led = pyb.LED(4) intensity = 0 while True:

intensity = (intensity + 1) % 255 led.intensity(intensity) pyb.delay(20)

你可以对其他LED灯调用 instensity( ) 的方法,不过其只能被熄灭或被点亮。0 值将使之熄灭而最多到达255的其他值只能点亮该LED。

开关,回调和中断

TPYBoard 开发板上有两个小按键,分别标示为 USR 和 RST。 RST 按键属于复位按键,如果按下的话将重新擦写重启开发板,相当于将开发板断电再重启。

USR按键供用户使用,且其可以通过声明一个按键对象(Switch object)进行控制。 创建开关对象的方法如下:

“>>> sw = pyb.Switch()“

如果你得到一个错误的名字PYB不存在,请记住,您可能需要键入import pyb

利用按键对象可以得到按键的状态:

“>>> sw()“ “False“

如果按键被按下将打印 True,松开则打印 False。可以尝试运行上述指令时按下 USR 按键。

按键回调函数

尽管按键算是一种简单的构造,但它具有明显的优势特征“sw.callback( )“ 函数。 该回调函数将在按键按下时创建一些东西,且使用了一个中断。 在理解中断工作机制前最好的是用一个例子进行描述。尝试在解释器里边运行如下的代码:

“>>> sw.callback(lambda:print(‘press!’))“

这个例子要求每次按下按键时都能打印 press! 字符。 先进行尝试:按下USR按键并观测你 PC 上的输出。 注意该打印将打断目前你在TPYBorad 板上的任何程序,且其属于一种异步中断例程。

尝试如下另一个例子:

“>>> sw.callback(lambda:pyb.LED(1).toggle())“

这将在每次按键按下时翻转 LED 的亮灭状态,且它能打断当前其他代码的运行。

若要关闭开关回调,只需将回调函数的参数设置为 None 即可:

“>>> sw.callback(None)“

你可以传递不带参数的函数作为参数给按键回调函数使用。 我们可以充分利用 Python 中的 lamba 声明特性,我们可以用下面的形式替代:

“>>> def f():“ “... pyb.LED(1).toggle()“ “...“ “>>> sw.callback(f)“

这将创建一个名为“f”的函数,并将其传递给按键回调函数。 当 lamba 比较复杂时你可以尝试使用这种方法。

注意回调函数一定不能含有任何分配内存的定义(比如不能声明创建列表和元组)。 回调函数应该相对简单。 如果你需要做一个列表,事先作出它,并存储在全局变量(或定义为局部变量并对其进行封装)。 如果需要做一个多次复杂的计算,那么可以用按键回调设置一个标志供其他代码响应使用。

中断的原理细节

让我们现在来看看按键回调函数发生时的细节。 当你调用了含有 sw.callback( )的函数时,按键将在其连接引脚产生一个边沿触发(下降沿)外部中断。 这意味着芯片将监听该引脚的任何状态变换,且会发生如下错误:

  1. 当开关按下时引脚将发生改变(电平从低到高),芯片处理器将记录这种变化。
  2. 处理器完成当前机器指令的执行,退出执行并保存其当前状态(将寄存器的内容推入栈中)。这将停止当前运行的任何代码,例如正在运行的Python脚本。
  3. 芯片开始执行与按键相关的特定外部中断触发处理,该处理指向你在 sw.callback( )函数中指定的函数功能并执行。
  4. 您的回调函数被执行,直到它完成,返回控制中断处理。
  5. 按键中断处理程序返回,而芯片处理器是确认记录该中断已处理。
  6. 芯片调回步骤 2 的状态;
  7. 继续执行开始时的代码,除了短暂的暂停,此代码好像没有被他中断过。

当同一时间多个中断同时发生上述的过程时将会复杂得多。 这种情况下拥有最高优先级别的中断将被首先执行,其他的中断按各自的优先级数序执行。 开关中断设置在最低优先级。

进一步参考

进一步使用硬件中断的信息可参考文档:writing interrupt handlers <isr_rules>.

加速度传感器

通过本篇教程你将学到如何读取加速度计的信号并能通过左右倾斜开发板改变LED灯的状态。

加速度传感器的使用

开发板上有一个能够检测角度和运动状态的加速度传感器(小封装小模块)。 X ,Y, Z 轴上各有不同的传感器。 通过创建一个 pyb.Accel( ) 对象和调用 x( ) 方法可以获取加速度传感器的数值。

>>> accel = pyb.Accel()
>>> accel.x()
7

上述例子返回-30 到 30 之间的带符号的角度值。 注意其测量结果不算精准,这意味着即使保持 TPYboard 的完全静止不动依旧会有测量数据出现。 因此,x( ) 方法得到的数据不能当成精确值使用,而应视其为一定精度的范围值。

倾斜开发板,通过加速度传感器点亮 LED 灯的 代码如下所示:

accel = pyb.Accel() light = pyb.LED(3) SENSITIVITY = 3

while True:

x = accel.x() if abs(x) > SENSITIVITY:

light.on()
else:
light.off()

pyb.delay(100)

上述代码中我们创建了 Accel 和 LED 两个对象,然后直接获得加速度传感器在 X 方向上的数值。 如果 x 值的大小比定值 SENSITIVITY 大,LED 灯将被点亮,否则将被熄灭。 循环中调用了 pyb.delay( ) 函数,否则当 x 的值接近 SENSITIVITY 时LED灯将闪烁得十分频繁。 尝试在 TPYboard 开发板上运行该程序,直到左右倾斜开发板使 LED 灯亮或灭。

**练习:改变上述脚本使得倾斜的角度越大蓝色的LED灯越亮。
提示: 你需要重新调整数值,其大小在 0 到 255 之间**

制作水平仪

上面的例子只使用了 x 方向上的角度值,然而我们可以通过 y( ) 函数的值和更多的LED灯将 TPYboard 开发板打造成一个水平仪。

xlights = (pyb.LED(2), pyb.LED(3))
ylights = (pyb.LED(1), pyb.LED(4))

accel = pyb.Accel()
SENSITIVITY = 3

while True:
    x = accel.x()
    if x > SENSITIVITY:
        xlights[0].on()
        xlights[1].off()
    elif x < -SENSITIVITY:
        xlights[1].on()
        xlights[0].off()
    else:
        xlights[0].off()
        xlights[1].off()

    y = accel.y()
    if y > SENSITIVITY:
        ylights[0].on()
        ylights[1].off()
    elif y < -SENSITIVITY:
        ylights[1].on()
        ylights[0].off()
    else:
        ylights[0].off()
        ylights[1].off()

    pyb.delay(100)

一开始我们创建了 一个包含 x 和 y 方向上的 LED 对象的元组。 python 语言中元组是不可更改的对象,这意味着一旦创建后就不能被改变。 然后我们像上个例程开始的那样,但当 x 的值为正或为负时分别点亮不同的 LED 灯。 y 方向上也是同样的原理。 这看起来不算很复杂但确实实现了水平仪的功能。 在你的TPYboard 板上运行这个程序,现象为:向不同方向倾斜开发板点亮不同的 LED 灯。

安全模式和恢复出厂设置

当你的TPYBoard 板出了毛病尤其是在编错程序的时候不用害怕。

首先要做的事情是进入安全模式:这将临时跳过“ boot.py“ 和 “main.py“ 的执行,直接获取默认的 USB 设定。

如果你有文件系统的问题,你可以做一个恢复出厂设置,它可以将文件系统恢复到原来的状态。

安全模式

按如下步骤操作可以进入安全模式:

  1. 通过USB线连接TPYBoard板并提供电源;
  2. 按下USR;
  3. 按住USR的同时,按下和松开RST开关;
  4. 然后LED灯将持续绿色循环到黄色+绿色+黄色循环再回来;
  5. 保持按住USR直到只有黄色LED灯点亮,然后就可以松开USR;
  6. 黄色LED灯将迅速闪光4次,然后熄灭;
  7. 现在你就进入了安全模式;

在安全模式下,“boot.py“和“main.py“文件将不被执行,因此TPYBoard板将按照默认的设置启动。 这意味着现在你可以通过 USB 驱动连接文件系统并对“boot.py“和“main.py“文件进行编辑以解决问题。 进入安全模式是暂时的,在TPYBoard文件中不作任何更改。

恢复出厂设置文件系统

如果你的TPYBoard板的文件系统遭到损坏(例如忘记退出或卸载使用),或者你在 “boot.py“和“main.py“文件中编写了无法退出的代码,那么你可以重置文件系统。 重置文件系统将删除开发板里边存储的所有文件(不包括SD卡),然后将 “boot.py“, “README.TXT“, 和 “pybcd.inf“ 文件恢复为其初始状态。

恢复出厂设置的方法与进入安全模式的方法相似,除了松开USR时是绿色和黄色的LED灯一起亮起:

  1. 通过USB线连接TPYBoard板并提供电源;
  2. 按下USR按键;
  3. 按住USR的同时按下和松开RST开关;
  4. 然后LED灯将闪烁绿色循环到黄色+绿色+黄色,依次循环;
  5. 保持按住USR直到绿色和黄色指示灯点亮,然后就可放开USR开关;
  6. 黄色和绿色LED灯将迅速闪光4次,然后熄灭
  7. 红色的LED灯亮起(目前红色绿色黄色的LED灯都亮);
  8. TPYBoard板现在重置了文件系统(将花费几秒的时间);

9. 所有的LED灯一起熄灭; 10.现在你重置了文件系统,并进入了安全模式; 11.按下RST按键后释放将自行启动;

使TPYboard作为USB鼠标

该 TPYboard 是一个USB设备,可配置为用作鼠标而不是默认的USB闪存驱动器。

为此,我们必须首先编辑boot.py文件以更改USB配置。 如果你还没有触到你的boot.py文件,那么它将会是这样的:

# boot.py – run on boot-up # can run arbitrary Python, but best to keep it minimal

import pyb #pyb.main(‘main.py’) # main script to run after this one #pyb.usb_mode(‘VCP+MSC’) # act as a serial and a storage device #pyb.usb_mode(‘VCP+HID’) # act as a serial device and a mouse

启用鼠标模式,请取消注释文件的最后一行,使其看起来像:

pyb.usb_mode(‘VCP+HID’) # act as a serial device and a mouse

如果您已经更改了boot.py文件,则需要使用的最小代码是:

import pyb pyb.usb_mode(‘VCP+HID’)

这告诉TPYboard将其自身配置为启动时的VCP(虚拟COM端口,即串行端口)和HID(人机界面设备,在我们的例子中是鼠标)USB设备。

弹出/卸载TPYboard驱动器,并使用RST开关重新设置。您的电脑现在应该检测到TPYboard为鼠标!

手动发送鼠标事件

为了让鼠标做任何事情,我们需要将鼠标事件发送到PC。 我们将首先使用REPL提示手动进行此操作。使用串行程序连接到您的TPYboard,并键入以下内容:

>>> hid = pyb.USB_HID()
>>> hid.send((0, 10, 0, 0))

你的鼠标应该向右移动10像素!在上面的命令中,您将发送4条信息:按钮状态,x,y和滚动。 数字10告诉PC机鼠标在x方向移动10个像素。

让我们让鼠标左右摆动:

>>> import math
>>> def osc(n, d):
...   for i in range(n):
...     hid.send((0, int(20 * math.sin(i / 10)), 0, 0))
...     pyb.delay(d)
...
>>> osc(100, 50)

函数的第一个参数osc是要发送的鼠标事件的数量,第二个参数是事件之间的延迟(以毫秒为单位)。 尝试玩不同的数字。

练习:让鼠标绕成一圈。

用加速度计制作鼠标

现在让使用加速度计的鼠标移动基于TPYboard的角度。 可以直接在REPL提示符下键入以下代码,也可以将其放入main.py文件中。 在这里,我们会加入main.py,因为要做到这一点,我们将学习如何进入安全模式。

目前,TPYboard充当串行USB设备和HID(鼠标)。所以您无法访问main.py文件系统来编辑文件。

您也无法编辑您boot.py的HID模式,并使用USB驱动器恢复正常模式...

为了解决这个问题,我们需要进入安全模式。这在[安全模式教程](tut-reset)中有描述,但是我们在此重复说明:

  1. 按住USR开关。
  2. 同时按住USR,按下并释放RST开关。
  3. 然后LED将循环绿色至橙色至绿色+橙色并再次返回。
  4. 继续按住USR,直到只有橙色LED点亮,然后放开USR开关。
  5. 橙色LED应闪烁4次,然后关闭。
  6. 你现在处于安全模式。

在安全模式下,boot.py并且main.py文件不被执行,因此TPYboard启动时使用默认设置。 这意味着您现在可以访问文件系统(USB驱动器应该出现),您可以编辑main.py。(boot.py按原样离开,因为我们完成编辑后仍然要回到HID模式main.py。)

在main.py下面的代码中:

import pyb

switch = pyb.Switch() accel = pyb.Accel() hid = pyb.USB_HID()

while not switch():
hid.send((0, accel.x(), accel.y(), 0)) pyb.delay(20)

保存文件,弹出/卸载您的TPYboard驱动器,并使用RST开关重置它。 它现在应该用作鼠标,并且板的角度将移动鼠标。尝试一下,看看是否可以让鼠标静止不动!

按USR开关停止鼠标移动。

你会注意到y轴是倒置的。这很容易解决:只需在上方的y坐标前放一个减号hid.send()。

恢复您的TPYboard正常

如果你按原样离开你的TPYboard,每当你插入它,它就会像鼠标一样表现出来。 你可能想把它改成正常。要做到这一点,您需要先进入安全模式(见上文),然后编辑boot.py文件。 在boot.py文件中,注释掉(放在#前面)的行与 VCP+HID设置,所以它看起来像:

#pyb.usb_mode(‘VCP+HID’) # act as a serial device and a mouse

保存文件,弹出/卸载驱动器,并重置TPYboard。现在回到正常的工作模式。

定时器

该板具有14个定时器,每个定时器由用户定义的频率运行的独立计数器组成。 它们可以设置为以特定间隔运行功能。 14个定时器编号为1到14,但3个保留供内部使用,5和6用于伺服和ADC / DAC控制。 如果可以,避免使用这些计时器。

让我们创建一个定时器对象:

>>> tim = pyb.Timer(4)

现在我们来看看刚刚创建的内容:

>>> tim
Timer(4)

这个TPYboard告诉我们tim是附加到定时器4,但它还没有初始化。 所以让我们初始化它以10Hz(即每秒10次)触发:

>>> tim.init(freq=10)

现在,它已初始化,我们可以看到有关定时器的一些信息:

>>> tim
Timer(4, prescaler=624, period=13439, mode=UP, div=1)

该信息意味着该计时器设置为在外设运行时钟速度除以624 + 1, 它将从0到13439计数,此时触发中断,然后再次从0开始计数。 设置使定时器触发为10 Hz:定时器的源频率为84MHz(由运行发现tim.source_freq()), 所以我们得到84MHz / 625/13440 = 10Hz。

定时器计数器

那么我们可以用定时器做什么呢?最基本的是获取其计数器的当前值:

>>> tim.counter()
21504

此计数器将不断变化,并计数。

定时器回调

接下来我们可以注册一个回调函数,使定时器在触发时执行(参见[switch tutorial](tut-switch)来介绍回调函数):

>>> tim.callback(lambda t:pyb.LED(1).toggle())

这应该立即开始红色LED闪烁。 它将以5 Hz闪烁(1闪光灯需要2个切换,因此10 Hz的切换使其以5 Hz闪烁)。 您可以通过重新初始化定时器来更改频率:

>>> tim.init(freq=20)

您可以通过传递值来禁用回调:

>>> tim.callback(None)

传递给回调的函数必须采用1个参数,即触发的定时器对象。这允许您从回调函数内控制定时器。

我们可以创建2个计时器并独立运行:

>>> tim4 = pyb.Timer(4, freq=10)
>>> tim7 = pyb.Timer(7, freq=20)
>>> tim4.callback(lambda t: pyb.LED(1).toggle())
>>> tim7.callback(lambda t: pyb.LED(2).toggle())

因为回调是正确的硬件中断,所以我们可以在这些计时器运行时继续使用TPYboard来进行其他的操作。

制造一个微秒计数器

您可以使用计时器创建一个微秒计数器,当您正在进行需要准确计时的操作时,它可能会很有用。 我们将使用定时器2,因为定时器2有一个32位计数器(定时​​器5也是这样,但如果使用定时器5,则不能同时使用继动驱动器)。

我们设置定时器2如下:

>>> micros = pyb.Timer(2, prescaler=83, period=0x3fffffff)

预分频器设置为83,使定时器计数为1 MHz。 这是因为运行在168 MHz的CPU时钟除以2,然后由预分频器+ 1分频,为定时器2提供168 MHz / 2 /(83 + 1)= 1 MHz的频率。 该周期设置为大数量,使定时器可以计数到大量之前回绕到零。 在这种情况下,大约需要17分钟才能循环回零。

要使用此定时器,最好首先将其重置为0:

>>> micros.counter(0)

然后执行你的计时:

>>> start_micros = micros.counter()

... do some stuff ...

>>> end_micros = micros.counter()

内联汇编

在这里,您将学习如何在MicroPython中编写内联汇编程序。

注意:这是一个高级教程,适用于了解微控制器和汇编语言的一些用户。

MicroPython包括一个内联汇编器。 它允许你写汇编程序时作为Python函数,您可以按照您的要求调用它们一个普通的Python函数。

返回一个值

内联汇编器函数由特殊函数装饰器表示。首先,我们从最简单的例子开始:

@micropython.asm_thumb def fun():

movw(r0, 42)

您可以在脚本或REPL中输入。 此功能不需要参数并返回数字42,“r0“是一个寄存器和值。当函数返回时,在该寄存器中返回值。 MicroPython总是将“r0“解释为整数,并将其转换为调用者的整数对象。

如果你运行“print(fun())“你会看到它打印出来42。

访问外设

对于一些有点复杂的事情,让我们打开一个LED灯:

@micropython.asm_thumb def led_on():

movwt(r0, stm.GPIOA) movw(r1, 1 << 13) strh(r1, [r0, stm.GPIO_BSRRL])

此代码使用以下几个新概念:

  • “stm“是一个提供一组常量的模块,访问TPYBoard微控制器的寄存器。 尝试在REPL上运行“import stm“然后“help(stm)“,它会给你列出所有可用的常量。
  • “stm.GPIOA“是GPIOA外设的内存地址。

     在TPYBoard上,红色LED指示灯位于端口A,引脚PA13上。

  • “movwt“将32位数字移入一个寄存器。这是一个方便功能变成两个拇指指令:“movw“,后跟“movt“。

     “movt“也把立即数值右移16位。

  • “strh“存储一个半字(16位),上面的说明书“r1”的低16位进入内存位置“r0 + stm.GPIO_BSRRL“。 这具有将端口A上的所有引脚设置为高的效果,“r0”中的相应位置为1。在上面的例子中,第13个

    “r0”中的位被设置,所以PA13被拉高,这将打开红色LED指示灯。

接受参数

内联汇编程序函数最多可以接受4个参数,如果使用,它们必须被命名为“r0“,“r1“,“r2“和“r3“来反映寄存器和调用约定。

这里是一个添加其参数的函数:

@micropython.asm_thumb def asm_add(r0, r1):

add(r0, r0, r1)

这执行计算“r0 = r0 + r1“。 由于结果被放在“r0“里,就是返回的。所以去尝试“asm_add(1,2)“,它应该返回3。

循环

我们可以使用“label(my_label)“分配标签,并使用它们分支“b(my_label)“,或“bgt(my_label)“条件分支。

以下示例闪烁绿色LED灯。它闪烁“r0“次“:

@micropython.asm_thumb def flash_led(r0):

# get the GPIOA address in r1 movwt(r1, stm.GPIOA)

# get the bit mask for PA14 (the pin LED #2 is on) movw(r2, 1 << 14)

b(loop_entry)

label(loop1)

# turn LED on strh(r2, [r1, stm.GPIO_BSRRL])

# delay for a bit movwt(r4, 5599900) label(delay_on) sub(r4, r4, 1) cmp(r4, 0) bgt(delay_on)

# turn LED off strh(r2, [r1, stm.GPIO_BSRRH])

# delay for a bit movwt(r4, 5599900) label(delay_off) sub(r4, r4, 1) cmp(r4, 0) bgt(delay_off)

# loop r0 times sub(r0, r0, 1) label(loop_entry) cmp(r0, 0) bgt(loop1)

进一步阅读

有关内联汇编程序支持的指令的更多信息, 请参阅:ref:reference documentation <asm_thumb2_index>

电源控制

:meth:pyb.wfi()用于在等待中断等事件时降低功耗。您将在以下情况下使用它:

while True:
do_some_processing() pyb.wfi()

控制频率pyb.freq():

pyb.freq(30000000) # set CPU frequency to 30MHz

扩展组建教程

Controlling hobby servo motors

There are 4 dedicated connection points on the pyboard for connecting up hobby servo motors (see eg [Wikipedia](http://en.wikipedia.org/wiki/Servo_%28radio_control%29)). These motors have 3 wires: ground, power and signal. On the pyboard you can connect them in the bottom right corner, with the signal pin on the far right. Pins X1, X2, X3 and X4 are the 4 dedicated servo signal pins.

_images/pyboard_servo.jpg

In this picture there are male-male double adaptors to connect the servos to the header pins on the pyboard.

The ground wire on a servo is usually the darkest coloured one, either black or dark brown. The power wire will most likely be red.

The power pin for the servos (labelled VIN) is connected directly to the input power source of the pyboard. When powered via USB, VIN is powered through a diode by the 5V USB power line. Connect to USB, the pyboard can power at least 4 small to medium sized servo motors.

If using a battery to power the pyboard and run servo motors, make sure it is not greater than 6V, since this is the maximum voltage most servo motors can take. (Some motors take only up to 4.8V, so check what type you are using.)

Creating a Servo object

Plug in a servo to position 1 (the one with pin X1) and create a servo object using:

>>> servo1 = pyb.Servo(1)

To change the angle of the servo use the angle method:

>>> servo1.angle(45)
>>> servo1.angle(-60)

The angle here is measured in degrees, and ranges from about -90 to +90, depending on the motor. Calling angle without parameters will return the current angle:

>>> servo1.angle()
-60

Note that for some angles, the returned angle is not exactly the same as the angle you set, due to rounding errors in setting the pulse width.

You can pass a second parameter to the angle method, which specifies how long to take (in milliseconds) to reach the desired angle. For example, to take 1 second (1000 milliseconds) to go from the current position to 50 degrees, use

>>> servo1.angle(50, 1000)

This command will return straight away and the servo will continue to move to the desired angle, and stop when it gets there. You can use this feature as a speed control, or to synchronise 2 or more servo motors. If we have another servo motor (servo2 = pyb.Servo(2)) then we can do

>>> servo1.angle(-45, 2000); servo2.angle(60, 2000)

This will move the servos together, making them both take 2 seconds to reach their final angles.

Note: the semicolon between the 2 expressions above is used so that they are executed one after the other when you press enter at the REPL prompt. In a script you don’t need to do this, you can just write them one line after the other.

Continuous rotation servos

So far we have been using standard servos that move to a specific angle and stay at that angle. These servo motors are useful to create joints of a robot, or things like pan-tilt mechanisms. Internally, the motor has a variable resistor (potentiometer) which measures the current angle and applies power to the motor proportional to how far it is from the desired angle. The desired angle is set by the width of a high-pulse on the servo signal wire. A pulse width of 1500 microsecond corresponds to the centre position (0 degrees). The pulses are sent at 50 Hz, ie 50 pulses per second.

You can also get continuous rotation servo motors which turn continuously clockwise or counterclockwise. The direction and speed of rotation is set by the pulse width on the signal wire. A pulse width of 1500 microseconds corresponds to a stopped motor. A pulse width smaller or larger than this means rotate one way or the other, at a given speed.

On the pyboard, the servo object for a continuous rotation motor is the same as before. In fact, using angle you can set the speed. But to make it easier to understand what is intended, there is another method called speed which sets the speed:

>>> servo1.speed(30)

speed has the same functionality as angle: you can get the speed, set it, and set it with a time to reach the final speed.

>>> servo1.speed()
30
>>> servo1.speed(-20)
>>> servo1.speed(0, 2000)

The final command above will set the motor to stop, but take 2 seconds to do it. This is essentially a control over the acceleration of the continuous servo.

A servo speed of 100 (or -100) is considered maximum speed, but actually you can go a bit faster than that, depending on the particular motor.

The only difference between the angle and speed methods (apart from the name) is the way the input numbers (angle or speed) are converted to a pulse width.

Calibration

The conversion from angle or speed to pulse width is done by the servo object using its calibration values. To get the current calibration, use

>>> servo1.calibration()
(640, 2420, 1500, 2470, 2200)

There are 5 numbers here, which have meaning:

  1. Minimum pulse width; the smallest pulse width that the servo accepts.
  2. Maximum pulse width; the largest pulse width that the servo accepts.
  3. Centre pulse width; the pulse width that puts the servo at 0 degrees or 0 speed.
  4. The pulse width corresponding to 90 degrees. This sets the conversion in the method angle of angle to pulse width.
  5. The pulse width corresponding to a speed of 100. This sets the conversion in the method speed of speed to pulse width.

You can recalibrate the servo (change its default values) by using:

>>> servo1.calibration(700, 2400, 1510, 2500, 2000)

Of course, you would change the above values to suit your particular servo motor.

Fading LEDs

In addition to turning LEDs on and off, it is also possible to control the brightness of an LED using Pulse-Width Modulation (PWM), a common technique for obtaining variable output from a digital pin. This allows us to fade an LED:

http://upload.wikimedia.org/wikipedia/commons/a/a9/Fade.gif
Components

You will need:

  • Standard 5 or 3 mm LED
  • 100 Ohm resistor
  • Wires
  • Breadboard (optional, but makes things easier)
Connecting Things Up

For this tutorial, we will use the X1 pin. Connect one end of the resistor to X1, and the other end to the anode of the LED, which is the longer leg. Connect the cathode of the LED to ground.

_images/fading_leds_breadboard_fritzing.png
Code

By examining the [Micropython]TPYBoardV10X学习使用OLED显示屏, we see that X1 is connected to channel 1 of timer 5 (TIM5 CH1). Therefore we will first create a Timer object for timer 5, then create a TimerChannel object for channel 1:

from pyb import Timer
from time import sleep

# timer 5 will be created with a frequency of 100 Hz
tim = pyb.Timer(5, freq=100)
tchannel = tim.channel(1, Timer.PWM, pin=pyb.Pin.board.X1, pulse_width=0)

Brightness of the LED in PWM is controlled by controlling the pulse-width, that is the amount of time the LED is on every cycle. With a timer frequency of 100 Hz, each cycle takes 0.01 second, or 10 ms.

To achieve the fading effect shown at the beginning of this tutorial, we want to set the pulse-width to a small value, then slowly increase the pulse-width to brighten the LED, and start over when we reach some maximum brightness:

# maximum and minimum pulse-width, which corresponds to maximum
# and minimum brightness
max_width = 200000
min_width = 20000

# how much to change the pulse-width by each step
wstep = 1500
cur_width = min_width

while True:
  tchannel.pulse_width(cur_width)

  # this determines how often we change the pulse-width. It is
  # analogous to frames-per-second
  sleep(0.01)

  cur_width += wstep

  if cur_width > max_width:
    cur_width = min_width
Breathing Effect

If we want to have a breathing effect, where the LED fades from dim to bright then bright to dim, then we simply need to reverse the sign of wstep when we reach maximum brightness, and reverse it again at minimum brightness. To do this we modify the while loop to be:

while True:
  tchannel.pulse_width(cur_width)

  sleep(0.01)

  cur_width += wstep

  if cur_width > max_width:
    cur_width = max_width
    wstep *= -1
  elif cur_width < min_width:
    cur_width = min_width
    wstep *= -1
Advanced Exercise

You may have noticed that the LED brightness seems to fade slowly, but increases quickly. This is because our eyes interprets brightness logarithmically (Weber’s Law ), while the LED’s brightness changes linearly, that is by the same amount each time. How do you solve this problem? (Hint: what is the opposite of the logarithmic function?)

Addendum

We could have also used the digital-to-analog converter (DAC) to achieve the same effect. The PWM method has the advantage that it drives the LED with the same current each time, but for different lengths of time. This allows better control over the brightness, because LEDs do not necessarily exhibit a linear relationship between the driving current and brightness.

The LCD and touch-sensor skin

Soldering and using the LCD and touch-sensor skin.

pyboard with LCD skin pyboard with LCD skin

The following video shows how to solder the headers onto the LCD skin. At the end of the video, it shows you how to correctly connect the LCD skin to the pyboard.

For circuit schematics and datasheets for the components on the skin see TPYBoard 相关下载.

Using the LCD

To get started using the LCD, try the following at the MicroPython prompt. Make sure the LCD skin is attached to the pyboard as pictured at the top of this page.

>>> import pyb
>>> lcd = pyb.LCD('X')
>>> lcd.light(True)
>>> lcd.write('Hello uPy!\n')

You can make a simple animation using the code:

import pyb
lcd = pyb.LCD('X')
lcd.light(True)
for x in range(-80, 128):
    lcd.fill(0)
    lcd.text('Hello uPy!', x, 10, 1)
    lcd.show()
    pyb.delay(25)
Using the touch sensor

To read the touch-sensor data you need to use the I2C bus. The MPR121 capacitive touch sensor has address 90.

To get started, try:

>>> import pyb
>>> i2c = pyb.I2C(1, pyb.I2C.MASTER)
>>> i2c.mem_write(4, 90, 0x5e)
>>> touch = i2c.mem_read(1, 90, 0)[0]

The first line above makes an I2C object, and the second line enables the 4 touch sensors. The third line reads the touch status and the touch variable holds the state of the 4 touch buttons (A, B, X, Y).

There is a simple driver here which allows you to set the threshold and debounce parameters, and easily read the touch status and electrode voltage levels. Copy this script to your pyboard (either flash or SD card, in the top directory or lib/ directory) and then try:

>>> import pyb
>>> import mpr121
>>> m = mpr121.MPR121(pyb.I2C(1, pyb.I2C.MASTER))
>>> for i in range(100):
...   print(m.touch_status())
...   pyb.delay(100)
...

This will continuously print out the touch status of all electrodes. Try touching each one in turn.

Note that if you put the LCD skin in the Y-position, then you need to initialise the I2C bus using:

>>> m = mpr121.MPR121(pyb.I2C(2, pyb.I2C.MASTER))

There is also a demo which uses the LCD and the touch sensors together, and can be found here.

The AMP audio skin

Soldering and using the AMP audio skin.

AMP skin AMP skin

The following video shows how to solder the headers, microphone and speaker onto the AMP skin.

For circuit schematics and datasheets for the components on the skin see TPYBoard 相关下载.

Example code

The AMP skin has a speaker which is connected to DAC(1) via a small power amplifier. The volume of the amplifier is controlled by a digital potentiometer, which is an I2C device with address 46 on the IC2(1) bus.

To set the volume, define the following function:

import pyb
def volume(val):
    pyb.I2C(1, pyb.I2C.MASTER).mem_write(val, 46, 0)

Then you can do:

>>> volume(0)   # minimum volume
>>> volume(127) # maximum volume

To play a sound, use the write_timed method of the DAC object. For example:

import math
from pyb import DAC

# create a buffer containing a sine-wave
buf = bytearray(100)
for i in range(len(buf)):
    buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf)))

# output the sine-wave at 400Hz
dac = DAC(1)
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)

You can also play WAV files using the Python wave module. You can get the wave module here and you will also need the chunk module available here. Put these on your pyboard (either on the flash or the SD card in the top-level directory). You will need an 8-bit WAV file to play, such as this one, or to convert any file you have with the command:

avconv -i original.wav -ar 22050 -codec pcm_u8 test.wav

Then you can do:

>>> import wave
>>> from pyb import DAC
>>> dac = DAC(1)
>>> f = wave.open('test.wav')
>>> dac.write_timed(f.readframes(f.getnframes()), f.getframerate())

This should play the WAV file.

The LCD160CR skin

This tutorial shows how to get started using the LCD160CR skin.

LCD160CRv1.0 picture

For detailed documentation of the driver for the display see the lcd160cr module.

Plugging in the display

The display can be plugged directly into a pyboard (all pyboard versions are supported). You plug the display onto the top of the pyboard either in the X or Y positions. The display should cover half of the pyboard. See the picture above for how to achieve this; the left half of the picture shows the X position, and the right half shows the Y position.

Getting the driver

You can control the display directly using a power/enable pin and an I2C bus, but it is much more convenient to use the driver provided by the lcd160cr module. This driver is included in recent version of the pyboard firmware (see here). You can also find the driver in the GitHub repository here, and to use this version you will need to copy the file to your board, into a directory that is searched by import (usually the lib/ directory).

Once you have the driver installed you need to import it to use it:

import lcd160cr
Testing the display

There is a test program which you can use to test the features of the display, and which also serves as a basis to start creating your own code that uses the LCD. This test program is included in recent versions of the pyboard firmware and is also available on GitHub here.

To run the test from the MicroPython prompt do:

>>> import lcd160cr_test

It will then print some brief instructions. You will need to know which position your display is connected to (X or Y) and then you can run (assuming you have the display on position X):

>>> test_all('X')
Drawing some graphics

You must first create an LCD160CR object which will control the display. Do this using:

>>> import lcd160cr
>>> lcd = lcd160cr.LCD160CR('X')

This assumes your display is connected in the X position. If it’s in the Y position then use lcd = lcd160cr.LCD160CR('Y') instead.

To erase the screen and draw a line, try:

>>> lcd.set_pen(lcd.rgb(255, 0, 0), lcd.rgb(64, 64, 128))
>>> lcd.erase()
>>> lcd.line(10, 10, 50, 80)

The next example draws random rectangles on the screen. You can copy-and-paste it into the MicroPython prompt by first pressing “Ctrl-E” at the prompt, then “Ctrl-D” once you have pasted the text.

from random import randint
for i in range(1000):
    fg = lcd.rgb(randint(128, 255), randint(128, 255), randint(128, 255))
    bg = lcd.rgb(randint(0, 128), randint(0, 128), randint(0, 128))
    lcd.set_pen(fg, bg)
    lcd.rect(randint(0, lcd.w), randint(0, lcd.h), randint(10, 40), randint(10, 40))
Using the touch sensor

The display includes a resistive touch sensor that can report the position (in pixels) of a single force-based touch on the screen. To see if there is a touch on the screen use:

>>> lcd.is_touched()

This will return either False or True. Run the above command while touching the screen to see the result.

To get the location of the touch you can use the method:

>>> lcd.get_touch()

This will return a 3-tuple, with the first entry being 0 or 1 depending on whether there is currently anything touching the screen (1 if there is), and the second and third entries in the tuple being the x and y coordinates of the current (or most recent) touch.

Directing the MicroPython output to the display

The display supports input from a UART and implements basic VT100 commands, which means it can be used as a simple, general purpose terminal. Let’s set up the pyboard to redirect its output to the display.

First you need to create a UART object:

>>> import pyb
>>> uart = pyb.UART('XA', 115200)

This assumes your display is connected to position X. If it’s on position Y then use uart = pyb.UART('YA', 115200) instead.

Now, connect the REPL output to this UART:

>>> pyb.repl_uart(uart)

From now on anything you type at the MicroPython prompt, and any output you receive, will appear on the display.

No set-up commands are required for this mode to work and you can use the display to monitor the output of any UART, not just from the pyboard. All that is needed is for the display to have power, ground and the power/enable pin driven high. Then any characters on the display’s UART input will be printed to the screen. You can adjust the UART baudrate from the default of 115200 using the set_uart_baudrate method.

提示, 技巧和深入了解

Debouncing a pin input

A pin used as input from a switch or other mechanical device can have a lot of noise on it, rapidly changing from low to high when the switch is first pressed or released. This noise can be eliminated using a capacitor (a debouncing circuit). It can also be eliminated using a simple function that makes sure the value on the pin is stable.

The following function does just this. It gets the current value of the given pin, and then waits for the value to change. The new pin value must be stable for a continuous 20ms for it to register the change. You can adjust this time (to say 50ms) if you still have noise.

import pyb

def wait_pin_change(pin):
    # wait for pin to change value
    # it needs to be stable for a continuous 20ms
    cur_value = pin.value()
    active = 0
    while active < 20:
        if pin.value() != cur_value:
            active += 1
        else:
            active = 0
        pyb.delay(1)

Use it something like this:

import pyb

pin_x1 = pyb.Pin('X1', pyb.Pin.IN, pyb.Pin.PULL_DOWN)
while True:
    wait_pin_change(pin_x1)
    pyb.LED(4).toggle()

Making a UART - USB pass through

It’s as simple as:

import pyb
import select

def pass_through(usb, uart):
    usb.setinterrupt(-1)
    while True:
        select.select([usb, uart], [], [])
        if usb.any():
            uart.write(usb.read(256))
        if uart.any():
            usb.write(uart.read(256))

pass_through(pyb.USB_VCP(), pyb.UART(1, 9600))

TPYBoard 实例教程

本教程的目的是让我们开始您的TPYBoard的使用。 我们需要一块TPYBoard和一根USB线并连接到电脑上。 如果你是第一次,建议按照教程让我们开始编程吧。

*TPYBoard 典型实例

TPYBoard v10x 典型实例

[Micropython]TPYBoard控制LCD5110汉字显示温度时间

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

1. 实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 什么是SPI接口。
  3. 学习TPYBoard I2C接口的用法。
  4. 学习LCD5110接线方法。
  5. DS3231的接线方法。
  6. 16*16汉字显示温度与当前时间。
2. 所需元器件
DS3231模块一个 TPYBoard板子一块 LCD5110显示屏一个 数据线一条 杜邦线若干
3.TPYBoard的SPI接口
LCD5110需要SPI接口与TPYBoard进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,TPYBoard有两个SPI接口,我们用的为SPI1接口。
http://www.micropython.net.cn/ueditor/php/upload/image/20161229/1482973399550325.png
4.TPYBoard的I2C接口
DS3231是I2C接口通信的,它通过I2C接口与TPYboard进行数据通讯,DS3231通过这个接口与TPYBoard进行双向通讯,进行数据传输,TPYBoard有两个I2C接口,我们在这用的是I2C接口1。
http://www.micropython.net.cn/ueditor/php/upload/image/20161229/1482973431559379.png
5.DS3231的接线方法
DS会我们在这只用到DS3231的SCL,SDA,VCC,GND四个针脚即可设定读出当前时间,我们用的是TPYBoard的I2C接口1,即DS3231的针脚SCL接TPYboard的针脚X9,针脚SDA接TPYBoard的针脚X10,VCC接TPYBoard的3.3V,GND接TPYBoard的GND。
http://www.micropython.net.cn/ueditor/php/upload/image/20161229/1482973477928543.png
6.控制5110显示屏显示16x16汉字

先看一下LCD5110针脚含义吧(注意:LCD5110的针脚有些不一样的) TPYBoard的针脚与5110的针脚对应关系如下:

TPYBoard | LCD5110 | memo |

+================+=================+====================================================+ | Pin | RST | Reset pin (0=reset, 1=normal) |

Pin | CE | Chip Enable (0=listen for input, 1=ignore input) | +—————-+—————–+—————————————————-+
Pin | DC | Data/Command (0=commands, 1=data) | +—————-+—————–+—————————————————-+
MOSI | DIN | data flow (Master out, Slave in) | +—————-+—————–+—————————————————-+
SCK | CLK | SPI clock | +—————-+—————–+—————————————————-+
3V3/Pin | VCC | 3.3V logic voltage (0=off, 1=on) | +—————-+—————–+—————————————————-+
Pin | LIGHT | Light (0=on, 1=off) | +—————-+—————–+—————————————————-+
GND | GND | +—————-+—————–+—————————————————-+

还是看不明白的话,直接上针脚编号吧

TPYBoard | LCD5110 | memo |

+================+=================+====================================================+ | X1 | RST | Reset pin (0=reset, 1=normal) |

X2 | CE | Chip Enable (0=listen for input, 1=ignore input) | +—————-+—————–+—————————————————-+
X3 | DC | Data/Command (0=commands, 1=data) | +—————-+—————–+—————————————————-+
X8 | DIN | data flow (Master out, Slave in) | +—————-+—————–+—————————————————-+
X6 | CLK | SPI clock | +—————-+—————–+—————————————————-+
VCC | +—————-+—————–+—————————————————-+
X4 | LIGHT | Light (0=on, 1=off) | +—————-+—————–+—————————————————-+
GND | +—————-+—————–+—————————————————-+
http://www.micropython.net.cn/ueditor/php/upload/image/20161229/1482973640480164.png http://www.micropython.net.cn/ueditor/php/upload/image/20161229/1482973647210289.png

接线ok后,并且导入font.py文件、upcd8544.py、chinsese.py文件以及DS3231.py,编写main.py设定时间,运行main.py即可将当前温度与时间显示在5110显示屏上,如上图所示。

7.源代码
# main.py -- put your code here!
import pyb
import upcd8544
from machine import SPI,Pin
from DS3231 import DS3231

ds=DS3231(1) #定义DS3231

# 用于设定时间和日期
def setDateTime(year,month,day,time,minutes,seconds):
        ds.DATE([year,month,day])
        ds.TIME([time,minutes,seconds])

# 在LCD5110 显示时间或日期,separator 中间的分割符
# x,y 在LCD5110 显示的位置
def showTimeOrDate(why,x,y,separator=':'):
        # [HH,MM,SS] >> HH:MM:SS
        why = why.replace('[','')
        why = why.replace(']','')
        why = why.replace(',',separator)
        print(why)
        lcd_5110.lcd_write_string(why,x,y)


def main():
        lcd_5110.lcd_write_chinese('萝',14,0)
        lcd_5110.lcd_write_chinese('卜',30,0)
        lcd_5110.lcd_write_chinese('智',46,0)
        lcd_5110.lcd_write_chinese('能',62,0)
        lcd_5110.lcd_write_string('TEM:',14,2)
        lcd_5110.lcd_write_string(str(ds.TEMP()),44,2)
        lcd_5110.lcd_write_chinese("当",14,3)
        lcd_5110.lcd_write_chinese("前",30,3)
        lcd_5110.lcd_write_chinese("时",46,3)
        lcd_5110.lcd_write_chinese("间",62,3)
        showTimeOrDate(str(ds.TIME()),14,5)
        print(str(ds.TIME()))
        pyb.delay(1000)

if __name__ == '__main__':
        #setDateTime(2016,12,27,13,17,00)#设置时间
        ds.DATE()
        SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
        #DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
        #CLK =>SPI(1).SCK  'X6' SPI clock
        RST    = pyb.Pin('X1')
        CE     = pyb.Pin('X2')
        DC     = pyb.Pin('X3')
        LIGHT  = pyb.Pin('X4')
        lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
        while(1):
        main()

LCD5110 ..LINK:http://www.micropython.net.cn/ueditor/php/upload/file/20161229/1482973799786626.zip

[Micropython]TPYBoardV10X心形8*8点阵

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

1.实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。
  3. 学习8*8点阵与TPYBoard的接线方法,点亮点阵。
2.所需元器件
8*8点阵一个 TPYBoard板子一块 数据线一条 杜邦线若干
3.点亮8*8LED点阵
4.控制8*8点阵
http://www.micropython.net.cn/ueditor/php/upload/image/20161031/1477882469674497.jpg

效果图

我们按照上面的步骤做完以后,然后通电,编写main.py文件,即可显示你想要显示的字符或者图案,下面代码是在8*8点阵上显示心形图案,具体代码如下:

# main.py -- put your code here!
import  pyb
from pyb import Pin
x_PIN = [Pin(i, Pin.OUT_PP) for i in ['X1','X2','X3','X4','X5','X6','X7','X8']]
y_PIN = [Pin(i, Pin.OUT_PP) for i in ['Y1','Y2','Y3','Y4','Y5','Y6','Y7','Y8']]
hanzi=['11111111','11011101','10001000','10000000','10000000','11000001','11100011','11110111']
def displayLED():
        flag=0
        for x_ in range(0,8):
                for b in range(0,8):
                        print(b)
                        if b!=flag:
                                x_PIN[b].value(0)
                li_l = hanzi[x_]
                y_PIN[0].value(int(li_l[:1]))
                y_PIN[1].value(int(li_l[1:2]))
                y_PIN[2].value(int(li_l[2:3]))
                y_PIN[3].value(int(li_l[3:4]))
                y_PIN[4].value(int(li_l[4:5]))
                y_PIN[5].value(int(li_l[5:6]))
                y_PIN[6].value(int(li_l[6:7]))
                y_PIN[7].value(int(li_l[7:8]))
                x_PIN[flag].value(1)
                flag=flag+1
                pyb.delay(2)
while 1:
        displayLED()

[Micropython]TPYBoardV10X加速度无线小车

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

现在无线控制已经成为了电子科学领域的主流,这次就来教大家做一个主流中的主流–无线控制的小车,先给大家看一下最终的成品演示视频:

首先介绍一下需要用到的材料:
TPYBoardv10x开发板两块 小车底盘一个 LORA无线模块两块 充电宝一个 9014三极管两个(为什么用到它呢,后面再说)。

在这个开发板上有一个及速度传感器,我是看到开发板上有个加速度传感器才想起来这样做的,这里的呢我们先介绍一下加速度传感器。

加速度传感器,包括由硅膜片、上盖、下盖,膜片处于上盖、下盖之间,键合在一起;一维或二维纳米材料 、金电极和引线分布在膜片上,并采用压焊工艺引出导线;工业现场测振传感器,主要是压电式加速度传感器。其工作原理主要利于压电敏感元件的压电效应得到与振动或者压力成正比的电荷量或者电压量。目前工业现场典型采用IEPE型加速度传感器,及内置IC电路压电加速度传感器,传感器输出与振动量正正比的电压信号,例如:100mV/g (每个加速度单位输出100mV电压值。1g=9.81m/s-2)。

关于上面的介绍你是不是没看懂?没看懂也没关系,那是我参照官方的介绍写的,其实我也看不懂。其实通俗的说吧,加速度传感器就是通过测量由于重力引起的加速度,你可以计算出设备相对于水平面的倾斜角度。通过分析动态加速度,你可以分析出设备移动的方式。是不是还是不太懂怎么获取这个倾斜的值?那也没关系,我们的Python语言里有获得这个倾斜值的函数,直接使用就可以啦。但是这里值得注意的是,这个函数返回的倾斜度是一个值,每一个传感器因为做工时的差异,返回值不同,这个需要大家自己做实验看一下。

得到倾斜值后,下面的工作的就简单了,那就是判断板子在怎么倾斜,然后把倾斜的信号传出去,这样就OK啦,妥妥哒。

介绍完了这控制端的,那咱们得说说怎么把控制的信号传出吧。这里呢主要是使用了lora模块,这个模块现在还是挺流行的。我亲自去做过一个传输距离的实验,具体的距离我没测,但是我感觉最起码也得有个二三里地吧,这距离对于做个小车妥妥哒够用啦。

说一下lora模块的使用吧,lora模块的使用呢,也很简单,串口通信,无线透传。就是说你使用单片机通过串口给模块什么,模块就给你传输什么(定点的话需要带上地址信道),这个lora模块说明说的很详细。但是是不是觉得还要用串口,感觉好麻烦?我也觉得麻烦,但是Python语言和这个开发板的功能都很强大,有一个写好的使用串口的方法,直接调用就可以(瞬间感觉开发好简单啦)。

上面介绍了控制端的工作和原理,下面说一下被控制端(就是按在小车上的)。

被控制端就是要使用开发板控制小车地盘的电机转动,这里被我被坑了一次,我在某宝上买这架车的时候,问了客服需不需要其他的东西,客服说不用。我感觉现在连电机的驱动都不用啦,感觉好高端,但是买回来发现还是需要一个L298N驱动。瞬间感觉被骗了,但是,悲愤的同时,我的两个9014上场了,简单的做了一个三极管开关电路,妥妥哒(虽然速度略慢)。

信号接收部分,这个和控制端差不多的,都是使用了lora模块,然后把收到的数据做判断。判断后再按照自己的逻辑驱动电机,小车就开起来了(小车怎么拐弯的我就不介绍了,网上教程大把多)。

上面说了这么多,其实也很抽象啦,下面来个聚象的,上图。

先上一个自己画的简单的原理图。

http://www.micropython.net.cn/ueditor/php/upload/image/20160815/1471255048558130.png

控制器

http://www.micropython.net.cn/ueditor/php/upload/image/20160815/1471255085467193.png

被控制端

这两张图是我画来帮助大家理解的(我这样做的被控制端的电路,速度略慢。大家可以在驱动那里做个放大电路,速度可以上去的,但是不能后退,大家可以直接使用L298N驱动。),我做的时候是使用杜邦线的,并没有电路图,再上一张成品图给大家看。
http://www.micropython.net.cn/ueditor/php/upload/image/20160815/1471255116488443.jpg

成品图

这些都是给大家参考的,大家做的时候多学习多看看,亲身体验了才能真的学到东西。

下面的程序给大家,大家可以参考一下。

控制端源代码:

import pyb
xlights = (pyb.LED(2), pyb.LED(3))
ylights = (pyb.LED(1), pyb.LED(4))
from pyb import UART
from pyb import Pin
#from ubinascii import hexlify
from ubinascii import *
accel = pyb.Accel()
u2 = UART(2, 9600)
i=0
K=1

*******************************主程序**********************************
print('while')
while (K>0):
        _dataRead=u2.readall()
        if(1>0):
                x = accel.x()
                print("x=")
                print(x)
                if x > 10:
                        xlights[0].on()
                        xlights[1].off()
                        u2.write('\x00\x05\x18YOU')
                        #pyb.delay(1000)
                        print('\x00\x01\x18YOU')
                elif x < -10:
                        xlights[1].on()
                        xlights[0].off()
                        u2.write('\x00\x05\x18ZUO')
                        print('\x00\x01\x18ZUO')
                        #pyb.delay(1000)

                else:
                        xlights[0].off()
                        xlights[1].off()

                y = accel.y()
                print("y=")
                print(y)
                if y > 15:
                        ylights[0].on()
                        ylights[1].off()
                        #u2.write('\x00\x05\x18HOU')
                        #pyb.delay(1000)
                        #print('\x00\x01\x18HOU')
                elif y < -15:
                        ylights[1].on()
                        ylights[0].off()
                        u2.write('\x00\x05\x18QIAN')
                        #pyb.delay(1000)
                        print('\x00\x01\x18QIAN')
                else:
                        ylights[0].off()
                        ylights[1].off()

                pyb.delay(10)

被控制端源代码:

import pyb
from pyb import UART
from pyb import Pin
from ubinascii import hexlify
from ubinascii import *
M1 = Pin('X1', Pin.OUT_PP)
M3 = Pin('Y1', Pin.OUT_PP)
u2 = UART(2, 9600)
i=0
K=1
*******************************主程序**********************************
print('while')
while (K>0):
        M1.high()
        pyb.delay(3)
        M3.high()
        if(u2.any()>0):
                        print('1234')
                        M1.low()
                        M3.low()
                        pyb.delay(3)
                        _dataRead=u2.readall()
                        print('123',_dataRead)
                        if(_dataRead.find(b'QIAN')>-1):
                                M1.low()
                                M3.low()
                                print('QIAN')
                                pyb.delay(250)
                        elif(_dataRead.find(b'ZUO')>-1):
                                M1.low()
                                M3.high()
                                print('ZUO')
                                pyb.delay(250)
                        elif(_dataRead.find(b'YOU')>-1):
                                M1.high()
                                M3.low()
                                print('ZUO')
                                pyb.delay(250)

[Micropython]TPYBoardV10X DIY智能温控小风扇

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。

3. 学习DS18B20的接线方法,并利用DS18B20检测当前温度。 4.学习三极管9014的用法。 5.通过18B20智能控制直流电机驱动小风扇。

所需元器件
TPYBoard板子一块 直流电机一个 面包板一块 数据线一条 三极管9014(NPN)一个 杜邦线若干
学习DS18B20的接线方法,检测当前温度
http://www.micropython.net.cn/ueditor/php/upload/image/20161125/1480062707271272.png

先看一下DS18B20针脚含义,如上图:

TPYBoard的针脚与DS18B20的针脚对应关系如下:

TPYBoard DS18B20
3V3/Pin VDD
Pin DO
GND GND

还是看不明白的话,直接上针脚编号

TPYBoard DS18B20
3.3v VDD
GND GND
Y10 DO

接线ok后,在MicroPython的源码目录中,进入driversonewire目录,然后将目录下的文件ds18x20.py和onewire.py复制到PYBFLASH磁盘的根目录。复制文件后要安全退出磁盘,然后重新接入,不然找不到文件,即可运行main.py文件了,打印温度,即可用Putty看到当前的温度。

main.py源代码:

#main.py
import pyb
from pyb import Pin
from ds18x20 import DS18X20

Pin("Y11",Pin.OUT_PP).low()#GND
Pin("Y9",Pin.OUT_PP).high()#VCC
pyb.delay(100)
DQ=DS18X20(Pin('Y10'))#DQ
while True:
   tem = DQ.read_temp()
   print(tem)
   pyb.delay(1000)
三极管的原理
源代码
http://www.micropython.net.cn/ueditor/php/upload/image/20161125/1480063122271025.png

我们按照上面的步骤做完以后,然后通电,编写main.py文件,即可通过温度控制风扇的转动,具体代码如下:

#main.py
import pyb
from pyb import Pin
from ds18x20 import DS18X20

Pin("Y9",Pin.OUT_PP).high()#VCC
Pin("Y11",Pin.OUT_PP).low()#GND
x1 = Pin('X1', Pin.OUT_PP)
pyb.delay(100)
DQ=DS18X20(Pin('Y10'))#DQ
while 1:
        tem = DQ.read_temp()
        if tem > 18:
                x1.value(1)
        else:
                x1.value(0)

[Micropython]TPYBoard 无线蓝牙智能小车

原创版权归山东萝卜科技有限公司所有,转载必须以链接形式注明作者和原始出处。

1.实验目的

1. 学习在PC机系统中扩展简单I/O 接口的方法。 2.进一步学习编制数据输出程序的设计方法。 3.学习蓝牙模块的接线方法及其工作原理。 4. 学习 L298N电机驱动板模块的接线方法。 5. 学习蓝牙控制小车的工作原理。

2.所需元器件

TPYBoard板子一块 蓝牙串口模块一个 L298N电机驱动板模块一个 智能小车底盘一个 数据线一条 杜邦线若干

http://www.tpyboard.com/ueditor/php/upload/image/20161215/1481791277901030.jpg
3.蓝牙串口模块原理

(1)引出接口包括EN,5V,GND,TX,RX,STATE,我们小车只用到RX,TX,GND,5V四个针脚。 (2)模块默认波特率位9600,默认配对密码为1234,默认名称位为HC-06。 (3)led指示蓝牙连接状态,闪烁表示没有蓝牙连接,常亮表示蓝牙已连接并打开了端口,当我们用安卓手机软件发送指令时,通过串口给TPYBoard发送指令,TPYBoard收到指令通过L298BN模块来驱动小车前进,后退,向左,向右或者停止。

如下图接线,5V 接TPYBoard的VIN, GND 为地线,TX接TPYBoard的RX(这用的是TPYBoard串口2,X3,X4)即X4,RX接TPYBoard的TX即X3。

http://www.tpyboard.com/ueditor/php/upload/image/20161215/1481791173622577.png
4.学习L298N电机驱动板模块的接线方法

本模块是2路的H桥驱动,所以可以同时驱动两个电机,接法如图所示使能ENA ENB之后,可以分别从IN1 IN2输入PWM信号驱动电机1的转速和方向,可以分别从IN3 IN4输入PWM信号驱动电机2的转速和方向。我们将电机1接口的OUT1与OUT2与小车的一个电机的正负极连接起来,将电机2接口的OUT3与OUT4与小车的另一个电机的正负极连接起来。然后将两边的接线端子,即供电正极(中间的接线端子为接地)连接TPYboard的VIN,中间的接线端子即接地,连接TPYBoard的GND,In1-In4连接TPYBoard的Y1,Y2,Y3,Y4,通过Y1,Y2与Y3,Y4的高低电平,来控制电机的转动,从而让小车前进,后退,向左,向右。

http://www.tpyboard.com/ueditor/php/upload/image/20161215/1481791212316208.jpg

接线ok后,编写main.py,给TOYBoard通电就ok了,下面是源代码。

5.源代码
import pyb
from pyb import UART
from pyb import Pin

M2 = Pin('X3', Pin.IN)
M3 = Pin('X4', Pin.IN)
N1 = Pin('Y1', Pin.OUT_PP)
N2 = Pin('Y2', Pin.OUT_PP)
N3 = Pin('Y3', Pin.OUT_PP)
N4 = Pin('Y4', Pin.OUT_PP)

u2 = UART(2, 9600)

while True:
        pyb.LED(2).on()
        pyb.LED(3).on()
        pyb.LED(4).on()
        _dataRead=u2.readall()
        if _dataRead!=None:
        #停止(读取手机APP传过来的指令,不同的软件指令可能不同,可以自己设定,在这里是默认的,下同)
                if(_dataRead.find(b'\xa5Z\x04\xb1\xb5\xaa')>-1):
                        print('stop')
                        N1.low()
                        N2.low()
                        N3.low()
                        N4.low()
                #向左
                elif(_dataRead.find( b'\xa5Z\x04\xb4\xb8\xaa')>-1):
                        print('left')
                        N1.low()
                        N2.high()
                        N3.high()
                        N4.low()
                #向右
                elif(_dataRead.find( b'\xa5Z\x04\xb6\xba\xaa')>-1):
                        print('right')
                        N1.high()
                        N2.low()
                        N3.low()
                        N4.high()
                #后退
                elif(_dataRead.find(b'\xa5Z\x04\xb5\xb9\xaa')>-1):
                        print('back')
                        N2.high()
                        N1.low()
                        N4.high()
                        N3.low()
                #向前
                elif(_dataRead.find( b'\xa5Z\x04\xb2\xb6\xaa')>-1):
                        print('go')
                        N1.high()
                        N2.low()
                        N3.high()
                        N4.low()

[Micropython]TPYBoard DIY电子时钟

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 什么是SPI接口。
  3. 学习TPYBoard I2C接口的用法。
  4. 学习LCD5110接线方法。
  5. 设定时钟并将当前时间显示在LCD5110上。
所需元器件
DS3231模块一个 TPYBoard板子一块 LCD5110显示屏一个 数据线一条 杜邦线若干
TPYBoard的SPI接口
LCD5110需要SPI接口与TPYBoard进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,TPYBoard有两个SPI接口,我们用的为SPI1接口。
http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150621179364.png
TPYBoard的I2C接口
DS3231是I2C接口通信的,它通过I2C接口与TPYboard进行数据通讯,DS3231通过这个接口与TPYBoard进行双向通讯,进行数据传输,TPYBoard有两个I2C接口,我们在这用的是I2C接口1。
http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150651145892.png http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150657750799.png
DS3231的接线方法
DS会我们在这只用到DS3231的SCL,SDA,VCC,GND四个针脚即可设定读出当前时间,我们用的位I2C接口1,即DS3231的针脚SCL接TPYboard的针脚X9,针脚SDA接TPYBoard的针脚X10。
http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150682569300.png
控制5110显示屏显示6x8字符

先看一下LCD5110针脚含义吧(注意:LCD5110的针脚有些不一样的)

TPYBoard LCD5110 memo

# any Pin => RST Reset pin (0=reset, 1=normal) # any Pin => CE Chip Enable (0=listen for input, 1=ignore input) # any Pin => DC Data/Command (0=commands, 1=data) # MOSI => DIN data flow (Master out, Slave in) # SCK => CLK SPI clock # 3V3 or any Pin => VCC 3.3V logic voltage (0=off, 1=on) # any Pin => LIGHT Light (0=on, 1=off) # GND => GND

还是看不明白的话,直接上针脚编号吧

TPYBoard LCD5110 memo

Y10 => RST Reset pin (0=reset, 1=normal) Y11 => CE Chip Enable (0=listen for input, 1=ignore input) Y9 => DC Data/Command (0=commands, 1=data) X8 => DIN data flow (Master out, Slave in) X6 => CLK SPI clock VCC Y12 => LIGHT Light (0=on, 1=off) GND

http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150739943842.png
源代码

接线ok后,并且导入font.py文件、upcd8544.py文件以及DS3231.py,编写main.py设定时间,运行main.py即可将当前时间显示在5110显示屏上。


1 # main.py – put your code here! 2 import pyb 3 import upcd8544 4 from machine import SPI,Pin 5 from DS3231 import DS3231 6 7 ds=DS3231(1) 8 ds.DATE([16,11,26]) 9 ds.TIME([16,14,6]) 10 11 while True: 12 ds.TEMP() 13 ds.DATE() 14 SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK 15 #DIN =>SPI(1).MOSI ‘X8’ data flow (Master out, Slave in) 16 #CLK =>SPI(1).SCK ‘X6’ SPI clock 17 RST = pyb.Pin(‘Y10’) 18 CE = pyb.Pin(‘Y11’) 19 DC = pyb.Pin(‘Y9’) 20 LIGHT = pyb.Pin(‘Y12’) 21 lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT) 22 lcd_5110.lcd_write_string(‘Date’,0,0) 23 lcd_5110.lcd_write_string(str(ds.DATE()),0,1) 24 lcd_5110.lcd_write_string(‘Time’,0,2) 25 lcd_5110.lcd_write_string(str(ds.TIME()),0,3) 26 lcd_5110.lcd_write_string(‘Tem’,0,4 ) 27 lcd_5110.lcd_write_string(str(ds.TEMP()),0,5) 28 pyb.delay(1000)

DS3231.RAR link:http://www.tpyboard.com/ueditor/php/upload/file/20170111/1484102983654809.rar

[Micropython]TPYBoardV10X 红外防坠落小车

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

智能小车现在差不多是电子竞赛或者DIY中的主流了,寻迹,壁障,遥控什么的,相信大家也都见得很多了,这次就大家探讨一下防坠落小车的制作方法,不同于以往的是这次的程序不用C语言写,而是要使用python语言写。下面给大家看一下视频演示:
http://www.micropython.net.cn/ueditor/php/upload/image/20161104/1478249731266844.png

查看视频

1.实验目的
研究智能小车结合红外探头寻迹前进。
2.实验材料

TPYBoard开发板1块(能跑python语言的开发板,小车 的大脑) 四路红外感应探头(小车的眼睛) 数据线一根。 充电宝一个(给整个系统供电) 智能小车底盘(包括驱动模块) 杜邦线若干

实验目的和实验材料准备齐了,先来介绍一下各个主要部件。

2.1 PYBoard开发板
MicroPython是在单片机上可以跑的Python,也就是说,你可以通过Python脚本语言开发单片机程序。 由剑桥大学的理论物理学家乔治·达明设计。和Arduino类似,但Micro Python更强大。 MicroPython开发板让你可以通过Python代码轻松控制微控制器的各种外设,比如LED等,读取管脚电压,播放歌曲,和其他设备联网等等。TPYBoard是TurnipSmart公司制作的一款MicroPython开发板,这款开发板运行很流畅,关键是价格很便宜。
2.2 四路红外感应探头

1、当模块检测到前方障碍物信号时,电路板上红色指示灯点亮,同时OUT端口持续输出低电平信号,该模块检测距离2~60cm,检测角度35°,检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检测距离减少。

2、传感器属于红外线反射探测,因此目标的反射率和形状是探测距离的关键。其中黑色探测距离最小,白色最大;小面积物体距离小,大面积距离大。

3、 传感器模块输出端口OUT可直接与单片机IO口连接即可, 也可以直接驱动一个5V继电器模块或者蜂鸣器模块;连接方式: VCC-VCC;GND-GND;OUT-IO。

4、比较器采用LM339,工作稳定;

5、可采用3.3V-5V直流电源对模块进行供电。当电源接通时, 绿色电源指示灯点亮。

2.3 智能小车底盘
双电机驱动,万向轮改变方向。这是实验中最常用到的小车底盘,使用差速的方法进行转弯。配合使用L298N电机驱动模块,使用方法很简单,不多做介绍。
3.寻迹原理
说完了原料的问题,下面说一下小车寻迹的原理。
3.1红外探头的安装
小车寻迹的原理其实就光的吸收,反射和散射。在小车的前端有安装孔,使用螺丝把红外传感器固定在安装孔上。保持发射端和接收端都保持竖直向下。
3.2返回信号的判断
在上面已经说了,红外探头在检测到物体存在的时候,在OUT端会持续的输出低电平。那么调节调距电阻,调节到一个适合的检测距离。在小车行驶路面检测到物体的时候,说明是前面是有路的,不是悬空的。那么小车 保持直行。如果前方检测到没有返回,没返回说明没有检测到物体,妈就说明前面是没有路的,是悬空的,那么小车就先进行后退,在进行右转(也可以左转,也可以一次右转一次左转,这个比较随意。)。
4.硬件接线

接线其实很简单四路红外探头接线很简单,虽然有十八根线,但是有十二根是三根三根的分成四组的,对应着很好接线,剩下的六根,VCC和GND不多说了,还有四根是直接接到单片结IO口上就可以的。L298N的接线更简单了,这里不多介绍。

上个简单的帮助理解的原理图 (其实我们做实验都是插线,不做PCB图和原理图的)。

红外小车2 .png 再上个实物图给大家看看。

红外小车3.jpg

5.运行与调试
制作完成后,剩下的就是该调试了,调试中应该注意细节和小车稳定性的优化。
6.代码编写

再把我写的程序给大家看一下,有需要的可以看一下。

源代码:

import pyb
from pyb import UART
from pyb import Pin

M0 = Pin('X1', Pin.IN)
M1 = Pin('X2', Pin.IN)
M2 = Pin('X3', Pin.IN)
M3 = Pin('X4', Pin.IN)
N1 = Pin('Y1', Pin.OUT_PP)
N2 = Pin('Y2', Pin.OUT_PP)
N3 = Pin('Y3', Pin.OUT_PP)
N4 = Pin('Y4', Pin.OUT_PP)

print('while')
while True:
        print('while')
        if(M2.value()|M1.value()|M3.value()|M0.value()==0):
                N1.low()
                N2.high()
                N4.high()
                N3.low()
                pyb.LED(2).on()
                pyb.LED(3).off()
        elif(M2.value()|M1.value()|M3.value()|M0.value()==1):
                N1.high()
                N2.low()
                N4.low()
                N3.high()
                pyb.delay(300)
                N1.low()
                N2.high()
                N3.high()
                N4.low()
                pyb.delay(200)
                pyb.LED(3).on()
                pyb.LED(2).off()

[Micropython]TPYBoardV10X 红外寻迹无线小车

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

前面给大家介绍过TPYBoardv102开发板控制加速度无线传感器小车→猛戳回忆在此←,下面给大家介绍的是TPYBoard开发板制作红外寻迹小车。

先给大家看一下视频演示吧!

http://www.micropython.net.cn/ueditor/php/upload/image/20161031/1477877141332316.png

查看视频

厉害了我的TPYBoard,还是同样的开发板、还是同样的小车!跟着小编一起学起来~

智能小车现在差不多是电子竞赛或者DIY中的主流了,寻迹,壁障,遥控什么的,相信大家也都见得很多了,这次就大家探讨一下寻迹小车的制作方法,不同于以往的是这次的程序不用C语言写,而是要使用python语言写。

1.实验目的
研究智能小车结合红外探头寻迹前进。
2.实验材料

TPYBoard开发板1块(能跑python语言的开发板,小车 的大脑。) 四路红外感应探头(小车的眼睛)。 数据线一根。 充电宝一个(给整个系统供电)。 智能小车底盘(包括驱动模块)。 杜邦线若干。

实验目的和实验材料准备齐了,先来介绍一下各个主要部件。

*PYBoard开发板

MicroPython是在单片机上可以跑的Python,也就是说,你可以通过Python脚本语言开发单片机程序。 由剑桥大学的理论物理学家乔治·达明设计。和Arduino类似,但Micro Python更强大。 MicroPython开发板让你可以通过Python代码轻松控制微控制器的各种外设,比如LED等,读取管脚电压,播放歌曲,和其他设备联网等等。TPYBoard是TurnipSmart公司制作的一款MicroPython开发板,这款开发板运行很流畅,关键是价格很便宜。

*四路红外感应探头

1、当模块检测到前方障碍物信号时,电路板上红色指示灯点亮,同时OUT端口持续输出低电平信号,该模块检测距离2~60cm,检测角度35°,检测距离可以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检测距离减少。

2、传感器属于红外线反射探测,因此目标的反射率和形状是探测距离的关键。其中黑色探测距离最小,白色最大;小面积物体距离小,大面积距离大。

3、 传感器模块输出端口OUT可直接与单片机IO口连接即可, 也可以直接驱动一个5V继电器模块或者蜂鸣器模块;连接方式: VCC-VCC;GND-GND;OUT-IO。

4、比较器采用LM339,工作稳定;

5、可采用3.3V-5V直流电源对模块进行供电。当电源接通时, 绿色电源指示灯点亮。

*智能小车底盘

双电机驱动,万向轮改变方向。这是实验中最常用到的小车底盘,使用差速的方法进行转弯。配合使用L298N电机驱动模块,使用方法很简单,不多做介绍。

3.寻迹原理

说完了原料的问题,下面说一下小车寻迹的原理。

*红外探头的安装

小车寻迹的原理其实就光的吸收,反射和散射。大家都知道,白色反射所有颜色的光,而黑色吸收所有颜色的光,这就为小车寻迹提供了有力的科学依据。在小车的车头上安装上红外探头(我是安装了四个),一字顺序排开。哪个探头接收不到反射或者散射回来的光时,说明这个探头此时正在黑色的寻迹带上。

*返回信号的判断 如果要是正前方的探头接收不到光,那么说明小车此时走在黑色的寻迹带上。可以使小车直线行走。如果左面的探头接收不到光,那么说明小车左面出现了黑色寻迹带,此时小车应该执行左转弯。右转弯同左转弯原理。

如果要是小车前面,左面,右面三个方向全都接收不到光,或者是两个方向上的探头都接收不到光,到底是左转弯,右转弯还是继续直行,这个就要看你自己在程序里怎么做判断了。

*硬件接线

接线其实很简单四路红外探头接线很简单,虽然有十八根线,但是有十二根是三根三根的分成四组的,对应着很好接线,剩下的六根,VCC和GND不多说了,还有四根是直接接到单片结IO口上就可以的。L298N的接线更简单了,这里不多介绍。

上个简单的帮助理解的原理图 (其实我们做实验都是插线,不做PCB图和原理图的)。

http://www.micropython.net.cn/ueditor/php/upload/image/20161029/1477732081757742.png

原理图

再上个实物图给大家看看。
http://www.micropython.net.cn/ueditor/php/upload/image/20161031/1477877362324105.jpg

实物图

5.运行与调试
制作完成后,剩下的就是该调试了,调试中应该注意细节和小车稳定性的优化。
6.代码编写

再把我写的程序给大家看一下,有需要的可以看一下。

源代码:

import pyb
from pyb import UART
from pyb import Pin

M0 = Pin('X1', Pin.IN)
M1 = Pin('X2', Pin.IN)
M2 = Pin('X3', Pin.IN)
M3 = Pin('X4', Pin.IN)
N1 = Pin('Y1', Pin.OUT_PP)
N2 = Pin('Y2', Pin.OUT_PP)
N3 = Pin('Y3', Pin.OUT_PP)
N4 = Pin('Y4', Pin.OUT_PP)

print('while')
while True:
        print('while')
        pyb.LED(4).off()
        pyb.LED(3).off()
        pyb.LED(2).off()
        if(M0.value()==1):#检测到物体返回0。
                pyb.LED(4).on()
                pyb.delay(50)
                N1.low()
                N2.high()
                N3.low()
                N4.high()
                pyb.delay(30)
                #pyb.delay(5000)
        if(M3.value()==1):#检测到物体返回0。
                pyb.LED(3).on()
                pyb.delay(50)
                N1.high()
                N2.low()
                N3.high()
                N4.low()
                pyb.delay(30)
        if(M2.value()&M1.value()==1):
                pyb.LED(2).on()
                N1.low()
                N2.high()
                N3.high()
                N4.low()
                pyb.delay(70)

TPYBoard v10x 模拟红绿灯教程

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法
  • 进一步学习编制数据输出程序的设计方法
  • 学习模拟交通灯控制的方法
所需器件
  • 1位共阴红色LED数码管(SM42056) 1个
  • TPYBoard v10X开发板 1块
  • 红、绿、黄LED灯 各1个
  • micro USB数据线 1条
  • 220欧直插电阻 1个
  • 杜邦线 若干
  • 面包板 1块
点亮LED灯
  • 1.将三个LED灯插在面包板上,LED负极插入面包板的负极(横向插孔),正极插入面包板的纵向插孔。
  • 2.将222欧电阻插入面包板的负极上(横向插孔)和纵向插孔中,将LED灯的正极分别与TPYBoard v10x的引脚连接。
  • 3.将红、黄、绿3个LED灯的正极依次通过杜邦线连接到TPYBoard v10x的Y1,、Y2、Y3的引脚上, 然后将电阻纵向插孔用杜邦线接到TPYBoard v10x的GND引脚。
  • 4.在main.py文件中将Y1、Y2、Y3引脚的电平拉高,即可看到三个灯同时亮起来。

main.py 内容如下:

# main.py -- put your code here!
import pyb
led1 = pyb.Pin("Y1",pyb.Pin.OUT_PP)
led2 = pyb.Pin("Y2",pyb.Pin.OUT_PP)
led3 = pyb.Pin("Y3",pyb.Pin.OUT_PP)
While True:
    led1.value(1)
    led2.value(1)
    led3.value(1)

效果如图:

_images/test_11.png
点亮数码管

SM42056是0.56英寸一位共阴/红色LED数码管,共10个引脚。

_images/test_12.png

当小数点在你的右下角时,上面一排5个引脚,从左至右依次为g,f,GND,a,b,下面一排五个引脚,从左至右依次为 e,d,GND,c,dp。 如果我们想让数码管显示数字8的话,需要将a,b,c,d,e,f,g所连接的TPYBoard v10x的引脚拉高,把GND与TPYBoard v10x的GND引脚接起来就可以了。

效果图:

_images/test_13.png
模拟红绿灯

我们按照上面的步骤做完以后,然后通过准备的数据线给TPYBoard v10x通电。

main.py 内容如下::

# main.py – put your code here! import pyb led1 = pyb.Pin(“Y1”,pyb.Pin.OUT_PP) led2 = pyb.Pin(“Y2”,pyb.Pin.OUT_PP) led3 = pyb.Pin(“Y3”,pyb.Pin.OUT_PP) x1 = pyb.Pin(“X1”,pyb.Pin.OUT_PP) x2 = pyb.Pin(“X2”,pyb.Pin.OUT_PP) x3 = pyb.Pin(“X3”,pyb.Pin.OUT_PP) x4 = pyb.Pin(“X4”,pyb.Pin.OUT_PP) x5 = pyb.Pin(“X5”,pyb.Pin.OUT_PP) x6 = pyb.Pin(“X6”,pyb.Pin.OUT_PP) x8 = pyb.Pin(“X8”,pyb.Pin.OUT_PP) def six():

x1.value(1) x2.value(1) x3.value(1) x5.value(1) x6.value(1) x8.value(1) pyb.delay(1000) x1.value(0) x2.value(0) x3.value(0) x6.value(0) x5.value(0) x8.value(0)
def nine():
x1.value(1) x2.value(1) x3.value(1) x4.value(1) x5.value(1) x8.value(1) pyb.delay(1000) x1.value(0) x2.value(0) x3.value(0) x4.value(0) x5.value(0) x8.value(0)
def eight():
x1.value(1) x2.value(1) x3.value(1) x4.value(1) x5.value(1) x6.value(1) x8.value(1) pyb.delay(1000) x1.value(0) x2.value(0) x3.value(0) x4.value(0) x5.value(0) x6.value(0) x8.value(0)
def zero():
x2.value(1) x3.value(1) x4.value(1) x5.value(1) x6.value(1) x8.value(1) pyb.delay(1000) x2.value(0) x3.value(0) x4.value(0) x5.value(0) x6.value(0) x8.value(0)
def seven():
x3.value(1) x4.value(1) x8.value(1) pyb.delay(1000) x3.value(0) x4.value(0) x8.value(0)
def five():
x1.value(1) x2.value(1) x3.value(1) x5.value(1) x8.value(1) pyb.delay(1000) x1.value(0) x2.value(0) x3.value(0) x5.value(0) x8.value(0)
def four():
x1.value(1) x2.value(1) x4.value(1) x8.value(1) pyb.delay(1000) x1.value(0) x2.value(0) x4.value(0) x8.value(0)
def three():
x1.value(1) x3.value(1) x4.value(1) x5.value(1) x8.value(1) pyb.delay(1000) x1.value(0) x4.value(0) x3.value(0) x5.value(0) x8.value(0)
def two():
x1.value(1) x3.value(1) x4.value(1) x5.value(1) x6.value(1) pyb.delay(1000) x1.value(0) x3.value(0) x4.value(0) x5.value(0) x6.value(0)
def one():
x2.value(1) x6.value(1) pyb.delay(1000) x2.value(0) x6.value(0)
while True:
led1.value(1) nine() eight() seven() six() five() four() three() two() one() zero() led1.value(0) led2.value(1) nine() eight() seven() six() five() four() three() two() one() zero() led2.value(0) led3.value(1) three() two() one() zero() led3.value(0)
效果演示

[Micropython]TPYBoard DIY金属检测仪

原创版权归山东萝卜科技有限公司所有,转载必须以链接形式注明作者和原始出处。

1.实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输入输出程序的设计方法。
  3. 学习LJ12A3-4-Z/BX 金属接近开关的工作原理。
  4. 硬件接线方法。
  5. 学会用TPYBoard接收金属接近开关的输出信号,并对信号进行判断处理,点亮LED发光二极管。
2.所需元器件
TPYBoard板子一块 LJ12A3-4-Z/BX 金属接近开关一个 面包板一块 发光二极管一个 数据线一条 杜邦线若干
3.LJ12A3-4-Z/BX 接近开关工作原理

LJ12A3-4-Z/BX接近开关

4.硬件接线方法
上面我们将接近开关线接好后,TPYboard开发板即可通过Y1针脚收集金属开关传递过来的数字信号,我们即可通过这个信号,来让开发板控制自动门开,报警等,在这只是做了一个简单易懂的应用,点亮我们的红色LED发光二极管。
http://www.tpyboard.com/ueditor/php/upload/image/20161220/1482216954934573.png

周围没金属 接近金属时

5.源代码
# main.py -- put your code here!
import pyb
from machine import Pin

y1 = Pin('Y1', Pin.IN)
x1 = Pin('X1', Pin.OUT_PP)

while 1:
        #无金属时
        if y1.value() == 1 :
                print(y1.value())
                x1.value(0)
        #有金属时
        else:
                print(y1.value())
                x1.value(1)

[Micropython]TPYBoard DIY声光电控小夜灯

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

1.实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。
  3. 学习光敏模块的工作原理。
  4. 学习声音的工作原理。
  5. 学习TPYboard与声音传感器与光敏传感器的接线方法以及利用声音与光控制发光二极管亮灭。
2.所需元器件
TPYBoard板子一块 声音传感器一个 光敏传感器一个 面包板一块 发光二极管若干 数据线一条 杜邦线若干
3.光敏传感器模块工作原理
1.光敏电阻模块对环境光线最敏感,一般用来检测周围环境的光线的亮度,触发单片机或继电器模块等; 2.模块在环境光线亮度达不到设定阈值时,DO端输出高电平,当外界环境光线亮度超过设定阈值时,DO端输出低电平; 3.DO输出端可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的光线亮度改变; 4.DO输出端可以直接驱动本店继电器模块,由此可以组成一个光控开关。
http://www.micropython.net.cn/ueditor/php/upload/image/20161119/1479545872307793.png

光敏传感器

4.声音传感器模块工作原理
1.声音模块对环境声音强度最敏感,一般用来检测周围环境的声音强度。 2.模块在环境声音强度达不到设定阈值时,OUT输出高电平,当外界环境声音强度超过设定阈值时,模块OUT输出低电平; 3.小板数字量输出OUT可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的声音; 4.小板数字量输出OUT可以直接驱动本店继电器模块,由此可以组成一个声控开关;
http://www.micropython.net.cn/ueditor/php/upload/image/20161119/1479545901165245.png

声音传感器

5.硬件接线方法
上面我们已经知道光敏传感器跟声音传感器的工作原理,以及三根针脚的作用,那么我们只需讲电源正极与电源负极跟我们TPYBoard的3.3V跟GND连接起来,然后将光敏传感器与声音传感器的信号输出针脚连接到我们TPYBoard,本人声音传感器信号输出引脚连接的是TPYBoard的Y1针脚,光敏传感器信号输出引脚连接TOYBoard的Y2针脚,这样传感器就连接完毕,然后我们将发光数码管的正极插入面包板正极上,负极插入面包板的纵向插孔里(a,b,c,d,e,f,g,h,i,j),然后用杜邦线将负极连接到TPYBoard的GND上,灯的正极连接到我们TOYBoard的X1针脚,然后我们声音大小以及光亮强度来控制X1针脚输出高电平或者低电平来控制发光二极管的亮灭,接线ok后,编写main.py,这样我们的DIY声光电控开关就完成了。
6.源代码
# main.py -- put your code here!
import pyb
from pyb import Pin

voice = Pin('Y1',Pin.IN)
light = Pin('Y2',Pin.IN)
led = pyb.Pin("X1",pyb.Pin.OUT_PP)

while 1:
        if light.value()==1:
                if voice.value()==1:
                        led.value(0)
                        pyb.LED(2).off()
                        pyb.LED(3).off()
                        pyb.LED(4).on()
                else:
                        pyb.LED(3).off()
                        pyb.LED(4).off()
                        led.value(1)
                        pyb.LED(2).on()
                        pyb.delay(5000)
        else:
                pyb.LED(3).on()
                pyb.LED(2).off()
                pyb.LED(4).off()
                led.value(0)

[Micropython]TPYBoardV10X学习使用OLED显示屏

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

1. 实验目的
1.学习在PC机系统中扩展简单I/O 接口的方法。 2.进一步学习编制数据输出程序的设计方法。 3.学习TPYBoard控制OLED显示字符。
2. 所需元器件
TPYBoard板子一块 数据线一条 杜邦线若干 OLED液晶屏一块
3.什么是OLED显示屏
1.OLED显示屏简介

有机发光二极管(organic light-emitting diode,OLED)是一种由柯达公司开发并拥有专利的显示技术,这项技术使用有机聚合材料作为发光二极管中的半导体(semiconductor)材料。聚合材料可以是天然的,也可能是人工合成的,可能尺寸很大,也可能尺寸很小。其广泛运用于手机、数码摄像机、DVD机、个人数字助理(PDA)、笔记本电脑、汽车音响和电视。OLED显示器很薄很轻,因为它不使用背光。

本例中使用0.96 寸OLED显示屏,该屏具有高亮度,低功耗屏,显示颜色纯正,在阳光下有很好的可视效果。模块供电可以是3.3V 也可以是5V,不需要修改模块电路,同时兼容3种通信方式:4 线SPI、3线SPI、 IIC,通信模式的选择可以根据提供的BOM表进行跳选。该模块一共有三种颜色:蓝色、白色、黄蓝双色。OLED 屏具有多个控制指令,可以控制OLED 的亮度、对比度、开关升压电路等指令。操作方便,功能丰富。同时为了方便应用在产品上,预留4个M2 固定孔,方便用户固定在机壳上。0.96寸OLED显示屏的驱动芯片为:SSD1306(已集成在屏中)。

2.实际显示效果

http://www.micropython.net.cn/ueditor/php/upload/image/20170211/1486776004559236.png

3.OLED接口定义

1> GND= 电源地 2> VCC= 电源地(2.8V~5.5V) 3> D0 = 时钟线 4> D1 = 数据线 5> RES= 复位线 6> DC = 数据/命令 7> CS = 片选

4.硬件的接线方法

在这OLED需要SPI接口与TPYBoard进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,TPYBoard自带两个SPI接口,本实验中我们用的TPYBoard的SPI1接口。
1.具体接线方法
_images/oled.png
2.实物接线图
3.源代码
#main.py
import pyb
import upcd8544
from ssd1306 import SSD1306

display = SSD1306(pinout={'dc': 'Y9',
                      'res': 'Y10'},
              height=64,
              external_vcc=False)

led_red = pyb.LED(1)
led_red.off()
display.poweron()
display.init_display()
display.draw_text(1,1,'Hello World!',size=1,space=1)
display.draw_text(1,10,'this is TPYBoard V102!',size=1,space=1)
# 显示出你想要显示的内容
display.display()

OLED.ZIP ..LINK: http://www.micropython.net.cn/ueditor/php/upload/file/20170211/1486776338127363.zip

5.实现效果
http://www.micropython.net.cn/ueditor/php/upload/image/20170211/1486776202255121.png

[Micropython]TPYBoardV10X PM2.5检测仪制作

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明
一、[Micropython]TPYBoardV10X PM2.5检测仪制作
秋冬季节,雾霾天气的持续,让人们对空气质量的关注程度提升。而近期人们对于空气质量的关注总也绕不开一个词–“PM2.5”。《环境空气质量标准》将PM2.5、臭氧(8小时浓度)纳入常规空气质量评价,是我国首次制定关于PM2.5的监测标准。细颗粒物又称细粒、细颗粒、PM2.5.细颗粒物指环境空气中空气动力学当量直径小于等于 2.5 微米的颗粒物。PM2.5粒径小、面积大、活性强、易附带有毒、有害物质(例如,重金属、微生物等)。PM2.5对人体健康有着致命的危害。
那么PM2.5(细颗粒物)是什么?

科普:PM2.5到底是神马?

因为各国标准不一样,天气预报也报空气质量,预报的空气质量与实际的空气质量一样吗?但这个问题,想动手制作一个PM2.5检测仪,有了自己动手制作的PM2.5检测仪的话,当空气质量较差或者严重污染的时候,提醒家人,同学和身边的人尽量减少户外活动,真正减少吸入细颗粒物。

制作一个PM2.5检测仪的想法是好,在1个小时内能否制作出一个PM2.5检测仪呢?利用C/C++是贴近硬件的语言来做的话,要花好长一段时间甚至半年先学习C语言以后,再考虑动手制作,更不用说1个小时内制作出一个PM2.5检测仪。

接下来我介绍一个在1个小时内制作一个PM2.5的方法,也就是利用拥有自家的解析器、编译器、虚拟机和类库等,也就是具备二次开发和环境的TPYBoard开发板制作一个PM2.5检测仪吧。

先一起看下最终的视频演示效果吧!

1. PM2.5检测仪的目的

采用TPYBoard开发板为控制处理器,通过串口由PM2.5灰尘传感器GP2Y1010AU0F检测低程度的空气污染PM2.5能够甄别香烟和室内/室外灰尘,并通过SPI接口由LCD5110显示屏显示当前空气粉尘浓度(ug/m?)。当空气中粉尘浓度达到所设定限度点亮不同的LED灯来知道当前空气质量等级。

本系统电路简单、工作稳定、集成度高,调试方便,测试精度高,具有一定的实用价值。该检测仪通过Python脚本语言实现硬件底层的访问和控制细颗粒物检测传感器,每间隔一定时间,传感器自动进行检测,检测到的空气粉尘浓度数据通过串口上传至主控板,主控板收集到数据后,同样使用Python脚本语言将PM2.5的检测结果显示到LCD5110上。

参照1:TPYBoardLED亮灯状态与 PM2.5日均浓度对应的指数等级对应表

PM2.5值数 日均浓度值(ug/m³ ) 空气质量等级 LED灯状态
0~50 0-35 绿灯亮
50~100 35-75 绿灯亮
100~150 75-115 轻度污染 蓝灯亮
150~200 115-150 中度污染 黄灯亮
200~300 150-250 重度污染 红灯亮
>300 >250 严重污染 红灯亮
参照2: TPYBoard的硬件特点:
√ STM32F405RG MCU. √ 168 MHz Cortex-M4 CPU with 32-bit hardware floating point. √ 1 MiB flash storage, 192 KiB RAM. √ USB口, 支持 串口,通用存储,HID协议。 √ SD卡插槽。 √ MMA76603轴加速度计. √ 4 LEDs, 1复位按钮, 1通用按钮. √ 3.3V0.3A板载 LDO , 可从USB口或者外置电池供电。 √ 实时时钟。 √ 30个通用IO口,其中28个支持5V输入输出。 √ 2个 SPI接口, 2个 CAN接口, 2个I2C接口, 5个USART接口. √ 14个 12-bit ADC引脚。 √ 2个DAC 引脚。
2. 材料准备
制作PM2.5检测仪所需材料如下:
1.PM2.5粉尘传感器1个,检测PM2.5(细颗粒物)传感器,TXD串口输出。 2.TPYBoard开发板1块,主要用来当主控开发板,读入传感器数据。 3.Lcd5110显示屏1个,主要用来显示检测的信息。 4.杜邦线若干。 5.数据线一条。
http://www.micropython.net.cn/ueditor/php/upload/image/20160823/1471943991787031.png
3.硬件接线方法
3.1 传感器的针脚
传感器上一共六根线,从1到6依次是GND,VCC,NC,NC,RX,TX。其中我们只用三根线,电源(GND,VCC)和串口(TX),传感器与TPYBorad接线参照图1,具体用哪个串口请参照官方网站上文档TPYBoard 关于串口的使用,小编用的串口为 UART(2) is on: (TX, RX) = (X3, X4) = (PA2, PA3),因为只需要将数据传到PTYBoard,所以只用到RED即PTYBoard的X4引脚。
http://www.micropython.net.cn/ueditor/php/upload/image/20160823/1471941893958432.png

图1

3.2 LCD5110的针脚

先看一下LCD5110针脚含义吧(注意:LCD5110的针脚有些不一样的 TPYBoard的针脚与5110的针脚对应关系如下:

TPYBoard LCD5110 memo
Pin RST Reset pin (0=reset, 1=normal)
Pin CE Chip Enable (0=listen for input,1=ignore input)
Pin DC Data/Command (0=commands, 1=data)
MOSI DIN data flow (Master out, Slave in)
SCK CLK SPI clock
3V3/Pin VCC 3.3V logic voltage (0=off, 1=on)
Pin LIGHT Light (0=on, 1=off)
GND GND

还是看不明白的话,直接上针脚编号吧

TPYBoard LCD5110 memo
Y10 RST Reset pin (0=reset, 1=normal)
Y11 CE Chip Enable (0=listen for input,1=ignore input)
Y9 DC Data/Command (0=commands, 1=data)
X8 DIN data flow (Master out, Slave in)
X6 CLK SPI clock
VCC
Y12 LIGHT Light (0=on, 1=off)
GND
http://www.micropython.net.cn/ueditor/php/upload/image/20160823/1471942009875006.png

图2

3.3 PM2.5检测仪整体接线方法
按照图1、图2所示将PM2.5粉尘传感器以及5110显示屏与PTYBoard连接起来,硬件连接完毕,如图3:
http://www.micropython.net.cn/ueditor/php/upload/image/20160823/1471942098496980.png

图3

4.PM2.5粉尘传感器工作原理及数据处理
4.1 PM2.5粉尘传感器工作原理

PM2.5粉尘传感器的工作原理是根据光的散射原理来开发的,微粒和分子在光的照射下会产生光的散射现象,与此同时,还吸收部分照射光的能量。

当一束平行单色光入射到被测颗粒场时,会受到颗粒周围散射和吸收的影响,光强将被衰减。如此一来便可求得入射光通过待测浓度场的相对衰减率。而相对衰减率的大小基本上能线性反应待测场灰尘的相对浓度。光强的大小和经光电转换的电信号强弱成正比,通过测得电信号就可以求得相对衰减率,进而就可以测定待测场里灰尘的浓度。在传感器的中间有一个洞,这个洞可以让空气在里面流通。在洞的两个边缘 ,一面安装有一个激光发射器,另一面安装有激光接收器。这样一来,空气流过这个小洞,空气里的颗粒物呢就会挡住激光,从而产生散射,另一面的接收器,是依据接收到的激光强度来发出不同的信号的(其实就是输出不同的电压值)。这样一来,空气里的颗粒物越多,输出的电压越高,颗粒物越少,输出的电压越低。

内部结构如图内部结构仿真图所示:

http://www.micropython.net.cn/ueditor/php/upload/image/20160823/1471942150331605.png

内部结构仿真图

4.2 PM2.5粉尘传感器传感器数据处理

上面说了传感器的原理,接下来就说说它传出来的信号和对于接收到的信号的计算吧。

这个传感器的输出数据是靠串口进行传输的,传感器会通过串口每10ms不到(一般3~4ms)发送一个数据,数据的类型大致是个“0X00”这样的16进制的数据。每次的数据会以“0XAA”作为起始端,以“0XFF”作为结束端。共7个数据位,7个数据位中包含了起始位,结束位,数据高位,数据低位,数据高校验位,数据低校验位和校验位(校验位是怎样计算出来的,下面会讲到)。数据格式大致如下:

http://www.micropython.net.cn/ueditor/php/upload/image/20160823/1471942195856275.png

其中校验位长度=Vout(H)+Vout(L)+Vref(H)+Vref(L)的长度。

数据的组成一共是有7个数据位,但是只有Vout(H)和Vout(L)这两个数据才是我们真正所需要的。我们需要依照这两个数据算出来串口输出的数字数据,从而通过数模转换公式来计算出输出的电压。进一步的通过比例系数计算出空气中颗粒物的数量。下面来说一下怎么计算。

传感器输出的数据分为高位和低位,其中呢Vout(H)为高位,Vout(L)为低位。因为串口传进来的Vout(H)和Vout(L)是16进制的,第一步先转化成10进制的(这个大家都会,不多说了)。然后根据这两个输出值的10进制数计算出串口输出数值的电压。

公式如下(其中Vout(H)和Vout(L)是已转化为10进制的):

Vout=(Vout(H)*256+Vout(L))/1024*5

这样就算出来了他输出出来的电压了,再根据比例系数A,就可以计算出空气中的颗粒物的值了。(A的值一般是在800到1000,具体的数值还要根据你买到的传感器的精度,准确度和误差值进行确定。我现在用的是800。)

5.PM2.5粉尘传感器的采样频率及程序编码
5.1PM2.5粉尘传感器的采样频率

PM2.5粉尘传感器的采样频率是非常高的,一般3~4ms发送一个16进制的采样数据,也就是说传感器通电(接通VCC和GND)后,每隔3~4ms发送一个16进制的采样数据,这么高的采样频率作为一个检测仪来说显然是没有必要的。

TPYBoard通过串口接收粉尘传感器数据,使用串口当然先定义串口,通过打开就可以接收串口数据,关闭串口就停止接收数据的特点,来自由控制PM2.5粉尘传感器的采样频率。

5.2程序编码
我们main.py中,采用首先定义串口,其次是打开串口接收采样数据,最后关闭串口,并且处理采样数据及显示,依次循环。
6.运行测试
接线ok后,导入font.py文件和upcd8544.py文件(主要用于5110显示数据),再运行main.py即可看到当前的空气质量等级以及PM2.5的浓度值了。
7.源代码
把我写的程序的源码分享给大家,有需要的可以参考一下。
# main.py -- put your code here!
#main.py
import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *


leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
#A比例系数,在北方一般使用800-1000.南方空气好一些,一般使用600-800.这个还和你使用的传感器灵敏度有关的,需要自己测试再定下来
A=800
#G为固定系数,是为了把串口收到的数据转换成PM标准值
G=1024/5
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST        = pyb.Pin('Y10')
CE         = pyb.Pin('Y11')
DC         = pyb.Pin('Y9')
LIGHT  = pyb.Pin('Y12')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
u2 = UART(2, 2400)
count_=0
def ChangeLEDState(num_):
        global leds
        len_=len(leds)
        for i in range(0,len_):
                if i!=num_:
                        leds[i].off()
                else:
                        leds[i].on()
while True:
        u2.init(2400, bits=8, parity=None, stop=1)
        pyb.delay(80)
        Quality='DATA NULL'
        if(u2.any()>0):
                u2.deinit()
                _dataRead=u2.readall()
                #R代表截取数据的起始位
                R=_dataRead.find(b'\xaa')
                #R>-1代表存在起始位,长度大于起始位位置+2
                if R>-1 and len(_dataRead)>(R+2):
                        P=_dataRead[R+1]
                        L=_dataRead[R+2]
                        #把串口收到的十六进制数据转换成十进制
                        SHI=P*256+L
                        SHUCHU=SHI/G*A
                if(SHUCHU<35):
                        Quality = 'Excellente'
                        print('环境质量:优','PM2.5=',SHUCHU)
                        count_=1
                elif(35<SHUCHU<75):
                        Quality = 'Good'
                        print('环境质量:良好','PM2.5=',SHUCHU)
                        count_=1
                elif(75<SHUCHU<115):
                        Quality = 'Slightly-polluted'
                        print('环境质量:轻度污染 ','PM2.5=',SHUCHU)
                        count_=3
                elif(115<SHUCHU<150):
                        Quality = 'Medium pollution'
                        print('环境质量:中度污染 ','PM2.5=',SHUCHU)
                        count_=2
                elif(150<SHUCHU<250):
                        Quality = 'Heavy pollution'
                        print('环境质量:重度污染 ','PM2.5=',SHUCHU)
                        count_=0
                elif(250<SHUCHU):
                        Quality = 'Serious pollution'
                        print('环境质量:严重污染 ','PM2.5=',SHUCHU)
                        count_=0
        ChangeLEDState(count_)
        lcd_5110.lcd_write_string('AQI Level',0,0)
        lcd_5110.lcd_write_string(str(Quality),0,1)
        lcd_5110.lcd_write_string('PM2.5:',0,2)
        lcd_5110.lcd_write_string(str(SHUCHU),0,3)

TPYBoard v10x 驱动舵机教程

引言

大家应该都看到过机器人的手臂啊腿脚啊什么的一抽一抽的在动弹吧...是不是和机械舞一样的有节奏,现在很多机器人模型里面的动力器件都是舵机。

但是大家一般见到的动力器件都是像步进电机,直流电机这一类的动力器件,应该对舵机比较陌生。

舵机主要有以下3个优点:

一是体积紧凑,便于安装;

二是输出力矩大,稳定性好;

三是控制简单,便于和数字系统接口。

本次教程中使用的是SG90的舵机,个人感觉性能一般,但是比较稳定和耐用,做DIY实验器材用还是比较不错的。

舵机的基本介绍
  • 1.舵机的组成与参数

    舵机,又称伺服马达,是一种具有闭环控制系统的机电结构。舵机主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。 其工作原理是由控制器发出PWM(脉冲宽度调制)信号给舵机,经电路板上的IC处理后计算出转动方向,再驱动无核心马达转动, 透过减速齿轮将动力传至摆臂,同时由位置检测器(电位器)返回位置信号,判断是否已经到达设定位置,一般舵机只能旋转180度。 .. image:: ../img/test_31.png

  • 2.舵机的接线

    舵机有3根线,棕色为地,红色为电源正,橙色为信号线,但不同牌子的舵机,线的颜色可能不同。

  • 3.舵机的控制原理

    舵机的转动的角度是通过调节PWM(脉冲宽度调制)信号的占空比来实现的。 占空比:

    1.指高电平在一个周期之内所占的时间比率。 2.正脉冲的持续时间与脉冲总周期的比值。例如:正脉冲宽度1μs,信号周期10μs的脉冲序列占空比为0.1。即:脉冲的宽度除以脉冲的周期称为占空比。

    标准PWM(脉冲宽度调制)信号的周期固定为20ms(50Hz),理论上脉宽分布应在1ms到2ms之间,但是,事实上脉宽可由0.5ms到2.5ms之间,脉宽和舵机的转角0°~180°相对应。

Python语言驱动舵机的方法
其实说了以上这些呢,都是为了给大家介绍利用Python语言来控制舵机的转动角度,和普通单片机一样的,都是需要用不同宽度的脉冲来控制器转动的角度。 说白了,我们需要做的就是使用Python语言来输出不同宽度的脉冲信号,来给到信号线里面去。现在一般的舵机脉宽那都是在0.5ms到2.5ms之间,这就可以计算了。 0.5MS-2.5MS这两毫秒里面可以控制转动到180度,这样算下来,转一度的脉冲时间大约就是2毫秒/180度=0.011毫秒/度,这样依次计算就可以了。剩下的就是写一个脉冲信号了,相信写脉冲信号的程序大家都很熟悉啦。 但是,在舵机里面有一些几点几的毫秒的延时脉冲,这个在Python语言里如果想要利用delay()函数来做延时的话,很难做到每个角度都可以转到,甚至说是很难做到转动到大多数的角度。所以,你需要找到一个比毫秒延时还要精确的延时函数来作为脉冲的计时延时函数。我现在用的是time.sleep(i)这个函数,这个函数里面的i,建议设置在0.0000-0.0035之间。不能说精确的转动到每个角度吧,但是百分之九十的角度都是可以转到。如果想让舵机进行循环摆动,一定要记得加上适当的延时,因为程序可以飞快的跑,但是舵机转动也是需要一点时间的。舵机转动时间肯定要比程序跑一遍的时间要长的多啦。
TPYBoard v10x驱动舵机
  • 实验目的

    通过加速度传感器的X方向控制舵机的转动,让舵机随TPYBoard 的转动而转动

  • 实验材料

    1. TPYBoard v10x 开发板 1块
    2. SG90舵机 1个
    3. 杜邦线 若干
  • 实验线路图

    这里电路图很简单,只需要给舵机接上VCC和GNG(这是最基本的,这个开发板上好多电源和地可以用)。 然后把舵机的信号线接到任意一个GPIO口(后面程序里面要在这个GPIO往外输出脉冲的,我用了X1,还有很多其他的GPIO口可以用。)就可以了。 接线原理图: .. image:: http://www.tpyboard.com/ueditor/php/upload/image/20160722/1469172131214565.png 实物连接图: .. image:: http://www.tpyboard.com/ueditor/php/upload/image/20160722/1469172305445497.jpg

  • 实验代码

    注意:实验中用0做了x的分界点,有的开发板,x的范围可能在11-31不等,所以这个分界点,可以在实验中自己取值。

    main.py 内容如下:

    import pyb import time from pyb import Pin xlights = (pyb.LED(2), pyb.LED(3)) ylights = (pyb.LED(1), pyb.LED(4)) M0 = Pin(‘X1’, Pin.OUT_PP) accel = pyb.Accel() i=0.0001 j=0.0000 while True:

    x = accel.x() print(“x=”) print(x) Y=x+20 M0.high() time.sleep(i*Y) M0.low() time.sleep(i*Y) pyb.delay(12) if x > 0:

    xlights[0].on() xlights[1].off()

    elif x < 0:

    xlights[1].on() xlights[0].off()

    else:

    xlights[0].off() xlights[1].off()

效果演示

视频观看地址:

虽然舵机只是能实现转动指定的角度,看起来功能很单一,但是单一的功能结合起来,就能完成很复杂的任务。

TPYBoard v10x 驱动LCD5110显示6x8字符

实验目的
  • 学习LCD5110的使用方法
  • 了解SPI接口的使用方法
所需器件
  • TPYBoard v10X开发板 1块
  • LCD5110显示屏 1个
  • micro USB数据线 1条
  • 杜邦线 若干
LCD5110显示屏的针脚含义
  • RST:复位
  • CE :片选
  • DC :数据/指令选择
  • DIN:串行数据线
  • CLK:串行时钟线
  • VCC:电源输入(3.3v和5v均可)
  • BL :背光控制端
  • GND:地线
驱动LCD5110显示屏

TPYBoard v10x的针脚与LCD5110的针脚对应关系如下:

_images/test_21.png

当小数点在你的右下角时,上面一排5个引脚,从左至右依次为g,f,GND,a,b,下面一排五个引脚,从左至右依次为 e,d,GND,c,dp。 如果我们想让数码管显示数字8的话,需要将a,b,c,d,e,f,g所连接的TPYBoard v10x的引脚拉高,把GND与TPYBoard v10x的GND引脚接起来就可以了。

main.py 内容如下:

# main.py -- put your code here!
import pyb
import upcd8544
from machine import SPI,Pin

def main():
    SPI    = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
    #DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
    #CLK =>SPI(1).SCK  'X6' SPI clock

    RST    = pyb.Pin('Y10')
    CE     = pyb.Pin('Y11')
    DC     = pyb.Pin('Y9')
    LIGHT  = pyb.Pin('Y12')
    lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)

    lcd_5110.lcd_write_string('Hello Python!',0,0)
    lcd_5110.lcd_write_string('Micropython',6,1)
    lcd_5110.lcd_write_string('TPYBoard',12,2)
    lcd_5110.lcd_write_string('v102',60,3)
    lcd_5110.lcd_write_string('This is a test of LCD5110',0,4)
if __name__ == '__main__':
    main()

效果图:

_images/test_22.png

[Micropython]TPYBoardV10X DIY温度计

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

1、实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。

3. 学习DS18B20的接线方法,并利用DS18B20检测当前温度 3. 学习8*8LED点阵接线方法,并将当前温度显示

2、所需元器件

TPYBoard板子一块 数据线一条 杜邦线若干 8*8LED点阵一个 DS18B20温度传感器一个

3、学习DS18B20的接线方法,检测当前温度
http://www.micropython.net.cn/ueditor/php/upload/image/20160815/1471247227119424.png

先看一下DS18B20针脚含义,如上图:

TPYBoard的针脚与DS18B20的针脚对应关系如下:

TPYBoard DS18B20
3V3/Pin VDD
Pin DO
GND GND

还是看不明白? 直接上针脚编号

TPYBoard LCD5110
3.3v VDD
GND GND
Y10 DO

接线ok后,在MicroPython的源码目录中,进入driversonewire目录,然后将目录下的文件ds18x20.py和onewire.py复制到PYBFLASH磁盘的根目录。复制文件后要安全退出磁盘,然后重新接入,不然找不到文件,即可运行main.py文件了,打印温度,即可用Putty看到当前的温度。

main.py源代码:

#main.py
import pyb
from pyb import Pin
from ds18x20 import DS18X20
Pin("Y11",Pin.OUT_PP).low()#GND
Pin("Y9",Pin.OUT_PP).high()#VCC
pyb.delay(100)
DQ=DS18X20(Pin('Y10'))#DQ
while True:
        tem = DQ.read_temp()
        print(tem)
        pyb.delay(1000)
4、点亮8*8LED点阵
5、点将温度显示在8*8LED点阵上
接线成功以后,我们将测试出温度通过分割函数将十位,个位,小数点,以及后面的数字显示出来,代码如下:
import pyb
from pyb import Pin
from ds18x20 import DS18X20
x_PIN = [Pin(i, Pin.OUT_PP) for i in ['X1','X2','X3','X4','X5','X6','X7','X8']]
y_PIN = [Pin(i, Pin.OUT_PP) for i in ['Y1','Y2','Y3','Y4','Y5','Y6','Y7','Y8']]
temp=['0000,0110,0110,0110,0110,0110,0110,0000','1101,1101,1101,1101,1101,1101,1101,1101,
'0000,1110,1110,0000,0111,0111,0111,0000','0000,1110,1110,0000,1110,1110,1110,0000',
'0101,0101,0101,0000,1101,1101,1101,1101','0000,0111,0111,0000,1110,1110,1110,0000',
'0000,0111,0111,0000,0110,0110,0110,0000','0000,1110,1110,1110,1110,1110,1110,1110',
'0000,0110,0110,0000,0110,0110,0110,0000','0000,0110,0110,0000,1110,1110,1110,0000']
tempValue=0
def show(l_num,r_num):
        flag=0
        for x_ in range(0,8):
                for x_ in range(0,8):
                        if x_!=flag:
                                x_PIN[x_].value(0)
                left_ = temp[l_num]
                left_item=left_.split(',')
                right_ = temp[r_num]
                right_item=right_.split(',')
                li_l=left_item[flag]
                li_r=right_item[flag]
                y_PIN[0].value(int(li_l[:1]))
                y_PIN[1].value(int(li_l[1:2]))
                y_PIN[2].value(int(li_l[2:3]))
                y_PIN[3].value(int(li_l[3:4]))
                y_PIN[4].value(int(li_r[:1]))
                y_PIN[5].value(int(li_r[1:2]))
                y_PIN[6].value(int(li_r[2:3]))
                y_PIN[7].value(int(li_r[3:4]))
                x_PIN[flag].value(1)
                flag=flag+1
                pyb.delay(2)
def display(time_,l_num,r_num):
        for x in range(0,time_):
                for y in range(0,110):
                        show(l_num,r_num)
if __name__=='__main__':
        #time_t=Timer(4,freq=5,callback=randSensor)
        DQ=DS18X20(Pin('Y10'))#DQ
        while 1:
                tempValue =int(DQ.read_temp())
                print(tempValue)
                l_n=tempValue//10
                r_n=tempValue%10
                print(l_n)
                print(r_n)
                display(60,l_n,r_n)
                for i in x_PIN:
                        i.value(0)

[Micropython]TPYBoard DIY超声波测距仪

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

1.实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。
  3. 学习超声波模块的测距原理。
  4. 学习LCD5110接线方法
  5. 学习TPYboard控制超声波模块测距。
2.所需元器件
超声波模块一个 TPYBoard板子一块 5110LCD显示屏一个 数据线一条 杜邦线若干
3.超声波模块工作原理
(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。 (2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回。 (3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。 如下图接线,VCC 供 5V电源, GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四个接口端。
http://www.micropython.net.cn/ueditor/php/upload/image/20161116/1479286451773829.png
4.控制5110显示屏显示6x8字符

先看一下LCD5110针脚含义吧(注意:LCD5110的针脚有些不一样的) TPYBoard的针脚与5110的针脚对应关系如下:

TPYBoard LCD5110 memo
Pin RST Reset pin (0=reset, 1=normal)
Pin CE Chip Enable (0=listen for input,1=ignore input)
Pin DC Data/Command (0=commands, 1=data)
MOSI DIN data flow (Master out, Slave in)
SCK CLK SPI clock
3V3/Pin VCC 3.3V logic voltage (0=off, 1=on)
Pin LIGHT Light (0=on, 1=off)
GND GND

还是看不明白的话,直接上针脚编号吧.

TPYBoard LCD5110 memo
Y10 RST Reset pin (0=reset, 1=normal)
Y11 CE Chip Enable (0=listen for input, 1=ignore input)
Y9 DC Data/Command (0=commands, 1=data)
X8 DIN data flow (Master out, Slave in)
X6 CLK SPI clock
VCC
Y12 LIGHT Light (0=on, 1=off)
GND
5.源代码
import pyb
from pyb import Pin
from pyb import Timer
import upcd8544
from machine import SPI,Pin

Trig = Pin('X2',Pin.OUT_PP)
Echo = Pin('X1',Pin.IN)
num=0
flag=0
run=1
def start(t):
        global flag
        global num
        if(flag==0):
                num=0
        else:
                num=num+1
def stop(t):
        global run
        if(run==0):
                run=1
start1=Timer(1,freq=10000,callback=start)
stop1=Timer(4,freq=2,callback=stop)

while True:
        if(run==1):
                SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
                #DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
                #CLK =>SPI(1).SCK  'X6' SPI clock
                RST        = pyb.Pin('Y10')
                CE         = pyb.Pin('Y11')
                DC         = pyb.Pin('Y9')
                LIGHT  = pyb.Pin('Y12')
                lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
                Trig.value(1)
                pyb.udelay(100)
                Trig.value(0)
                while(Echo.value()==0):
                        Trig.value(1)
                        pyb.udelay(100)
                        Trig.value(0)
                        flag=0
                if(Echo.value()==1):
                        flag=1
                        while(Echo.value()==1):
                                flag=1
                if(num!=0):
                        #print('num:',num)
                        distance=num/10000*34000/2
                        print('Distance')
                        print(distance,'cm')
                        lcd_5110.lcd_write_string('Distance',0,0)
                        lcd_5110.lcd_write_string(str(distance),6,1)
                        lcd_5110.lcd_write_string('cm',58,1)
                        lcd_5110.lcd_write_string('This is a test of Distance',0,2)
                flag=0
                run=0

TPYBoard v201 典型实例

[Micropython]TPYBoardV201建立云加法器

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

前面的一篇文档向大家介绍了v201的开发板作为客户端终端向TCPS上传数据的基本过程,这次向大家简单介绍一下怎样使用V201开发板搭建一台简易的服务器做远程云加法器。
一.实验器件
TPYBoard_V201开发板一块
二.TPYBoard_V201开发板

TPYBoard_V201是以遵照MIT许可的MicroPython为基础,由TurnipSmart公司制作的一款MicroPython开发板,它基于STM32F405单片机,通过USB接口进行数据传输。该开发板内置4个LED灯、板载V201网口功能,可在3.3V-10V之间的电压正常工作。可以说这个开发板在网络稳定方面是一霸也不为过,板上其他硬件资源也非常丰富,像单总线,i2c,spi,串口等接口也是应有尽有,这次我们就要用到串口的功能。

上面介绍了所需器件,下面我们来说一下实验所需的环境。这里只需要能给开发板供电,以及可以支持有线网络连接(可以给开发板接上网线)即可。

实验的第一步,给开发板进行供电和插上网线,看到V201网口上的绿色指示灯亮起来,说明已经连接上网络。

三.配置V201网口

这一步是为了设置V201网口模块的目的地址,本地端口,波特率,数据位,校验位等一系列信息,具体配置方向详见:V201网口配置使用文档。

接着我们来说一下基本的逻辑流程:

1.确认供电和网络完好;

2.确认网络完好,接下来就是进行传输和处理,在保证网络通畅的前提下,设置串口6,也就是Y1和Y2,具体的波特率这个要参照你前面设置给V201网口的波特率来定;

3.在这里需要说一句的是,这个开发板在使用以太网功能的时候,Y1,Y2,Y3这三个引脚是被占用的,其中Y1和Y2是串口,执行通信功能;

4.这里需要介绍一下Y3,Y3是V201网口的设置引脚,当Y3不为低电平时,V201网口处于正常工作状态,可以进行数据上传,也可以利用设置软件通过网络进行配置。当Y3为低电平时,V201网口进入串口配置模式,可利用设置软件通过串口进行配置,此时不能进行数据上传;

5.以上工作全部完成后,剩下的就是时刻监控串口6是否有数据; 6.当第一收到数据的时候,把计数变量加一,并利用寄存变量保存数据; 7.当第二次收到数据之后,把计数变量加一,并利用寄存器变量保存数据; 8.当判断到计数变量为二时,把两次收到的数据相加; 9.最后我们只需要把两次相加的结果从串口6发送出去即可;

四.实物及数据图
下面是我做实验的实物图和数据监控截图,我是在我的电脑上开了个模拟的客户端口,虽然low了点,但是效果一样的。
http://www.micropython.net.cn/ueditor/php/upload/image/20170415/1492221696685070.jpg

实物图

http://www.micropython.net.cn/ueditor/php/upload/image/20170415/1492221741955689.png

数据监控截图

五.源代码

下面是我做的源代码,共享给大家。

import pyb
from pyb import UART
from pyb import Pin
from ubinascii import hexlify
from ubinascii import *

ulan = UART(6, 9600)#定义连接网口的串口
K=1
jia=0
jie1=0
he=0
js=0#设置寄存变量
#*******************************主程序**********************************
print('while')
while (K>0):
        _dataRead=ulan.readall()#读取客户端数据
        if _dataRead!=None:#判断客户端是否传来数据
                print(_dataRead)
                js=js+1#计数判断执行命令标志
                if(js==1):
                        jia=_dataRead.decode('utf-8')#数据转换
                        jia=int(jia)#数据转换
                        print(jia)
                if(js==2):
                        jia1=_dataRead.decode('utf-8')
                        jia1=int(jia1)
                        print(jia1)
                if(js==2):
                        he=jia+jia1
                        js=0
                        ulan.write(str(jia)+'+'+str(jia1)+'='+str(he)+'\r\n')#计算结果返回给客户端

[Micropython]TPYBoardV201 温湿度上传

版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明

历来关于温湿度的检测都是没有间断过的,这次我们继续检测温湿度,同样还是使用DHT11来检测。但是这次检测到的温湿度不进行显示,也不进行报警,这次要把检测到的数据通过以太网上传到服务器上去。

先来说一下需要的器件:

TPYBoardV201开发板一块; DHT11温湿度模块一个; 面包板一个(可省略); 杜邦线若干; 先来简单介绍一下各个器件。

TPYBoardV201开发板

TPYBoardV201是以遵照MIT许可的MicroPython为基础,由TurnipSmart公司制作的一款MicroPython开发板,它基于STM32F405单片机,通过USB接口进行数据传输。该开发板内置4个LED灯、板载V201网口功能,可在3.3V-10V之间的电压正常工作。可以说这个开发板在网络稳定方面是一霸也不为过,板上其他硬件资源也非常丰富,像单总线,i2c,spi,串口等接口也是应有尽有,这次我们就要用到串口和单总线的功能。

DHT11

DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。

上面介绍了所需器件,下面我们来说一下实验所需的环境。这里只需要能给开发板供电,以及可以支持有线网络连接(可以给开发板接上网线)即可。

下面实验开始

一.按照下表进行接线
DHT11V201 开发板
GND GND
VCC VIN
DATA X8

其次就是给开发板进行供电和插上网线,看到V201网口上的绿色指示灯亮起来,说明已经连接上网络。

二.配置V201网口

这一步是为了设置V201网口模块的目的地址,本地端口,波特率,数据位,校验位等一系列信息,具体配置方向详见:V201网口配置使用文档。

接着我们来说一下基本的逻辑流程:

我们这次是为了把温湿度数据上传服务器,第一步肯定是现在开发板上获取到温湿度的数据,关于DHT11的使用,开发板这边提供了非常详细的使用方法和DHT11的库,这里就不做多余介绍啦。

在我们成功获取到温湿度以后,把温湿度数据进行分割处理,说白了就是把温度和湿度分开。

前面把要传的数据都处理好了,接下来就是进行传输,在保证网络通畅的前提下,设置串口6,也就是Y1和Y2,具体的波特率这个要参照你前面设置给V201网口的波特率来定。

在这里需要说一句的是,这个开发板在使用以太网功能的时候,Y1,Y2,Y3这三个引脚是被占用的,其中Y1和Y2是串口,执行通信功能。

这里需要介绍一下Y3,Y3是V201网口的设置引脚,当Y3不为低电平时,V201网口处于正常工作状态,可以进行数据上传,也可以利用设置软件通过网络进行配置。当Y3为低电平时,V201网口进入串口配置模式,可利用设置软件通过串口进行配置,此时不能进行数据上传。

以上工作全部完成后,剩下的就是把配置好的数据,通过串口6发送出去。

最后我们只需要监控数据是不是上传正常就可以了。

下面是我做实验的实物图和数据监控截图,我是在我的电脑上开了个模拟的端口,虽然low了点,但是效果一样的。

http://www.micropython.net.cn/ueditor/php/upload/image/20170415/1492220610497650.jpg

实物图

http://www.micropython.net.cn/ueditor/php/upload/image/20170415/1492220644727630.png

数据监控截图

源代码

下面是源代码,共享给大家。

import pyb
from pyb import UART
from pyb import Pin
from ubinascii import hexlify
from ubinascii import *
from DHT11 import DHT11#定义温湿度传感器的库

ulan = UART(6, 115200)#定义串口,我的网口设置了115200的波特率
K=1
#*******************************主程序**********************************
print('while')
while (K>0):
        S=DHT11()#调用温湿度传感器的方法
        A=S.read_temps()#读取温湿度的值
        print('A:',A)
        print('A:',A[0:2])
        print('A:',A[3:5])#打印温湿度的值
        ulan.write('temperature is:'+A[0:2]+'\r\n')#上传温度
        pyb.delay(2000)#做延时是为了让给模拟服务器一个反应时间
        ulan.write('wet is:'+A[3:5]+'%'+'\r\n')#上传湿度
        pyb.delay(12000)

TPYBoard v202 典型实例

[Micropython]TPYBoardV202快速入门

通用方法 machine类库:

import machine
machine.freq()          # get the current frequency of the CPU
machine.freq(160000000) # set the CPU frequency to 160 MHz

esp类库:

import esp
esp.osdebug(None)       # turn off vendor O/S debugging messages
esp.osdebug(0)          # redirect vendor O/S debugging messages to UART(0)

联网 network类库:

import network
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True)       # activate the interface
wlan.scan()             # scan for access points
wlan.isconnected()      # check if the station is connected to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac')      # get the interface's MAC adddress
wlan.ifconfig()         # get the interface's IP/netmask/gw/DNS addresses
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.active(True)         # activate the interface
ap.config(essid='ESP-AP') # set the ESSID of the access point

连接到本地WiFi网络:

def do_connect():
        import network
        wlan = network.WLAN(network.STA_IF)
        wlan.active(True)
        if not wlan.isconnected():
                print('connecting to network...')
                wlan.connect('essid', 'password')
                while not wlan.isconnected():
                        pass
        print('network config:', wlan.ifconfig())

延迟和时间 time 类库

import time
time.sleep(1)           # sleep for 1 second
time.sleep_ms(500)      # sleep for 500 milliseconds
time.sleep_us(10)       # sleep for 10 microseconds
start = time.ticks_ms() # get millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference

计时器

import time
time.sleep(1)           # sleep for 1 second
time.sleep_ms(500)      # sleep for 500 milliseconds
time.sleep_us(10)       # sleep for 10 microseconds
start = time.ticks_ms() # get millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference

周期以毫秒为单位。

引脚和GPIO 使用machine.Pin类库:

from machine import Pin
p0 = Pin(0, Pin.OUT)    # create output pin on GPIO0
p0.high()               # set pin to high
p0.low()                # set pin to low
p0.value(1)             # set pin to high
p2 = Pin(2, Pin.IN)     # create input pin on GPIO2
print(p2.value())       # get value, 0 or 1
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation

可用引脚为:0,1,2,3,4,5,12,13,14,15,16,其对应于ESP8266芯片的实际GPIO引脚号。请注意,许多终端用户板使用自己的adhoc引脚编号(标记为D0,D1,...)。由于MicroPython支持不同的单板和模块,所以选择物理引脚编号作为最低的公分母。对于逻辑引脚和物理芯片引脚之间的映射,请参阅电路板文档。

注意,引脚(1)和引脚(3)分别是REPL UART TX和RX。还要注意,Pin(16)是一个特殊的引脚(用于从深睡眠模式唤醒),可能不适用于更高级别的类 Neopixel。

PWM(脉宽调制) 除引脚(16)外的所有引脚都可以使能PWM。所有通道都有一个频率,范围介于1到1000(以Hz为单位)。占空比介于0和1023之间。

使用machine.PWM类:

from machine import Pin, PWM
pwm0 = PWM(Pin(0))      # create PWM object from a pin
pwm0.freq()             # get current frequency
pwm0.freq(1000)         # set frequency
pwm0.duty()             # get current duty cycle
pwm0.duty(200)          # set duty cycle
pwm0.deinit()           # turn off PWM on the pin
pwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go

ADC(模数转换) ADC在专用引脚上可用。请注意,ADC引脚上的输入电压必须在0v和1.0v之间。

使用machine.ADC类:

from machine import ADC
adc = ADC(0)            # create ADC object on ADC pin
adc.read()              # read value, 0-1024

SPI总线 有两个SPI驱动程序。一个在软件(bit-banging)中实现,并可在所有引脚上工作:

from machine import Pin, SPI
# construct an SPI bus on the given pins# polarity is the idle state of SCK# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
spi.init(baudrate=200000) # set the baudrate
spi.read(10)            # read 10 bytes on MISO
spi.read(10, 0xff)      # read 10 bytes while outputing 0xff on MOSI
buf = bytearray(50)     # create a buffer
spi.readinto(buf)       # read into the given buffer (reads 50 bytes in this case)spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
spi.write(b'12345')     # write 5 bytes on MOSI
buf = bytearray(4)      # create a buffer
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf

硬件SPI更快(高达80Mhz),但仅适用于以下引脚: MISOGPIO12 MOSI是GPIO13,SCK是GPIO14。它具有与上述bitbanging SPI类相同的方法,除了构造函数和init的引脚参数(正如固定的那样):

from machine import Pin, SPI
hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)

I2C总线 I2C驱动程序通过以下程序来实现,并可在TPYBoard v202所有引脚上工作:

from machine import Pin, I2C  # construct an I2C bus
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
i2c.readfrom(0x3a, 4)   # read 4 bytes from slave device with address 0x3a
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
buf = bytearray(10)     # create a buffer with 10 bytes
i2c.writeto(0x3a, buf)  # write the given buffer to the slave

深度睡眠模式 将GPIO16连接到复位引脚(HUZZAH上的RST)。可以使用以下代码进行睡眠,唤醒并检查复位原因:

import machine
# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
# check if the device woke from a deep sleepif machine.reset_cause() == machine.DEEPSLEEP_RESET:
        print('woke from a deep sleep')
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000)
# put the device to sleep
machine.deepsleep()

OneWire驱动 OneWire驱动程序通过以下程序实现,并可在TPYBoard v202所有引脚上工作:

from machine import Pinimport onewire
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
ow.scan()               # return a list of devices on the bus
ow.reset()              # reset the bus
ow.readbyte()           # read a byte
ow.writebyte(0x12)      # write a byte on the bus
ow.write('123')         # write bytes on the bus
ow.select_rom(b'12345678') # select a specific device by its ROM code

DS18S20和DS18B20的驱动程序:

import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
        print(ds.read_temp(rom))

确保在数据线上放置4.7k的上拉电阻。请注意,convert_temp()每次要采样温度时都必须调用该方法。

NeoPixel驱动 使用neopixel类库:

from machine import Pin
from neopixel import NeoPixel
pin = Pin(0, Pin.OUT)   # set GPIO0 to output to drive NeoPixels
np = NeoPixel(pin, 8)   # create NeoPixel driver on GPIO0 for 8 pixels
np[0] = (255, 255, 255) # set the first pixel to white
np.write()              # write data to all pixels
r, g, b = np[0]         # get first pixel colour

对于NeoPixel的入门使用:

import esp
esp.neopixel_write(pin, grb_buf, is800khz)

APA102驱动 使用apa102类库:

from machine import Pin
from apa102 import APA102
clock = Pin(14, Pin.OUT)     # set GPIO14 to output to drive the clock
data = Pin(13, Pin.OUT)      # set GPIO13 to output to drive the data
apa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixels
apa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31apa.write()                  # write data to all pixels
r, g, b, brightness = apa[0] # get first pixel colour

对于APA102的入门使用:

import esp
esp.apa102_write(clock_pin, data_pin, rgbi_buf)

DHT驱动 DHT驱动程序通过以下代码实现,并可在TPYBoard v202所有引脚上工作:

import dhtimport machine
d = dht.DHT11(machine.Pin(4))
d.measure()d.temperature() # eg. 23 (째C)
d.humidity()    # eg. 41 (% RH)
d = dht.DHT22(machine.Pin(4))
d.measure()d.temperature() # eg. 23.6 (째C)
d.humidity()    # eg. 41.3 (% RH)

[Micropython][ESP8266] TPYBoardV202文件查看修改

MicroPython开发板都是带有文件系统的,与tpyboard v102不同,V202上没有USB接口(只有USB转TTL串口),所以只能通过串口或者Wifi方式访问。
一、介绍几个简单的命令

显示文件列表 通过串口访问文件的方法,跟tpyboard一样,都是通过os列出当前目录下的文件和目录:

>>> import os
>>> os.listdir()
['boot.py', 'demos', 'drive', 'main.py']

查看当前目录 >>> os.getcwd()

改变当前目录 >>> os.chdir()

创建目录: >>> os.mkdir(“demos”) os.mkdir(“demos”)命令就是创建一个demos的目录,档执行os.listdir()时会显示[‘boot.py’, ‘main.py’, ‘demos’]说明已经在开发板中建立了一个demos的目录。

删除指定文件 >>>os.remove()

删除指定目录 >>>os.rmdir()

二、利用串口进行查看文件列表和修改文件
1.首先打开工具,进入调试串口页面
http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489559217503207.png http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489559228312214.png

点击open出现下面界面

三、TPYBoard V202网络配置
下面我们将TPYBoard V202连接本地网络

[Micropython][TPYBoard-ESP8266开发板]之固件的烧写

今天,带大家一起玩一下最新的开发板TPYBoard-esp8266开发板,这是一款esp8266版的micropython开发板。

一、准备工作

1.TPYBoard-esp8266开发板 1个 2.USB数据线 1条 3.电脑 1台(嘻嘻,本篇文章以windows7系统为例)

二、烧写固件

第一步:下载烧写固件所需的软件

在windows系统下可以使用ESPFlashDownloadTool_v3.3.4软件。不用担心不好找,见下面的附件压缩包。

flash_download_tools_v3.3.4_win.zip

第二步:连接TPYBoard-esp8266开发板
通过USB数据线将电脑和TPYBoard-esp8266开发板连接起来,会自动安装USB转串的驱动。 安装完毕后,查看设备管理器,是否正确创建串口。我的电脑是COM44
http://www.tpyboard.com/ueditor/php/upload/image/20170222/1487750528571423.png

[Micropython][ESP8266]TPYBoardV202固件刷新及flash擦除

1.实验目的
  1. 学会TPYBoard v202开发板的固件完整性检查
  2. 学会flash的擦除方法
2.准备工作
·所需元器件 TPYBoard板子一块 数据线一条 电脑 1台(本次实验以win7为例) ·所需软件 PuTTY
3. 固件完整性检查
第一步:下载安装所需的软件–PuTTY 第二步:连接TPYBoard v202开发板 通过USB数据线将电脑和TPYBoard v202开发板连接起来,会自动安装USB转串的驱动。 安装完毕后,查看设备管理器,是否正确创建串口。
http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557520973289.png

第三步:打开PuTTY,根据下图标记的红色框进行设置。

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557553767371.png http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557752936716.png

第四步:设置完成后,单击open按钮。

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557763855186.png

第五步:按下板子上的rst,进行重置。

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557774682280.png

第六步:按下图命令操作

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557784930344.png

如果最后显示True,代表固件是完整的,否则可能存在问题。 如果显示False,最好重新刷一次固件,详细操作请参考: http://www.tpyboard.com/support/tutorial22/269.html

4. flash的擦除方法
第一步:安装Python环境 从Python的官方网站http://www.python.org下载最新的2.7版本

[Micropython][ESP8266]TPYBoardV202之GPIO

1.实验目的
  1. 学习在PC机系统中GPIO(General Purpose I/O Ports,即通用输入/输出端口)的使用方法。
  2. 学会用TPYBoard接收GPIO的高低电平,控制板子上LED灯的发光与否。
2.准备工作
·所需元器件 TPYBoard板子一块 数据线一条 电脑 1台(本次实验以win7为例) ·所需软件 ESPlorer
3. LED灯的发光原理
4. 实验方法
第一步:下载安装所需的软件–ESPlorer 下载地址:http://www.tpyboard.com/download/tool/169.html 第二步:连接TPYBoard-esp8266开发板 通过USB数据线将电脑和TPYBoard-esp8266开发板连接起来,会自动安装USB转串的驱动。 安装完毕后,查看设备管理器,是否正确创建串口。
http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489560660603166.png http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489560910187276.png http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489560920923300.png

蓝灯亮灭

5.源代码
from machine import Pin
import time

p2 = Pin(2, Pin.OUT)    # create output pin on GPIO2
p2.value(1)             # set pin to high

while True:
  p2.low()                # set pin to low
  p2.value()
  time.sleep(3)           # sleep for 3 second
  p2.high()               # set pin to high
  p2.value()
  time.sleep(3)           # sleep for 3 second

[Micropython][ ESP8266] TPYBoardV202之Network

1.实验目的
  1. 学习在PC机系统中网络(network)的使用方法。
  2. 学习TPYBoard V202连接网络的使用。
2.准备工作
(1)所需元器件 TPYBoard V202一块 数据线一条 电脑 1台(本次实验以win7为例) (2)所需软件 ESPlorer (3)下载地址:http://www.tpyboard.com/download/tool/169.html Network库的使用方法 网络模块用于配置WiFi连接。一共两种模式,模式一,是tpyboardv202当sta节点,即连接路由器的节点。模式二,是tpyboardv202做为ap,充当路由。使用以下命令创建这些对象的实例: (1)当ESP8266连接到路由器时:
import network
wlan = network.WLAN(network.STA_IF)      # 创建一个站(当ESP8266连接到路由器时)接口
wlan.active(True)                          # 激活接口
wlan.scan()                                 # 扫描接入点
wlan.isconnected()                         # 检查站点是否连接到路由器
wlan.connect('essid', 'password')        # 连接到路由器
wlan.config('mac')      # 获取接口的MAC地址
wlan.ifconfig()         # 获取接口的IP / netmask / gw / DNS地址

#检查是否连接是否建立:
wlan.isconnected()
#检查接口是否活动:
wlan.active()
#检查接口的网络设置:
wlan.ifconfig()

在这教大家TPYBoard v202上电自动连接本地网络:

from machine import Pin
import network
import time
def led_state():
        p2 = Pin(2, Pin.OUT)
        p2.value(0)
        time.sleep_ms(500)
        p2.value(1)
        time.sleep_ms(500)
        p2.value(0)
        time.sleep_ms(500)
p2.value(1)
        time.sleep_ms(500)
def do_connect():
        sta_if = network.WLAN(network.STA_IF)
        p2 = Pin(2, Pin.OUT)
        sta_if.active(False)
        if not sta_if.isconnected():
                p2.low()
                print('connecting to network...')
                sta_if.active(True)
                sta_if.connect('TurnipSmart', 'turnip2016')
                while not sta_if.isconnected():
                        pass
        if sta_if.isconnected():
                print('connect success')
                led_state()
                print('network config:', sta_if.ifconfig())
do_connect()

只需要将上面代码写入boot.py,在开发板上电后,就看到蓝灯常亮(正在连接网络),然后蓝灯交替闪烁两次,控制台打印connect success,证明已经连接到本地网络。

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489562186715918.png

(2)当其他设备连接到ESP8266时:

import network
ap = network.WLAN(network.AP_IF) #创建接入点接口
ap.active(True)         # 激活接口
ap.config(essid='ESP-AP') # 设计接入点的ESSID

(3)向指定地址发送数据的方法:

def http_get(url):
        _, _, host, path = url.split('/', 3)
        addr = socket.getaddrinfo(host, 80)[0][-1]
        s = socket.socket()
        s.connect(addr)
        s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
        while True:
                data = s.recv(100)
                if data:
                        print(str(data, 'utf8'), end='')
                else:
                        break
        s.close()
4.实验一
(1)实验要求
当TPYBoard v202未连接到网络时,led亮起警示,当连接成功后,熄灭。

(2)main.py程序代码

import network
from machine import Pin
sta_if = network.WLAN(network.STA_IF)
p2 = Pin(2, Pin.OUT)
#我们在这里把接入点接口禁用,方便观看实验效果,非实验可以去掉
sta_if.active(False)
if not sta_if.isconnected():
        p2.low()
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect('TurnipSmart', 'turnip2016')
        while not sta_if.isconnected():
                pass
if sta_if.isconnected():
        print('connect success')
        p2.high()
        print('network config:', sta_if.ifconfig())
(3)实验效果
当我们复位,把程序写进去的时候会看到TPYBoard V202板载的蓝灯亮起来,当连接成功后蓝灯熄灭,控制台打印connect success。
5.实验二

(1)实验要求 当TPYBoard v202连接网络成功后,通过get方式向网址 http://www.tpyboard.com/esp8266/test.php?val=A 发送字符A,网站接到后,页面显示begin,并返回bigin,TPYBoard V202收到bigin,LED 快闪2次。 (2)main.py程序代码

import network
from machine import Pin
import socket
import urllib
import time

def led_state():
        p2 = Pin(2, Pin.OUT)
        p2.value(0)
        time.sleep_ms(500)
        p2.value(1)
        time.sleep_ms(500)
        p2.value(0)
        time.sleep_ms(500)
        p2.value(1)

def do_connect():
        sta_if = network.WLAN(network.STA_IF)
        p2 = Pin(2, Pin.OUT)
        sta_if.active(False)
        if not sta_if.isconnected():
                p2.low()
                print('connecting to network...')
                sta_if.active(True)
                sta_if.connect('TurnipSmart', 'turnip2016')
                while not sta_if.isconnected():
                        pass
        if sta_if.isconnected():
                print('connect success')
                p2.high()
                print('network config:', sta_if.ifconfig())

def http_get(url):
        _, _, host, path = url.split('/', 3)
        addr = socket.getaddrinfo(host, 80)[0][-1]
        s = socket.socket()
        s.connect(addr)
        s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
        while True:
                data = s.recv(50)
                if data:
                        recive=str(data, 'utf8')
                        #print('recive:',recive)
                        print(str(data, 'utf8'), end='')
                        if(recive.find('begin')>-1):
                           led_state()
                else:
                        break
        s.close()
do_connect()
http_get('http://www.tpyboard.com/esp8266/test.php?val=A')

(3)实验效果

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489562363252568.png

当点击Send to ESP时,控制台显示从页面上传过来的内容为begin,并且led灯交替闪烁两次。 当访问的网址http://www.tpyboard.com/esp8266/test.php?val=X后面参数不是A的时候,

[Micropython][ESP8266]TPYBoardV202连接putty教程

TPYBoard V202是遵照MIT协议,以MicroPython为基础,研发的一款支持Python和lua语言的Wifi通信开发板,TPYBoard V202有9个通用GPIO口,1费ADC接口,1个SPI接口,1个I2C 接口,1个USART接口。
1.实验目的
学习在PC机系统中通过putty连接开发板教程
2.所需元器件
TPYBoard V202开发板一块 数据线一条
3.所需软件
1.TPYBoard v202开发板驱动下载地址: <http://www.micropython.net.cn/download/tool/163.html> 2.PuTTY_0.67.0.0.exe 下载地址: <http://www.micropython.net.cn/download/tool/3.html>
4.板子连接方法
1.安装驱动
http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489556668728667.png http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489556775793306.png http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489556846690984.png

[Micropython][ESP8266]TPYBoard V202之定时器

1.实验目的
  1. 学习在PC机系统中通过putty使用定时器功能。
2.所需元器件
TPYBoard-esp8266开发板一块 数据线一条
3.实现方法

1.增加一个执行一次的定时器

from machine import Timer tim = Timer(-1) #新建一个虚拟定时器 tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1)) 此处执行时程序会等待5秒打印1,period=5000 以毫秒为单位,mode=Timer.ONE_SHOT 表示只执行一次 callback=lambda 回调函数(period=5000, mode=Timer.ONE_SHOT,t:print(1))

2.增加一个循环定时器

from machine import Timer tim = Timer(-1) #新建一个虚拟定时器 tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2)) 此方法执行时系统会每隔两秒无限打印2。

4.利用定时器来获取温湿度
1.硬件实物图
from machine import Timer
import dht
import machine
def f(t):
        d=dht.DHT11(machine.Pin(4))
        d.measure()
        a=d.temperature()
        b=d.humidity()
        print('温度:',a,'°C')
        print('湿度:',b,'%')

tim = Timer(-1)  #新建一个虚拟定时器
tim.init(period=2000, mode=Timer.PERIODIC, callback=f)

用串口调试工具的效果图即每2秒读取一次温湿度,并打印

http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489561615972014.png

若想做一下扩展,可将温湿度显示到OLED显示屏上,这样一个小型的DIY温湿度检测仪就诞生了。

TPYBoard v702 典型实例

[Micropython][TPYBoard]v702 GPRS功能测试

一、什么是TPYBoardV702

TPYBoardV702是山东萝卜电子科技有限公司最新开发的,目前市面上唯一支持通信通信功能的MicroPython开发板:支持Python3.0及以上版

本直接运行。支持GPS+北斗双模通信、GPRS通信、短信功能、电话功能;板载温湿度、光敏、三轴加速度传感器、蜂鸣器、LCD5110显示屏。

免费提供通信测试服务平台。实物如下图:

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188183717935.png
二、利用TPYBoardV702完成利用GPRS功能把数据上传至服务器

1、具体要求

利用TPYBoardV702完成利用GPRS功能把数据上传至服务器

2、所需器件

TPYBoardV702开发板一块

Gsm手机卡一张

TPYBoardV702开发板板载GPRS通信功能,无需外接

3、板载通信功能及使用介绍

V702的开发板的整体整体亮点置一就是能板载通信功能,只要在开发板的卡槽上插上一张可以使用的手机卡(不支持电信),即可使用该功能。 开发板板载的通信功能包括了电话,短信,GPRS等功能,在这个实验里面我们只使用GPRS这个功能。 我们使用GPRS功能,主要是为了借助这个功能向服务器透传数据,所以我们第一步是要打开透传功能。 然后我们要和服务器建立连接,这时我们需要知道服务器的地址和端口。这个实验我们借用官方提供的测试平台,发送一个自己编辑的数据包,来学习一下GPRS功能的使用方法。 下面仔细说一下制作过程。
三、制作主要过程

先上个图,下面再开始说代码的问题。

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188237747626.png

Putty数据监控图

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188346729478.png

示例定位图

1、制作过程

(1)第一步是先把手机卡插到开发板开槽上,需要保证手机卡可以使用;

(2)在上面工作完成后,我们开始main().py文件代码的编辑;

(3)对需要用到的类库进行声明和定义;

(4)把我们需要使用的变量进行一下定义;

(5)把我们需要用到的接口进行声明和定义,这里我们主要用到了串口4这个接口,声明串口4的时候,需要把串口波特率设置为115200

(7)下面开始主函数的编写,这个实验里面我们用到了数据包,我们先新建一个符合格式的数据包;

(8)完成以上之后,我们需要做一个最重要的事情,那就是定义“Y6”引脚为输出,然后把:“Y6”引脚拉低两秒以上,之后把此引脚

拉高。因为“Y6”引脚是控制整个板载通信系统开启的开关,如果平时我们没有用到通信系统的话,为了节省功耗,板载通信系统是处于关

闭状态的,需要使用时只需要拉低“Y6”引脚两秒以上;

(9)当看到开发板上的红色直插LED灯快速闪烁的时候,说明板载通信系统正在启动,当这个红色直插指示灯结束快闪(如果插在开发

板卡槽上的手机可用,指示灯处于慢闪状态)说明板载通信系统已经启动;

(10)完成以上工作后,准备工作就已经完成了,下面我们需要先把通信系统的通信方式设置为透传,之后再和相应的服务器地址和端

口进行连接;

(11)和服务器建立连接后,就可以开始想服务器发送数据了,直接把数据从串口4送出去就可以了,通信系统会原封不动的把你发的数

据发送到服务器。

2、具体代码:
import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *#以上为声明使用到的类库


leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST        = pyb.Pin('X20')
CE         = pyb.Pin('X19')
DC         = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)#以上为初始化显示屏的函数,虽然

                                                                                  #这次没有用到显示,但是备用
count_=0
N2 = Pin('Y3', Pin.OUT_PP)
N1 = Pin('Y6', Pin.OUT_PP)#定义通信系统启动引脚
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)#拉高拉低引脚,启动通信系统
u2 = UART(4, 115200)#定义串口4,设置 波特率为115200
K=5#设置一个选择变量K
while (K==5):#这个循环是为了设置通信区域模式为透传模式。
        u2.write('AT+CIPMODE=1\r\n')
        pyb.delay(500)
        if(u2.any()>0):
                print('透传')
                _dataRead=u2.readall()
                print('透传',_dataRead.decode('utf-8'))
                if(_dataRead.find(b'OK')>-1):
                        K=0
                        pyb.delay(20)
u2.write('AT+CIPSTART="TCP","139.196.109.178",30000\r\n')#这个语句是为了搭建通信连

                                                                                           #接。
pyb.delay(10000)
print('123')
while (K==0):#这里是为了判断通信连接是否已经建立起来,如果没有建立起来通信的连接,                                        #则等待。
        pyb.delay(3000)
        if(u2.any()>0):
                _dataRead=u2.readall()
                print('oo',_dataRead)
                if(_dataRead.find(b'CONNECT OK')>-1):#这个判断是为了判断是否已经和服务器建

                                                 #立起连接来
                        K=1#开发板已经和服务器建立起连接来,则改变选择变量的值,使其进入下                                             #一个循环
                        pyb.LED(1).on()
while (K==1):#这个循环是执行数据传输命令的执行所在,在这个循环中进行各种数据的裁                            #剪拼接和发送。
        print('DOU')
        #u2.write('+++')  此时整个系统进入透传通信模式,想要退出,则发送‘+++’,即可        #退出;
        #u2.write('ATO0') 想让系统从指令模式进入透传模式,则发送‘ATO0’,则进入透传;
        #pyb.delay(1500)
        pyb.LED(2).off()
        pyb.LED(3).off()
        pyb.LED(2).on()
        u2.write('TPGPS,1234567890abcde,36.67191670,119.17200000,201701120825,25,50,END')
        #这个报文详细格式参照服务平台示例报文格式。
        #把这格式里面的经纬度数据换成从定位系统获取到的经纬度,就可以实时定位了。
        pyb.delay(13000)#延时一下时间,官方提供的测试平台有上传频率限制
        if(u2.any()>0):#在向服务器发送了数据后,服务器会对数据进行判断,并返相应的报文                                          #(报文参数详见服务

平台)
                                        #这个返回仅适用于官方提供的服务平台,客户自己搭建的平台是否                                                          #存在这个功能

,客户自主搭建。
                _dataRead=u2.readall()
                print('1212',_dataRead)
        pyb.LED(3).on()
        pyb.delay(10000)

[Micropython][TPYBoard v702]5110显示当前经纬度

一、什么是TPYBoard V702

TPYBoardV702是目前市面上唯一支持通信定位功能的MicroPython开发板:支持Python3.0及以上版本直接运行。支持GPS+北斗双模定位、GPRS通信、短信功能、电话功能;板载温湿度、光敏、三轴加速度传感器、蜂鸣器、LCD5110显示屏。免费提供定位测试服务平台。实物如下图:

http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493097896266097.png
二、利用TPYBoardV702完成所在地温湿度及亮度数据采集

1、具体要求

利用TPYBoardV702完成所在地经纬度采集,并在5110显示屏上显示

2、所需器件

TPYBoardV702开发板一块

5110显示屏一块

TPYBoardV702开发板板载定位功能,无需外接

3、板载定位功能及使用介绍

V702的开发板的整体整体亮点就是能进行定位,可以获取到当前所在地的经纬度,高度,时间等等的一些信息。在这个实验里面我们就要用到获取经纬度这一功能。

这个开发板上主要的硬件功能已嵌入到了开发板上,使用起来非常方便,我们只需要进行简单的设置操作就能获取到经纬度,然后再进行数据解析,分割以及数据转换等处理,就可以得到我们想要的经度和纬度了,之后我们在使用显示屏把经纬度显示出来就完成了在开发板上显示经纬度了。下面来具体的说一下制作的过程。

三、制作主要过程
先上个图,下面再开始说代码的问题。
import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *


leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST    = pyb.Pin('X20')
CE     = pyb.Pin('X19')
DC     = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
count_=0
N2 = Pin('Y3', Pin.OUT_PP)
N1 = Pin('Y6', Pin.OUT_PP)#定义板载定位系统开关引脚为输出
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)#通过拉低和拉高开关引脚的电平,启动板载定位系统
u2 = UART(4, 115200)#定义串口4,设置波特率为115200
i='0'
w=0
d=0
q=0
G=0
j=0
def DataConver(str_,flag):#预先编写数据处理函数,方便后期数据处理
        wei_=float(str_)/100
        wei_arr=str(wei_).split('.')
        val_=100000
        if flag==0:#纬度
                val_=10000
        wei_arr[1]=str(float(wei_arr[1])/60*val_).replace('.','')
        weidu=wei_arr[0]+'.'+wei_arr[1]
        return weidu
while True:
        pyb.LED(2).on()
        G=G+1
        u2.write('AT+GPSLOC=1\r\n')#通过串口发送指令,命令板载定位系统进行搜星操作
        pyb.delay(3000)
        _dataRead=u2.readall()
        print('搜星=',_dataRead)#延时,给系统搜星反应时间,提高搜星效率,并打印搜星结果
        pyb.delay(1000)
        u2.write('AT+GPSLOC=0\r\n')#通过串口发送获取经纬度的指令,命令板载定位系统进行                                            #经纬度获取
        pyb.delay(200)
        print('BEIDOU')
        _dataRead=u2.readall()#保存串口获取到的经纬度数据,如果定位信号不好,返回数据可                                      #能全部为零,这个情况会导致定位周期延长
        if _dataRead!=None:
                print('原始数据=',_dataRead)
                print('原始数据长度:',len(_dataRead))
                if 60<len(_dataRead)<70:#这里把正确的数据长度作为数据处理的开始
                        _dataRead = _dataRead.decode('utf-8')
                        _dataRead1=_dataRead.split(',')#把数据转成'utf-8'格式,并且把数据按照“,”分                                                           #隔开
                        print('数据=',_dataRead1)
                        print(len(_dataRead1),'***')
                        if len(_dataRead1)>4:#判断数据转换出来的数组数据长度(或者说是数组的元                                              #素个数)作为进行数据转换的开始
#*******************纬度计算********************
                                weidu=_dataRead1[1]
                                WD=DataConver(weidu,0)
#*******************经度计算********************
                                jingdu=_dataRead1[2]
                                JD=DataConver(jingdu,1)#利用我们上面做好的数据转换函数,把数据也转                                                                #换成我们可以正常使用的格式
#***********************时间************************
        lcd_5110.lcd_write_string('JINGDU:',0,0)
        lcd_5110.lcd_write_string(str(JD),0,1)
        lcd_5110.lcd_write_string('WEIDU:',0,2)
        lcd_5110.lcd_write_string(str(WD),0,3)#利用5110显示屏类库中的显示函数,进行数据显                                                               #示

[Micropython]TPYBoardV702开发板短信功能使用说明

1.TPYBordV702开发板简介

目前市面上唯一支持通信定位功能的MicroPython开发板:支持Python3.0及以上版本直接运行。支持GPS+北斗双模定位、GPRS通信、短信功能、电话功能;板载温湿度、光敏、三轴加速度传感器、蜂鸣器、LCD5110显示屏。免费提供定位测试服务平台。

TPYBord_V7.0.2开发板上板载的通信器件是由深圳合方圆公司研发发的GU620通信定位模块,此模块功能强大,同时支持GPS,GPRS,GSM,蓝牙等功能,这次就来具体的说一下发送短信的功能的使用。

能实现短信功能后还能依托着短信的功能实现温湿度的实时获取,经纬度的实时获取(可能比较费短信费哦)

http://www.tpyboard.com/ueditor/php/upload/image/20170316/1489665683266655.png
2.初识短信发送原理
手机的信号频率很高,一般在900Mhz左右,靠电离层反射传播,打电话的手机信号传到最近的基站,也就是移动或者连通的信号塔,再由基站把高频信号频率降低,由基站和基站之间通信,这个信号是直线传播,遇到高的建筑物会被挡住,所以那些塔都竖的很高,传到接电话的手机附近的基站,再转成高频信号发给手机。 短消息业务(SMS-Short Message Service)的实现原理很简单: 第一是存储转发机制。SMS传送数据包的工作由移动网络中的短消息中心而不是终端用户来完成,如果用户不在服务区内,短消息就被存储在短消息中心,等用户出现之后,再转发给他,这是GPRS等业务所不具备的。 第二是传递确认机制。在电路交换数据环境中,连接是端到端的,所以用户能够知道连接是否完成,以及数据传递的情况. 通俗点说: 基站永远是在发射信号的,其中很重要的一部分就是广播消息,广播消息中的一类是寻呼消息(含电话号码),每个手机都在时刻监听寻呼消息,当它发现一个寻呼消息是给它的话(即有人正打它电话),它就会和基站建立连接,通过基站和打你电话的人联系。
http://www.tpyboard.com/ueditor/php/upload/image/20170316/1489665696262351.png
3.了解GU620的短信发送流程

通过上面的描述,我们了解到了短信发送的基本原理和流程,下面我来了解一下GU620模块在应对这些流程时需要怎么做。

首先的我们需要把模块设置到短信发送的模式,这个通过AT指令AT+CMGF=1,来设置,这条指令是设置模块为打开短信发送格式,且以文本的格式发送。

上面一条我们说了,把短信以文本的模式发送,但是文本有很多种格式,这里我们再执行一条指令,把文本的格式设置成我们手机能稳定且正确识别的文本格式,AT+CSCS=“GB2312”,这条指令是把短信收发的文本格式设置为简体中文。

上面两条介绍了设置发送短信的模式和文本格式,这里说一个意外事件(在想要执行的流程之外发生的事件)发生的处理方法,要是在你正要发短信的时候,有一条新的短信进来了,那这个怎么办?要是新的短信一接收到,马上显示出来,显然不是很合理,会打断我们的流程,在这里我们使用AT+CNMI=2,1指令把接收到的新消息存储到SIM卡中,然后再给出提示,在我们想读的时候再读出来,这样比较符合常理。

在我们设置好以上的这些基本的设置步骤后,我们需要把发短信的一个重要因素,接收方的手机号码写进模块去,我们使用指令AT+CMGS=“手机号码”,这条指令是告诉模块想要通信的目的号码。

在发送了正确的指令和手机号后模块会有提示正确的返回值,当得到这个返回值的时候,我们就可以把我们想要发送的内容(不支持汉字)编辑进去,这样模块就会把编辑的短信内容发送给前面输入的手机号码上去。

当发送成功后,会返回发送的内容,以及相应的提示内容。

4.设置程序流程

根据以上的介绍,我们大致了解了短信发送的基本流程,那么我们疾苦依据这个基本流程来设置一下程序的流程。

1.开发板上电,红色电源指示灯会亮起; 2.首先定义串口4,波特率设置为115200,通信模块和32芯片是依靠串口通信的; 3.之后我们设置两个变量Message,number来存储短信内容和接收方的手机号码; 4.在程序的顶端,总循环的外面,使用程序把引脚Y6拉低两秒以上,Y6是连接通信模块的开关机引脚的; 5.之后拉高Y6,延时10秒,这样是为了确保通信模块正常开机; 6.之后我们发送AT+CMGF=1rn,设置模块为短信发送模式; 7.如果模块返回正确的提示内容,我们发送AT+CSCS=”GB2312”rn,设置文本的格式; 8.模块返回正确提示内容后,发送AT+CNMI=2,1rn,设置新短息的模式; 9.设置成后,发送AT+CMGS=”’+number+‘“rn,把手机号码发送进去; 10.当模块返回手机号码正确的提示后,发送Message+’rn’,把设置好的内容发送给模块; 11.模块返回发送的文本内容及相应的发送成功的提示后,结束程序。

5.源代码
下面是我写的简单的一个代码,提供给大家参考。
import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *

leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST        = pyb.Pin('X20')
CE         = pyb.Pin('X19')
DC         = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
count_=0
N2 = Pin('Y3', Pin.OUT_PP)
N1 = Pin('Y6', Pin.OUT_PP)
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)
u2 = UART(4, 115200)
Message='TPYBoard_GPS00000000000001'#输入你想要发送的短信的内容;
number='目的号码'#输入想要发送的手机号
w=0
r=0
while r<1:
        u2.write('AT+CMGF=1\r\n')
        pyb.delay(50)
        if(u2.any()>0):
                _dataRead=u2.readall()
                print('1:',_dataRead)
                lcd_5110.lcd_write_string('Message:',0,0)
                lcd_5110.lcd_write_string(str(Message),0,2)
                if(_dataRead==b'AT+CMGF=1\r\n\r\nOK\r\n'):
                        u2.write('AT+CSCS="GB2312"\r\n')
                        pyb.delay(50)
                        if(u2.any()>0):
                                _dataRead=u2.readall()
                                print('2:',_dataRead)
                                if(_dataRead==b'AT+CSCS="GB2312"\r\n\r\nOK\r\n'):
                                        u2.write('AT+CNMI=2,1\r\n')
                                        pyb.delay(50)
                                        if(u2.any()>0):
                                                _dataRead=u2.readall()
                                                print('3:',_dataRead)
                                                if(_dataRead==b'AT+CNMI=2,1\r\n\r\nOK\r\n'):
                                                        u2.write('AT+CMGS="'+number+'"\r\n')
                                                        pyb.delay(50)
                                                        if(u2.any()>0):
                                                                _dataRead=u2.readall()
                                                                print('4:',_dataRead)#b'AT+CMGF=1\r\n\r\nOK\r\n'
                                                                if(_dataRead== b'AT+CMGS="'+number+'"\r\n\r\n> '):
                                                                        u2.write(Message+'\r\n')#短信内容
                                                                        pyb.delay(50)
                                                                        if(u2.any()>0):
                                                                                _dataRead=u2.readall()
                                                                                print('5:',_dataRead)
                                                                                print(len(_dataRead))
                                                                                w=len(_dataRead)
                                                                                _dataRead=str(_dataRead)[2:w]
                                                                                print('6:',_dataRead)
                                                                                if(_dataRead==Message):
                                                                                        print('7:ok')
                                                                                        lcd_5110.lcd_write_string('Has been sent',0,5)
                                                                                        r=10
6.短信群发机制作:

1.短信群发机是建立在上面的程序代码的基础上的; 2.在上面的代码中,我们是建立了一个字符变量来存储电话号码,这里我们建立一个数组来 存放电话号码; 3.在电话号码全部录入后; 4.我们来查询一下这个数组里面有几个电话号码(也就是告诉芯片你要给几个手机发短信); 5.然后我们对这个数组里面的数据进行依次调用; 6.并对这个数据执行发送短信的流程; 7.并获取到这是数组中的第几个数据; 8.如果数组中的数据全部调用了一次后,结束程序的发送;

7.短信群发机例程

下面是短信群发机的例程,给出来参考一下。

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *

leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST        = pyb.Pin('X20')
CE         = pyb.Pin('X19')
DC         = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
count_=0
N2 = Pin('Y3', Pin.OUT_PP)
N1 = Pin('Y6', Pin.OUT_PP)
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)
u2 = UART(4, 115200)
Message='TPYBoard_GPS'#输入你想要发送的短信的内容;
number=['目的号码1','目的号码2','目的号码3']#输入想要发送的手机号
w=0
r=0
E=0
Q=0
while r<1:
        Q=len(number)
        print(Q)
        while E<Q:
                print(number[E])
                u2.write('AT+CMGF=1\r\n')
                pyb.delay(50)
                if(u2.any()>0):
                        _dataRead=u2.readall()
                        print('1:',_dataRead)
                        lcd_5110.lcd_write_string('Message:',0,0)
                        lcd_5110.lcd_write_string(str(Message),0,2)
                        if(_dataRead==b'AT+CMGF=1\r\n\r\nOK\r\n'):
                                u2.write('AT+CSCS="GB2312"\r\n')
                                pyb.delay(50)
                                if(u2.any()>0):
                                        _dataRead=u2.readall()
                                        print('2:',_dataRead)
                                        if(_dataRead==b'AT+CSCS="GB2312"\r\n\r\nOK\r\n'):
                                                u2.write('AT+CNMI=2,1\r\n')
                                                pyb.delay(50)
                                                if(u2.any()>0):
                                                        _dataRead=u2.readall()
                                                        print('3:',_dataRead)
                                                        if(_dataRead==b'AT+CNMI=2,1\r\n\r\nOK\r\n'):
                                                                u2.write('AT+CMGS="'+number[E]+'"\r\n')
                                                                pyb.delay(50)
                                                                if(u2.any()>0):
                                                                        _dataRead=u2.readall()
                                                                        print('4:',_dataRead)#b'AT+CMGF=1\r\n\r\nOK\r\n'
                                                                        if(_dataRead== b'AT+CMGS="'+number[E]+'"\r\n\r\n> '):
                                                                                u2.write(Message+'\r\n')#短信内容
                                                                                pyb.delay(50)
                                                                                if(u2.any()>0):
                                                                                        _dataRead=u2.readall()
                                                                                        print('5:',_dataRead)
                                                                                        print(len(_dataRead))
                                                                                        w=len(_dataRead)
                                                                                        _dataRead=str(_dataRead)[2:w]
                                                                                        print('6:',_dataRead)
                                                                                        if(_dataRead==Message):
                                                                                                print('7:ok')
                                                                                                E=E+1
                                                                                                lcd_5110.lcd_write_string('OK IS:'+str(E),0,5)
                                                                                                pyb.delay(24000)
        r=10
        E=0

[Micropython][TPYBoard v702]来电显示功能

一、什么是TPYBoardV702

TPYBoardV702是山东萝卜电子科技有限公司最新开发的,目前市面上唯一支持通信通信功能的MicroPython开发板:支持Python3.0及以上版本直接运行。支持GPS+北斗双模通信、GPRS通信、短信功能、电话功能;板载温湿度、光敏、三轴加速度传感器、蜂鸣器、LCD5110显示屏。免费提供通信测试服务平台。实物如下图:

http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493091949524542.png
二、利用TPYBoardV702完成接收提示来电,并在显示屏上显示来电号码及来电人员称谓

1、具体要求

利用TPYBoardV702完成接收提示来电,并在显示屏上显示来电号码及来电人员称谓

2、所需器件

TPYBoardV702开发板一块

5110显示屏 一块

Gsm手机卡 一张

TPYBoardV702开发板板载GSM通信功能,无需外接

3、板载通信功能及使用介绍

V702的开发板的整体整体亮点置一就是能板载通信功能,只要在开发板的卡槽上插上一张可以使用的手机卡(不支持电信),即可使用该功能。

开发板板载的通信功能包括了电话,短信,GPRS等功能,在这个实验里面我们只使用电话这个功能。

开发板板载的通信功能已经设计的很完善,在接到来电的时候,会主动的把来电的信息通过串口4发送进来,这样一来作为用户的我们就是需要把数据进行相应的处理加显示就可以了。

三、制作主要过程
先上个图,下面再开始说代码的问题。
http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493092006716181.png

这次不光有照片,还有视频: http://v.youku.com/v_show/id_XMjQ4MjgyMjI2OA==.html?spm=a2h3j.8428770.3416059.1

1、制作过程

(1)首选我们需要做的是把5100显示屏插到702开发板的5110显示屏接口处;

(2)在上面工作完成后,我们这里需要用到主要的类库,5110的类库,我们需要把这个类库的.py文件拷贝到开发板的盘符中;

(3)完成以上工作后,我们开始main().py文件代码的编辑;

(4)对需要用到的类库进行声明和定义;

(5)把我们需要使用的变量进行一下定义;

(6)把我们需要用到的接口进行声明和定义,这里我们主要用到了spi1和串口4这两个接口,声明串口4的时候,需要把串口波特率设置为115200;

(7)下面开始主函数的编写,这个实验里面我们用到了显示,我们在程序的开始部分先进行显示部分的初始化;

(8)完成显示部分初始化之后,我们需要做一个最重要的事情,那就是定义“Y6”引脚为输出,然后把:“Y6”引脚拉低两秒以上,之后把此引脚拉高。因为“Y6”引脚是控制整个板载通信系统开启的开关,如果平时我们没有用到通信系统的话,为了节省功耗,板载通信系统是处于关闭状态的,需要使用时只需要拉低“Y6”引脚两秒以上;

(9)当看到开发板上的红色直插LED灯快速闪烁的时候,说明板载通信系统正在启动,当这个红色直插指示灯结束快闪(如果插在开发板卡槽上的手机可用,指示灯处于慢闪状态)说明板载通信系统已经启动;

(10)完成以上工作后,准备工作就已经完成了,剩下需要做的就是监控串口4是否有数据发送过来,当检测到串口4有数据发送过来,对数据进行相应的判断及处理,并显示到显示屏上即可。

  2、具体代码:

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *#以上内容为声明所使用的类库


leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST    = pyb.Pin('X20')
CE     = pyb.Pin('X19')
DC     = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)#以上内容为声明并初始化显示屏
count_=0
N2 = Pin('Y3', Pin.OUT_PP)#定义“Y3”为输出模式,这个引脚是控制蜂鸣器的,来电话了                                     #需要响铃的
N1 = Pin('Y6', Pin.OUT_PP)#定义“Y6”位输出模式,“Y6”引脚是板载通信系统的开关控                                      #制引脚
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)#通过拉低拉高开光控制引脚,启动通信系统
u2 = UART(4, 115200)#设置串口4,并设置串口波特率为115200
i='0'
w=0
d=0
q=0
G=0
j=0
while 0<1:
        N2.low()#设置蜂鸣器控制引脚为低电平,不让蜂鸣器响
        if(u2.any()>0):#检测串口4是否有数据,如果有数据执行以下
                _dataRead=u2.readall()
                if _dataRead!=None:#判断串口4的数据是否为空,不为空执行以下代码
                        print('原始数据=',_dataRead)
                        print('原始数据长度:',len(_dataRead))
                        print('123',_dataRead[2:6])
                        RING=_dataRead[2:6]#截取包头,这个包头是为了判断数据是否正确的重要依                                                  #据
                        print('111',_dataRead[18:29])
                        HM=_dataRead[18:29]#数据的18至29位是数据中携带的手机号码,我们把它                                                  #们保存出来
                        WD='No such person'#设置一个变量,这个变量我们可以称为是电话本类比变                                               #量,主要是作为显示时什么人来电,例如显示张三,                                              #或者李四
                        if(RING==b'RING'):#判断包头正确,执行下面代码
                                if(HM==b'18654868920'):#判断来电是否是一个已经存储的号码
                                        WD='TPYBoard_GPS'#如果是,显示存储名称,如果没有存储显示'No                                                            #such person'
#**********************时间************************
                                N2.high()#拉高蜂鸣器控制引脚,使蜂鸣器响铃
                                lcd_5110.lcd_write_string('Phone Number:',0,0)
                                lcd_5110.lcd_write_string(HM.decode("utf8"),2,1)
                                lcd_5110.lcd_write_string('The contact:',0,2)
                                lcd_5110.lcd_write_string(str(WD),0,3)#显示相应的来电号码,来电人称谓                                                                              #等
                pyb.delay(1000)

[Micropython][TPYBoard v702]5110显示温度湿度亮度

一、什么是TPYBoardV702

TPYBoardV702是山东萝卜电子科技有限公司最新开发的,目前市面上唯一支持通信定位功能的MicroPython开发板:支持Python3.0及以上版本直接运行。支持GPS+北斗双模定位、GPRS通信、短信功能、电话功能;板载温湿度、光敏、三轴加速度传感器、蜂鸣器、LCD5110显示屏。免费提供定位测试服务平台。实物如下图:

http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493091129611195.png
二、利用TPYBoardV702完成所在地温湿度及亮度数据采集

1、具体要求

利用TPYBoardV702完成所在地温湿度及亮度数据采集

2、所需器件

TPYBoardV702开发板一块

温湿度传感器和光敏系统均属于板载器件,无需外接

3、温湿度传感器介绍

SHT20,新一代Sensirion湿度和温度传感器在尺寸与智能方面建立了新的标准:它嵌入了适于回流焊的双列扁平无引脚DFN封装,底面3x3mm,高度1.1mm。传感器输出经过标定的数字信号,标准I2C格式。

SHT21配有一个全新设计的CMOSens®芯片、一个经过改进的电容式湿度传感元件和一个标准的能隙温度传感元件,其性能已经大大提升甚至超出了前一代传感器(SHT1x和SHT7x)的可靠性水平。例如,新一代湿度传感器,已经经过改进使其在高湿环境下的性能更稳定。每一个传感器都经过校准和测试。在产品表面印有产品批号,同时在芯片内存储了电子识别码-可以通过输入命令读出这些识别码。

此外,SHT20的分辨率可以通过输入命令进行改变(8/12bit乃至12/14bit的RH/T),传感器可以检测到电池低电量状态,并且输出校验和,有助于提高通信的可靠性。

技术参数:

-输出:I2C数字接口

-功耗:1.5uw(8位测量,1次/秒)

-湿度范围0-100%RH

-温度范围-40-+125℃(-40-+257℉)

-RH响应时间8s(tau63%)

4、光敏系统介绍

V702开发板上板载了一个光敏传感的系统,利用stm32的ADC检测进行数值采集,这里的ADC数值输入引脚我们使用了Y12。并利用代码逻辑进行相应的数据转换,最终解析出当前光照强度,其中33为光照强度最大值。

三、制作主要过程

先上个图,下面再开始说代码的问题。

# main.py -- put your code here!
#main.py
import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART
from ubinascii import hexlify
from ubinascii import *
from SHT20 import SHT20

ds=SHT20(1)#从声明的类库中的函数
leds = [pyb.LED(i) for i in range(1,5)]
P,L,SHUCHU=0,0,0
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
#DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
#CLK =>SPI(1).SCK  'X6' SPI clock
RST    = pyb.Pin('X20')
CE     = pyb.Pin('X19')
DC     = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
count_=0
N2 = Pin('Y3', Pin.OUT_PP)#Y3引脚是用来控制蜂鸣器的
N1 = Pin('Y6', Pin.OUT_PP)
N1.low()
pyb.delay(2000)
N1.high()
while True:
        ads = pyb.ADC(Pin('Y12'))#定义当前光敏系统中使用到的引脚;
        a=ads.read()#读取出当前引脚的ADC数值
        a=a/100
        a=33-a#对读取出的数值进行相应的转换
        print("a=",a)
        H=ds.TEMP()
        S=ds.TEMP1()
        H=125*H/256-6
        S=175.72*S/256-46.85#以上为温湿度数据的读取以及温湿度数据的转换
        if(a<10):#判断当前亮度是否小于十,如果小于十,那么蜂鸣器发出声音
                N2.high()
        lcd_5110.lcd_write_string('WENDU:',0,0)#以下代码为显示屏显示代码
        lcd_5110.lcd_write_string(str(S),0,1)
        lcd_5110.lcd_write_string('SHIDU:',0,2)
        lcd_5110.lcd_write_string(str(H),0,3)
        lcd_5110.lcd_write_string('LIANGDU:',0,4)
        lcd_5110.lcd_write_string(str(a),0,5)
        N2.low()

MicroPython类库

本章介绍了构成micropython的模块(函数和类库)。有几类模块:

  • 内置模块:标准Python功能的子集,用户不能扩展。
  • 扩展模块:实现了Python功能的一个子集,并提供用户扩展(通过Python代码)。
  • 扩展模块:实现micropython的Python标准库。
  • 硬件驱动模块:特定端口或者硬件驱动的模块,因此不可移植。

Note about the availability of modules and their contents: This documentation in general aspires to describe all modules and functions/classes which are implemented in MicroPython. However, MicroPython is highly configurable, and each port to a particular board/embedded system makes available only a subset of MicroPython libraries. For officially supported ports, there is an effort to either filter out non-applicable items, or mark individual descriptions with “Availability:” clauses describing which ports provide a given feature. With that in mind, please still be warned that some functions/classes in a module (or even the entire module) described in this documentation may be unavailable in a particular build of MicroPython on a particular board. The best place to find general information of the availability/non-availability of a particular feature is the “General Information” section which contains information pertaining to a specific port.

Beyond the built-in libraries described in this documentation, many more modules from the Python standard library, as well as further MicroPython extensions to it, can be found in the micropython-lib repository.

Python标准库和微型库

标准的Python库被 “微型化”后,就是micropython标准库。它们仅仅提供了该模块的核心功能。一些模块没有直接使用标准的Python的名字,而是冠以”u”,例如``ujson``代替``json``。也就是说micropython标准库(=微型库),只实现了一部分模块功能。通过他们的名字不同,用户有选择的去写一个Python级模块扩展功能,也是为实现更好的兼容性。

在嵌入式平台上,可添加Python级别封装库从而实现命名兼容CPython,微模块即可调用他们的u-name,也可以调用non-u-name。根据non-u-name包路径的文件可重写。

例如,``import json``的话,首先搜索一个``json.py``文件或``json``目录进行加载。如果没有找到,它回退到加载内置``ujson``模块。

Builtin 函数

所有的内置功能介绍。也可通过内置模块查找。

abs()
all()
any()
bin()
class bool
class bytearray
class bytes
callable()
chr()
classmethod()
compile()
class complex
delattr(obj, name)

*name*参数是字符类型, 该函数删除*obj*的指定参数属性。

class dict
dir()
divmod()
enumerate()
eval()
exec()
filter()
class float
class frozenset
getattr()
globals()
hasattr()
hash()
hex()
id()
input()
class int
classmethod from_bytes(bytes, byteorder)

MicroPython中 byteorder 是位索引 (兼容CPython)。

to_bytes(size, byteorder)

MicroPython中 byteorder 是位索引 (兼容CPython)。

isinstance()
issubclass()
iter()
len()
class list
locals()
map()
max()
class memoryview
min()
next()
class object
oct()
open()
ord()
pow()
print()
property()
range()
repr()
reversed()
round()
class set
setattr()
class slice

slice 是内置类型。

sorted()
staticmethod()
class str
sum()
super()
class tuple
type()
zip()

array – 数字数据数组

查看更多 Python 数组 信息。

支持代码格式: b, B, h, H, i, I, l, L, q, Q, f, d (后2个支持浮点数)。

class array.array(typecode[, iterable])

指定类型创建数组元素。用可选项[]做为数组的初始值,可选项[]未指定的,则创建空数组。

append(val)

将新元素添加到数组的结尾,并将其扩展。

extend(iterable)

使用迭代方式将新元素添加到数组的结尾,并将其扩展。

cmath – 复数的数学函数

``cmath``提供了基本的复数运算功能。它不支持 WiPy 和 ESP8266,因为需要浮点库支持.

函数
cmath.cos(z)

返回``z``的余弦。

cmath.exp(z)

返回``z``的指数。

cmath.log(z)

返回``z``的对数。

cmath.log10(z)

返回``z``的常用对数。

cmath.phase(z)

返回``z``的相位, 范围是(-pi, +pi],以弧度表示。

cmath.polar(z)

返回``z``的极坐标.

cmath.rect(r, phi)

返回`模量`r``和相位``phi``的复数。

cmath.sin(z)

返回``z``的正弦。

cmath.sqrt(z)

返回``z``的平方根。

常数
cmath.e

自然对数的指数。

cmath.pi

圆周率。

gc – 控制垃圾回收

Functions
gc.enable()

启动自动垃圾回收。

gc.disable()

禁用自动垃圾回收。 堆内存仍然可以分配,垃圾回收仍然可以手动启动使用 gc.collect().

gc.collect()

运行垃圾回收。

gc.mem_alloc()

返回分配的堆RAM的字节数。

gc.mem_free()

返回可用堆内存的字节数。

math – 数学函数

用浮点数实现一些基本数学函数。

Note: 需要带有硬件FPU,精度是32位。

Availability: not available on WiPy. Floating point support required for this module.

函数
math.acos(x)

返回 ``x``的反余弦。

math.acosh(x)

返回 ``x``的逆双曲余弦。

math.asin(x)

返回 ``x``的反正弦。

math.asinh(x)

返回``x``的逆双曲正弦。

math.atan(x)

返回 ``x``的逆切线。

math.atan2(y, x)

Return the principal value of the inverse tangent of y/x.

math.atanh(x)

Return the inverse hyperbolic tangent of x.

math.ceil(x)

Return an integer, being x rounded towards positive infinity.

math.copysign(x, y)

Return x with the sign of y.

math.cos(x)

Return the cosine of x.

math.cosh(x)

Return the hyperbolic cosine of x.

math.degrees(x)

Return radians x converted to degrees.

math.erf(x)

Return the error function of x.

math.erfc(x)

Return the complementary error function of x.

math.exp(x)

Return the exponential of x.

math.expm1(x)

Return exp(x) - 1.

math.fabs(x)

Return the absolute value of x.

math.floor(x)

Return an integer, being x rounded towards negative infinity.

math.fmod(x, y)

Return the remainder of x/y.

math.frexp(x)

Decomposes a floating-point number into its mantissa and exponent. The returned value is the tuple (m, e) such that x == m * 2**e exactly. If x == 0 then the function returns (0.0, 0), otherwise the relation 0.5 <= abs(m) < 1 holds.

math.gamma(x)

Return the gamma function of x.

math.isfinite(x)

Return True if x is finite.

math.isinf(x)

Return True if x is infinite.

math.isnan(x)

Return True if x is not-a-number

math.ldexp(x, exp)

Return x * (2**exp).

math.lgamma(x)

Return the natural logarithm of the gamma function of x.

math.log(x)

Return the natural logarithm of x.

math.log10(x)

Return the base-10 logarithm of x.

math.log2(x)

Return the base-2 logarithm of x.

math.modf(x)

Return a tuple of two floats, being the fractional and integral parts of x. Both return values have the same sign as x.

math.pow(x, y)

Returns x to the power of y.

math.radians(x)

Return degrees x converted to radians.

math.sin(x)

Return the sine of x.

math.sinh(x)

Return the hyperbolic sine of x.

math.sqrt(x)

Return the square root of x.

math.tan(x)

Return the tangent of x.

math.tanh(x)

Return the hyperbolic tangent of x.

math.trunc(x)

返回一个整数, x 接近于0。

常数
math.e

自然对数的底

math.pi

圆周率

select – 等待流事件

提供了在流上等待事件的功能(选择可操作的流)。

TPYBoard特性

轮询是在多个对象上等待读/写活动的有效方法。 当前支持: pyb.UART,:class:pyb.USB_VCP.

函数
select.poll()

创建轮询类的实例。

select.select(rlist, wlist, xlist[, timeout])

等待激活一组对象。

提供的兼容性和效率不高。 推荐使用 Poll

Poll
方法
poll.register(obj[, eventmask])

登记轮询对象 objeventmask 是以下逻辑:

  • select.POLLIN - 读取可用数据
  • select.POLLOUT - 写入更多数据
  • select.POLLERR - 发生错误
  • select.POLLHUP - 流结束/连接终止检测

eventmask 默认 select.POLLIN | select.POLLOUT.

poll.unregister(obj)

注销轮询对象 obj

poll.modify(obj, eventmask)

修改对象``obj``的 eventmask

poll.poll([timeout])

等待至少一个已注册的对象准备就绪。返回列表(obj, event, ...) 元组, event 元素指定了一个流发生的事件,是上面所描述的 `select.POLL*`常量组合。 在元组中可能有其他元素,取决于平台和版本,所以不要假定它的大小是2。如果超时,则返回空列表。

超时为毫秒。

sys – 系统特有功能函数

函数
sys.exit(retval=0)

终止当前程序给定的退出代码。 函数会抛出 SystemExit 异常。

sys.print_exception(exc, file=sys.stdout)

打印异常与追踪到一个类似文件的对象 file (或者缺省 sys.stdout ).

Difference to CPython

This is simplified version of a function which appears in the traceback module in CPython. Unlike traceback.print_exception(), this function takes just exception value instead of exception type, exception value, and traceback object; file argument should be positional; further arguments are not supported. CPython-compatible traceback module can be found in micropython-lib.

常数
sys.argv

当前程序启动时参数的可变列表。

sys.byteorder

系统字节顺序 (“little” or “big”).

sys.implementation

使用当前Python实现的。对于micropython,它具有以下属性:

  • name - string “micropython”
  • version - tuple (major, minor, micro), e.g. (1, 7, 0)

This object is the recommended way to distinguish MicroPython from other Python implementations (note that it still may not exist in the very minimal ports).

Difference to CPython

CPython mandates more attributes for this object, but the actual useful bare minimum is implemented in MicroPython.

sys.maxsize

一个土生土长的整数类型的最大值可以把握当前的平台,或最大值的micropython整型表示, 如果它小于平台最大值(即micropython端口没有长整型数据支持的情况下)。

   可用于检测“意义”的一个平台(32位和64位,等)。建议不要直接将此属性与某些值比较,而是计算它的位数:

bits = 0
v = sys.maxsize
while v:
    bits += 1
    v >>= 1
if bits > 32:
    # 64-bit (or more) platform
    ...
else:
    # 32-bit (or less) platform
    # Note that on 32-bit platform, value of bits may be less than 32
    # (e.g. 31) due to peculiarities described above, so use "> 16",
    # "> 32", "> 64" style of comparisons.
sys.modules

加载模块字典。在一部分环境中它可能不包含内置模块。

sys.path

搜索导入模块的可变目录列表。

sys.platform

The platform that MicroPython is running on. For OS/RTOS ports, this is usually an identifier of the OS, e.g. "linux". For baremetal ports it is an identifier of a board, e.g. “pyboard” for the original MicroPython reference board. It thus can be used to distinguish one board from another. If you need to check whether your program runs on MicroPython (vs other Python implementation), use sys.implementation instead.

sys.stderr

标准错误流。

sys.stdin

标准输入流。

sys.stdout

标准输出流。

sys.version

符合的Python语言版本,如字符串。

sys.version_info

Python语言版本,实现符合,作为一个元组的值。

ubinascii – 二进制/ ASCII转换

实现了二进制数据以ASCII形式的各种编码之间的转换(两个方向)。

函数
ubinascii.hexlify(data[, sep])

将二进制数据转换为十六进制表示。

Difference to CPython

If additional argument, sep is supplied, it is used as a separator between hexadecimal values.

ubinascii.unhexlify(data)

将十六进制数据转换为二进制表示。返回字节串 (换言之, 反二进制转换)

ubinascii.a2b_base64(data)

Base64编码的数据转换为二进制表示。返回字节串。

ubinascii.b2a_base64(data)

编码base64格式的二进制数据。返回的字符串。

ucollections – 收集和容器类型

模块实现先进的集合和容器类型来保存/累积各种对象。

ucollections.namedtuple(name, fields)

这是工厂函数创建一个新的namedtuple型与一个特定的字段名称和集合。 namedtuple是元组允许子类要访问它的字段不仅是数字索引,而且还具有属性使用符号字段名访问语法。 字段是字符串序列指定字段名称。为了兼容的实现也可以用空间分隔的字符串命名的字段(但效率较低) 使用示例:

from ucollections import namedtuple

MyTuple = namedtuple("MyTuple", ("id", "name"))
t1 = MyTuple(1, "foo")
t2 = MyTuple(2, "bar")
print(t1.name)
assert t2.name == t2[1]
ucollections.OrderedDict(...)

dict 类型的子类,记住并保留键的追加顺序。keys/items返回的顺序被加入:

from ucollections import OrderedDict

# To make benefit of ordered keys, OrderedDict should be initialized
# from sequence of (key, value) pairs.
d = OrderedDict([("z", 1), ("a", 2)])
# More items can be added as usual
d["w"] = 5
d["b"] = 3
for k, v in d.items():
    print(k, v)

输出:

z 1
a 2
w 5
b 3

uhashlib – 哈希算法

该模块实现了二进制数据哈希算法。精确可用的算法依赖于TPYBoard。其中的算法可能实施:

  • SHA256 - The current generation, modern hashing algorithm (of SHA2 series). It is suitable for cryptographically-secure purposes. Included in the MicroPython core and any board is recommended to provide this, unless it has particular code size constraints.
  • SHA1 - A previous generation algorithm. Not recommended for new usages, but SHA1 is a part of number of Internet standards and existing applications, so boards targetting network connectivity and interoperatiability will try to provide this.
  • MD5 - A legacy algorithm, not considered cryptographically secure. Only selected boards, targetting interoperatibility with legacy applications, will offer this.
构造器
class uhashlib.sha256([data])

创建一个SHA256哈希对象并提供 data 赋值。

class uhashlib.sha1([data])

创建一个SHA1哈希对象并提供 data 赋值。

class uhashlib.md5([data])

创建一个MD5哈希对象并提供 data 赋值。

方法
hash.update(data)

将更多二进制数据放入哈希表中。

hash.digest()

返回字节对象哈希的所有数据。调用此方法后,将无法将更多数据送入哈希。

hash.hexdigest()

此方法没有实现, 使用 ubinascii.hexlify(hash.digest()) 达到类似效果。

uheapq – 堆排序算法

提供了堆排序算法。

堆队列是一个列表,它的元素以特定的方式存储。

函数
uheapq.heappush(heap, item)

item 推到 heap

uheapq.heappop(heap)

``heap``弹出第一个元素并返回。 如果是堆时空的会抛出IndexError。

uheapq.heapify(x)

将列表 x 转换成堆。

uio – 输入/输出流

包含流类型 (类似文件) 对象和帮助函数。

概念层次

Difference to CPython

Conceptual hierarchy of stream base classes is simplified in MicroPython, as described in this section.

(Abstract) base stream classes, which serve as a foundation for behavior of all the concrete classes, adhere to few dichotomies (pair-wise classifications) in CPython. In MicroPython, they are somewhat simplified and made implicit to achieve higher efficiencies and save resources.

An important dichotomy in CPython is unbuffered vs buffered streams. In MicroPython, all streams are currently unbuffered. This is because all modern OSes, and even many RTOSes and filesystem drivers already perform buffering on their side. Adding another layer of buffering is counter- productive (an issue known as “bufferbloat”) and takes precious memory. Note that there still cases where buffering may be useful, so we may introduce optional buffering support at a later time.

But in CPython, another important dichotomy is tied with “bufferedness” - it’s whether a stream may incur short read/writes or not. A short read is when a user asks e.g. 10 bytes from a stream, but gets less, similarly for writes. In CPython, unbuffered streams are automatically short operation susceptible, while buffered are guarantee against them. The no short read/writes is an important trait, as it allows to develop more concise and efficient programs - something which is highly desirable for MicroPython. So, while MicroPython doesn’t support buffered streams, it still provides for no-short-operations streams. Whether there will be short operations or not depends on each particular class’ needs, but developers are strongly advised to favor no-short-operations behavior for the reasons stated above. For example, MicroPython sockets are guaranteed to avoid short read/writes. Actually, at this time, there is no example of a short-operations stream class in the core, and one would be a port-specific class, where such a need is governed by hardware peculiarities.

The no-short-operations behavior gets tricky in case of non-blocking streams, blocking vs non-blocking behavior being another CPython dichotomy, fully supported by MicroPython. Non-blocking streams never wait for data either to arrive or be written - they read/write whatever possible, or signal lack of data (or ability to write data). Clearly, this conflicts with “no-short-operations” policy, and indeed, a case of non-blocking buffered (and this no-short-ops) streams is convoluted in CPython - in some places, such combination is prohibited, in some it’s undefined or just not documented, in some cases it raises verbose exceptions. The matter is much simpler in MicroPython: non-blocking stream are important for efficient asynchronous operations, so this property prevails on the “no-short-ops” one. So, while blocking streams will avoid short reads/writes whenever possible (the only case to get a short read is if end of file is reached, or in case of error (but errors don’t return short data, but raise exceptions)), non-blocking streams may produce short data to avoid blocking the operation.

The final dichotomy is binary vs text streams. MicroPython of course supports these, but while in CPython text streams are inherently buffered, they aren’t in MicroPython. (Indeed, that’s one of the cases for which we may introduce buffering support.)

Note that for efficiency, MicroPython doesn’t provide abstract base classes corresponding to the hierarchy above, and it’s not possible to implement, or subclass, a stream class in pure Python.

函数
uio.open(name, mode='r', **kwargs)

打开一个文件,关联到内建函数``open()``。所有端口 (用于访问文件系统) 需要支持模式参数,但支持其他参数不同的端口。

class uio.FileIO(...)

这个文件类型用二进制方式打开文件,等于使用``open(name, “rb”)``。 不应直接使用这个实例。

class uio.TextIOWrapper(...)

这个类型以文本方式打开文件,等同于使用``open(name, “rt”)``不应直接使用这个实例。

class uio.StringIO([string])
class uio.BytesIO([string])

内存文件对象。StringIO 用于文本模式 I/O (用 “t” 打开文件),BytesIO 用于二进制方式 (用 “b” 方式)。文件对象的初始内容可以用字符串参数指定(stringio 用普通字符串,bytesio用byets对象)。所有的文件方法,如 read(), write(), seek(), flush(), close() 都可以用在这些对象上,包括下面方法:

getvalue()

获取缓存去内容。

ujson – JSON编码与解码

提供 Python 对象到 JSON(JavaScript Object Notation) 数据格式的转换。

函数
ujson.dumps(obj)

返回 obj JSON字符串。

ujson.loads(str)

解析 str 字符串并返回对象。如果字符串格式错误将引发 ValueError 异常。

uos – 基本的 “操作系统” 服务

os 模块包含用于文件系统访问和``urandom``功能。

端口详解

``/``文件系统的根目录和可用的物理驱动器可以从这里访问。 如下:

/flash – 内部闪存文件系统

/sd – SD卡(如果插入SD卡)

函数
uos.chdir(path)

更改当前目录。

uos.getcwd()

获取当前目录。

uos.ilistdir([dir])

这个函数返回一个迭代器,然后产生三元组对应正在列出的目录中的条目。没有参数,它列出了

当前目录,否则它列出了目录给出的`dir`。

3-元组的形式`(name, type, inode)`:

  • name 是一个字符串(或字节,如果是一个字节对象),是输入的名称;
  • type 是一个整数,指定的条目类型,与普通文件和目录0x4000 0x8000;
  • inode 对应文件的inode的整数,可0的文件系统,没有这样的概念。
uos.listdir([dir])

没有参数,列出当前目录。否则列出给定目录。

uos.mkdir(path)

创建一个目录。

uos.remove(path)

删除文件。

uos.rmdir(path)

删除目录。

uos.rename(old_path, new_path)

重命名文件。

uos.stat(path)

获取文件或目录的状态。

uos.statvfs(path)

得到一个文件系统的状态。

按下列顺序返回带有文件系统信息的元组:

  • f_bsize – file system block size
  • f_frsize – fragment size
  • f_blocks – size of fs in f_frsize units
  • f_bfree – number of free blocks
  • f_bavail – number of free blocks for unpriviliged users
  • f_files – number of inodes
  • f_ffree – number of free inodes
  • f_favail – number of free inodes for unpriviliged users
  • f_flag – mount flags
  • f_namemax – maximum filename length

Parameters related to inodes: f_files, f_ffree, f_avail and the f_flags parameter may return 0 as they can be unavailable in a port-specific implementation.

uos.sync()

同步所有的文件系统。

uos.urandom(n)

返回带有n个随机字节的字节对象。它由硬件随机数生成器生成。

ure – 正则表达式

正则表达式用于测试字符串的某个模式,执行正则表达式操作。 正则表达式支持 CPython 子集 re 模块 (实际是 POSIX 扩展正则表达式的子集)。

支持操作符:

'.'
匹配任意字符。
'[]'
匹配字符集合,支持单个字符和一个范围。

'^'

'$'

'?'

'*'

'+'

'??'

'*?'

'+?'

重复计数 ({m,n}), 不支持高级的断言、命名组等。

函数
ure.compile(regex)

编译正则表达式,返回 regex 对象。

ure.match(regex, string)

string 匹配 regex,匹配总是从字符串的开始匹配。

ure.search(regex, string)

string 中搜索 regex。不同于匹配,它搜索第一个匹配位置的正则表达式字符串 (结果可能会是0)。

ure.DEBUG

标志值,显示表达式的调试信息。

Regex 对象

编译正则表达式,使用``ure.compile()``创建实例。

regex.match(string)
regex.search(string)
regex.split(string, max_split=-1)
匹配对象

匹配对象是 match()search() 方法返回值。

match.group([index])

只支持数字组。

usocket – 套接字模块

提供的BSD套接字接口。

参考对应的`CPython 模块 <https://docs.python.org/3/library/socket.html>`_进行比较。

Difference to CPython

CPython used to have a socket.error exception which is now deprecated, and is an alias of OSError. In MicroPython, use OSError directly.

Difference to CPython

For efficiency and consistency, socket objects in MicroPython implement a stream (file-like) interface directly. In CPython, you need to convert a socket to a file-like object using makefile() method. This method is still supported by MicroPython (but is a no-op), so where compatibility with CPython matters, be sure to use it.

Socket 地址格式

下面函数使用 (ipv4_address, port) 网络地址, ipv4_address 是由点和数字组成的字符串,如 "8.8.8.8",端口是 1-65535 的数字。注意不能使用域名做为 ipv4_address,域名需要先用 socket.getaddrinfo() 进行解析。

函数
socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)

创建新的套接字,使用指定的地址、类型和协议号。

socket.getaddrinfo(host, port)

传递 主机/端口 到一个5个数据的元组。元组列表的结构如下:

(family, type, proto, canonname, sockaddr)

下面显示了怎样连接到一个网址:

s = socket.socket()
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])

Difference to CPython

CPython raises a socket.gaierror exception (OSError subclass) in case of error in this function. MicroPython doesn’t have socket.gaierror and raises OSError directly. Note that error numbers of getaddrinfo() form a separate namespace and may not match error numbers from uerrno module. To distinguish getaddrinfo() errors, they are represented by negative numbers, whereas standard system errors are positive numbers (error numbers are accessible using e.args[0] property from an exception object). The use of negative values is a provisional detail which may change in the future.

常数
socket.AF_INET
socket.AF_INET6

TCP类型定义,可用性取决于特定的开发板。

socket.SOCK_STREAM
socket.SOCK_DGRAM

Socket类型.

socket.IPPROTO_UDP
socket.IPPROTO_TCP

IP协议号。

socket.SOL_*

Socket option levels (an argument to setsockopt()). The exact inventory depends on a board.

socket.SO_*

Socket options (an argument to setsockopt()). The exact inventory depends on a board.

Constants specific to WiPy:

socket.IPPROTO_SEC

Special protocol value to create SSL-compatible socket.

class socket
方法
socket.close()

关闭套接字。一旦关闭后,套接字所有的功能都将失效。远端将接收不到任何数据 (清理队列数据后)。 在回收垃圾时套接字会自动关闭,但还是推荐在必要时用 close() 去关闭,或, or to use a with statement around them。

socket.bind(address)

将套接字绑定到地址,套接字不能是已经绑定的。

socket.listen([backlog])

允许服务器接收连接。如果指定了 backlog,它不能小于0 (如果小于0将自动设置为0);超出后系统将拒绝新的连接。如果没有指定,将使用默认值。

socket.accept()

接收连接。套接字需要指定地址并监听连接。返回值是 (conn, address),其中conn是用来接收和发送数据的套接字,address是绑定到另一端的套接字。

socket.connect(address)

连接到指定地址的远端套接字。

socket.send(bytes)

发送数据。套接字需要已连接到远程。

socket.sendall(bytes)

发送数据。套接字已连接到远程。 Unlike send(), this method will try to send all of data, by sending data chunk by chunk consecutively.

The behavior of this method on non-blocking sockets is undefined. Due to this, on MicroPython, it’s recommended to use write() method instead, which has the same “no short writes” policy for blocking sockets, and will return number of bytes sent on non-blocking sockets.

socket.recv(bufsize)

接收数据,返回值是数据字节对象。bufsize是接收数据的最大数量。

socket.sendto(bytes, address)

发送数据。套接字没有连接到远程,目标套接字由地址参数指定。

socket.recvfrom(bufsize)

接收数据。返回值是 (bytes, address),其中 bytes 是字节对象,address 是发送数据的套接字。

socket.setsockopt(level, optname, value)

设置套接字参数。需要的符号常数定义在套接字模块 (SO_* 等)。value 可以是整数或字节对象。

socket.settimeout(value)

设置阻塞套接字超时时间。value 参数可以是代表秒的正浮点数或 None。如果设定大于 0 的参数,在后面套接字操作超出指定时间后将引起 timeout 异常。如果参数是 0,套接字将使用非阻塞模式。如果是 None,套接字使用阻塞模式。

Difference to CPython

CPython raises a socket.timeout exception in case of timeout, which is an OSError subclass. MicroPython raises an OSError directly instead. If you use except OSError: to catch the exception, your code will work both in MicroPython and CPython.

socket.setblocking(flag)

设置阻塞或非阻塞模式: 如果 flag 是 false,设置非阻塞模式。

This method is a shorthand for certain settimeout() calls:

  • sock.setblocking(True) is equivalent to sock.settimeout(None)
  • sock.setblocking(False) is equivalent to sock.settimeout(0)
socket.makefile(mode='rb', buffering=0)

Return a file object associated with the socket. The exact returned type depends on the arguments given to makefile(). The support is limited to binary modes only (‘rb’, ‘wb’, and ‘rwb’). CPython’s arguments: encoding, errors and newline are not supported.

Difference to CPython

As MicroPython doesn’t support buffered streams, values of buffering parameter is ignored and treated as if it was 0 (unbuffered).

Difference to CPython

Closing the file object returned by makefile() WILL close the original socket as well.

socket.read([size])

Read up to size bytes from the socket. Return a bytes object. If size is not given, it reads all data available from the socket until EOF; as such the method will not return until the socket is closed. This function tries to read as much data as requested (no “short reads”). This may be not possible with non-blocking socket though, and then less data will be returned.

socket.readinto(buf[, nbytes])

Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at most len(buf) bytes. Just as read(), this method follows “no short reads” policy.

Return value: number of bytes read and stored into buf.

socket.readline()

读取一行,以换行符结束。 返回读取的数据行。

socket.write(buf)

Write the buffer of bytes to the socket. This function will try to write all data to a socket (no “short writes”). This may be not possible with a non-blocking socket though, and returned value will be less than the length of buf.

Return value: number of bytes written.

ustruct – 打包和解包原始数据类型

更多内容参考 Python struct

支持 size/byte 的前缀: @, <, >, !.

支持的格式代码: b, B, h, H, i, I, l, L, q, Q, s, P, f, d (最后2个需要浮点库支持).

函数
ustruct.calcsize(fmt)

返回需要的字节数`fmt`。

ustruct.pack(fmt, v1, v2, ...)

按照字符串格式`fmt` 压缩参数 v1, v2, ... 。 返回值是参数编码后的字节对象。

ustruct.pack_into(fmt, buffer, offset, v1, v2, ...)

按照字符串格式`fmt` 压缩参数 v1, v2, ... 到缓冲区`buffer`,开始位置是`offset`。`offset`可以是负数,从缓冲区末尾开始计数。

ustruct.unpack(fmt, data)

按照字符串格式`fmt`解压数据`data`。 返回值是解压后参数的元组。

ustruct.unpack_from(fmt, data, offset=0)

fmtoffset 开始解压数据,如果 offset 是负数就是从缓冲区末尾开始计算。 返回值是解压后参数元组。

utime – 时间相关函数

utime 模块 提供获取当前时间和日期、测量时间间隔和延迟的功能。

初始时刻: Unix 使用 POSIX 系统标准,从 1970-01-01 00:00:00 UTC开始。 嵌入式程序从 2000-01-01 00:00:00 UTC 开始。

保持实际日历日期/时间:需要一个实时时钟 (RTC)。在底层系统 (包括一些 RTOS 中),RTC 已经包含在其中。设置时间是通过 OS/RTOS 而不是 MicroPython 完成,查询日期/时间也需要通过系统 API。对于裸板系统时钟依赖于 machine.RTC() 对象。设置时间通过 machine.RTC().datetime(tuple) 函数,并通过下面方式维持:

  • 后备电池 (可能是选件、扩展板等)。
  • 使用网络时间协议 (需要用户设置)。
  • 每次上电时手工设置 (大部分只是在硬复位时需要设置,少部分每次复位都需要设置)。

如果实际时间不是通过系统/MicroPython RTC维持,那么下面函数结果可能不是和预期的相同。

函数
utime.localtime([secs])

从初始时间的秒转换为元组: (年, 月, 日, 时, 分, 秒, 星期, yearday) 。如果 secs 是空或者 None,那么使用当前时间。

  • year 年份包括世纪(例如2014)。
  • month is 1-12
  • mday is 1-31
  • hour is 0-23
  • minute is 0-59
  • second is 0-59
  • weekday is 0-6 for Mon-Sun
  • yearday is 1-366
utime.mktime()

时间的反函数,它的参数是完整8参数的元组,返回值一个整数自2000年1月1日以来的秒数。

utime.sleep(seconds)

休眠指定的时间(秒),Seconds 可以是浮点数。注意有些版本的 MicroPython 不支持浮点数,为了兼容可以使用 sleep_ms()``sleep_us()``函数。

utime.sleep_ms(ms)

延时指定毫秒,参数不能小于0。

utime.sleep_us(us)

延时指定微秒,参数不能小于0。

utime.ticks_ms()

返回不断递增的毫秒计数器,在某些值后会重新计数(未指定)。计数值本身无特定意义,只适合用在``ticks_diff()``。

注:执行标准数学运算(+,-)或关系运算符(<,>,>,> =)直接在这些值上会导致无效结果。执行数学运算然后传递结果作为论据来` ` ticks_diff() ` ` ticks_add() ` `也将导致后一个函数的无效结果。

utime.ticks_us()

和上面``ticks_ms()``类似,只是返回微秒。

utime.ticks_cpu()

ticks_ms()ticks_us() 类似,具有更高精度 (使用 CPU 时钟)。

可用性:并非每个端口都实现此功能。

utime.ticks_add(ticks, delta)

Offset ticks value by a given number, which can be either positive or negative. Given a ticks value, this function allows to calculate ticks value delta ticks before or after it, following modular-arithmetic definition of tick values (see ticks_ms() above). ticks parameter must be a direct result of call to ticks_ms(), ticks_us(), or ticks_cpu() functions (or from previous call to ticks_add()). However, delta can be an arbitrary integer number or numeric expression. ticks_add() is useful for calculating deadlines for events/tasks. (Note: you must use ticks_diff() function to work with deadlines.)

Examples:

# Find out what ticks value there was 100ms ago
print(ticks_add(time.ticks_ms(), -100))

# Calculate deadline for operation and test for it
deadline = ticks_add(time.ticks_ms(), 200)
while ticks_diff(deadline, time.ticks_ms()) > 0:
    do_a_little_of_something()

# Find out TICKS_MAX used by this port
print(ticks_add(0, -1))
utime.ticks_diff(ticks1, ticks2)

Measure ticks difference between values returned from ticks_ms(), ticks_us(), or ticks_cpu() functions. The argument order is the same as for subtraction operator, ticks_diff(ticks1, ticks2) has the same meaning as ticks1 - ticks2. However, values returned by ticks_ms(), etc. functions may wrap around, so directly using subtraction on them will produce incorrect result. That is why ticks_diff() is needed, it implements modular (or more specifically, ring) arithmetics to produce correct result even for wrap-around values (as long as they not too distant inbetween, see below). The function returns signed value in the range [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (that’s a typical range definition for two’s-complement signed binary integers). If the result is negative, it means that ticks1 occured earlier in time than ticks2. Otherwise, it means that ticks1 occured after ticks2. This holds only if ticks1 and ticks2 are apart from each other for no more than TICKS_PERIOD/2-1 ticks. If that does not hold, incorrect result will be returned. Specifically, if two tick values are apart for TICKS_PERIOD/2-1 ticks, that value will be returned by the function. However, if TICKS_PERIOD/2 of real-time ticks has passed between them, the function will return -TICKS_PERIOD/2 instead, i.e. result value will wrap around to the negative range of possible values.

Informal rationale of the constraints above: Suppose you are locked in a room with no means to monitor passing of time except a standard 12-notch clock. Then if you look at dial-plate now, and don’t look again for another 13 hours (e.g., if you fall for a long sleep), then once you finally look again, it may seem to you that only 1 hour has passed. To avoid this mistake, just look at the clock regularly. Your application should do the same. “Too long sleep” metaphor also maps directly to application behavior: don’t let your application run any single task for too long. Run tasks in steps, and do time-keeping inbetween.

ticks_diff() is designed to accommodate various usage patterns, among them:

Polling with timeout. In this case, the order of events is known, and you will deal only with positive results of ticks_diff():

# Wait for GPIO pin to be asserted, but at most 500us
start = time.ticks_us()
while pin.value() == 0:
    if time.ticks_diff(time.ticks_us(), start) > 500:
        raise TimeoutError

Scheduling events. In this case, ticks_diff() result may be negative if an event is overdue:

# This code snippet is not optimized
now = time.ticks_ms()
scheduled_time = task.scheduled_time()
if ticks_diff(now, scheduled_time) > 0:
    print("Too early, let's nap")
    sleep_ms(ticks_diff(now, scheduled_time))
    task.run()
elif ticks_diff(now, scheduled_time) == 0:
    print("Right at time!")
    task.run()
elif ticks_diff(now, scheduled_time) < 0:
    print("Oops, running late, tell task to run faster!")
    task.run(run_faster=true)

Note: Do not pass time() values to ticks_diff(), you should use normal mathematical operations on them. But note that time() may (and will) also overflow. This is known as https://en.wikipedia.org/wiki/Year_2038_problem .

utime.time()

Returns the number of seconds, as an integer, since the Epoch, assuming that underlying RTC is set and maintained as described above. If an RTC is not set, this function returns number of seconds since a port-specific reference point in time (for embedded boards without a battery-backed RTC, usually since power up or reset). If you want to develop portable MicroPython application, you should not rely on this function to provide higher than second precision. If you need higher precision, use ticks_ms() and ticks_us() functions, if you need calendar time, localtime() without an argument is a better choice.

Difference to CPython

In CPython, this function returns number of seconds since Unix epoch, 1970-01-01 00:00 UTC, as a floating-point, usually having microsecond precision. With MicroPython, only Unix port uses the same Epoch, and if floating-point precision allows, returns sub-second precision. Embedded hardware usually doesn’t have floating-point precision to represent both long time ranges and subsecond precision, so they use integer value with second precision. Some embedded hardware also lacks battery-powered RTC, so returns number of seconds since last power-up or from other relative, hardware-specific point (e.g. reset).

uzlib – zlib 解压缩

使用 DEFLATE 算法解压缩二进制数据 (常用的 zlib 库和 gzip 文档)。目前不支持压缩。

函数
uzlib.decompress(data)

返回解压后的 bytes 数据。

MicroPython类库详述

MicroPython的特有功能如下。

btree – 简单的二叉树数据库

``btree``模块实现了一个简单的键值使用外部存储(磁盘文件,或在一般情况下,随机访问流)的数据库。 密钥存储在数据库中,除了由一个关键值的有效检索,数据库还支持有效的有序范围扫描(检索与给定范围内的键的值)。 在应用程序界面,BTree数据库工作接近可能的方式标准字典,一个显著的区别是,键和值必须是字节的对象(所以,如果你想存储其他类型的对象,你需要它们序列化字节第一)。

该模块是基于著名的BerkelyDB类库,版本1.xx。

例子:

import btree

# First, we need to open a stream which holds a database
# This is usually a file, but can be in-memory database
# using uio.BytesIO, a raw flash section, etc.
f = open("mydb", "w+b")

# Now open a database itself
db = btree.open(f)

# The keys you add will be sorted internally in the database
db[b"3"] = b"three"
db[b"1"] = b"one"
db[b"2"] = b"two"

# Prints b'two'
print(db[b"2"])

# Iterate over sorted keys in the database, starting from b"2"
# until the end of the database, returning only values.
# Mind that arguments passed to values() method are *key* values.
# Prints:
#   b'two'
#   b'three'
for word in db.values(b"2"):
    print(word)

del db[b"2"]

# No longer true, prints False
print(b"2" in db)

# Prints:
#  b"1"
#  b"3"
for key in db:
    print(key)

db.close()

# Don't forget to close the underlying stream!
f.close()
函数
btree.open(stream, *, flags=0, cachesize=0, pagesize=0, minkeypage=0)

从随机访问流(如打开文件)打开数据库。所有其他参数都是可选的关键字,并允许调整数据库操作先进的参数(大多数用户不需要):

  • flags - 当前未使用
  • cachesize - 建议的最大内存缓存大小为字节。对于一个使用较大值的内存可以提高性能。这个值只是一个建议,如果可能使用更多的内存模块值设置太低。
  • pagesize - 页面大小用于BTree节点。可接受的范围内是512-65536。如果0,将使用底层I/O块大小(内存使用和性能之间的最佳折衷方案)。
  • minkeypage - 每页存储关键字的最小数目。默认值0等于2。

返回一个` 二叉树 `对象,实现一个字典协议(的方法),和一些额外的方法介绍如下。

方法
btree.close()

关闭数据库。在处理结束时关闭数据库是强制性的,因为一些不成文的数据可能仍在缓存中。注意,这不会关闭数据库打开的底层流,它应该分别关闭(这也是强制性的,以确保从缓冲区刷新到基础存储的数据)。

btree.flush()

将缓存中的任何数据写入基础流。

btree.__getitem__(key)
btree.get(key, default=None)
btree.__setitem__(key, val)
btree.__detitem__(key)
btree.__contains__(key)

标准字典的方法.

btree.__iter__()

可直接遍历(类似于字典)二叉树对象来获取所有的键值。

btree.keys([start_key[, end_key[, flags]]])
btree.values([start_key[, end_key[, flags]]])
btree.items([start_key[, end_key[, flags]]])

这些方法与标准字典方法类似,但也可以使用可选参数迭代一个关键子区域,而不是整个数据库。

常数
btree.INCL

keys(), values(), `items()`方法的标志,用于扫描键值直到结束。

btree.DESC

keys(), values(), items() 方法的标志,用于降序扫描。

framebuf — Frame buffer manipulation

该模块提供了一个通用的帧缓冲区,可以用来创建位图图像,然后可以发送到一个显示。

class FrameBuffer

帧级提供一个像素缓冲区可借鉴的像素,线,矩形,文本和其他帧,用于生成输出显示器。

例如:

import framebuf

# FrameBuffer needs 2 bytes for every RGB565 pixel
fbuf = FrameBuffer(bytearray(10 * 100 * 2), 10, 100, framebuf.RGB565)

fbuf.fill(0)
fbuf.text('MicroPython!', 0, 0, 0xffff)
fbuf.hline(0, 10, 96, 0xffff)
构造器
class framebuf.FrameBuffer(buffer, width, height, format, stride=width)

构建一个帧缓存对象。参数是:

  • buffer FrameBuffer对象的缓存。
  • width FrameBuffer对象的宽度。
  • height FrameBuffer对象的高度。
  • format 指定用于FrameBuffer像素的类型; valid values are framebuf.MVLSB, framebuf.RGB565 and framebuf.GS4_HMSB. MVLSB is monochrome 1-bit color, RGB565 is RGB 16-bit color, and GS4_HMSB is grayscale 4-bit color. Where a color value c is passed to a method, c is a small integer with an encoding that is dependent on the format of the FrameBuffer.
  • stride is the number of pixels between each horizontal line of pixels in the FrameBuffer. This defaults to width but may need adjustments when implementing a FrameBuffer within another larger FrameBuffer or screen. The buffer size must accommodate an increased step size.

One must specify valid buffer, width, height, format and optionally stride. Invalid buffer size or dimensions may lead to unexpected errors.

Drawing primitive shapes

The following methods draw shapes onto the FrameBuffer.

FrameBuffer.fill(c)

Fill the entire FrameBuffer with the specified color.

FrameBuffer.pixel(x, y[, c])

If c is not given, get the color value of the specified pixel. If c is given, set the specified pixel to the given color.

FrameBuffer.hline(x, y, w, c)
FrameBuffer.vline(x, y, h, c)
FrameBuffer.line(x1, y1, x2, y2, c)

Draw a line from a set of coordinates using the given color and a thickness of 1 pixel. The line method draws the line up to a second set of coordinates whereas the hline and vline methods draw horizontal and vertical lines respectively up to a given length.

FrameBuffer.rect(x, y, w, h, c)
FrameBuffer.fill_rect(x, y, w, h, c)

Draw a rectangle at the given location, size and color. The rect method draws only a 1 pixel outline whereas the fill_rect method draws both the outline and interior.

Drawing text
FrameBuffer.text(s, x, y[, c])

Write text to the FrameBuffer using the the coordinates as the upper-left corner of the text. The color of the text can be defined by the optional argument but is otherwise a default value of 1. All characters have dimensions of 8x8 pixels and there is currently no way to change the font.

Other methods
FrameBuffer.scroll(xstep, ystep)

Shift the contents of the FrameBuffer by the given vector. This may leave a footprint of the previous colors in the FrameBuffer.

FrameBuffer.blit(fbuf, x, y[, key])

Draw another FrameBuffer on top of the current one at the given coordinates. If key is specified then it should be a color integer and the corresponding color will be considered transparent: all pixels with that color value will not be drawn.

This method works between FrameBuffer’s utilising different formats, but the resulting colors may be unexpected due to the mismatch in color formats.

Constants
framebuf.MONO_VLSB

Monochrome (1-bit) color format This defines a mapping where the bits in a byte are vertically mapped with bit 0 being nearest the top of the screen. Consequently each byte occupies 8 vertical pixels. Subsequent bytes appear at successive horizontal locations until the rightmost edge is reached. Further bytes are rendered at locations starting at the leftmost edge, 8 pixels lower.

framebuf.MONO_HLSB

Monochrome (1-bit) color format This defines a mapping where the bits in a byte are horizontally mapped. Each byte occupies 8 horizontal pixels with bit 0 being the leftmost. Subsequent bytes appear at successive horizontal locations until the rightmost edge is reached. Further bytes are rendered on the next row, one pixel lower.

framebuf.MONO_HMSB

Monochrome (1-bit) color format This defines a mapping where the bits in a byte are horizontally mapped. Each byte occupies 8 horizontal pixels with bit 7 being the leftmost. Subsequent bytes appear at successive horizontal locations until the rightmost edge is reached. Further bytes are rendered on the next row, one pixel lower.

framebuf.RGB565

Red Green Blue (16-bit, 5+6+5) color format

framebuf.GS4_HMSB

Grayscale (4-bit) color format

machine — 与硬件相关的功能

machine 模块包含与特定板上的硬件相关的特定函数。 在这个模块中的大多数功能允许实现直接和不受限制地访问和控制系统上的硬件块(如CPU,定时器,总线等)。 使用不当,会导致故障,死机,你会崩溃,在极端的情况下,硬件损坏。

A note of callbacks used by functions and class methods of machine module: all these callbacks should be considered as executing in an interrupt context. This is true for both physical devices with IDs >= 0 and “virtual” devices with negative IDs like -1 (these “virtual” devices are still thin shims on top of real hardware and real hardware interrupts). See isr_rules.

复位功能
machine.reset()

重置设备的方式类似类似按下rst按钮。

machine.reset_cause()

Get the reset cause. See constants for the possible return values.

中断功能
machine.disable_irq()

Disable interrupt requests. Returns the previous IRQ state which should be considered an opaque value. This return value should be passed to the enable_irq function to restore interrupts to their original state, before disable_irq was called.

machine.enable_irq(state)

Re-enable interrupt requests. The state parameter should be the value that was returned from the most recent call to the disable_irq function.

有效的相关功能
machine.freq()

Returns CPU frequency in hertz.

machine.idle()

Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods. Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).

machine.sleep()

Stops the CPU and disables all peripherals except for WLAN. Execution is resumed from the point where the sleep was requested. For wake up to actually happen, wake sources should be configured first.

machine.deepsleep()

Stops the CPU and all peripherals (including networking interfaces, if any). Execution is resumed from the main script, just as with a reset. The reset cause can be checked to know that we are coming from machine.DEEPSLEEP. For wake up to actually happen, wake sources should be configured first, like Pin change or RTC timeout.

更多功能
machine.unique_id()

Returns a byte string with a unique identifier of a board/SoC. It will vary from a board/SoC instance to another, if underlying hardware allows. Length varies by hardware (so use substring of a full value if you expect a short ID). In some MicroPython ports, ID corresponds to the network MAC address.

machine.time_pulse_us(pin, pulse_level, timeout_us=1000000)

Time a pulse on the given pin, and return the duration of the pulse in microseconds. The pulse_level argument should be 0 to time a low pulse or 1 to time a high pulse.

If the current input value of the pin is different to pulse_level, the function first (*) waits until the pin input becomes equal to pulse_level, then (**) times the duration that the pin is equal to pulse_level. If the pin is already equal to pulse_level then timing starts straight away.

The function will return -2 if there was timeout waiting for condition marked (*) above, and -1 if there was timeout during the main measurement, marked (**) above. The timeout is the same for both cases and given by timeout_us (which is in microseconds).

常数
machine.IDLE
machine.SLEEP
machine.DEEPSLEEP

IRQ wake values.

machine.PWRON_RESET
machine.HARD_RESET
machine.WDT_RESET
machine.DEEPSLEEP_RESET
machine.SOFT_RESET

Reset causes.

machine.WLAN_WAKE
machine.PIN_WAKE
machine.RTC_WAKE

Wake-up reasons.

class I2C – a two-wire serial protocol

I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.

I2C objects are created attached to a specific bus. They can be initialised when created, or initialised later on.

Printing the I2C object gives you information about its configuration.

Example usage:

from machine import I2C

i2c = I2C(freq=400000)          # create I2C peripheral at frequency of 400kHz
                                # depending on the port, extra parameters may be required
                                # to select the peripheral and/or pins to use

i2c.scan()                      # scan for slaves, returning a list of 7-bit addresses

i2c.writeto(42, b'123')         # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(42, 4)             # read 4 bytes from slave with 7-bit address 42

i2c.readfrom_mem(42, 8, 3)      # read 3 bytes from memory of slave 42,
                                #   starting at memory-address 8 in the slave
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42
                                #   starting at address 2 in the slave
Constructors
class machine.I2C(id=-1, *, scl, sda, freq=400000)

Construct and return a new I2C object using the following parameters:

  • id identifies the particular I2C peripheral. The default value of -1 selects a software implementation of I2C which can work (in most cases) with arbitrary pins for SCL and SDA. If id is -1 then scl and sda must be specified. Other allowed values for id depend on the particular port/board, and specifying scl and sda may or may not be required or allowed in this case.
  • scl should be a pin object specifying the pin to use for SCL.
  • sda should be a pin object specifying the pin to use for SDA.
  • freq should be an integer which sets the maximum frequency for SCL.
General Methods
I2C.init(scl, sda, *, freq=400000)

Initialise the I2C bus with the given arguments:

  • scl is a pin object for the SCL line
  • sda is a pin object for the SDA line
  • freq is the SCL clock rate
I2C.deinit()

Turn off the I2C bus.

Availability: WiPy.

I2C.scan()

Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of those that respond. A device responds if it pulls the SDA line low after its address (including a write bit) is sent on the bus.

Primitive I2C operations

The following methods implement the primitive I2C master bus operations and can be combined to make any I2C transaction. They are provided if you need more control over the bus, otherwise the standard methods (see below) can be used.

I2C.start()

Generate a START condition on the bus (SDA transitions to low while SCL is high).

Availability: ESP8266.

I2C.stop()

Generate a STOP condition on the bus (SDA transitions to high while SCL is high).

Availability: ESP8266.

I2C.readinto(buf, nack=True)

Reads bytes from the bus and stores them into buf. The number of bytes read is the length of buf. An ACK will be sent on the bus after receiving all but the last byte. After the last byte is received, if nack is true then a NACK will be sent, otherwise an ACK will be sent (and in this case the slave assumes more bytes are going to be read in a later call).

Availability: ESP8266.

I2C.write(buf)

Write the bytes from buf to the bus. Checks that an ACK is received after each byte and stops transmitting the remaining bytes if a NACK is received. The function returns the number of ACKs that were received.

Availability: ESP8266.

Standard bus operations

The following methods implement the standard I2C master read and write operations that target a given slave device.

I2C.readfrom(addr, nbytes, stop=True)

Read nbytes from the slave specified by addr. If stop is true then a STOP condition is generated at the end of the transfer. Returns a bytes object with the data read.

I2C.readfrom_into(addr, buf, stop=True)

Read into buf from the slave specified by addr. The number of bytes read will be the length of buf. If stop is true then a STOP condition is generated at the end of the transfer.

The method returns None.

I2C.writeto(addr, buf, stop=True)

Write the bytes from buf to the slave specified by addr. If a NACK is received following the write of a byte from buf then the remaining bytes are not sent. If stop is true then a STOP condition is generated at the end of the transfer, even if a NACK is received. The function returns the number of ACKs that were received.

Memory operations

Some I2C devices act as a memory device (or set of registers) that can be read from and written to. In this case there are two addresses associated with an I2C transaction: the slave address and the memory address. The following methods are convenience functions to communicate with such devices.

I2C.readfrom_mem(addr, memaddr, nbytes, *, addrsize=8)

Read nbytes from the slave specified by addr starting from the memory address specified by memaddr. The argument addrsize specifies the address size in bits. Returns a bytes object with the data read.

I2C.readfrom_mem_into(addr, memaddr, buf, *, addrsize=8)

Read into buf from the slave specified by addr starting from the memory address specified by memaddr. The number of bytes read is the length of buf. The argument addrsize specifies the address size in bits (on ESP8266 this argument is not recognised and the address size is always 8 bits).

The method returns None.

I2C.writeto_mem(addr, memaddr, buf, *, addrsize=8)

Write buf to the slave specified by addr starting from the memory address specified by memaddr. The argument addrsize specifies the address size in bits (on ESP8266 this argument is not recognised and the address size is always 8 bits).

The method returns None.

class Pin – control I/O pins

A pin object is used to control I/O pins (also known as GPIO - general-purpose input/output). Pin objects are commonly associated with a physical pin that can drive an output voltage and read input voltages. The pin class has methods to set the mode of the pin (IN, OUT, etc) and methods to get and set the digital logic level. For analog control of a pin, see the ADC class.

A pin object is constructed by using an identifier which unambiguously specifies a certain I/O pin. The allowed forms of the identifier and the physical pin that the identifier maps to are port-specific. Possibilities for the identifier are an integer, a string or a tuple with port and pin number.

Usage Model:

from machine import Pin

# create an output pin on pin #0
p0 = Pin(0, Pin.OUT)

# set the value low then high
p0.value(0)
p0.value(1)

# create an input pin on pin #2, with a pull up resistor
p2 = Pin(2, Pin.IN, Pin.PULL_UP)

# read and print the pin value
print(p2.value())

# reconfigure pin #0 in input mode
p0.mode(p0.IN)

# configure an irq callback
p0.irq(lambda p:print(p))
Constructors
class machine.Pin(id, mode=-1, pull=-1, *, value, drive, alt)

Access the pin peripheral (GPIO pin) associated with the given id. If additional arguments are given in the constructor then they are used to initialise the pin. Any settings that are not specified will remain in their previous state.

The arguments are:

  • id is mandatory and can be an arbitrary object. Among possible value types are: int (an internal Pin identifier), str (a Pin name), and tuple (pair of [port, pin]).
  • mode specifies the pin mode, which can be one of:
    • Pin.IN - Pin is configured for input. If viewed as an output the pin is in high-impedance state.
    • Pin.OUT - Pin is configured for (normal) output.
    • Pin.OPEN_DRAIN - Pin is configured for open-drain output. Open-drain output works in the following way: if the output value is set to 0 the pin is active at a low level; if the output value is 1 the pin is in a high-impedance state. Not all ports implement this mode, or some might only on certain pins.
    • Pin.ALT - Pin is configured to perform an alternative function, which is port specific. For a pin configured in such a way any other Pin methods (except Pin.init()) are not applicable (calling them will lead to undefined, or a hardware-specific, result). Not all ports implement this mode.
    • Pin.ALT_OPEN_DRAIN - The Same as Pin.ALT, but the pin is configured as open-drain. Not all ports implement this mode.
  • pull specifies if the pin has a (weak) pull resistor attached, and can be one of:
    • None - No pull up or down resistor.
    • Pin.PULL_UP - Pull up resistor enabled.
    • Pin.PULL_DOWN - Pull down resistor enabled.
  • value is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial output pin value if given, otherwise the state of the pin peripheral remains unchanged.
  • drive specifies the output power of the pin and can be one of: Pin.LOW_POWER, Pin.MED_POWER or Pin.HIGH_POWER. The actual current driving capabilities are port dependent. Not all ports implement this argument.
  • alt specifies an alternate function for the pin and the values it can take are port dependent. This argument is valid only for Pin.ALT and Pin.ALT_OPEN_DRAIN modes. It may be used when a pin supports more than one alternate function. If only one pin alternate function is supported the this argument is not required. Not all ports implement this argument.

As specified above, the Pin class allows to set an alternate function for a particular pin, but it does not specify any further operations on such a pin. Pins configured in alternate-function mode are usually not used as GPIO but are instead driven by other hardware peripherals. The only operation supported on such a pin is re-initialising, by calling the constructor or Pin.init() method. If a pin that is configured in alternate-function mode is re-initialised with Pin.IN, Pin.OUT, or Pin.OPEN_DRAIN, the alternate function will be removed from the pin.

Methods
Pin.init(mode=-1, pull=-1, *, value, drive, alt)

Re-initialise the pin using the given parameters. Only those arguments that are specified will be set. The rest of the pin peripheral state will remain unchanged. See the constructor documentation for details of the arguments.

Returns None.

Pin.value([x])

This method allows to set and get the value of the pin, depending on whether the argument x is supplied or not.

If the argument is omitted then this method gets the digital logic level of the pin, returning 0 or 1 corresponding to low and high voltage signals respectively. The behaviour of this method depends on the mode of the pin:

  • Pin.IN - The method returns the actual input value currently present on the pin.
  • Pin.OUT - The behaviour and return value of the method is undefined.
  • Pin.OPEN_DRAIN - If the pin is in state ‘0’ then the behaviour and return value of the method is undefined. Otherwise, if the pin is in state ‘1’, the method returns the actual input value currently present on the pin.

If the argument is supplied then this method sets the digital logic level of the pin. The argument x can be anything that converts to a boolean. If it converts to True, the pin is set to state ‘1’, otherwise it is set to state ‘0’. The behaviour of this method depends on the mode of the pin:

  • Pin.IN - The value is stored in the output buffer for the pin. The pin state does not change, it remains in the high-impedance state. The stored value will become active on the pin as soon as it is changed to Pin.OUT or Pin.OPEN_DRAIN mode.
  • Pin.OUT - The output buffer is set to the given value immediately.
  • Pin.OPEN_DRAIN - If the value is ‘0’ the pin is set to a low voltage state. Otherwise the pin is set to high-impedance state.

When setting the value this method returns None.

Pin.out_value()

Return the value stored in the output buffer of a pin, regardless of its mode.

Not all ports implement this method.

Pin.__call__([x])

Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin. It is equivalent to Pin.value([x]). See Pin.value() for more details.

Pin.toggle()

Toggle the output value of the pin. Equivalent to pin.value(not pin.out_value()). Returns None.

Not all ports implement this method.

Availability: WiPy.

Pin.id()

Get the pin identifier. This may return the id as specified in the constructor. Or it may return a canonical software-specific pin id.

Pin.mode([mode])

Get or set the pin mode. See the constructor documentation for details of the mode argument.

Pin.pull([pull])

Get or set the pin pull state. See the constructor documentation for details of the pull argument.

Pin.drive([drive])

Get or set the pin drive strength. See the constructor documentation for details of the drive argument.

Not all ports implement this method.

Availability: WiPy.

Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), *, priority=1, wake=None)

Configure an interrupt handler to be called when the trigger source of the pin is active. If the pin mode is Pin.IN then the trigger source is the external value on the pin. If the pin mode is Pin.OUT then the trigger source is the output buffer of the pin. Otherwise, if the pin mode is Pin.OPEN_DRAIN then the trigger source is the output buffer for state ‘0’ and the external pin value for state ‘1’.

The arguments are:

  • handler is an optional function to be called when the interrupt triggers.

  • trigger configures the event which can generate an interrupt. Possible values are:

    • Pin.IRQ_FALLING interrupt on falling edge.
    • Pin.IRQ_RISING interrupt on rising edge.
    • Pin.IRQ_LOW_LEVEL interrupt on low level.
    • Pin.IRQ_HIGH_LEVEL interrupt on high level.

    These values can be OR’ed together to trigger on multiple events.

  • priority sets the priority level of the interrupt. The values it can take are port-specific, but higher values always represent higher priorities.

  • wake selects the power mode in which this interrupt can wake up the system. It can be machine.IDLE, machine.SLEEP or machine.DEEPSLEEP. These values can also be OR’ed together to make a pin generate interrupts in more than one power mode.

This method returns a callback object.

Attributes
class Pin.board

Contains all Pin objects supported by the board. Examples:

Pin.board.GP25
led = Pin(Pin.board.GP25, mode=Pin.OUT)
Pin.board.GP2.alt_list()

Availability: WiPy.

Constants

The following constants are used to configure the pin objects. Note that not all constants are available on all ports.

Pin.IN
Pin.OUT
Pin.OPEN_DRAIN
Pin.ALT
Pin.ALT_OPEN_DRAIN

Selects the pin mode.

Pin.PULL_UP
Pin.PULL_DOWN

Selects whether there is a pull up/down resistor. Use the value None for no pull.

Pin.LOW_POWER
Pin.MED_POWER
Pin.HIGH_POWER

Selects the pin drive strength.

Pin.IRQ_FALLING
Pin.IRQ_RISING
Pin.IRQ_LOW_LEVEL
Pin.IRQ_HIGH_LEVEL

Selects the IRQ trigger type.

class RTC – real time clock

The RTC is and independent clock that keeps track of the date and time.

Example usage:

rtc = machine.RTC()
rtc.init((2014, 5, 1, 4, 13, 0, 0, 0))
print(rtc.now())
Constructors
class machine.RTC(id=0, ...)

Create an RTC object. See init for parameters of initialization.

Methods
RTC.init(datetime)

Initialise the RTC. Datetime is a tuple of the form:

(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])
RTC.now()

Get get the current datetime tuple.

RTC.deinit()

Resets the RTC to the time of January 1, 2015 and starts running it again.

RTC.alarm(id, time, /*, repeat=False)

Set the RTC alarm. Time might be either a millisecond value to program the alarm to current time + time_in_ms in the future, or a datetimetuple. If the time passed is in milliseconds, repeat can be set to True to make the alarm periodic.

RTC.alarm_left(alarm_id=0)

Get the number of milliseconds left before the alarm expires.

RTC.cancel(alarm_id=0)

Cancel a running alarm.

RTC.irq(*, trigger, handler=None, wake=machine.IDLE)

Create an irq object triggered by a real time clock alarm.

  • trigger must be RTC.ALARM0
  • handler is the function to be called when the callback is triggered.
  • wake specifies the sleep mode from where this interrupt can wake up the system.
Constants
RTC.ALARM0

irq trigger source

class SPI – a Serial Peripheral Interface bus protocol (master side)

SPI is a synchronous serial protocol that is driven by a master. At the physical level, a bus consists of 3 lines: SCK, MOSI, MISO. Multiple devices can share the same bus. Each device should have a separate, 4th signal, SS (Slave Select), to select a particular device on a bus with which communication takes place. Management of an SS signal should happen in user code (via machine.Pin class).

Constructors
class machine.SPI(id, ...)

Construct an SPI object on the given bus, id. Values of id depend on a particular port and its hardware. Values 0, 1, etc. are commonly used to select hardware SPI block #0, #1, etc. Value -1 can be used for bitbanging (software) implementation of SPI (if supported by a port).

With no additional parameters, the SPI object is created but not initialised (it has the settings from the last initialisation of the bus, if any). If extra arguments are given, the bus is initialised. See init for parameters of initialisation.

Methods
SPI.init(baudrate=1000000, *, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))

Initialise the SPI bus with the given parameters:

  • baudrate is the SCK clock rate.
  • polarity can be 0 or 1, and is the level the idle clock line sits at.
  • phase can be 0 or 1 to sample data on the first or second clock edge respectively.
  • bits is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware.
  • firstbit can be SPI.MSB or SPI.LSB.
  • sck, mosi, miso are pins (machine.Pin) objects to use for bus signals. For most hardware SPI blocks (as selected by id parameter to the constructor), pins are fixed and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver (id = -1).
  • pins - WiPy port doesn’t sck, mosi, miso arguments, and instead allows to specify them as a tuple of pins parameter.
SPI.deinit()

Turn off the SPI bus.

SPI.read(nbytes, write=0x00)

Read a number of bytes specified by nbytes while continuously writing the single byte given by write. Returns a bytes object with the data that was read.

SPI.readinto(buf, write=0x00)

Read into the buffer specified by buf while continuously writing the single byte given by write. Returns None.

Note: on WiPy this function returns the number of bytes read.

SPI.write(buf)

Write the bytes contained in buf. Returns None.

Note: on WiPy this function returns the number of bytes written.

SPI.write_readinto(write_buf, read_buf)

Write the bytes from write_buf while reading into read_buf. The buffers can be the same or different, but both buffers must have the same length. Returns None.

Note: on WiPy this function returns the number of bytes written.

Constants
SPI.MASTER

for initialising the SPI bus to master; this is only used for the WiPy

SPI.MSB

set the first bit to be the most significant bit

SPI.LSB

set the first bit to be the least significant bit

class Timer – control hardware timers

Hardware timers deal with timing of periods and events. Timers are perhaps the most flexible and heterogeneous kind of hardware in MCUs and SoCs, differently greatly from a model to a model. MicroPython’s Timer class defines a baseline operation of executing a callback with a given period (or once after some delay), and allow specific boards to define more non-standard behavior (which thus won’t be portable to other boards).

See discussion of important constraints on Timer callbacks.

注解

Memory can’t be allocated inside irq handlers (an interrupt) and so exceptions raised within a handler don’t give much information. See micropython.alloc_emergency_exception_buf() for how to get around this limitation.

Constructors
class machine.Timer(id, ...)

Construct a new timer object of the given id. Id of -1 constructs a virtual timer (if supported by a board).

Methods
Timer.deinit()

Deinitialises the timer. Stops the timer, and disables the timer peripheral.

Constants
Timer.ONE_SHOT
Timer.PERIODIC

Timer operating mode.

class UART – duplex serial communication bus

UART implements the standard UART/USART duplex serial communications protocol. At the physical level it consists of 2 lines: RX and TX. The unit of communication is a character (not to be confused with a string character) which can be 8 or 9 bits wide.

UART objects can be created and initialised using:

from machine import UART

uart = UART(1, 9600)                         # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters

Supported paramters differ on a board:

Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With parity=None, only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits are supported.

WiPy/CC3200: Bits can be 5, 6, 7, 8. Stop can be 1 or 2.

A UART object acts like a stream object and reading and writing is done using the standard stream methods:

uart.read(10)       # read 10 characters, returns a bytes object
uart.read()         # read all available characters
uart.readline()     # read a line
uart.readinto(buf)  # read and store into the given buffer
uart.write('abc')   # write the 3 characters
Constructors
class machine.UART(id, ...)

Construct a UART object of the given id.

Methods
UART.deinit()

Turn off the UART bus.

UART.any()

Return true value if there’re characters available for reading. On some boards, the number of available characters is returned.

UART.read([nbytes])

Read characters. If nbytes is specified then read at most that many bytes, otherwise read as much data as possible.

Return value: a bytes object containing the bytes read in. Returns None on timeout.

UART.readinto(buf[, nbytes])

Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at most len(buf) bytes.

Return value: number of bytes read and stored into buf or None on timeout.

UART.readline()

Read a line, ending in a newline character.

Return value: the line read or None on timeout.

UART.write(buf)

Write the buffer of bytes to the bus.

Return value: number of bytes written or None on timeout.

UART.sendbreak()

Send a break condition on the bus. This drives the bus low for a duration longer than required for a normal transmission of a character.

class WDT – watchdog timer

The WDT is used to restart the system when the application crashes and ends up into a non recoverable state. Once started it cannot be stopped or reconfigured in any way. After enabling, the application must “feed” the watchdog periodically to prevent it from expiring and resetting the system.

Example usage:

from machine import WDT
wdt = WDT(timeout=2000)  # enable it with a timeout of 2s
wdt.feed()

Availability of this class: pyboard, WiPy.

Constructors
class machine.WDT(id=0, timeout=5000)

Create a WDT object and start it. The timeout must be given in seconds and the minimum value that is accepted is 1 second. Once it is running the timeout cannot be changed and the WDT cannot be stopped either.

Methods
wdt.feed()

Feed the WDT to prevent it from resetting the system. The application should place this call in a sensible place ensuring that the WDT is only fed after verifying that everything is functioning correctly.

micropython – 访问并控制MicroPython底层

函数
micropython.alloc_emergency_exception_buf(size)

为异常缓冲区分配``size``内存字节(大小约为100字节)。 缓冲区被用来创建异常的情况下,当正常的RAM分配将失败(如在中断处理程序),因此在这些情况下,提供有用的回溯信息。

使用这个函数的一个好方法是把它放在主脚本的开始(如boot.py或mail.py)然后急救例外缓冲区将积极为所有它之后的代码。

micropython.mem_info([verbose])

打印当前使用的内存信息。如果给出了``verbose``参数,则打印额外的信息。

打印的信息是实现依赖的,但当前包含堆栈和堆的使用量。 在详细模式中,它打印出整个堆,标示被使用和可用块。

micropython.qstr_info([verbose])

目前关于保留的字符串打印信息。如果给出了``verbose``参数,则打印额外的信息。

The information that is printed is implementation dependent, but currently includes the number of interned strings and the amount of RAM they use. In verbose mode it prints out the names of all RAM-interned strings.

network — 网络配置

提供网络驱动程序和路由配置。micropython变量/编译与网络功能必须安装。 特定硬件的网络驱动程序可在此模块中使用,并用于配置硬件网络接口。 通过配置接口提供的网络服务可用于通过:mod:socket.

例如:

# configure a specific network interface
# see below for examples of specific drivers
import network
nic = network.Driver(...)
print(nic.ifconfig())

# now use socket as usual
import socket
addr = socket.getaddrinfo('tpyboard.com', 80)[0][-1]
s = socket.socket()
s.connect(addr)
s.send(b'GET / HTTP/1.1\r\nHost: tpyboard.com\r\n\r\n')
data = s.recv(1000)
s.close()

uctypes – access binary data in a structured way

This module implements “foreign data interface” for MicroPython. The idea behind it is similar to CPython’s ctypes modules, but the actual API is different, streamlined and optimized for small size. The basic idea of the module is to define data structure layout with about the same power as the C language allows, and the access it using familiar dot-syntax to reference sub-fields.

参见

Module ustruct
Standard Python way to access binary data structures (doesn’t scale well to large and complex structures).
Defining structure layout

Structure layout is defined by a “descriptor” - a Python dictionary which encodes field names as keys and other properties required to access them as associated values. Currently, uctypes requires explicit specification of offsets for each field. Offset are given in bytes from a structure start.

Following are encoding examples for various field types:

  • Scalar types:

    "field_name": uctypes.UINT32 | 0
    

    in other words, value is scalar type identifier ORed with field offset (in bytes) from the start of the structure.

  • Recursive structures:

    "sub": (2, {
        "b0": uctypes.UINT8 | 0,
        "b1": uctypes.UINT8 | 1,
    })
    

    i.e. value is a 2-tuple, first element of which is offset, and second is a structure descriptor dictionary (note: offsets in recursive descriptors are relative to a structure it defines).

  • Arrays of primitive types:

    "arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 2),
    

    i.e. value is a 2-tuple, first element of which is ARRAY flag ORed with offset, and second is scalar element type ORed number of elements in array.

  • Arrays of aggregate types:

    "arr2": (uctypes.ARRAY | 0, 2, {"b": uctypes.UINT8 | 0}),
    

    i.e. value is a 3-tuple, first element of which is ARRAY flag ORed with offset, second is a number of elements in array, and third is descriptor of element type.

  • Pointer to a primitive type:

    "ptr": (uctypes.PTR | 0, uctypes.UINT8),
    

    i.e. value is a 2-tuple, first element of which is PTR flag ORed with offset, and second is scalar element type.

  • Pointer to an aggregate type:

    "ptr2": (uctypes.PTR | 0, {"b": uctypes.UINT8 | 0}),
    

    i.e. value is a 2-tuple, first element of which is PTR flag ORed with offset, second is descriptor of type pointed to.

  • Bitfields:

    "bitf0": uctypes.BFUINT16 | 0 | 0 << uctypes.BF_POS | 8 << uctypes.BF_LEN,
    

    i.e. value is type of scalar value containing given bitfield (typenames are similar to scalar types, but prefixes with “BF”), ORed with offset for scalar value containing the bitfield, and further ORed with values for bit offset and bit length of the bitfield within scalar value, shifted by BF_POS and BF_LEN positions, respectively. Bitfield position is counted from the least significant bit, and is the number of right-most bit of a field (in other words, it’s a number of bits a scalar needs to be shifted right to extra the bitfield).

    In the example above, first UINT16 value will be extracted at offset 0 (this detail may be important when accessing hardware registers, where particular access size and alignment are required), and then bitfield whose rightmost bit is least-significant bit of this UINT16, and length is 8 bits, will be extracted - effectively, this will access least-significant byte of UINT16.

    Note that bitfield operations are independent of target byte endianness, in particular, example above will access least-significant byte of UINT16 in both little- and big-endian structures. But it depends on the least significant bit being numbered 0. Some targets may use different numbering in their native ABI, but uctypes always uses normalized numbering described above.

Module contents
class uctypes.struct(addr, descriptor, layout_type=NATIVE)

Instantiate a “foreign data structure” object based on structure address in memory, descriptor (encoded as a dictionary), and layout type (see below).

uctypes.LITTLE_ENDIAN

Layout type for a little-endian packed structure. (Packed means that every field occupies exactly as many bytes as defined in the descriptor, i.e. the alignment is 1).

uctypes.BIG_ENDIAN

Layout type for a big-endian packed structure.

uctypes.NATIVE

Layout type for a native structure - with data endianness and alignment conforming to the ABI of the system on which MicroPython runs.

uctypes.sizeof(struct)

Return size of data structure in bytes. Argument can be either structure class or specific instantiated structure object (or its aggregate field).

uctypes.addressof(obj)

Return address of an object. Argument should be bytes, bytearray or other object supporting buffer protocol (and address of this buffer is what actually returned).

uctypes.bytes_at(addr, size)

Capture memory at the given address and size as bytes object. As bytes object is immutable, memory is actually duplicated and copied into bytes object, so if memory contents change later, created object retains original value.

uctypes.bytearray_at(addr, size)

Capture memory at the given address and size as bytearray object. Unlike bytes_at() function above, memory is captured by reference, so it can be both written too, and you will access current value at the given memory address.

Structure descriptors and instantiating structure objects

Given a structure descriptor dictionary and its layout type, you can instantiate a specific structure instance at a given memory address using uctypes.struct() constructor. Memory address usually comes from following sources:

  • Predefined address, when accessing hardware registers on a baremetal system. Lookup these addresses in datasheet for a particular MCU/SoC.
  • As a return value from a call to some FFI (Foreign Function Interface) function.
  • From uctypes.addressof(), when you want to pass arguments to an FFI function, or alternatively, to access some data for I/O (for example, data read from a file or network socket).
Structure objects

Structure objects allow accessing individual fields using standard dot notation: my_struct.substruct1.field1. If a field is of scalar type, getting it will produce a primitive value (Python integer or float) corresponding to the value contained in a field. A scalar field can also be assigned to.

If a field is an array, its individual elements can be accessed with the standard subscript operator [] - both read and assigned to.

If a field is a pointer, it can be dereferenced using [0] syntax (corresponding to C * operator, though [0] works in C too). Subscripting a pointer with other integer values but 0 are supported too, with the same semantics as in C.

Summing up, accessing structure fields generally follows C syntax, except for pointer dereference, when you need to use [0] operator instead of *.

Limitations

Accessing non-scalar fields leads to allocation of intermediate objects to represent them. This means that special care should be taken to layout a structure which needs to be accessed when memory allocation is disabled (e.g. from an interrupt). The recommendations are:

  • Avoid nested structures. For example, instead of mcu_registers.peripheral_a.register1, define separate layout descriptors for each peripheral, to be accessed as peripheral_a.register1.
  • Avoid other non-scalar data, like array. For example, instead of peripheral_a.register[0] use peripheral_a.register0.

Note that these recommendations will lead to decreased readability and conciseness of layouts, so they should be used only if the need to access structure fields without allocation is anticipated (it’s even possible to define 2 parallel layouts - one for normal usage, and a restricted one to use when memory allocation is prohibited).

TPYBoard类库详述

以下是TPYBoard的具体类库。

pyb — 开发板关联功能函数

pyb 模块的主要功能与函数

时间相关函数
pyb.delay(ms)

延时函数,参数的单位为毫秒。

pyb.udelay(us)

延时函数,参数的单位为微秒。

pyb.millis()

返回自上次重置电路以来的毫秒数, 结果是一个31位有符号整数,在2**30(约12.4天)后开始返回负数。

Note that if pyb.stop() is issued the hardware counter supporting this function will pause for the duration of the “sleeping” state. This will affect the outcome of pyb.elapsed_millis().

pyb.micros()

返回自上次重置电路以来的微秒数。结果是一个31位有符号整数,在2**30微秒(约17.8分钟)后开始返回负数。

Note that if pyb.stop() is issued the hardware counter supporting this function will pause for the duration of the “sleeping” state. This will affect the outcome of pyb.elapsed_micros().

pyb.elapsed_millis(start)

返回``start``已经过去的毫秒数。

负责计数器换行,并且始终返回正数。这意味着它可以用于测量高达约12.4天的周期。

例如:

start = pyb.millis()
while pyb.elapsed_millis(start) < 1000:
    # Perform some operation
pyb.elapsed_micros(start)

返回已经过去的微秒数 负责计数器换行,并且始终返回正数。这意味着它可以用于测量高达约17.8分钟的时间段。

例如:

start = pyb.micros()
while pyb.elapsed_micros(start) < 1000:
    # Perform some operation
    pass
重置相关函数
pyb.hard_reset()

重置开发板,相当于开发板上的复位键

pyb.bootloader()

启动Bootloader而不使用BOOT *引脚。

pyb.fault_debug(value)

启用或禁用硬故障调试。硬盘故障是在底层系统发生致命错误时,如无效内存访问。

如果值参数为`False`,那么如果存在硬故障,则主板将自动重置。

如果值参数为`True`,当主板有硬件故障,它会打印的寄存器和堆栈跟踪,并无限期地然后循环的指示灯。

默认值被禁用,即自动复位。

中断相关函数
pyb.disable_irq()

禁用中断请求。 返回上一个IRQ状态: False / True 分别为禁用/启用的IRQ。该返回值可以传递给enable_irq将IRQ恢复到原始状态。

pyb.enable_irq(state=True)

启用中断请求 如果 stateTrue (默认值) 启用中断状态。 如果 stateFalse 禁用中断状态。 这个函数的最常见的用法是传递返回的值``disable_irq``来退出临界区。

电源相关功能
其他功能
pyb.main(filename)

设置boot.py完成后要运行的主脚本的文件名。如果未调用此函数,则将执行默认文件main.py。

在boot.py中调用此函数。

pyb.repl_uart(uart)

获取或设置REPL重复的UART对象。

pyb.sync()

同步所有文件系统。

pyb.usb_mode([modestr, ]vid=0xf055, pid=0x9801, hid=pyb.hid_mouse)

如果没有参数调用,则返回当前的USB模式作为字符串。 如果被``modestr``提供,则尝试设置USB模式。这只有在从调用``boot.py``之前调用时才能:meth:`pyb.main()`完成。 以下值``modestr``被理解为:

  • None:禁用USB
  • 'VCP':使用VCP(虚拟COM端口)接口
  • 'VCP+MSC':使能VCP和MSC(大容量存储设备类)
  • 'VCP+HID':使能VCP和HID(人机界面设备)

为了向后兼容,'CDC'``被理解为是 ``'VCP'``(并且对于‘CDC+MSC’‘CDC+HID’``)。

该参数``vid``和``pid``参数允许您指定VID(供应商ID)和PID(产品ID)。

如果启用HID模式,您还可以传递``hid``关键字参数来指定HID详细信息。它需要一个元组(子类,协议,最大包长度,轮询间隔,报告描述符)。 默认情况下,它将为USB鼠标设置适当的值。还有一个``pyb.hid_keyboard``常数,这是USB键盘的一个适当的元组。

class Accel – 加速度控制

控制加速度对象 使用事例:

accel = pyb.Accel()
for i in range(10):
    print(accel.x(), accel.y(), accel.z())

原始值范围-32到31.

构造器
class pyb.Accel

创建并返回加速计对象。

方法
Accel.filtered_xyz()

获取3维的x,y和z的值。

实施说明:此方法当前执行为取4个样本的总和,从当前调用的前3个调用中采样,以及当前调用的示例。 因此,返回4次平均值。

Accel.tilt()

获取倾斜度。

Accel.x()

获取X轴值。

Accel.y()

获取Y轴值。

Accel.z()

获取Z轴值。

硬件说明

加速度计使用I2C总线1与处理器通信。因此,针脚X9和X10不能使用的(除了I2C)。 其他设备使用这些引脚,因此不能同时使用,是UART 1和定时器4通道1和2。

class ADC – 数模转换
构造器
方法
AdCall对象
class CAN – controller area network communication bus

CAN implements the standard CAN communications protocol. At the physical level it consists of 2 lines: RX and TX. Note that to connect the pyboard to a CAN bus you must use a CAN transceiver to convert the CAN logic signals from the pyboard to the correct voltage levels on the bus.

Example usage (works without anything connected):

from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))  # set a filter to receive messages with id=123, 124, 125 and 126
can.send('message!', 123)   # send a message with id 123
can.recv(0)                 # receive message on FIFO 0
Constructors
class pyb.CAN(bus, ...)

Construct a CAN object on the given bus. bus can be 1-2, or ‘YA’ or ‘YB’. With no additional parameters, the CAN object is created but not initialised (it has the settings from the last initialisation of the bus, if any). If extra arguments are given, the bus is initialised. See init for parameters of initialisation.

The physical pins of the CAN busses are:

  • CAN(1) is on YA: (RX, TX) = (Y3, Y4) = (PB8, PB9)
  • CAN(2) is on YB: (RX, TX) = (Y5, Y6) = (PB12, PB13)
Class Methods
classmethod CAN.initfilterbanks(nr)

Reset and disable all filter banks and assign how many banks should be available for CAN(1).

STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers. This function configures how many filter banks should be assigned to each. nr is the number of banks that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2). At boot, 14 banks are assigned to each controller.

Methods
CAN.init(mode, extframe=False, prescaler=100, *, sjw=1, bs1=6, bs2=8)

Initialise the CAN bus with the given parameters:

  • mode is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
  • if extframe is True then the bus uses extended identifiers in the frames (29 bits); otherwise it uses standard 11 bit identifiers
  • prescaler is used to set the duration of 1 time quanta; the time quanta will be the input clock (PCLK1, see pyb.freq()) divided by the prescaler
  • sjw is the resynchronisation jump width in units of the time quanta; it can be 1, 2, 3, 4
  • bs1 defines the location of the sample point in units of the time quanta; it can be between 1 and 1024 inclusive
  • bs2 defines the location of the transmit point in units of the time quanta; it can be between 1 and 16 inclusive

The time quanta tq is the basic unit of time for the CAN bus. tq is the CAN prescaler value divided by PCLK1 (the frequency of internal peripheral bus 1); see pyb.freq() to determine PCLK1.

A single bit is made up of the synchronisation segment, which is always 1 tq. Then follows bit segment 1, then bit segment 2. The sample point is after bit segment 1 finishes. The transmit point is after bit segment 2 finishes. The baud rate will be 1/bittime, where the bittime is 1 + BS1 + BS2 multiplied by the time quanta tq.

For example, with PCLK1=42MHz, prescaler=100, sjw=1, bs1=6, bs2=8, the value of tq is 2.38 microseconds. The bittime is 35.7 microseconds, and the baudrate is 28kHz.

See page 680 of the STM32F405 datasheet for more details.

CAN.deinit()

Turn off the CAN bus.

CAN.setfilter(bank, mode, fifo, params, *, rtr)

Configure a filter bank:

  • bank is the filter bank that is to be configured.
  • mode is the mode the filter should operate in.
  • fifo is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter.
  • params is an array of values the defines the filter. The contents of the array depends on the mode argument.
mode contents of parameter array
CAN.LIST16 Four 16 bit ids that will be accepted
CAN.LIST32 Two 32 bit ids that will be accepted
CAN.MASK16
Two 16 bit id/mask pairs. E.g. (1, 3, 4, 4)
The first pair, 1 and 3 will accept all ids
that have bit 0 = 1 and bit 1 = 0.
The second pair, 4 and 4, will accept all ids
that have bit 2 = 1.
CAN.MASK32 As with CAN.MASK16 but with only one 32 bit id/mask pair.
  • rtr is an array of booleans that states if a filter should accept a remote transmission request message. If this argument is not given then it defaults to False for all entries. The length of the array depends on the mode argument.
mode length of rtr array
CAN.LIST16 4
CAN.LIST32 2
CAN.MASK16 2
CAN.MASK32 1
CAN.clearfilter(bank)

Clear and disables a filter bank:

  • bank is the filter bank that is to be cleared.
CAN.any(fifo)

Return True if any message waiting on the FIFO, else False.

CAN.recv(fifo, *, timeout=5000)

Receive data on the bus:

  • fifo is an integer, which is the FIFO to receive on
  • timeout is the timeout in milliseconds to wait for the receive.

Return value: A tuple containing four values.

  • The id of the message.
  • A boolean that indicates if the message is an RTR message.
  • The FMI (Filter Match Index) value.
  • An array containing the data.
CAN.send(data, id, *, timeout=0, rtr=False)

Send a message on the bus:

  • data is the data to send (an integer to send, or a buffer object).
  • id is the id of the message to be sent.
  • timeout is the timeout in milliseconds to wait for the send.
  • rtr is a boolean that specifies if the message shall be sent as a remote transmission request. If rtr is True then only the length of data is used to fill in the DLC slot of the frame; the actual bytes in data are unused.

If timeout is 0 the message is placed in a buffer in one of three hardware buffers and the method returns immediately. If all three buffers are in use an exception is thrown. If timeout is not 0, the method waits until the message is transmitted. If the message can’t be transmitted within the specified time an exception is thrown.

Return value: None.

CAN.rxcallback(fifo, fun)

Register a function to be called when a message is accepted into a empty fifo:

  • fifo is the receiving fifo.
  • fun is the function to be called when the fifo becomes non empty.

The callback function takes two arguments the first is the can object it self the second is a integer that indicates the reason for the callback.

Reason  
0 A message has been accepted into a empty FIFO.
1 The FIFO is full
2 A message has been lost due to a full FIFO

Example use of rxcallback:

def cb0(bus, reason):
  print('cb0')
  if reason == 0:
      print('pending')
  if reason == 1:
      print('full')
  if reason == 2:
      print('overflow')

can = CAN(1, CAN.LOOPBACK)
can.rxcallback(0, cb0)
Constants
CAN.NORMAL
CAN.LOOPBACK
CAN.SILENT
CAN.SILENT_LOOPBACK

the mode of the CAN bus

CAN.LIST16
CAN.MASK16
CAN.LIST32
CAN.MASK32

the operation mode of a filter

class DAC – digital to analog conversion

The DAC is used to output analog values (a specific voltage) on pin X5 or pin X6. The voltage will be between 0 and 3.3V.

This module will undergo changes to the API.

Example usage:

from pyb import DAC

dac = DAC(1)            # create DAC 1 on pin X5
dac.write(128)          # write a value to the DAC (makes X5 1.65V)

dac = DAC(1, bits=12)   # use 12 bit resolution
dac.write(4095)         # output maximum value, 3.3V

To output a continuous sine-wave:

import math
from pyb import DAC

# create a buffer containing a sine-wave
buf = bytearray(100)
for i in range(len(buf)):
    buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf)))

# output the sine-wave at 400Hz
dac = DAC(1)
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)

To output a continuous sine-wave at 12-bit resolution:

import math
from array import array
from pyb import DAC

# create a buffer containing a sine-wave, using half-word samples
buf = array('H', 2048 + int(2047 * math.sin(2 * math.pi * i / 128)) for i in range(128))

# output the sine-wave at 400Hz
dac = DAC(1, bits=12)
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
Constructors
class pyb.DAC(port, bits=8)

Construct a new DAC object.

port can be a pin object, or an integer (1 or 2). DAC(1) is on pin X5 and DAC(2) is on pin X6.

bits is an integer specifying the resolution, and can be 8 or 12. The maximum value for the write and write_timed methods will be 2**``bits``-1.

Methods
DAC.init(bits=8)

Reinitialise the DAC. bits can be 8 or 12.

DAC.deinit()

De-initialise the DAC making its pin available for other uses.

DAC.noise(freq)

Generate a pseudo-random noise signal. A new random sample is written to the DAC output at the given frequency.

DAC.triangle(freq)

Generate a triangle wave. The value on the DAC output changes at the given frequency, and the frequency of the repeating triangle wave itself is 2048 times smaller.

DAC.write(value)

Direct access to the DAC output. The minimum value is 0. The maximum value is 2**``bits``-1, where bits is set when creating the DAC object or by using the init method.

DAC.write_timed(data, freq, *, mode=DAC.NORMAL)

Initiates a burst of RAM to DAC using a DMA transfer. The input data is treated as an array of bytes in 8-bit mode, and an array of unsigned half-words (array typecode ‘H’) in 12-bit mode.

freq can be an integer specifying the frequency to write the DAC samples at, using Timer(6). Or it can be an already-initialised Timer object which is used to trigger the DAC sample. Valid timers are 2, 4, 5, 6, 7 and 8.

mode can be DAC.NORMAL or DAC.CIRCULAR.

Example using both DACs at the same time:

dac1 = DAC(1)
dac2 = DAC(2)
dac1.write_timed(buf1, pyb.Timer(6, freq=100), mode=DAC.CIRCULAR)
dac2.write_timed(buf2, pyb.Timer(7, freq=200), mode=DAC.CIRCULAR)
class ExtInt – configure I/O pins to interrupt on external events

There are a total of 22 interrupt lines. 16 of these can come from GPIO pins and the remaining 6 are from internal sources.

For lines 0 through 15, a given line can map to the corresponding line from an arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and line 1 can map to Px1 where x is A, B, C, ...

def callback(line):
    print("line =", line)

Note: ExtInt will automatically configure the gpio line as an input.

extint = pyb.ExtInt(pin, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, callback)

Now every time a falling edge is seen on the X1 pin, the callback will be called. Caution: mechanical pushbuttons have “bounce” and pushing or releasing a switch will often generate multiple edges. See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed explanation, along with various techniques for debouncing.

Trying to register 2 callbacks onto the same pin will throw an exception.

If pin is passed as an integer, then it is assumed to map to one of the internal interrupt sources, and must be in the range 16 through 22.

All other pin objects go through the pin mapper to come up with one of the gpio pins.

extint = pyb.ExtInt(pin, mode, pull, callback)

Valid modes are pyb.ExtInt.IRQ_RISING, pyb.ExtInt.IRQ_FALLING, pyb.ExtInt.IRQ_RISING_FALLING, pyb.ExtInt.EVT_RISING, pyb.ExtInt.EVT_FALLING, and pyb.ExtInt.EVT_RISING_FALLING.

Only the IRQ_xxx modes have been tested. The EVT_xxx modes have something to do with sleep mode and the WFE instruction.

Valid pull values are pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN, pyb.Pin.PULL_NONE.

There is also a C API, so that drivers which require EXTI interrupt lines can also use this code. See extint.h for the available functions and usrsw.h for an example of using this.

Constructors
class pyb.ExtInt(pin, mode, pull, callback)

Create an ExtInt object:

  • pin is the pin on which to enable the interrupt (can be a pin object or any valid pin name).
  • mode can be one of: - ExtInt.IRQ_RISING - trigger on a rising edge; - ExtInt.IRQ_FALLING - trigger on a falling edge; - ExtInt.IRQ_RISING_FALLING - trigger on a rising or falling edge.
  • pull can be one of: - pyb.Pin.PULL_NONE - no pull up or down resistors; - pyb.Pin.PULL_UP - enable the pull-up resistor; - pyb.Pin.PULL_DOWN - enable the pull-down resistor.
  • callback is the function to call when the interrupt triggers. The callback function must accept exactly 1 argument, which is the line that triggered the interrupt.
Class methods
classmethod ExtInt.regs()

Dump the values of the EXTI registers.

Methods
ExtInt.disable()

Disable the interrupt associated with the ExtInt object. This could be useful for debouncing.

ExtInt.enable()

Enable a disabled interrupt.

ExtInt.line()

Return the line number that the pin is mapped to.

ExtInt.swint()

Trigger the callback from software.

Constants
ExtInt.IRQ_FALLING

interrupt on a falling edge

ExtInt.IRQ_RISING

interrupt on a rising edge

ExtInt.IRQ_RISING_FALLING

interrupt on a rising or falling edge

class I2C – a two-wire serial protocol

I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.

I2C objects are created attached to a specific bus. They can be initialised when created, or initialised later on.

Printing the i2c object gives you information about its configuration.

Constructors
Methods
I2C.deinit()

Turn off the I2C bus.

I2C.scan()

Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond. Only valid when in master mode.

Constants
I2C.MASTER

for initialising the bus to master mode

class LCD – LCD control for the LCD touch-sensor pyskin

The LCD class is used to control the LCD on the LCD touch-sensor pyskin, LCD32MKv1.0. The LCD is a 128x32 pixel monochrome screen, part NHD-C12832A1Z.

The pyskin must be connected in either the X or Y positions, and then an LCD object is made using:

lcd = pyb.LCD('X')      # if pyskin is in the X position
lcd = pyb.LCD('Y')      # if pyskin is in the Y position

Then you can use:

lcd.light(True)                 # turn the backlight on
lcd.write('Hello world!\n')     # print text to the screen

This driver implements a double buffer for setting/getting pixels. For example, to make a bouncing dot, try:

x = y = 0
dx = dy = 1
while True:
    # update the dot's position
    x += dx
    y += dy

    # make the dot bounce of the edges of the screen
    if x <= 0 or x >= 127: dx = -dx
    if y <= 0 or y >= 31: dy = -dy

    lcd.fill(0)                 # clear the buffer
    lcd.pixel(x, y, 1)          # draw the dot
    lcd.show()                  # show the buffer
    pyb.delay(50)               # pause for 50ms
Constructors
class pyb.LCD(skin_position)

Construct an LCD object in the given skin position. skin_position can be ‘X’ or ‘Y’, and should match the position where the LCD pyskin is plugged in.

Methods
LCD.command(instr_data, buf)

Send an arbitrary command to the LCD. Pass 0 for instr_data to send an instruction, otherwise pass 1 to send data. buf is a buffer with the instructions/data to send.

LCD.contrast(value)

Set the contrast of the LCD. Valid values are between 0 and 47.

LCD.fill(colour)

Fill the screen with the given colour (0 or 1 for white or black).

This method writes to the hidden buffer. Use show() to show the buffer.

LCD.get(x, y)

Get the pixel at the position (x, y). Returns 0 or 1.

This method reads from the visible buffer.

LCD.light(value)

Turn the backlight on/off. True or 1 turns it on, False or 0 turns it off.

LCD.pixel(x, y, colour)

Set the pixel at (x, y) to the given colour (0 or 1).

This method writes to the hidden buffer. Use show() to show the buffer.

LCD.show()

Show the hidden buffer on the screen.

LCD.text(str, x, y, colour)

Draw the given text to the position (x, y) using the given colour (0 or 1).

This method writes to the hidden buffer. Use show() to show the buffer.

LCD.write(str)

Write the string str to the screen. It will appear immediately.

class LED – LED发光二极管对象

LED对象控制单个LED(发光二极管)

构造器
class pyb.LED(id)

创建与给定LED相关联的LED对象:

  - id 是LED编号, 1-4.

方法
LED.intensity([value])

获取或设置LED强度。强度范围在0(关闭)和255(最亮)。 如果没有参数,返回LED强度。 如果一个参数,设置LED强度和返回``None``。

*注:*只有LED(3)和LED(4)可以有一个平滑变化的强度,他们使用定时器PWM来实现它。 LED(3)采用定时器(2)和LED(4)使用定时器(3)。 这些定时器仅配置为PWM,如果相关LED的强度设置为1和254之间的值。否则定时器是免费的一般用途。

LED.off()

关闭LED。

LED.on()

打开LED, 最大亮度。

LED.toggle()

切换之间的LED(最大强度)和关闭。如果LED是在非零强度,然后它被认为是 “on” 和切换将关闭它。

class Pin – 控制I/O引脚

一个引脚是基本的对象来控制I / O引脚。它有方法设置引脚的模式(输入,输出等)和方法来获取和设置数字逻辑电平。对于引脚的模拟控制,请参见ADC类。

使用模型:

All Board Pins are predefined as pyb.Pin.board.Name:

x1_pin = pyb.Pin.board.X1

g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN)

CPU pins which correspond to the board pins are available as pyb.cpu.Name. For the CPU pins, the names are the port letter followed by the pin number. On the PYBv1.0, pyb.Pin.board.X1 and pyb.Pin.cpu.A0 are the same pin.

You can also use strings:

g = pyb.Pin('X1', pyb.Pin.OUT_PP)

Users can add their own names:

MyMapperDict = { 'LeftMotorDir' : pyb.Pin.cpu.C12 }
pyb.Pin.dict(MyMapperDict)
g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)

and can query mappings:

pin = pyb.Pin("LeftMotorDir")

Users can also add their own mapping function:

def MyMapper(pin_name):
   if pin_name == "LeftMotorDir":
       return pyb.Pin.cpu.A0

pyb.Pin.mapper(MyMapper)

So, if you were to call: pyb.Pin("LeftMotorDir", pyb.Pin.OUT_PP) then "LeftMotorDir" is passed directly to the mapper function.

To summarise, the following order determines how things get mapped into an ordinal pin number:

  1. Directly specify a pin object
  2. User supplied mapping function
  3. User supplied mapping (object must be usable as a dictionary key)
  4. Supply a string which matches a board pin
  5. Supply a string which matches a CPU port/pin

You can set pyb.Pin.debug(True) to get some debug information about how a particular object gets mapped to a pin.

When a pin has the Pin.PULL_UP or Pin.PULL_DOWN pull-mode enabled, that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND respectively (except pin Y5 which has 11k Ohm resistors).

Now every time a falling edge is seen on the gpio pin, the callback will be executed. Caution: mechanical push buttons have “bounce” and pushing or releasing a switch will often generate multiple edges. See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed explanation, along with various techniques for debouncing.

All pin objects go through the pin mapper to come up with one of the gpio pins.

构造器
class pyb.Pin(id, ...)

如果额外的给出参数创建一个新的ID关联销对象,它们被用来初始化引脚。 参考:meth:pin.init.

Class 方法
classmethod Pin.debug([state])

Get or set the debugging state (True or False for on or off).

classmethod Pin.dict([dict])

Get or set the pin mapper dictionary.

classmethod Pin.mapper([fun])

Get or set the pin mapper function.

方法
Pin.init(mode, pull=Pin.PULL_NONE, af=-1)

Initialise the pin:

  • mode can be one of:

    • Pin.IN - configure the pin for input;
    • Pin.OUT_PP - configure the pin for output, with push-pull control;
    • Pin.OUT_OD - configure the pin for output, with open-drain control;
    • Pin.AF_PP - configure the pin for alternate function, pull-pull;
    • Pin.AF_OD - configure the pin for alternate function, open-drain;
    • Pin.ANALOG - configure the pin for analog.
  • pull can be one of:

    • Pin.PULL_NONE - no pull up or down resistors;
    • Pin.PULL_UP - enable the pull-up resistor;
    • Pin.PULL_DOWN - enable the pull-down resistor.
  • when mode is Pin.AF_PP or Pin.AF_OD, then af can be the index or name of one of the alternate functions associated with a pin.

Returns: None.

Pin.value([value])

Get or set the digital logic level of the pin:

  • With no argument, return 0 or 1 depending on the logic level of the pin.
  • With value given, set the logic level of the pin. value can be anything that converts to a boolean. If it converts to True, the pin is set high, otherwise it is set low.
Pin.__str__()

Return a string describing the pin object.

Pin.af()

Returns the currently configured alternate-function of the pin. The integer returned will match one of the allowed constants for the af argument to the init function.

Pin.af_list()

Returns an array of alternate functions available for this pin.

Pin.gpio()

Returns the base address of the GPIO block associated with this pin.

Pin.mode()

Returns the currently configured mode of the pin. The integer returned will match one of the allowed constants for the mode argument to the init function.

Pin.name()

Get the pin name.

Pin.names()

Returns the cpu and board names for this pin.

Pin.pin()

Get the pin number.

Pin.port()

Get the pin port.

Pin.pull()

Returns the currently configured pull of the pin. The integer returned will match one of the allowed constants for the pull argument to the init function.

Constants
Pin.AF_OD

initialise the pin to alternate-function mode with an open-drain drive

Pin.AF_PP

initialise the pin to alternate-function mode with a push-pull drive

Pin.ANALOG

initialise the pin to analog mode

Pin.IN

initialise the pin to input mode

Pin.OUT_OD

initialise the pin to output mode with an open-drain drive

Pin.OUT_PP

initialise the pin to output mode with a push-pull drive

Pin.PULL_DOWN

enable the pull-down resistor on the pin

Pin.PULL_NONE

don’t enable any pull up or down resistors on the pin

Pin.PULL_UP

enable the pull-up resistor on the pin

class PinAF – Pin Alternate Functions

A Pin represents a physical pin on the microprocessor. Each pin can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF object represents a particular function for a pin.

Usage Model:

x3 = pyb.Pin.board.X3
x3_af = x3.af_list()

x3_af will now contain an array of PinAF objects which are available on pin X3.

For the pyboard, x3_af would contain:
[Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM9, Pin.AF7_USART2]

Normally, each peripheral would configure the af automatically, but sometimes the same function is available on multiple pins, and having more control is desired.

To configure X3 to expose TIM2_CH3, you could use:

pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=pyb.Pin.AF1_TIM2)

or:

pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=1)
Methods
pinaf.__str__()

Return a string describing the alternate function.

pinaf.index()

Return the alternate function index.

pinaf.name()

Return the name of the alternate function.

pinaf.reg()

Return the base register associated with the peripheral assigned to this alternate function. For example, if the alternate function were TIM2_CH3 this would return stm.TIM2

class RTC – real time clock

The RTC is and independent clock that keeps track of the date and time.

Example usage:

rtc = pyb.RTC()
rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
print(rtc.datetime())
Constructors
class pyb.RTC

Create an RTC object.

Methods
RTC.datetime([datetimetuple])

Get or set the date and time of the RTC.

With no arguments, this method returns an 8-tuple with the current date and time. With 1 argument (being an 8-tuple) it sets the date and time.

class Servo – 3-wire hobby servo driver

Servo objects control standard hobby servo motors with 3-wires (ground, power, signal). There are 4 positions on the pyboard where these motors can be plugged in: pins X1 through X4 are the signal pins, and next to them are 4 sets of power and ground pins.

Example usage:

import pyb

s1 = pyb.Servo(1)   # create a servo object on position X1
s2 = pyb.Servo(2)   # create a servo object on position X2

s1.angle(45)        # move servo 1 to 45 degrees
s2.angle(0)         # move servo 2 to 0 degrees

# move servo1 and servo2 synchronously, taking 1500ms
s1.angle(-60, 1500)
s2.angle(30, 1500)

注解

The Servo objects use Timer(5) to produce the PWM output. You can use Timer(5) for Servo control, or your own purposes, but not both at the same time.

Constructors
class pyb.Servo(id)

Create a servo object. id is 1-4, and corresponds to pins X1 through X4.

Methods
Servo.angle([angle, time=0])

If no arguments are given, this function returns the current angle.

If arguments are given, this function sets the angle of the servo:

  • angle is the angle to move to in degrees.
  • time is the number of milliseconds to take to get to the specified angle. If omitted, then the servo moves as quickly as possible to its new position.
Servo.speed([speed, time=0])

If no arguments are given, this function returns the current speed.

If arguments are given, this function sets the speed of the servo:

  • speed is the speed to change to, between -100 and 100.
  • time is the number of milliseconds to take to get to the specified speed. If omitted, then the servo accelerates as quickly as possible.
Servo.pulse_width([value])

If no arguments are given, this function returns the current raw pulse-width value.

If an argument is given, this function sets the raw pulse-width value.

Servo.calibration([pulse_min, pulse_max, pulse_centre[, pulse_angle_90, pulse_speed_100]])

If no arguments are given, this function returns the current calibration data, as a 5-tuple.

If arguments are given, this function sets the timing calibration:

  • pulse_min is the minimum allowed pulse width.
  • pulse_max is the maximum allowed pulse width.
  • pulse_centre is the pulse width corresponding to the centre/zero position.
  • pulse_angle_90 is the pulse width corresponding to 90 degrees.
  • pulse_speed_100 is the pulse width corresponding to a speed of 100.
class SPI – a master-driven serial protocol

SPI is a serial protocol that is driven by a master. At the physical level there are 3 lines: SCK, MOSI, MISO.

Constructors
Methods
SPI.deinit()

Turn off the SPI bus.

Constants
class Switch – 按键对象

按键对象是一个可定义使用的用户按钮。

用法:

sw = pyb.Switch()       # create a switch object
sw()                    # get state (True if pressed, False otherwise)
sw.callback(f)          # register a callback to be called when the
                        #   switch is pressed down
sw.callback(None)       # remove the callback

例子:

pyb.Switch().callback(lambda: pyb.LED(1).toggle())
构造器
class pyb.Switch

创建并返回一个按钮。

方法
Switch.__call__()

调用按键对象来直接获取状态: True 按键按下, False 按键松开

Switch.callback(fun)

当按钮被按下时,注册回调函数。 如果 funNone, 禁用回调。

class Timer – control internal timers

Note: Memory can’t be allocated during a callback (an interrupt) and so exceptions raised within a callback don’t give much information. See micropython.alloc_emergency_exception_buf() for how to get around this limitation.

Constructors
class pyb.Timer(id, ...)
Methods
Timer.deinit()

Deinitialises the timer.

Disables any channel callbacks (and the associated irq). Stops the timer, and disables the timer peripheral.

class TimerChannel — setup a channel for a timer

Timer channels are used to generate/capture a signal using a timer.

TimerChannel objects are created using the Timer.channel() method.

Methods
class UART – 双工串行通信总线

UART实现标准UART / USART双工串行通信协议。在物理层,它包括2条线:RX和TX通信单元是一个字符(不与一个字符串混淆),可以是8或9位。

UART的对象可以被创建并初始化使用:

from pyb import UART

uart = UART(1, 9600)                         # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters

一个UART对象的行为就像一个流对象,读和写是使用标准流方法完成的:

uart.read(10)       # read 10 characters, returns a bytes object
uart.read()         # read all available characters
uart.readline()     # read a line
uart.readinto(buf)  # read and store into the given buffer
uart.write('abc')   # write the 3 characters

class pyb.UART(bus, ...)

Construct a UART object on the given bus. bus can be 1-6, or ‘XA’, ‘XB’, ‘YA’, or ‘YB’. With no additional parameters, the UART object is created but not initialised (it has the settings from the last initialisation of the bus, if any). If extra arguments are given, the bus is initialised. See init for parameters of initialisation.

The physical pins of the UART busses are:

  • UART(4) is on XA: (TX, RX) = (X1, X2) = (PA0, PA1)
  • UART(1) is on XB: (TX, RX) = (X9, X10) = (PB6, PB7)
  • UART(6) is on YA: (TX, RX) = (Y1, Y2) = (PC6, PC7)
  • UART(3) is on YB: (TX, RX) = (Y9, Y10) = (PB10, PB11)
  • UART(2) is on: (TX, RX) = (X3, X4) = (PA2, PA3)

The Pyboard Lite supports UART(1), UART(2) and UART(6) only. Pins are as above except:

  • UART(2) is on: (TX, RX) = (X1, X2) = (PA2, PA3)
方法
UART.init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, flow=0, timeout_char=0, read_buf_len=64)

Initialise the UART bus with the given parameters:

  • baudrate is the clock rate.
  • bits is the number of bits per character, 7, 8 or 9.
  • parity is the parity, None, 0 (even) or 1 (odd).
  • stop is the number of stop bits, 1 or 2.
  • flow sets the flow control type. Can be 0, UART.RTS, UART.CTS or UART.RTS | UART.CTS.
  • timeout is the timeout in milliseconds to wait for writing/reading the first character.
  • timeout_char is the timeout in milliseconds to wait between characters while writing or reading.
  • read_buf_len is the character length of the read buffer (0 to disable).

This method will raise an exception if the baudrate could not be set within 5% of the desired value. The minimum baudrate is dictated by the frequency of the bus that the UART is on; UART(1) and UART(6) are APB2, the rest are on APB1. The default bus frequencies give a minimum baudrate of 1300 for UART(1) and UART(6) and 650 for the others. Use pyb.freq to reduce the bus frequencies to get lower baudrates.

Note: with parity=None, only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits are supported.

UART.deinit()

关闭UART总线。

UART.any()

返回等待的字节数(可能是0)

UART.read([nbytes])

Read characters. If nbytes is specified then read at most that many bytes. If nbytes are available in the buffer, returns immediately, otherwise returns when sufficient characters arrive or the timeout elapses.

If nbytes is not given then the method reads as much data as possible. It returns after the timeout has elapsed.

Note: for 9 bit characters each character takes two bytes, nbytes must be even, and the number of characters is nbytes/2.

Return value: a bytes object containing the bytes read in. Returns None on timeout.

UART.readchar()

从总线上收到一个字符。

返回值:作为整数读取的字符。超时返回-1。

UART.readinto(buf[, nbytes])

Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at most len(buf) bytes.

Return value: number of bytes read and stored into buf or None on timeout.

UART.readline()

Read a line, ending in a newline character. If such a line exists, return is immediate. If the timeout elapses, all available data is returned regardless of whether a newline exists.

Return value: the line read or None on timeout if no data is available.

UART.write(buf)

Write the buffer of bytes to the bus. If characters are 7 or 8 bits wide then each byte is one character. If characters are 9 bits wide then two bytes are used for each character (little endian), and buf must contain an even number of bytes.

Return value: number of bytes written. If a timeout occurs and no bytes were written returns None.

UART.writechar(char)

Write a single character on the bus. char is an integer to write. Return value: None. See note below if CTS flow control is used.

UART.sendbreak()

Send a break condition on the bus. This drives the bus low for a duration of 13 bits. Return value: None.

常数
UART.RTS
UART.CTS

选择流量控制类型。

流量控制

On Pyboards V1 and V1.1 UART(2) and UART(3) support RTS/CTS hardware flow control using the following pins:

  • UART(2) is on: (TX, RX, nRTS, nCTS) = (X3, X4, X2, X1) = (PA2, PA3, PA1, PA0)
  • UART(3) is on :(TX, RX, nRTS, nCTS) = (Y9, Y10, Y7, Y6) = (PB10, PB11, PB14, PB13)

On the Pyboard Lite only UART(2) supports flow control on these pins:

(TX, RX, nRTS, nCTS) = (X1, X2, X4, X3) = (PA2, PA3, PA1, PA0)

In the following paragraphs the term “target” refers to the device connected to the UART.

When the UART’s init() method is called with flow set to one or both of UART.RTS and UART.CTS the relevant flow control pins are configured. nRTS is an active low output, nCTS is an active low input with pullup enabled. To achieve flow control the Pyboard’s nCTS signal should be connected to the target’s nRTS and the Pyboard’s nRTS to the target’s nCTS.

CTS: target controls Pyboard transmitter

If CTS flow control is enabled the write behaviour is as follows:

If the Pyboard’s UART.write(buf) method is called, transmission will stall for any periods when nCTS is False. This will result in a timeout if the entire buffer was not transmitted in the timeout period. The method returns the number of bytes written, enabling the user to write the remainder of the data if required. In the event of a timeout, a character will remain in the UART pending nCTS. The number of bytes composing this character will be included in the return value.

If UART.writechar() is called when nCTS is False the method will time out unless the target asserts nCTS in time. If it times out OSError 116 will be raised. The character will be transmitted as soon as the target asserts nCTS.

RTS: Pyboard controls target’s transmitter

If RTS flow control is enabled, behaviour is as follows:

If buffered input is used (read_buf_len > 0), incoming characters are buffered. If the buffer becomes full, the next character to arrive will cause nRTS to go False: the target should cease transmission. nRTS will go True when characters are read from the buffer.

Note that the any() method returns the number of bytes in the buffer. Assume a buffer length of N bytes. If the buffer becomes full, and another character arrives, nRTS will be set False, and any() will return the count N. When characters are read the additional character will be placed in the buffer and will be included in the result of a subsequent any() call.

If buffered input is not used (read_buf_len == 0) the arrival of a character will cause nRTS to go False until the character is read.

class USB_HID – USB Human Interface Device (HID)

The USB_HID class allows creation of an object representing the USB Human Interface Device (HID) interface. It can be used to emulate a peripheral such as a mouse or keyboard.

Before you can use this class, you need to use pyb.usb_mode() to set the USB mode to include the HID interface.

Constructors
class pyb.USB_HID

Create a new USB_HID object.

Methods
USB_HID.recv(data, *, timeout=5000)

Receive data on the bus:

  • data can be an integer, which is the number of bytes to receive, or a mutable buffer, which will be filled with received bytes.
  • timeout is the timeout in milliseconds to wait for the receive.

Return value: if data is an integer then a new buffer of the bytes received, otherwise the number of bytes read into data is returned.

USB_HID.send(data)

Send data over the USB HID interface:

  • data is the data to send (a tuple/list of integers, or a bytearray).
class USB_VCP – USB virtual comm port

The USB_VCP class allows creation of an object representing the USB virtual comm port. It can be used to read and write data over USB to the connected host.

Constructors
class pyb.USB_VCP

Create a new USB_VCP object.

Methods
USB_VCP.setinterrupt(chr)

Set the character which interrupts running Python code. This is set to 3 (CTRL-C) by default, and when a CTRL-C character is received over the USB VCP port, a KeyboardInterrupt exception is raised.

Set to -1 to disable this interrupt feature. This is useful when you want to send raw bytes over the USB VCP port.

USB_VCP.isconnected()

Return True if USB is connected as a serial device, else False.

USB_VCP.any()

Return True if any characters waiting, else False.

USB_VCP.close()

This method does nothing. It exists so the USB_VCP object can act as a file.

USB_VCP.read([nbytes])

Read at most nbytes from the serial device and return them as a bytes object. If nbytes is not specified then the method reads all available bytes from the serial device. USB_VCP stream implicitly works in non-blocking mode, so if no pending data available, this method will return immediately with None value.

USB_VCP.readinto(buf[, maxlen])

Read bytes from the serial device and store them into buf, which should be a buffer-like object. At most len(buf) bytes are read. If maxlen is given and then at most min(maxlen, len(buf)) bytes are read.

Returns the number of bytes read and stored into buf or None if no pending data available.

USB_VCP.readline()

Read a whole line from the serial device.

Returns a bytes object containing the data, including the trailing newline character or None if no pending data available.

USB_VCP.readlines()

Read as much data as possible from the serial device, breaking it into lines.

Returns a list of bytes objects, each object being one of the lines. Each line will include the newline character.

USB_VCP.write(buf)

Write the bytes from buf to the serial device.

Returns the number of bytes written.

USB_VCP.recv(data, *, timeout=5000)

Receive data on the bus:

  • data can be an integer, which is the number of bytes to receive, or a mutable buffer, which will be filled with received bytes.
  • timeout is the timeout in milliseconds to wait for the receive.

Return value: if data is an integer then a new buffer of the bytes received, otherwise the number of bytes read into data is returned.

USB_VCP.send(data, *, timeout=5000)

Send data over the USB VCP:

  • data is the data to send (an integer to send, or a buffer object).
  • timeout is the timeout in milliseconds to wait for the send.

Return value: number of bytes sent.

lcd160cr — control of LCD160CR display

This module provides control of the MicroPython LCD160CR display.

LCD160CRv1.0 picture

Further resources are available via the following links:

class LCD160CR

The LCD160CR class provides an interface to the display. Create an instance of this class and use its methods to draw to the LCD and get the status of the touch panel.

For example:

import lcd160cr

lcd = lcd160cr.LCD160CR('X')
lcd.set_orient(lcd160cr.PORTRAIT)
lcd.set_pos(0, 0)
lcd.set_text_color(lcd.rgb(255, 0, 0), lcd.rgb(0, 0, 0))
lcd.set_font(1)
lcd.write('Hello MicroPython!')
print('touch:', lcd.get_touch())
Constructors
class lcd160cr.LCD160CR(connect=None, *, pwr=None, i2c=None, spi=None, i2c_addr=98)

Construct an LCD160CR object. The parameters are:

  • connect is a string specifying the physical connection of the LCD display to the board; valid values are “X”, “Y”, “XY”, “YX”. Use “X” when the display is connected to a pyboard in the X-skin position, and “Y” when connected in the Y-skin position. “XY” and “YX” are used when the display is connected to the right or left side of the pyboard, respectively.
  • pwr is a Pin object connected to the LCD’s power/enabled pin.
  • i2c is an I2C object connected to the LCD’s I2C interface.
  • spi is an SPI object connected to the LCD’s SPI interface.
  • i2c_addr is the I2C address of the display.

One must specify either a valid connect or all of pwr, i2c and spi. If a valid connect is given then any of pwr, i2c or spi which are not passed as parameters (ie they are None) will be created based on the value of connect. This allows to override the default interface to the display if needed.

The default values are:

  • “X” is for the X-skin and uses: pwr=Pin("X4"), i2c=I2C("X"), spi=SPI("X")
  • “Y” is for the Y-skin and uses: pwr=Pin("Y4"), i2c=I2C("Y"), spi=SPI("Y")
  • “XY” is for the right-side and uses: pwr=Pin("X4"), i2c=I2C("Y"), spi=SPI("X")
  • “YX” is for the left-side and uses: pwr=Pin("Y4"), i2c=I2C("X"), spi=SPI("Y")

See this image for how the display can be connected to the pyboard.

Static methods
static LCD160CR.rgb(r, g, b)

Return a 16-bit integer representing the given rgb color values. The 16-bit value can be used to set the font color (see LCD160CR.set_text_color()) pen color (see LCD160CR.set_pen()) and draw individual pixels.

LCD160CR.clip_line(data, w, h):

Clip the given line data. This is for internal use.

Instance members

The following instance members are publicly accessible.

LCD160CR.w
LCD160CR.h

The width and height of the display, respectively, in pixels. These members are updated when calling LCD160CR.set_orient() and should be considered read-only.

Setup commands
LCD160CR.set_power(on)

Turn the display on or off, depending on the given value of on: 0 or False will turn the display off, and 1 or True will turn it on.

LCD160CR.set_orient(orient)

Set the orientation of the display. The orient parameter can be one of PORTRAIT, LANDSCAPE, PORTRAIT_UPSIDEDOWN, LANDSCAPE_UPSIDEDOWN.

LCD160CR.set_brightness(value)

Set the brightness of the display, between 0 and 31.

LCD160CR.set_i2c_addr(addr)

Set the I2C address of the display. The addr value must have the lower 2 bits cleared.

LCD160CR.set_uart_baudrate(baudrate)

Set the baudrate of the UART interface.

LCD160CR.set_startup_deco(value)

Set the start-up decoration of the display. The value parameter can be a logical or of STARTUP_DECO_NONE, STARTUP_DECO_MLOGO, STARTUP_DECO_INFO.

LCD160CR.save_to_flash()

Save the following parameters to flash so they persist on restart and power up: initial decoration, orientation, brightness, UART baud rate, I2C address.

Pixel access methods

The following methods manipulate individual pixels on the display.

LCD160CR.set_pixel(x, y, c)

Set the specified pixel to the given color. The color should be a 16-bit integer and can be created by LCD160CR.rgb().

LCD160CR.get_pixel(x, y)

Get the 16-bit value of the specified pixel.

LCD160CR.get_line(x, y, buf)

Get a line of pixels into the given buffer.

LCD160CR.screen_dump(buf)

Dump the entire screen to the given buffer.

LCD160CR.screen_load(buf)

Load the entire screen from the given buffer.

Drawing text

To draw text one sets the position, color and font, and then uses write to draw the text.

LCD160CR.set_pos(x, y)

Set the position for text output using LCD160CR.write(). The position is the upper-left corner of the text.

LCD160CR.set_text_color(fg, bg)

Set the foreground and background color of the text.

LCD160CR.set_font(font, scale=0, bold=0, trans=0, scroll=0)

Set the font for the text. Subsequent calls to write will use the newly configured font. The parameters are:

  • font is the font family to use, valid values are 0, 1, 2, 3.
  • scale is a scaling value for each character pixel, where the pixels are drawn as a square with side length equal to scale + 1. The value can be between 0 and 63.
  • bold controls the number of pixels to overdraw each character pixel, making a bold effect. The lower 2 bits of bold are the number of pixels to overdraw in the horizontal direction, and the next 2 bits are for the vertical direction. For example, a bold value of 5 will overdraw 1 pixel in both the horizontal and vertical directions.
  • trans can be either 0 or 1 and if set to 1 the characters will be drawn with a transparent background.
  • scroll can be either 0 or 1 and if set to 1 the display will do a soft scroll if the text moves to the next line.
LCD160CR.write(s)

Write text to the display, using the current position, color and font. As text is written the position is automatically incremented. The display supports basic VT100 control codes such as newline and backspace.

Drawing primitive shapes

Primitive drawing commands use a foreground and background color set by the set_pen method.

LCD160CR.set_pen(line, fill)

Set the line and fill color for primitive shapes.

LCD160CR.erase()

Erase the entire display to the pen fill color.

LCD160CR.dot(x, y)

Draw a single pixel at the given location using the pen line color.

LCD160CR.rect(x, y, w, h)
LCD160CR.rect_outline(x, y, w, h)
LCD160CR.rect_interior(x, y, w, h)

Draw a rectangle at the given location and size using the pen line color for the outline, and the pen fill color for the interior. The rect method draws the outline and interior, while the other methods just draw one or the other.

LCD160CR.line(x1, y1, x2, y2)

Draw a line between the given coordinates using the pen line color.

LCD160CR.dot_no_clip(x, y)
LCD160CR.rect_no_clip(x, y, w, h)
LCD160CR.rect_outline_no_clip(x, y, w, h)
LCD160CR.rect_interior_no_clip(x, y, w, h)
LCD160CR.line_no_clip(x1, y1, x2, y2)

These methods are as above but don’t do any clipping on the input coordinates. They are faster than the clipping versions and can be used when you know that the coordinates are within the display.

LCD160CR.poly_dot(data)

Draw a sequence of dots using the pen line color. The data should be a buffer of bytes, with each successive pair of bytes corresponding to coordinate pairs (x, y).

LCD160CR.poly_line(data)

Similar to LCD160CR.poly_dot() but draws lines between the dots.

Touch screen methods
LCD160CR.touch_config(calib=False, save=False, irq=None)

Configure the touch panel:

  • If calib is True then the call will trigger a touch calibration of the resistive touch sensor. This requires the user to touch various parts of the screen.
  • If save is True then the touch parameters will be saved to NVRAM to persist across reset/power up.
  • If irq is True then the display will be configured to pull the IRQ line low when a touch force is detected. If irq is False then this feature is disabled. If irq is None (the default value) then no change is made to this setting.
LCD160CR.is_touched()

Returns a boolean: True if there is currently a touch force on the screen, False otherwise.

LCD160CR.get_touch()

Returns a 3-tuple of: (active, x, y). If there is currently a touch force on the screen then active is 1, otherwise it is 0. The x and y values indicate the position of the current or most recent touch.

Advanced commands
LCD160CR.set_spi_win(x, y, w, h)

Set the window that SPI data is written to.

LCD160CR.fast_spi(flush=True)

Ready the display to accept RGB pixel data on the SPI bus, resetting the location of the first byte to go to the top-left corner of the window set by LCD160CR.set_spi_win(). The method returns an SPI object which can be used to write the pixel data.

Pixels should be sent as 16-bit RGB values in the 5-6-5 format. The destination counter will increase as data is sent, and data can be sent in arbitrary sized chunks. Once the destination counter reaches the end of the window specified by LCD160CR.set_spi_win() it will wrap around to the top-left corner of that window.

LCD160CR.show_framebuf(buf)

Show the given buffer on the display. buf should be an array of bytes containing the 16-bit RGB values for the pixels, and they will be written to the area specified by LCD160CR.set_spi_win(), starting from the top-left corner.

The framebuf module can be used to construct frame buffers and provides drawing primitives. Using a frame buffer will improve performance of animations when compared to drawing directly to the screen.

LCD160CR.set_scroll(on)

Turn scrolling on or off. This controls globally whether any window regions will scroll.

LCD160CR.set_scroll_win(win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0)

Configure a window region for scrolling:

  • win is the window id to configure. There are 0..7 standard windows for general purpose use. Window 8 is the text scroll window (the ticker).
  • x, y, w, h specify the location of the window in the display.
  • vec specifies the direction and speed of scroll: it is a 16-bit value of the form 0bF.ddSSSSSSSSSSSS. dd is 0, 1, 2, 3 for +x, +y, -x, -y scrolling. F sets the speed format, with 0 meaning that the window is shifted S % 256 pixel every frame, and 1 meaning that the window is shifted 1 pixel every S frames.
  • pat is a 16-bit pattern mask for the background.
  • fill is the fill color.
  • color is the extra color, either of the text or pattern foreground.
LCD160CR.set_scroll_win_param(win, param, value)

Set a single parameter of a scrolling window region:

  • win is the window id, 0..8.
  • param is the parameter number to configure, 0..7, and corresponds to the parameters in the set_scroll_win method.
  • value is the value to set.
LCD160CR.set_scroll_buf(s)

Set the string for scrolling in window 8. The parameter s must be a string with length 32 or less.

LCD160CR.jpeg(buf)

Display a JPEG. buf should contain the entire JPEG data. JPEG data should not include EXIF information. The following encodings are supported: Baseline DCT, Huffman coding, 8 bits per sample, 3 color components, YCbCr4:2:2. The origin of the JPEG is set by LCD160CR.set_pos().

LCD160CR.jpeg_start(total_len)
LCD160CR.jpeg_data(buf)

Display a JPEG with the data split across multiple buffers. There must be a single call to jpeg_start to begin with, specifying the total number of bytes in the JPEG. Then this number of bytes must be transferred to the display using one or more calls to the jpeg_data command.

LCD160CR.feed_wdt()

The first call to this method will start the display’s internal watchdog timer. Subsequent calls will feed the watchdog. The timeout is roughly 30 seconds.

LCD160CR.reset()

Reset the display.

Constants
lcd160cr.PORTRAIT
lcd160cr.LANDSCAPE
lcd160cr.PORTRAIT_UPSIDEDOWN
lcd160cr.LANDSCAPE_UPSIDEDOWN

orientation of the display, used by LCD160CR.set_orient()

lcd160cr.STARTUP_DECO_NONE
lcd160cr.STARTUP_DECO_INFO

type of start-up decoration, can be or’d together, used by LCD160CR.set_startup_deco()

TPYBoard 相关下载

TPYBoard 资料:

TPYBoard主要数据手册

MicroPython许可证信息

The MIT License (MIT)

Copyright (c) 2013-2015 Damien P. George, and others

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.

MicroPython资料索引

Indices and tables