TPYBoard Document

TPYBoard快速参考手册

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

TPYBoard v10x 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 v202[ESP8266]快速参考手册

Adafruit Feather TPYBoard

开发板基本控制

MicroPython REPL是UART0 (GPIO1=TX, GPIO3=RX)波特率115200。 Tab标签查找对象方法,粘贴(ctrl-E)用语粘贴大量Python代码到REPL(交互式解释器)。

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())

一旦网络建立可像往常一样创建和使用 socket 模块。

延时和定时

使用 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

定时器

支持虚拟(RTOS)定时器。使用 machine.Timer 类timerID为-1:

from machine import Timer

tim = Timer(-1)
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))

周期以毫秒为单位。

引脚和通用输入输出接口

使用 machine.Pin 类:

from machine import Pin

p0 = Pin(0, Pin.OUT)    # create output pin on GPIO0
p0.on()                 # turn on pin, set to high
p0.off()                # turn off pin, set 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

Available pins are: 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, which correspond to the actual GPIO pin numbers of ESP8266 chip. Note that many end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). As MicroPython supports different boards and modules, physical pin numbering was chosen as the lowest common denominator. For mapping between board logical pins and physical chip pins, consult your board documentation.

Note that Pin(1) and Pin(3) are REPL UART TX and RX respectively. Also note that Pin(16) is a special pin (used for wakeup from deepsleep mode) and may be not available for use with higher-level classes like Neopixel.

脉冲宽度调制PWM (pulse width modulation)

PWM can be enabled on all pins except Pin(16). There is a single frequency for all channels, with range between 1 and 1000 (measured in Hz). The duty cycle is between 0 and 1023 inclusive.

使用 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 (analog to digital conversion)

ADC is available on a dedicated pin. Note that input voltages on the ADC pin must be between 0v and 1.0v.

Use the machine.ADC class:

from machine import ADC

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

Software SPI bus

There are two SPI drivers. One is implemented in software (bit-banging) and works on all pins, and is accessed via the machine.SPI class:

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

Hardware SPI bus

The hardware SPI is faster (up to 80Mhz), but only works on following pins: MISO is GPIO12, MOSI is GPIO13, and SCK is GPIO14. It has the same methods as the bitbanging SPI class above, except for the pin parameters for the constructor and init (as those are fixed):

from machine import Pin, SPI

hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)

(SPI(0) is used for FlashROM and not available to users.)

I2C bus

The I2C driver is implemented in software and works on all pins, and is accessed via the machine.I2C class:

from machine import Pin, I2C

# construct an I2C bus
i2c = I2C(scl=Pin(14), sda=Pin(2), 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

Deep-sleep mode

Connect GPIO16 to the reset pin (RST on HUZZAH). Then the following code can be used to sleep, wake and check the reset cause:

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 sleep
if 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 driver

The OneWire driver is implemented in software and works on all pins:

from machine import Pin
import 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

There is a specific driver for DS18S20 and DS18B20 devices:

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))

Be sure to put a 4.7k pull-up resistor on the data line. Note that the convert_temp() method must be called each time you want to sample the temperature.

NeoPixel driver

Use the neopixel module:

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

For low-level driving of a NeoPixel:

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

APA102 driver

Use the apa102 module:

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 31
apa.write()                  # write data to all pixels
r, g, b, brightness = apa[0] # get first pixel colour

For low-level driving of an APA102:

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

DHT driver

The DHT driver is implemented in software and works on all pins:

import dht
import 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)

WebREPL (web browser interactive prompt)

WebREPL (REPL over WebSockets, accessible via a web browser) is an experimental feature available in ESP8266 port. Download web client from https://github.com/micropython/webrepl (hosted version available at http://micropython.org/webrepl), and configure it by executing:

import webrepl_setup

and following on-screen instructions. After reboot, it will be available for connection. If you disabled automatic start-up on boot, you may run configured daemon on demand using:

import webrepl
webrepl.start()

The supported way to use WebREPL is by connecting to ESP8266 access point, but the daemon is also started on STA interface if it is active, so if your router is set up and works correctly, you may also use WebREPL while connected to your normal Internet access point (use the ESP8266 AP connection method if you face any issues).

Besides terminal/command prompt access, WebREPL also has provision for file transfer (both upload and download). Web client has buttons for the corresponding functions, or you can use command-line client webrepl_cli.py from the repository above.

See the MicroPython forum for other community-supported alternatives to transfer files to ESP8266.

TPYBoard概述

TPYBoard的连接与下载

首先我们通过USB连接线将TPYBoard和PC连接起来

_images/1.png

等待驱动自动安装完毕后,打开我的电脑-TPYBFLASH

_images/2.bmp

将编写好的main文件替换到TPYBFLASH里的mian文件

_images/3.gif

等待TPYBoard上的红灯亮灭两次以后程序下载完毕,按下RST键即可运行最新下载的程序

本地文件系统和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循环和关闭缓慢,然后有一个硬故障。这不能恢复,你需要做一个硬复位。

Win10系统如何禁用驱动程序签名强制

Windows 10系统对驱动程序的使用要求有数字签名,否则无法正常使用,但我们有时需要用到没有数字签名的驱动程序,怎么办呢? -那就是禁用数字签名。如何禁用数字签名(驱动程序签名)强制呢?

-总结操作步骤如下:

  1. 开始---运行(输入gpedit.msc)---确定,打开本地组策略编辑器;
  2. 在打开的本地组策略编辑器窗口,找到(用户配置---管理模板---系统---驱动程序安装);
_images/win10-1.png
  1. 找到(设备驱动的代码签名,并左键双击---设备驱动的代码签名);
_images/win10-2.png

4. 在打开的设备驱动的代码签名窗口,选择(已启用); 在选项的下拉框中,有:警告、阻止、忽略供选择。

  • 警告:向用户通知未经数字签名的文件,并让用户决定是停止安装还是继续安装以及是否允许安装未经数字签名的文件。
  • 阻止:命令系统拒绝安装未经数字签名的文件。
  • 忽略:命令系统继续安装(包括安装未经数字签名的文件)。

如果我们要安装未经数字签名的驱动文件,可选择:忽略,再点击:确定。

(我倒是建议选择警告,每次用户自己选择确定。)

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依次流水灯闪烁。

由外部电源供电

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

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

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

运行第一个脚本

从这篇教程开始将动手在 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闪存驱动中,名为 "tpybcdc.inf"。

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

您现在需要运行您的终端程序。 你可以使用超级终端,如果你没有安装,或者下载免费程序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 进行软件复位。出现的消息如下所示:

>>>
TPYB: sync filesystems
TPYB: soft reboot
Micro Python v1.0 on 2014-05-03; TPYBoard v10x with STM32F405RG
Type "help()" for more information.
>>>

如果这是行不通的,你可以执行一个硬复位(关闭和再次打开)按RST按键硬件复位(开发板上USB接线下的黑色按键)。 这将断开与 TPYBoard的任何端口连接 如果你想准备进行硬件复位,建议你先关闭串口程序(PuTTY)和退出/卸载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( )的函数时,按键将在其连接引脚产生一个边沿触发(下降沿)外部中断。 这意味着芯片将监听该引脚的任何状态变换,且会发生如下错误:

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

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

进一步参考

进一步使用硬件中断的信息可参考文档: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“, 和 “tpybcd.inf“ 文件恢复为其初始状态。 恢复出厂设置的方法与进入安全模式的方法相似,除了松开USR时是绿色和黄色的LED灯一起亮起。

按如下步骤操作进行恢复出厂设置:

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

电源控制

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]TPYBoard v102 学习使用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))

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类库详述

TPYBoard的特有功能如下。

MFRC522 --- 射频卡关联功能函数

mfrc522 模块的主要功能与函数

功能相关函数
class mfrc522.MFRC522

创建一个MFRC522对象。

MFRC522.init_spi(SPI, RC522_RST, RC522_SDA)

MFRC522初始化函数。

  • SPI 硬件连接的SPI接口对象,类型pyb.SPI
  • RST RST连接的引脚编号
  • SDA SDA连接的引脚编号
MFRC522.SeekCard(order)

寻卡函数,搜索范围内指定的卡或者所有的卡。

  • order 搜索未休眠的卡:0x26,搜索所有的卡:0x52

返回值为:读卡状态,卡的类型

MFRC522.Anticoll()

读卡函数,读出卡ID号。 返回值为:读卡状态,卡的ID

MFRC522与开发板接线对应引脚:
TPYBoard MFRC522
X4 SDA
X6 SCK
X8 MOSI
X7 MISO
GND GND
X2 RST
3.3V 3V3
程序示例:
import pyb
import mfrc522
from machine import SPI,Pin

def main():
      SPI=pyb.SPI(1)                              #这里用的SPI1
      RC522_SDA='X4'
      RC522_RST='X2'
      rc52=mfrc522.MFRC522()
      rc52.init_spi(SPI,RC522_RST,RC522_SDA)      #设置rc522功能引脚
      while True:
              (status,backBits)=rc52.SeekCard(0x52)   #寻找区范围内所有能识别的卡
              if(status==0):                          #判断是否找到卡
                      (status,id,)=rc52.Anticoll()        #读出卡ID号
                      print("card_id=",id)                #打印卡号
              else :
                      print("NO_CARD")
              pyb.delay(1000)
main()

LCD1602 --- LCD1602液晶屏关联功能函数

LCD1602 模块的主要功能与函数

功能相关函数
class LCD1602.TPYBoardGpioLcd1602(rs_pin, enable_pin, d4_pin, d5_pin, d6_pin, d7_pin, num_lines=2, num_columns=16)

创建一个LCD1602对象,初始化显示屏配置参数。

  • rs_pin 显示屏RS连接的引脚对象,类型pyb.Pin
  • enable_pin 显示屏E连接的引脚对象,类型pyb.Pin
  • d4_pin 显示屏D4连接的引脚对象,类型pyb.Pin
  • d5_pin 显示屏D5连接的引脚对象,类型pyb.Pin
  • d6_pin 显示屏D6连接的引脚对象,类型pyb.Pin
  • d7_pin 显示屏D7连接的引脚对象,类型pyb.Pin
  • num_lines 行数最大值
  • num_columns 列数最大值
LCD1602.clear()

清屏函数,清除屏幕上显示的所有字符

LCD1602.move_to(x, y)

设置写入地址,x为行位置,y为列位置

LCD1602.lcd1602_write_string(string)

显示函数,输入参数为字符串

LCD1602与开发板接线对应引脚:
TPYBoard v102 LCD1602
GND VSS
3V3 VDD
电位器输出引脚 V0
Y10 RS
GND RW
Y9 E
NC D0
NC D1
NC D2
NC D3
Y5 D4
Y6 D5
Y7 D6
Y8 D7
3V3 A
GND K
程序示例:
# main.py -- put your code here!
import pyb
from pyb import Pin
from pyb import delay, udelay,millis
from tpyb_lcd1602 import TPYBoardLcd1602Api
from LCD1602 import TPYBoardGpioLcd1602

lcd = TPYBoardGpioLcd1602(rs_pin=Pin.board.Y10,                       #设置引脚
                        enable_pin=Pin.board.Y9,
                        d4_pin=Pin.board.Y5,
                        d5_pin=Pin.board.Y6,
                        d6_pin=Pin.board.Y7,
                        d7_pin=Pin.board.Y8,
                        num_lines=2, num_columns=16)
lcd.lcd1602_write_string("Hi,TurnipSmart!\n This TPYBoard!")
delay(5000)
lcd.clear()
lcd.lcd1602_write_string("This  lcd1602!\n Start Work!")
delay(5000)
lcd.clear()
count = 0
while True:
  lcd.move_to(0, 0)
  #%1d 宽度  返回运行当前程序的累计时间,单位是毫秒
  lcd.lcd1602_write_string("%1d" % (millis() // 1000))
  delay(1000)
  count += 1
  print(count)

LCD5110 --- LCD5110液晶屏关联功能函数

lcd5110 模块的主要功能与函数

功能相关函数
class lcd5110.LCD5110(spi, rst, ce, dc, light)

创建一个LCD5110对象。

  • spi pyb.SPI对象
  • rst pyb.Pin对象
  • ce pyb.Pin对象
  • dc pyb.Pin对象
  • light pyb.Pin对象
LCD5110.clear()

清屏函数,擦除屏幕上所有内容

LCD5110.reset()

复位函数,复位LCD5110

LCD5110.light_on()

打开背光LED

LCD5110.light_off()

关闭背光LED

LCD5110.lcd_write_string(string, x, y)

写字符串函数。

  • string 显示的字符串
  • x 横向坐标,范围0-83
  • y 纵向坐标,范围0-5
LCD5110与开发板接线对应引脚:
TPYBoard LCD5110
Y10 RST
Y11 CE
Y9 DC
Y12 LIGHT
X8 DIN
X6 CLK
GND GND
3.3V 3V3
程序示例:
# main.py -- put your code here!
import pyb
import lcd5110
from pyb 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 = lcd5110.LCD5110(SPI, RST, CE, DC, LIGHT) #设置LCD5110使用SPI1及其它功能引脚

  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()

LCD12864 --- LCD12864液晶屏关联功能函数

lcd12864 模块的主要功能与函数

功能相关函数
class lcd12864_lib.LCD12864(rs, e)

创建一个LCD12864对象。

  • rs 引脚名称
  • e 引脚名称
LCD12864.qp_12864()

清屏函数,清除所有显示信息

LCD12864.lcd_write_string(address, string, s_bit)

显示字符。

  • address 显示的起始地址(范围:80-87,90-97,88-8f,98-9f)
  • string 显示的内容
  • s_bit 1:非汉字 2:汉字
LCD12864与开发板接线对应引脚:

注意: PSB(串/并选择引脚)部分LCD12864是用电阻控制高低电平,接此线时需万用表量一下,如果是低电平,不可直接接5V,会短路。

TPYBoard LCD12864
GND GND
VIN VCC
Y4 RS
GND R/W
Y3 E
X1 DB0
X2 DB1
X3 DB2
X4 DB3
X5 DB4
X6 DB5
X7 DB6
X8 DB7
5V PSB
5V BLA
GND BLK
程序示例:
# main.py -- put your code here!
import pyb
import lcd12864_lib from LCD12864
def main():
      lcd=LCD12864(rs='Y4',e='Y3')            #设置LCD12864功能引脚
      lcd.lcd_write_string(0x82,"MicroPyton",1)
      lcd.lcd_write_string(0x91,"By TurnipSmart",1)
      lcd.lcd_write_string(0x8a,"萝卜电子",2)
      lcd.lcd_write_string(0x9a,"液晶测试 ",2)

if __name__ == '__main__':
      main()

TFTLCD --- TFT液晶屏关联功能函数

tftlcd 模块的主要功能与函数

功能相关函数
class tftlcd.TFT(spi, cs, rst, rs, color)

创建一个TFT对象。

  • spi pyb.SPI对象
  • cs 引脚编号
  • rst 引脚编号
  • rs 引脚编号
  • color 颜色值
TFT.clean(color)

清屏函数,color为屏幕底色

TFT.writecmd(cmd)

写指令函数,cmd为要传入的指令

TFT.writedata(data)

写指令函数,data为要传入的数据(8bit)

TFT.address_set(x, y, w, h)

设置显示区域函数,x,y为开始坐标,w,h为终点坐标(显示内容的尺寸)

TFT.writecolor(color)

写颜色函数,功能为写入一个颜色,color为要写入的颜色

TFT.point(x, y, color)

画点指令,x,y为写入坐标,color为写入点的颜色

TFT.line(xs, ys, xe, ye, color)

画线函数,xs,ys为起点坐标,xe,ye为终点坐标,color为线的颜色

TFT.fill(xs, ys, xe, ye, color)

画填充矩形函数,xs,ys为起点坐标,xe,ye为终点坐标,color为填充的颜色

TFT.rectangle(x1, y1, x2, y2, color)

画空心矩形函数,xs,ys为起点坐标,xe,ye为终点坐标,color为矩形线的颜色

TFT.round(x0, y0, r, color)

画圆函数,x0,y0为圆心坐标,r为半径,color为圆边框的颜色

TFT.data8(data, color)

写入一字节函数,功能为写入8个点,data为写入数据,color为点的颜色

TFT.write(x, y, a, b, fist, color)

指定位置写数据函数,x,y为起点坐标,a,b为数据尺寸,fist为字库指针,color为数据颜色 功能为在指定位置写入指定尺寸的数据,可指定颜色

TFT.write_str(x, y, wight, high, string, color)

显示字符串函数,x,y为起点坐标,wight,high为字符尺寸,string为显示内容,color为字符串颜色

TFT.write_pictuer(x, y, wight, high, pictuer, color)

显示指定颜色的黑白图像,x,y为起点坐标,wight,high为图像尺寸,pictuer为图像数组,color为图像颜色

TFT.init_str(font, indexes)

字库与索引表初始化函数,font为字符库,indexes为字符索引表

TFTLCD.displayfile(name, x, y, width, height)

bmp图像显示函数,name为图像文件名称,x,y为图像起点,width,height为图像尺寸

TFT与开发板接线对应引脚:
TPYBoard TFT
Y8 SDA
Y6 SCK
X9 RES
X10 RS
X11 CS
GND GND
3V3 3V3
程序示例:
import pyb
import tftlcd
import font1
import gc
from pyb import SPI,Pin
spi=SPI(2)
tft=tftlcd.TFT(spi,cs='X11',rst='X9',rs='X10',color=2000)   #初始化液晶屏
tft.clean(2000)     #清屏
# tft.point(10,20,100)      #画点
# tft.line(2,3,20,40,255)   #画线
# tft.fill(0,0,30,10,0)     #画填充矩形
# tft.rectangle(20,20,60,60,0)      #画空心矩形
# tft.round(50,50,10,50)    #画圆

indexes_chinese16="液晶屏测试"   #16*16汉字索引表
indexes_chinese12="文字测试"            #12*16汉字索引表
indexes_roman="0123456789"          # 8*16数字索引表

tft.init_str(font1.FONT().f16,indexes_chinese16)    #设置字库及索引表
tft.write_str(75,10,16,16,"液晶屏",0)                          #显示16*16汉字

tft.init_str(font1.FONT().f12,indexes_chinese12)    #设置字库及索引表
tft.write_str(86,30,16,12,"测试",255)                 #显示12*16汉字

tft.init_str(font1.FONT().fnum,indexes_roman)               #设置字库及索引表
tft.write_str(86,50,8,16,"149",tftlcd.RED)                  #显示8*16数字

tft.write_pictuer(5,40,72,75,font1.image().pictuer,tftlcd.BRED)     #显示黑白图像

gc.enable() #打开自动清理内存
gc.collect()        #手动清理内存

tft.displayfile("55.bmp", 0,0,67, 75)               #显示bmp图片55
  • 55.bmp
_images/55.bmp

DS18X20 --- DS18X20温度传感器关联功能函数

ds18x20 模块的主要功能与函数

功能相关函数
class ds18b20.DS18X20(pin)

创建一个DS18X20对象。

  • pin pyb.Pin对象
DS18X20.read_temp()

读取温度值,返回值为浮点型

DS18B20与开发板接线对应引脚:
TPYBoard DS18B20
GND GND
3V3 VCC
Y10 D0
程序示例:
# main.py -- put your code here!
from pyb import Pin
from ds18b20 import DS18X20
wd = DS18X20(Pin('Y10'))              #设置DS18B20 DO引脚为Y10

while True:
  print(当前温度:',wd.read_temp())
  pyb.delay(1000)

AM2320 --- 高精度温湿度传感器关联功能函数

am2320 模块的主要功能与函数

功能相关函数
class am2320.AM2320(id)

创建AM2320对象。

  • id 硬件连接的I2C编号
AM2320.measure()

温湿度获取函数,读取温湿度之前要调用

AM2320.temperature()

温度获取函数,返回读取到的温度

AM2320.humidity()

湿度获取函数,返回读取到的湿度

AM2320与开发板接线对应引脚:
TPYBoard AM2320
X9 SCL
X10 SDA
3V3 VDD
GND GND
程序示例:
import time
import am2320
am_2320 = am2320.AM2320(1)    #I2C1接口

while True:
      am_2320.measure()
      print('温度:',am_2320.temperature())
      print('湿度:',am_2320.humidity())
      time.sleep_ms(500)

GY-30/BH1750 --- 光照强度传感器关联功能函数

gy30 模块的主要功能与函数

功能相关函数
class gy30.GY30(id)

创建AM2320对象。

  • id 硬件连接的I2C编号
GY30.start()

启动传感器,程序初始化时调用一次

GY30.read()

读取当前光照强度,返回16值为数组,前两位组成16位光照数值

GY-30与开发板接线对应引脚:
TPYBoard GY-30
X9 SCL
X10 SDA
3V3 VDD
GND GND
程序示例:
from gy30 import GY30
gy_30=GY30(1)
gy_30.start()
while True:
      a=gy_30.read()
      print(a[0]*0xff+a[1])

GY-39/MAX44009+BME280 --- 气象监测模块关联功能函数

gy39 模块的主要功能与函数

功能相关函数
class gy39.GY39(id)

创建GY39对象。

  • id 硬件连接的UART编号
GY39.read()

读取当前环境函数,返回值为光照强度,温度,气压,湿度,海拔高度

GY-39与开发板接线对应引脚:
TPYBoard GY-39
X9 DR
X10 CT
3V3 VCC
GND GND
程序示例:
import pyb
from gy39 import GY39
import time
gy_39=GY39(1)

while True:
      l,t,p,h,H=gy_39.read()
      print('光照强度:%s lux'%l)
      print('当前温度:%s ℃'%t)
      print('当前湿度:%s %'%h)
      print('当前气压:%s pa'%p)
      print('海拔高度:%s m'%H)
      print('')
      time.sleep_ms(200)

GY-68/BMP180 --- 大气压传感器关联功能函数

bmp180 模块的主要功能与函数

功能相关函数
class bmp180.BMP180(id)

创建一个BMP180对象。

  • id 硬件所连接的I2C编号
BMP180.readpress()

读气压函数,返回值为当前气压,单位为pa,小数点保留两位

BMP180.readtemp()

读温度函数,返回值为当前温度,单位为摄氏度,小数点保留两位

BMP180.readaltitude()

海拔计算函数,返回值为根据气压计算的海拔,单位为m,小数点保留两位

BMP180与开发板接线对应引脚:
TPYBoard BMP180
Y10 SDA
Y9 SCL
GND GND
3V3 VIN
程序示例:
from bmp180 import BMP180
import time
bmp=BMP180(2) #I2C 2接口

while True:
      print('当前温度:%s ℃'%bmp.readtemp())
      print('当前气压:%s pa'%bmp.readpress())
      print('当前海拔:%s m'%bmp.readaltitude())
      time.sleep_ms(500)

DS3231 --- 时钟芯片关联功能函数

ds3221 模块的主要功能与函数

功能相关函数
class ds3221.DS3231(id)

创建一个DS3231对象。

  • id 硬件所连接的I2C编号
DS3231.DATE(dat=[])

设置/读取年月日函数,当dat为空的时候读取年月日,当dat为[a,b,c]的时候设置为a年b月c日

DS3231.TIME(dat=[])

设置/读取时间函数,当dat为空的时候读取时间,当dat为[a,b,c]的时候设置为a时b分c秒

DS3231.DateTime(dat=[])

设置/读取年月日时分秒函数,当dat为空的时候读取年月日时分秒,当dat为[a,b,c,d,e,f]的时候设置为a年b月c日d时e分f秒

DS3231.TEMP()

读取温度函数

DS3221与开发板接线对应引脚:
TPYBoard DS3221
GND GND
3V3 VCC
X9 SCL
X10 SDA
程序示例:
# main.py -- put your code here!
import pyb
from machine import SPI,Pin
from ds3231 import DS3231
ds=DS3231(1)                  #设置DS3231为I2C1接口,对应'X9' 'X10'
ds.DATE([16,11,26])
ds.TIME([16,14,6])
while True:
  print('Date',str(ds.DATE()),0,1)
  print('Time',str(ds.TIME()),0,3)
  print('Tem'str(ds.TEMP()),0,5)
  pyb.delay(1000)

VS1838B --- 红外接收关联函数

necir 模块的主要功能与函数

功能相关函数
class necir.NecIr(timer=2, channel=4, pin=pyb.Pin.board.X4)

创建一个NecIr对象。

  • timer 定时器编号
  • channel 定时器通道编号
  • pin pyb.Pin引脚对象
NecIr.callback(fn)

读取函数,读取接收到的信息,输入参数fn为存储函数名 存储函数可以如下方式

def nec_cb(nec, a, c, r)
   print(a, c, r)
VS1838B.necbm()

返回接收到的红外遥控器的键值数据

VS1838与开发板接线对应引脚:
TPYBoard VS1838
GND GND
VIN VCC
X4 OUT
程序示例:
# main.py -- put your code here!
from necir import NecIr
from bm import necbm
from bm import nec_cb

def main():
      nec = NecIr()
      while True:
              nec.callback(nec_cb)
              if necbm():
                      print("bm=",necbm())

main()

NRF24L01 --- 2.4G无线收发模块关联函数

nrf24l01use 模块的主要功能与函数

功能相关函数
class nrf24l01use.nrf24l01(spi, cs, ce)

创建一个NRF24L01对象。

  • spi pyb.SPI对象
  • cs pyb.Pin对象
  • ce pyb.Pin对象
nrf24l01.master(data)

发射函数,设置为发送端,并发送data。data为待发送数据。

nrf24l01.slave()

接收函数,返回值为接收到的数据。

NRF24L01与开发板接线对应引脚:
TPYBoard NRF24L01
GND GND
Y4 CE
Y5 CSN
Y6 SCK
Y8 MOSI
Y7 MISO
3V3 VCC
程序示例:
# main.py -- put your code here!
import nrf24l01use

nrf=nrf24l01use.nrf24l01(spi=2,csn='Y5',ce='Y4')      #设置SPI2接口csn引脚与ce引脚

while True:
      print(nrf.slave())#接收内容
import nrf24l01use

nrf=nrf24l01use.nrf24l01(spi=2,csn='Y5',ce='Y4')
i=0
while True:
      nrf.master(i)#发送内容
      i+=1

NRF905 --- 2.4G无线收发模块关联功能函数

nrf905 模块的主要功能与函数

功能相关函数
class nrf905.NRF905(spi, ce, txen, pwr, cd, dr, cs, RFConf, TxAddress)

创建一个NRF905对象。

  • spi pyb.SPI对象
  • ce 引脚编号
  • txen 引脚编号
  • pwr 引脚编号
  • cd 引脚编号
  • dr 引脚编号
  • cs 引脚编号
  • RFConf 模块相关配置参数,list类型
  • TxAddress 接收方的地址,list类型
NRF905.Config905()

设置nrf905寄存器函数

NRF905.setTXmode()

设置nrf905为发送模式

NRF905.txpacket(buf)

发送数据函数,buf为发送的内容

NRF905.sender_bruff(buf)

发送函数,buf为发送的内容

NRF905.checkDR()

读取DR引脚状态,返回值为DR引脚的状态,用于判断是否接收完毕数据包

NRF905.setRXmode()

设置nrf905为接收模式

NRF905.rxpacket()

接收数据函数,返回值为list

NRF905.recvrx()

接收函数,返回值为list

nrf905与开发板接线对应引脚:
TPYBoard nrf905
Y1 CE
Y2 TXEN
Y3 PWR
Y4 CD
Y12 DR
Y11 CS
Y8 MOSI
Y7 MISO
Y6 SCK
3V3 VCC
GND GND
程序示例:
import pyb                                    #发送模式
from nrf905 import NRF905
import time
from pyb import SPI

RFConf=[0x00,                                 #配置命令
              0x4c,                                   #频段设置为423Mhz
              0x0c,                                   #输出功率为10db,不重发,节电模式为正常
              0x44,                                   #地址宽度设置为4字节
              0x0a,0x0a,                              #接收发送有效数据长度为10字节
              0xcc,0xcc,0xcc,0xcc,    #接收地址
              0x58                                    #CRC允许,8位CRC校验,外部时钟信号不使能
              ]
TxAddress=[0xcc,0xcc,0xcc,0xcc]       #接收地址

buf=[0x06,0xa0,0xb0,0x01,0x02,0]      #发送内容

spi=pyb.SPI(2)
n=NRF905(spi=spi,ce='Y1',txen='Y2',pwr='Y3',cd='Y4',dr='Y12',cs='Y11',
                              RFConf=RFConf,TxAddress=TxAddress)
i=0
while True:
      buf[5]=i
      n.sender_bruff(buf)                     #发送buf内容
      time.sleep_ms(200)
      print(i)
      i+=1
import pyb                                    #接收模式
from nrf905 import NRF905
import time
import pyb

RFConf=[0x00,                                 #配置命令
              0x4c,                                   #频段设置为423Mhz
              0x0c,                                   #输出功率为10db,不重发,节电模式为正常
              0x44,                                   #地址宽度设置为4字节
              0x0a,0x0a,                              #接收发送有效数据长度为10字节
              0xcc,0xcc,0xcc,0xcc,    #接收地址
              0x58                                    #CRC允许,8位CRC校验,外部时钟信号不使能
              ]

spi=pyb.SPI(2)
n=NRF905(spi=spi,ce='Y1',txen='Y2',pwr='Y3',cd='Y4',dr='X9',cs='X10',
                              RFConf=RFConf,TxAddress=None)
while True:
      buf=n.recvrx()                          #接收内容存储到buf
      print (buf)

SYN6288 --- SYN6288语音合成芯片关联功能函数

syn6288 模块的主要功能与函数

功能相关函数
syn6288.sendspeak(uart, baud, data)

语音合成播报函数。

  • uart 硬件连接的串口编号
  • baud 通信波特率
  • data 要播报的数据,类型bytes
SYN6288与开发板接线对应引脚:
TPYBoard SYN6288
3V3 VDD
GND G/GND
X4 TXD
X3 RXD
程序示例:
from syn6288 import sendspeak

#使用串口2,波特率9600,播报(测试,abc,123)字符。
#该文本编码使用ASCI格式
sendspeak(2,9600,'测试,abc,123'.encode())

AT24C0X --- AT24C0X存储器关联功能函数

at24c0x 模块的主要功能与函数

功能相关函数
class at24c0x.AT24C0X(id)

创建一个AT24C0X对象。

  • id 硬件连接的I2C接口编号
AT24C0X.writeAT24C0X(addr, data)

写入函数。

  • addr 写入的地址
  • data 写入的数据
AT24C0X.readAT24C0X(add, bit_len)

读取函数。 - addr 读取的地址 - bit_len 读取的字节数

AT24C0X与开发板接线对应引脚:
TPYBoard AT24C0X
3V3 VCC
GND GND
Y9 SCL
Y10 SDA
程序示例:
# main.py -- put your code here!
import at24c0x

def main():
      at24c=at24c0x.AT24C0X(1)
      at24c.writeAT24C0X(0,'qxw')
      print(at24c.readAT24C0X(0,3))
main()

NixieTube --- 数码管关联功能函数

digital 模块的主要功能与函数

功能相关函数
class digital.Digital(type, pins)

创建一个Digital对象。

  • type 数码管类型。1:共阳,2:共阴
  • pins 数码管a~g脚连接的引脚对象的集合,类型list
Digital.display(data)

显示函数。

  • data 要显示的数字(0~9)
数码管与开发板接线对应引脚:

共阳数码管的COM接3V3,共阴数码管的COM接GND

TPYBoard 数码管
X1 a
X2 b
X3 c
X4 d
X5 e
X6 f
X7 g
X8 h
GND/3V3 COM
程序示例:
import pyb
from pyb import Pin
from digital import Digital

def main():
    pins = [Pin('X' + str(p),Pin.OUT_PP) for p in range(1,9)]
    d = Digital(1,pins)
    while True:
        for i in range(10):
            d.display(i)
            pyb.delay(500)

main()

SteperMotor --- 四相步进电机关联功能函数

stepermotor 模块的主要功能与函数

功能相关函数
class stepermotor.SteperMotor(pin, speed)

创建一个SteperMotor对象。

  • pin 驱动板IN1~IN4连接的引脚对象集合,类型list
  • speed 旋转速度,单位毫秒,最小值为2
SteperMotor.steperRun(angle)

控制步进电机旋转指定的角度。

  • angle 旋转的角度,范围在-360~360之间(负:逆时针转动)
四相步进电机与开发板接线对应引脚:
TPYBoard 步进电机
VIN
GND
X1 IN1
X2 IN2
X3 IN3
X4 IN4
程序示例:
from pyb import Pin
from stepermotor import SteperMotor

Pin_All=[Pin(p,Pin.OUT_PP) for p in ['X1','X2','X3','X4']]

if __name__=='__main__':
  #转速(ms) 数值越大转速越慢 最小值2ms
  sm = SteperMotor(pin = Pin_All,speed=2)
  sm.steperRun(-360)
  sm.steperRun(360)

PS2 --- PS2无线手柄关联功能函数

ps2 模块的主要功能与函数

功能相关函数
class ps2.PS2KEY(_di, _do, _cs, _clk)

创建一个PS2KEY对象。

  • _di 手柄接收器DAT连接的引脚编号
  • _do 手柄接收器CMD连接的引脚编号
  • _cs 手柄接收器CS连接的引脚编号
  • _clk 手柄接收器CLK连接的引脚编号
PS2KEY.ps2_key()

读取手柄状态,如果有按键按下返回键值,否则返回0

PS2无线手柄与开发板接线对应引脚:
TPYBoard PS2手柄
3V3 VCC
GND GND
X18 DAT
X19 CMD
X20 CS
X21 CLK
程序示例:
# main.py -- put your code here!
import ps2

while True:
      ps=ps2.PS2KEY('X18','X19','X20','X21')
      a=ps.ps2_key()  #读取手柄键值
      if(a==13):              #判断按键执行相关灯的开关
              pyb.LED(1).on()
      elif(a==14):
              pyb.LED(2).on()
      elif(a==15):
              pyb.LED(3).on()
      elif(a==16):
              pyb.LED(4).on()
      elif(a==5):
              pyb.LED(1).off()
      elif(a==6):
              pyb.LED(2).off()
      elif(a==7):
              pyb.LED(3).off()
      elif(a==8):
              pyb.LED(4).off()

AS608 --- AS608指纹识别关联功能函数

as608 模块的主要功能与函数

功能相关函数
class as608.FIG(id)

创建一个FIG对象。

  • id 模块所连接的UART编号
FIG.savefig(addr)

录入指纹函数。

  • addr 录入指纹的存储地址(范围为1-300)
FIG.disfig()

识别指纹函数。如果在指纹库中识别到指纹则返回该指纹的存储地址,否则返回0

AS608与开发板接线对应引脚:
TPYBoard AS608
3V3 U+
GND GND
X1 RX
X2 TX
程序示例:
# main.py -- put your code here!
import as608

fig=as608.FIG(4)      #使用串口4

fig.savefig(37)       #录入指纹存储到37地址
user=fig.disfig()     #识别指纹
if(user==0):
      print('无法识别')
else :
      print('找到用户',user)

TPYBoard 实例教程

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

TPYBoard 典型实例

TPYBoard v102 典型实例

新手入门

帮助初学者快速掌握TPYBoard v102开发板的使用技巧。

[Micropython]TPYBoard v102 快速入手教程

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

前言

当你第一次接触TPYBoard v102时,或许有些疑惑,不知道该如何使用它。不用担心,当你认真阅读完本篇文章后,保证你用起来游刃有余。

初次见面
  • 实物图
_images/v102.png

初次见到TPYBoard v102(以下简称v102)时,我们首先通过micro接口的USB数据线将v102接入电脑。这时,你会看到开发板上的4个LED呈现流水灯的效果,这是我们的出厂默认程序。

一般情况下,电脑会自动出现一个类似U盘的可移动磁盘 TPYBFLASH 如下:

_images/flash.png

也有可能有的小伙伴的电脑,不能自动安装时,可安装驱动人生进行USB驱动的修复。

可参考教程

深入了解

打开 TPYBFLASH 可以看到里面默认有4个文件:

  • boot.py 开发板启动配置文件,例如可以设置开发板USB设备的模式(CDC、MSC、HID)或者指定第一个运行的脚本等。
  • main.py 默认第一个运行的脚本,可在boot.py中进行设置。
  • README.txt 一些帮助信息。
  • tpybcdc.inf 开发板的USB转虚拟串口的驱动,可用于REPL调试。(下一篇讲解如何使用REPL调试)
编辑器的选择

在后面的开发中,主要是在main.py文件中进行编程实现功能。那我们该如何挑选合适的编辑器呢?

其实对于一个脚本文件来说,任何一个编辑工具都可以。但最好别直接使用文本文档,这样会使代码格式乱掉。你要明白Python是通过缩进来区分代码块的,有的人会使用空格缩进,而大部分的人会使用tab键缩进,不同的编辑器会有不同的tab缩进规则,所以就会导致直接拷贝过来的程序运行会出错等。但无论是哪一种缩进方式,只要保证整体一致即可。

不在REPL调试模式下,我们是看不到错误信息的,但是当你发现开发板上出现了红、绿色LED交替闪烁几次后熄灭的情况,就说明程序出现了错误。

PythonEditor拼插编辑器

对于零基础编程的小伙伴,推荐我们自主开发的一款拼插编辑器 点击进入。它同时支持拼插和代码两种方式,方便编程入门。

代码编辑器

推荐Visual Studio Code、Notepad++、PyCharm、Python IDLE。VSCode和PyCharm都可以安装micropython的插件,支持代码提示补全和REPL调试。Notepad++在win10下会出现文件损坏的BUG。

和谐相处

为了防止代码丢失,养成良好的编程习惯,建议在电脑本地编写好main.py后去覆盖 TPYBFLASH 中的main.py文件,不要直接在 TPYBFLASH 中打开main.py文件进行编辑。

接下来,我们写一段代码,点亮板载的第4个LED。新建一个main.py文件,输入下面的代码。

import pyb
pyb.LED(4).on()

将编写好的main.py文件拷贝替换掉 TPYBFLASH 里的mian.py文件。

_images/copy.gif

注意:文件覆盖、修改保存时,板载的红色LED会亮起,说明正在写入板子内部FLASH,需等待熄灭后再进行其他操作。如果第一次使用的话,可能会看不到红色LED的变化,因为里面默认的是流水灯程序,这时保存之后大约等待6~8秒即可。

保存完毕后,按下板载的RST按键进行复位,板载的蓝色LED就会亮起。

点击进入TPYBoard v102视频教程 (建议使用谷歌浏览器观看,效果更佳哦)

点击进入TPYBoard v102快速参考手册

[Micropython]TPYBoard v102 获取REPL提示信息

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

前言

REPL(交互式解释器)全称是 Read Evaluate Print Loop,TPYBoard 允许用户和 MicorPython 的交互式连接。 使用REPL是迄今为止来测试你的代码、获取程序错误信息和运行命令的最简单的方法。

REPL调试

使用REPL需安装USB转串口的驱动,不同的系统不同的安装方式。

Windows

大部分win10系统会自动安装驱动。安装完成后,打开【设备管理器】就可以看到安装的端口号。

_images/win10.png

其他情况下,会出现下面的提示。

_images/q1.png

这时就需要我们去【设备管理器】进行手动安装。【其他设备】下看到一个带黄色感叹号图标的设备,右键选择更新驱动程序文件,定位到 TPYBFLASH 目录即可。

_images/qu.gif

但是,有的朋友的电脑可能会安装失败,主要有两种情况:

  • 提示“没有INF签名的驱动程序”,这是因为有的电脑开启了驱动强制签名的设置,把此设置关闭即可。解决方案
  • 提示“系统找不到指定的文件”等类似的问题,这是因为有些电脑是通过GHOST方式装的系统,它会删减一些系统文件。解决方法

Windows下我们使用PuTTY软件进行REPL交互。 下载PuTTY软件

打开Putty软件,【Connection type】分类中选择【Serial】串口模式,输入串口端口号和波特率(默认波特率:9600)。例如端口号是COM10 (这里的端口号是指自己设备管理器对应的端口号)

_images/putty.png

点击【Open】,进行连接。连接成功后,如下图:

_images/putty1.png

有时打开时无任何信息,就看见一个光标和空屏幕,如下图:

_images/1511.png

出现这种情况下,不用担心,并不是没有连接成功,而是当前没有信息输出而已。这时,你按下CTRL+C键出现">>>"提示符就好了。

_images/152.png

有时可能会多输出一些信息,如下图:

_images/153.png

这是因为开发板此时正在运行程序,我们通过外部快捷键CTRL+C强行停止运行,所以出现了上图错误的信息,大家可以忽略这个错误,它并不妨碍我们的正常使用。 同时我们也可以使用快捷键CTRL+D的方式让程序重新运行(软复位)。

_images/00.png

那么问题来了,我们在PuTTY软件中看到的这些信息都是什么呢?

_images/154.png

我们在程序中调用print()函数,打印的信息也会出现在PuTTY上。

_images/155.png

REPL交互模式下,我们不仅可以看到输出的信息,也可以输入一些简单的程序进行交互。例如:

>>> print("hello tpyboard!")
hello tpyboard!

在上面的例子中用户不需要敲入">>>"字符,而是应该在">>>"字符后写入内容。输入print("hello tpyboard!")文本并按下回车键,输出结果将在屏幕上,如上。 如果你已经知道一些Python知识,你也可以尝试一些基本的命令在这里。

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

PuTTY常用快捷键

  • Ctrl+C:停止运行程序
  • Ctrl+D:重新运行程序(软复位)

注意:

  • 1.在使用Ctrl+D快捷键时,需要保证程序是停止运行的状态才会有效。
  • 2.有时必须按下RST键进行硬件复位时,需先关闭PuTTY再进行操作,否则下次连接会出错。如果出错了,就再硬复位一次重新打开PuTTY就好了。

常见的程序格式错误

如果出现“SyntaxError: invalid syntax“错误:可能就是tab和空格没对齐的问题。

如果出现“IndentationError: unindent does not match any outer indentation level”错误:可能就是使用的缩进方式不一致。

Linux(Ubuntu)

执行查看端口命令

ls -a /dev/ttyA*

使用picocom,若没有安装的,请执行下面命令进行安装。

apt-get install picocom

执行命令打开picocom,连接端口。例如端口号为ttyACM1。

picocom /dev/ttyACM1

提示输入配置参数,基本配置如下:

  • 波特率:9600
  • 校验位:none
  • 数据位:8
  • 停止位:1

退出关闭-组合键Ctrl+A+Q。

MacOS

打开一个终端并运行

screen /dev/tty.usbmodem*

退出关闭-快捷键 CTRL-A CTRL-。

PyCharm安装MicroPython插件的方法介绍 点击进入

[Micropython]TPYBoard v102 介绍TPYBoard v10x系列开发板

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

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

小心你的TPYBoard v10x系列开发板

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

  • 轻力插拔 USB 线。尽管 USB 接头是焊接在电路板上且十分牢固的,一旦有所损坏将非常难以修理。
  • 静电能够损坏开发板上的元器件。如果你在你的工作范围积累了许多的静电(例如干冷的环境下),需要额外小心注意不要击穿开发板。如果开发板是装在静电袋里边的,这个袋子将是保存和携带该开发板的最好的抗静电工具(其由传导性泡沫的塑料组成)。
  • 如果在硬件层面你能够注意到这些事项,开发板使用起来不会有大问题。软件层面造成开发板损坏几乎是不可能的,所以大可随心所欲敲写你的代码。如果文件系统损坏,可以在接下来的内容中了解如何修复它。最糟糕的情况乃是需要重刷新MicroPython固件,但这可以轻易地通过一条USB线实现。
TPYBoard v10x的布局

USB 接头在板子的右上方,TF卡槽在其左上方。卡槽和接口之下是四颗 LED 灯,从上到下依次为蓝色,橙色,绿色和红色。开关有两个,左边的用户开关和右边的复位开关。

插入式供电

TPYBoard v10x是通过 USB 线供电的。通过USB线连接PC是唯一适合的方法。如果连接成功,绿色的LED灯将亮起。

外部电源供电

TPYBoard v10x开发板可以通过干电池或其他外部电源供电。连接电源时需要特别注意其正极负极,TPYBoard v10x开发板上没有极性保护,所以任何东西连接其正极时都要非常非常小心。

[Micropython]TPYBoard v102 点亮LEDS及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将在约1秒后亮起,大约5秒后熄灭。需等红色LED熄灭后,再运行脚本程序,先以CTRL-D进行软件复位(需程序已经停止运行才能操作)。tpyboard 将被重启且能够看到绿色的 LED 持续闪烁。至此先恭喜你在“the army of evil robot”的路途上迈出了重要的一步!当需要关闭烦人的闪灯时,直接在终端界面按下 CLRT -C 即可。 到目前为止代码做了什么事情呢?首先我们需要引用一些术语。Python 是一门面向对象语言(object-oriented),pyhon 中一切几乎都是类(class)和通过声明得到的类的对象(object)。通过方法(methods,也称为成员函数)我们连接类,并和对象相交互或者控制它。 程序的第一行我们通过实例化了LED对象并命名为led。当这个对象被创建时,它唯一的参数必须在1和4之间,与开发板上四颗LED相呼应。pyb.LED这个类有三个我们使用的重要成员函数:on(), off()以及 toggle()。另一个使用到的函数pyb.delay()仅是一个简单的毫秒级别的延时。一旦我们创建了LED对象,while True 这个声明将创建一个无限循环等待一秒时间的 led亮灭翻转。

在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 灯将从之前运行的状态突然进入到我们精心设计的迪斯科。可以通过在脚本初始化时关闭所有的 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。

[Micropython]TPYBoard v102 LED-按键手册

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

点亮LED实验

通过前面的python入门和有关pyb的介绍,相信你已经很想通过pyb来做一些东西了。那么本篇文章就带大家做一个点亮LED的pyb入门小实验——点亮LED。

步骤一:连接pyb开发板

步骤二:成功连接pyb开发板后,使用编辑器打开tpyboard里面的main.py文件,输入以下代码:

import pyb
Led2=pyb.LED(2)
Led2.on()

import pyb,引用pyb封装的类库,实例化一个LED对象命名为led2,LED对象的唯一参数是1-4之间的数字,分别对应开发板上的LED1、LED2、LED3和LED4。然后调用on()函数来点亮LED2。

pyb.LED类的函数有:LED.on()亮灯,LED.off()关灯,LED.toggle() 与LED现在的状态对调,LED.intensity([value])设置LED亮度,value是亮度值,0-255,0是关,255最亮(仅LED3和LED4支持)

步骤三:输入代码后保存文件,pyb上的LED1(标有LED标示的LED)亮起大约5秒后熄灭,这是因为开发板正在将我们修改的内容写入到FLASH中。如果使用TF卡的话,将不会出现这种情况,因为TF卡的写入速度快。为了运行我们新写的脚本,需要将pyb进行复位操作,只要按下开发板上标注的RST按键即可。

同学们可尝试使用Pyb.LED类的其他函数,实现流水灯、LED4由亮变暗的小实验

按键控制LED实验

pyb上有两个按键,分别是USR和RST,上一篇【点亮LED】的实验中已介绍RST是复位按键,相当于执行对pyb断电后重新上电的操作。本篇将介绍通过USR用户按键控制LED的亮灭实验。

按键控制LED亮灭

步骤一:连接pyb开发板,使用编辑器打开tpyboard里面的main.py文件,输入以下代码

import pyb
sw=pyb.Switch()
led=pyb.LED(1)
led3=pyb.LED(3)
while True:
    sw_state=sw()
    if sw_state:
        led.on()
        led3.off()
    else:
        led.off()
        led3.on()

实例化一个Switch对象命名为sw,定义两个LED灯,通过LED的亮灭来表示按键的状态(按下或未按下)。sw()函数获取按键当前状态,按下返回True,反之False。当按键按下时,LED1亮起、LED3熄灭。

步骤二:按下RST按键,查看运行效果。

按键回调函数

按键回调函数:sw.callback()函数。该函数会在按键按下会执行一些创建的代码,且使用一个中断。我们在main.py输入一下代码:

import pyb
sw=pyb.Switch()
sw.callback(lambda:pyb.LED(1).toggle())

以上例程实现按键每次按下翻转LED1的状态,并且能打断pyb开发板上的任何程序,属于一种异步中断。 其实,你还可以传递不带参数的函数作为参数给按键回调函数使用,上面的功能我们还可以通过以下形式实现同样的效果:

import pyb
sw=pyb.Switch()
led=pyb.LED(1)
def test():
    led.toggle()
sw.callback(test)

如果你不想使用按键回调函数,可以关闭按键回调,只需将函数的参数设置为None即可。

sw.callback(None)
中断的原理细节

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

1.当按键被按下时引脚将发生改变(电平由低到高),芯片处理器将记录这种变化;

2.处理器完成当前机器指令,退出执行状态并保存当前的状态(将寄存器的内容推入栈中)。这将停止当前运行的任何代码,例如正在执行着的 python 脚本;

3.芯片开始执行与按键相关的特定外部中断触发处理。该处理指向你在 sw.callback( )函数中指定的函数功能并执行之;

4.直到回调函数执行完毕,控制主权将回到中断处理手上;

5.按键中断处理将返回,芯片处理器确认记录该中断被执行过;

6.芯片调回步骤 2 的状态;

7.继续执行开始时的代码,除了短暂的暂停,这部分代码看起来似乎没有被打断过。

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

更多资料请参考:http://docs.micropython.org/en/latest/tpyboard/

[Micropython]TPYBoard v102 按键开关,回调函数和中断

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

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

USR按键供用户使用,且其可以通过声明一个按键对象(Switch object)进行控制。

创建开关对象的方法如下:

>>> sw = pyb.Switch()

当提示 pyb 不存在的错误出现时 ,其大意为你忘记键入 import pyb 语句。

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

>>> sw()
False

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

按键回调函数

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

>>> sw.callback(lambda:print('press!'))

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

可以尝试如下另一个例子:

>>> 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 。

[Micropython]TPYBoard v102 加速度传感器

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

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

加速度传感器的使用

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

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

上述例子返回-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 方向上也是同样的原理。这看起来不算很牛 B 但确实实现了水平仪的功能。在你的 tpyboard 板上运行这个程序,现象为向不同方向倾斜开发板点亮不同的 LED 灯。

效果展示:

http://www.tpyboard.com/ueditor/php/upload/image/20160622/1466586763759252.png http://www.tpyboard.com/ueditor/php/upload/image/20160622/1466586770917523.png http://www.tpyboard.com/ueditor/php/upload/image/20160622/1466586774747375.png http://www.tpyboard.com/ueditor/php/upload/image/20160622/1466586778992398.png
[Micropython]TPYBoard v102 安全模式和恢复出厂设置

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

当你的tpyboard 板除了出了毛病时不用太沮丧,尤其是在编错了程序的时候。首先要做的事情是进入安全模式:这将临时跳过 boot.py 和 main.py 的执行,直接获取默认的 USB 设定。如果对于文件系统有困惑的话可以尝试出厂重置,其将把文件系统恢复为起始状态。

安全模式

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

  • 通过 USB 线连接 tpyboard 板并提供电源;
  • 按下用户按键;
  • 保持用户按键按下的同时,按下重置按键后松开
  • LED 灯将持续亮绿灯,然后橙灯再到绿橙灯一起亮的循环;
  • 保持按下用户按键直到橙色的LED 灯亮起,然后就可松开用户按键;
  • 橙色的 LED 灯将快速闪烁四次,然后熄灭;
  • 现在你进入了安全模式。

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

恢复出厂重设置

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

恢复出厂设置的方法与进入安全模式的方法相似,除了松开用户按键时是绿色和橙色的 LED 灯一起亮起。

  • 通过 USB 线连接 tpyboard 板并提供电源;
  • 按下用户按键;
  • 保持用户按键按下的同时,按下重置按键后松开
  • LED 灯将持续亮绿灯,然后橙灯再到绿橙灯一起亮的循环;
  • 保持按下用户按键直到橙色和绿色的LED灯亮起,然后就可松开用户按键;
  • 绿色和橙色的 LED 灯将快速闪烁四次,然后熄灭;
  • 红色的 LED 灯亮起(目前红色绿色橙色的 LED 灯皆亮);
  • tpyboard 板现在重置了文件系统(这将花费几秒的时间);
  • 所有的 LED灯 一起熄灭;
  • 现在你重置了文件系统,并进入了安全模式;
  • 按下复位按键后释放将自行启动。
[Micropython]TPYBoard v102 使用macroSD卡

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

本篇重点讲述TPYBV101板上microSD卡的操作方法。

引言

TPYBoard v10x系列开发板(以下简称TPYBoard)自带microSD卡槽,可以直接插入TF卡(支持FAT/FAT32格式)使用。

如果不插入TF卡,系统将从内部flash启动,此时一切操作是对内部flash进行的。如修改main.py程序后,点击保存,TPYBoard的LED1会亮起,直到到LED1熄灭后,才说明写入成功,之所以有这么一段时间,是因为flash的写入要慢一点。

如果插入TF卡,系统将检索TF卡内是否有boot.py和main.py等程序,如果有则执行。另外,在TF卡上进行文件修改或者保存时,LED1灯不会亮起,修改完,正常退出后,就可以按RST键看程序运行结果。

另外,TPYBoard还可以做TF卡读卡器用,速度在500KB/s左右。这里我们重点来看一下TF卡的操作。

TF卡路径及主要操作方法

系统分内部flash和tf卡两个路径:内部flash为//flash,TF卡的路径是//sd,这里注意区分大小写。

TF的主要操作方法:

最重要open函数

#open(路径+文件名,读写模式) ,如 f=open('/tmp/hello','w')
#读写模式:r只读,r+读写,w新建(会覆盖原有文件),a追加,b二进制文件。如:'rb','wb','r+b'等等
读写模式的类型有:
rU 或 Ua 以读方式打开, 同时提供通用换行符支持 (PEP 278)
w     以写方式打开,
a     以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+     以读写模式打开
w+     以读写模式打开 (参见 w )
a+     以读写模式打开 (参见 a )
rb     以二进制读模式打开
wb     以二进制写模式打开 (参见 w )
ab     以二进制追加模式打开 (参见 a )
rb+    以二进制读写模式打开 (参见 r+ )
wb+    以二进制读写模式打开 (参见 w+ )
ab+    以二进制读写模式打开 (参见 a+ )

注意:(A 使用'W',文件若存在,首先要清空,然后(重新)创建,B 使用'a'模式 ,把所有要写入文件的数据都追加到文件的末尾,即使你使用了seek()指向文件的其他地方,如果文件不存在,将自动被创建。)

open的主要方法

f.read([size]) #size未指定则返回整个文件,如果文件大小>2倍内存则有问题.f.read()读到文件尾时返回""(空字串)

file.readline() #返回一行

file.readline([size]) #返回包含size行的列表,size 未指定则返回全部行

for line in f: print line #通过迭代器访问

f.write("hello\n") #如果要写入字符串以外的数据,先将他转换为字符串.

f.tell() #返回一个整数,表示当前文件指针的位置(就是到文件头的字节数)。

f.seek(偏移量,[起始位置])  #用来移动文件指针,偏移量:单位:字节,可正可负,起始位置:0-文件头,默认值;1-当前位置;2-文件尾。

f.close() #关闭文件

其它os方法

os.chdir(path)          #修改路径
os.getcwd()             #获取当前路径
os.listdir(dir)         #目录列表
os.mkdir(dir)           #创建目录
os.remove(path)         #删除文件
os.rmdir(dir)           #删除目录
os.rename(old_path, new_path)   #文件改名
os.stat(path)           #文件/目录状态,具体解释如下:
http://www.tpyboard.com/ueditor/php/upload/image/20160623/1466642004109911.jpg

以下为Python中关于os.stat()输出解释:

>>> import os
 >>> print os.stat("/root/python/zip.py")
 (33188, 2033080, 26626L, 1, 0, 0, 864, 1297653596, 1275528102, 1292892895)
 >>> print os.stat("/root/python/zip.py").st_mode   #权限模式
 33188
 >>> print os.stat("/root/python/zip.py").st_ino   #inode number
 2033080
 >>> print os.stat("/root/python/zip.py").st_dev    #device
 26626
 >>> print os.stat("/root/python/zip.py").st_nlink  #number of hard links
 1
 >>> print os.stat("/root/python/zip.py").st_uid    #所有用户的user id
 0
 >>> print os.stat("/root/python/zip.py").st_gid    #所有用户的group id
 0
 >>> print os.stat("/root/python/zip.py").st_size  #文件的大小,以位为单位
 864
 >>> print os.stat("/root/python/zip.py").st_atime  #文件最后访问时间
 1297653596
 >>> print os.stat("/root/python/zip.py").st_mtime  #文件最后修改时间
 1275528102
 >>> print os.stat("/root/python/zip.py").st_ctime  #文件创建时间
 1292892895
os.sync()#同步文件
os.urandom(n)#返回n个硬件产生的随机数

注意:

(1)引用os库,import os

(2)请不要使用中文文件名和路径名

(3)文件操作后,不会立即更新到TF卡,需要从系统中安全移出磁盘后才会生效,如果不先移出磁盘,可能会丢失文件,甚至破坏TF卡上的文件系统。

实例

1、向TF卡写入一个log文件,在tf卡上写入boot.py和main.py文件,修改tf卡上的main.py。

代码:

#main.py
# main.py -- put your code here!

import pyb
pyb.LED(2).on()  #打开led(2)
log=open('/sd/log.txt','w')  #如果无log.txt,建立log.txt,如果有,直接打开
for i in range(100):
    log.write("%d ok\r\n" %i)
log.close()
pyb.LED(2).off() #关闭led(2)

运行结果:板子通电后,可看到led2亮起,此时开始写入log.txt文件,然后len2熄灭,说明文件操作完成。结果如下:

http://www.tpyboard.com/ueditor/php/upload/image/20160623/1466642269338229.jpg

2、查看文件指针位置

代码1:

# main.py -- put your code here!
import pyb
log=open('/sd/log.txt','w')
s=log.tell()
print(s)

运行结果:为了便于查看结果,我们用putty进行REPL调试。保存好main.py后,在Putty中,按ctrl+D,显示结果如下:

>>>
PYB: sync filesystems
PYB: soft reboot
0
MicroPython v1.8-95-gb580958 on 2016-05-21; PYBv1.0 with STM32F405RG
Type "help()" for more information.

可以看出s为0,即默认在文件头。

代码2:

# main.py -- put your code here!

import pyb
log=open('/sd/log.txt','w')
#从文件头偏移20个比特
log.seek(24,0)
s=log.tell()
print(s)

运行结果:

>>>
PYB: sync filesystems
PYB: soft reboot
24
MicroPython v1.8-95-gb580958 on 2016-05-21; PYBv1.0 with STM32F405RG
Type "help()" for more information.

3、那么当移动24个字节后,再来写入时,会出现内容写到什么位置了?

为了便于观察,先在log.txt写入30个1,如图

http://www.tpyboard.com/ueditor/php/upload/image/20160623/1466642454130343.jpg

代码:

# main.py -- put your code here!

import pyb
pyb.LED(2).on()
log=open('/sd/log.txt','w')
#for i in range(100):
#    log.write("%d ok\r\n" %i)
#log.close()
log.seek(24,0)
s=log.tell()
print(s)

log.write("HH")

log.close()
pyb.LED(2).off()

安全退出来,点RST看运行结果:

http://www.tpyboard.com/ueditor/php/upload/image/20160623/1466642507125721.jpg

可以看出,在第24个字节写入了HH。如果这里的open里,把w改成a,结果又会是怎样?大家自己试吧。

4、判断文件是否存在,如果存在,删除文件

判断flash中某文件是否存在,最常用的方法是os.path.isfile(),然而试了一下发现,micropython中没有os.path,于是想到用try...except……的方法。考虑用os.stat()一个不存在的文件,利用OSError错误提示。

代码:

# main.py -- put your code here!

import pyb
##
import os
pyb.LED(2).on()
##
try:
    s=os.stat('/sd/b.txt')
    os.remove('/sd/b.txt')
    print("Del file ok!")
    pyb.LED(2).off()
except OSError:
    pyb.LED(3).on()

运行结果:首先亮起led(2),如果tf卡上存在文件b.txt,则删除后,LED(2)熄灭,如果不存在,LED(3)与(2)均亮起。

注意:发现如果是纯数字的文件名,好像tpyb也不认,如1.txt,运行上面的程序时,总是提示文件不存在。具体大家可以再试试。

[Micropython]TPYBoard v102 定时器

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

定时器介绍

Timer库,可进行定时的触发操作

定时器的使用

要使用定时器,先需要导入Timer库。from pyb import Timer。

定义Timer:

tm=Timer(n)
n=1,2,4,7,8,9,10,11,12,13,14,#其中之一  所以定时器最大数量为11个

tm.freq(100)#定义频率 数字越大频率越高
tm.callback(f)#回调函数 若不需要传入None

实例:

from pyb import Timer #导入库
tim = pyb.Timer(4) #设置Timer编号
tim.init(freq=10) #设置轮巡时间
tim.callback(lambda t:pyb.LED(4).toggle()) #回调函数这里使用了lambda表达式

也可以写成:

def f(t):
    pyb.LED(4).toggle()
tim.callback(f)

此程序运行效果为下图快速闪动:

http://www.tpyboard.com/images/upload/20160622/14665732359271.png http://www.tpyboard.com/images/upload/20160622/1466573215437.png
[Micropython]TPYBoard v102 嵌入汇编

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

本篇教程将学习如何在 MicroPython 里边嵌入汇编语言。

注意:本篇教程属于进阶教程,用户最好知道了解处理器结构和汇编语言的相关知识。

MicroPython 包涵可内联的汇编,允许用户使用汇编语言作为 Python 的子程序,且你可以像正常使用函数般使用它们。

返回值

内联汇编函数用特定的函数装饰器标示。我们从最简单的例子下手:

@micropython.asm_thumb
def fun():
    movw(r0, 42)

你可以在脚本或是解释器里边使用该函数。该函数没有任何参数且返回数值42 。r0 是一个寄存器,其中的数值在函数返回值返回时被更改。MicroPython 一直将 r0视为一个整数并将其作为整数变量供使用者调用。

如果使用了命令 print(fun()) 将能看到数值42被打印出来。

汇编语言基础

稍微复杂一些些,我们尝试点亮一盏灯:

@micropython.asm_thumb
def led_on():
    movwt(r0, stm.GPIOA)
    movw(r1, 1 << 13)
    strh(r1, [r0, stm.GPIO_BSRRL])

上述代码使用了一些新的概念:

  • stm 为 pyboard 的微处理器提供了一系列内容以便于连接寄存器。尝试在 REPL 里运行 import stm 和 help(stm) 。这将得到一清单的有用内容:
  • stm.GPIOA 对应外围设备GPIOA 在内存中的地址。在 pyboard 板上红色的led 灯对应 A端口,PA13 引脚;
  • movwt 将32位数值放入寄存器中。其可视为由两个指令集组成的简便函数:先是 movw 然后 movt 。movt 将16位立即数移 动。
  • strh 存储半字数据。上述代码里将r1的低16位数值存入 r0 +stm.GPIO_BSRRL 的内存地址中。这将按照 r0 里设定的数值将 A 端口对应的引脚设置为高。例程中r0的第13位值被置位,故PA13 被拉高。因此红色LED 灯被点亮。
接受参数

内联汇编语言最多可以接收四个参数。一旦被使用,必须为 r0,r1,r2,r3 的寄存器或其里边的调用内容。以下是使用了这些参数的函数:

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

这里使用了 r0=r0+r1 的计算。由于将结果放入了 r0 中,故其为返回结果。尝试运行asm(1,2),将能得到 3 的返回值。

循环

我们可以分配 label(my_label)的标号,然后使用 b(my_label) 跳转到该分支,或者用 bgt(my_lable)进行有条件的跳转。下面例程使绿色的 LED 灯闪烁,闪烁次数存放在 r0 里边。

@micropython.asm_thumbdef 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)
进一步扩展

更多内联汇编指令可以参考: reference documentation

进阶训练

学习使用TPYBoard v102开发板进行一些基础的实例训练。

[Micropython]TPYBoard v102 模拟红绿灯教程
实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法
  • 进一步学习编制数据输出程序的设计方法
  • 学习模拟交通灯控制的方法
所需器件
  • 1位共阴红色LED数码管(SM42056) 1个
  • TPYBoard v102开发板 1块
  • 红、绿、黄LED灯 各1个
  • micro USB数据线 1条
  • 220欧直插电阻 1个
  • 杜邦线 若干
  • 面包板 1块
点亮LED灯

1.将三个LED灯插在面包板上,LED负极插入面包板的负极(横向插孔),正极插入面包板的纵向插孔。 2.将222欧电阻插入面包板的负极上(横向插孔)和纵向插孔中,将LED灯的正极分别与TPYBoard v102的引脚连接。 3.将红、黄、绿3个LED灯的正极依次通过杜邦线连接到TPYBoard v102的Y1,、Y2、Y3的引脚上,然后将电阻纵向插孔用杜邦线接到TPYBoard v102的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
点亮数码管

数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数可分为七段数码管和八段数码管,八段比七段多一个发光二极管单元,也就是多一个小数点(DP);按能显示可分为1位、2位、3位、4位、5位、6位、7位等数码管。 按使用类型可分为共阴数码管和共阳数码管。 数码管针脚图如下:

_images/test_12.png

共阴数码管 共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,在使用时公共端应接到地线GND上;若想点亮a段发光二极管,那么就把对应的a针脚设置为高电平,反之设置为低电平。

共阳数码管 共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,在使用时公共端应接到3.3V~5V上,若想点亮a段发光二极管,那么就把对应的a针脚设置为低电平,反之设置为高电平。

具体接线方式如下表:

TPYBoardv10x 数码管
X1 a
X2 b
X3 c
X4 d
X5 e
X6 f
X7 g
3V3 COM

注意:因为我们用的是共阳数码管,所以公共端(COM)应接开发板的VIN(3V3),点亮需置低电平。本次实验没有用到小数点,故dp针脚悬空无需接线。

定义7个引脚用于控制数码管中a~g段的发光二极管。

#数码管a~g对应的开发板引脚X1~X7
d_Pins=[Pin(i,Pin.OUT_PP) for i in ['X1','X2','X3','X4','X5','X6','X7']]

列举一下数码管要显示0~9之间的数,对应的每个针脚的高低电平的状态,便于程序的编写,如下图:

_images/test_00.png

根据上面的对应关系表,我们新建一个列表number,用来存放显示每个数字时,7个引脚应设置的电平值。

number=[
[0,0,0,0,0,0,1],#0
[1,1,1,1,0,0,1],#1
[0,0,1,0,0,1,0],#2
[0,0,0,0,1,1,0],#3
[1,0,0,1,1,0,0],#4
[0,1,0,0,1,0,0],#5
[0,1,0,0,0,0,0],#6
[0,0,0,1,1,1,1],#7
[0,0,0,0,0,0,0],#8
[0,0,0,0,1,0,0],#9
]

添加一个函数display用于控制数码管显示数字,参数是要显示的数字。

def display(num):
  global number
  count=0
  for pin in d_Pins:#X1~X7分别设置电平值 动态显示num的值
    pin.value(number[num][count])
    count+=1
模拟红绿灯

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

main.py 内容如下:

# main.py -- put your code here!
import pyb
from pyb import Pin

r_LED=Pin('Y1',Pin.OUT_PP)#red
y_LED=Pin('Y2',Pin.OUT_PP)#yellow
g_LED=Pin('Y3',Pin.OUT_PP)#green

#数码管a~g对应的开发板引脚X1~X7
d_Pins=[Pin(i,Pin.OUT_PP) for i in ['X1','X2','X3','X4','X5','X6','X7']]

number=[
[0,0,0,0,0,0,1],#0
[1,1,1,1,0,0,1],#1
[0,0,1,0,0,1,0],#2
[0,0,0,0,1,1,0],#3
[1,0,0,1,1,0,0],#4
[0,1,0,0,1,0,0],#5
[0,1,0,0,0,0,0],#6
[0,0,0,1,1,1,1],#7
[0,0,0,0,0,0,0],#8
[0,0,0,0,1,0,0],#9
]

def display(num):
    global number
    count=0
    for pin in d_Pins:#X1~X7分别设置电平值 动态显示num的值
        pin.value(number[num][count])
        count+=1

if __name__=='__main__':
    while True:
        #红灯亮10秒
        r_LED.value(1)
        for i in range(0,10):
            display(9-i)
            pyb.delay(1000)#1s
        r_LED.value(0)
        #黄灯亮3秒
        y_LED.value(1)
        for i in range(0,3):
            display(2-i)
            pyb.delay(1000)#1s
        y_LED.value(0)
        #绿灯亮10秒
        g_LED.value(1)
        for i in range(0,10):
            display(9-i)
            pyb.delay(1000)#1s
        g_LED.value(0)
效果演示

效果图:

_images/test_13.png
[Micropython]TPYBoard v102 DIY金属检测仪

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输入输出程序的设计方法。
  • 学习LJ12A3-4-Z/BX金属接近开关的工作原理。
  • 硬件接线方法。
  • 学会用TPYBoard接收金属接近开关的输出信号,并对信号进行判断处理,点亮LED发光二极管。
所需元器件
  • TPYBoard v102 板子 1块
  • LJ12A3-4-Z/BX 金属接近开关 1个
  • 面包板 1块
  • 发光二极管 1个
  • micro USB数据线 1条
  • 杜邦线 若干
LJ12A3-4-Z/BX 接近开关工作原理
硬件接线方法
LJ12A3-4-Z/BX接近开关
http://www.tpyboard.com/ueditor/php/upload/image/20161220/1482216954934573.png
源代码
# 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 v102 DIY声光控小夜灯

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习光敏模块的工作原理。
  • 学习声音的工作原理。
  • 学习TPYboard与声音传感器与光敏传感器的接线方法以及利用声音与光控制发光二极管亮灭。
所需元器件
  • TPYBoard v102板子 1块
  • 声音传感器 1个
  • 光敏传感器 1个
  • 面包板 1块
  • 发光二极管 若干
  • micro USB数据线 1条
  • 杜邦线 若干
光敏传感器模块工作原理

1.光敏电阻模块对环境光线最敏感,一般用来检测周围环境的光线的亮度,触发单片机或继电器模块等; 2.模块在环境光线亮度达不到设定阈值时,DO端输出高电平,当外界环境光线亮度超过设定阈值时,DO端输出低电平; 3.DO输出端可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的光线亮度改变; 4.DO输出端可以直接驱动本店继电器模块,由此可以组成一个光控开关。

光敏传感器实物图:

http://old.tpyboard.com/ueditor/php/upload/image/20161119/1479545872307793.png
声音传感器模块工作原理

1.声音模块对环境声音强度最敏感,一般用来检测周围环境的声音强度; 2.模块在环境声音强度达不到设定阈值时,OUT输出高电平,当外界环境声音强度超过设定阈值时,模块OUT输出低电平; 3.小板数字量输出OUT可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的声音; 4.小板数字量输出OUT可以直接驱动本店继电器模块,由此可以组成一个声控开关;

声音传感器实物图:

http://old.tpyboard.com/ueditor/php/upload/image/20161119/1479545901165245.png
硬件接线方法

上面我们已经知道光敏传感器跟声音传感器的工作原理,以及3个针脚的作用,我们只需讲电源正极与电源负极跟我们TPYBoard v102的3.3V跟GND连接起来, 然后将光敏传感器与声音传感器的信号输出针脚连接到TPYBoard v102的GPIO上(本次实验声音传感器连接的是Y1针脚,光敏传感器连接的是Y2针脚)。 然后将发光数码管的正极插入面包板正极上,负极插入面包板的负极上,用杜邦线将负极连接到TPYBoard v102的GND上,正极连接到TOYBoard v102的X1针脚。

源代码
# 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]TPYBoard v102 驱动DHT11模块获取温湿度

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

实验器件
  • TPYBoard v102 1块
  • DHT11温湿度模块 1个
  • micro USB 数据线 1根
  • 面包板 1块
  • 杜邦线 若干
器件说明
DHT11温湿度传感器说明

DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃。

_images/dht11.jpg

引脚说明

_images/dht11_pin.jpg

正面朝上,引脚依次从左到右编号为1~4。

Pin 名称 说明
1 VDD 供电 3-5.5VDC
2 DATA 串行数据,单总线
3 NC 空脚,请悬空
4 GND 接地,电源负极

使用说明

_images/dht11_1.jpg

MCU(单片机)与DHT11之间连接线长度小于20米时,应在第2引脚(数据引脚)上接入5K的上拉电阻(大于20米时根据实际情况接入合适的上拉电阻)。 为了使用方便,我们本次直接采用DH11温湿度模块,上面已经做好了上拉电阻的处理。

_images/DHT11.png

DHT11温湿度模块共有3个引脚,具体参照如下:

_images/DHT112.png
接线方式

TPYBoard v102连接DHT11

_images/102+DHT11.png
源代码

TPYBoard v102 main.py文件内容如下:

import pyb
from pyb import Pin
from dht11 import DHT11

dht = DHT11('X12')
def readTaHData():
    DATA = dht.read_data()#读取温湿度的值
    print(DATA[0],'℃')
    print(DATA[1],'%')
while True:
    readTaHData()
    pyb.delay(1000)
[Micropython]TPYBoard v102 跳动的心

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习8*8点阵与TPYBoard的接线方法,点亮点阵。
所需元器件
  • 8*8 LED点阵屏 1个
  • TPYBoard v102板子 1块
  • micro USB数据线 1条
  • 杜邦线 若干
点亮8*8 LED点阵

8*8 LED点阵屏针脚图:

http://old.tpyboard.com/ueditor/php/upload/image/20161031/1477879225908683.png

通过针脚图,大家可以看出点阵屏中发光二极管对应的行、列数与实际针脚编号不是顺序对应的。上图中带圆圈的数字表示的是点阵屏的针脚编号,不带圆圈的数字表示的是灯珠的行、列编号。

比如,我们要点亮第一行第一个,则将第9针脚接高电平,第13针脚接低电平,就会被点亮。如果要将第一行全部点亮,则将第9针脚接高电平,第13、3、4、10、6、11、15、16针脚接低电平,那第一行就会被全部点亮。

了解完显示原理后,接下来介绍一下点阵屏的针脚。点阵屏背面图:

_images/8x81.jpg

大家翻到点阵屏的背面,可以看到有一侧凸出了一个小点,这个小点表示为点阵屏的底部。 通过这个小点,我们就可以区别开点阵屏的针脚,下图中用红点表示底部凸起的小点。

不同厂家标注的方式不同,有的会直接在1号针脚旁标注1。

_images/8x82.jpg

针脚确认了,接下来我们就可以接线了(注意下表中小括号内的数字为点阵屏的针脚编号)。

点阵屏ROW TPYBoard v10x
1(9) X1
2(14) X2
3(8) X3
4(12) X4
5(1) X5
6(7) X6
7(2) X7
8(5) X8
点阵屏COL TPYBoard v10x
1(13) Y1
2(3) Y2
3(4) Y3
4(10) Y4
5(6) Y5
6(11) Y6
7(15) Y7
8(16) Y8
8*8 LED点阵显示心形

效果图:

http://old.tpyboard.com/ueditor/php/upload/image/20161031/1477882469674497.jpg

我们按照上面的步骤接线完毕后,编写main.py文件,下面是显示心形图案的源代码:

# main.py -- put your code here!
import  pyb
from pyb import Pin
x_row = [Pin(i, Pin.OUT_PP) for i in ['X1','X2','X3','X4','X5','X6','X7','X8']]
y_col = [Pin(i, Pin.OUT_PP) for i in ['Y1','Y2','Y3','Y4','Y5','Y6','Y7','Y8']]
tuxing = [
#大心
['11111111','10011001','00000000','00000000','10000001','11000011','11100111','11111111'],
#小心
['11111111','11111111','10011001','10000001','11000011','11100111','11111111','11111111']
]
def displayLED(num):
    for i,j in enumerate(x_row):
        x_row[i-1].value(0)
        data = tuxing[num][i]
        for k,v in enumerate(data):
            y_col[k].value(int(v))
        j.value(1)
        pyb.delay(1)

while True:
    for i in range(2):
        for k in range(100):
            displayLED(i)
[Micropython]TPYBoard v102 DIY温度计

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习DS18B20的接线方法,并利用DS18B20检测当前温度
  • 学习8*8LED点阵接线方法,并将当前温度显示
所需元器件
  • TPYBoard v102开发板 1块
  • micro USB数据线 1条
  • 杜邦线 若干
  • 8*8LED点阵屏 1个
  • DS18B20温度传感器 1个
学习DS18B20的接线方法
http://old.tpyboard.com/ueditor/php/upload/image/20160815/1471247227119424.png

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

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

TPYBoard DS18B20
3V3/Pin VDD
Y10 DO
GND GND

文章末有源码下载链接,下载到本地后将目录下的文件ds18b20.py和onewire_lib.py复制到TPYBFLASH磁盘的根目录。 复制文件后要安全退出磁盘,然后重新接入,即可运行main.py文件了。通过Putty可查看打印的温度信息。

main.py源代码:

#main.py
import pyb
from pyb import Pin
from ds18b20 import DS18X20
DQ=DS18X20(Pin('Y10'))#DQ
while True:
    tem = DQ.read_temp()
    print(tem)
    pyb.delay(1000)
控制8*8LED点阵显示温度
http://old.tpyboard.com/ueditor/php/upload/image/20160815/1471247464571951.png

点阵后面有两排针脚,一排以1开头,即1-8针脚,一排以9开头,即9-16针脚,上图中圆圈内的数字即为针脚的对应数字。当ROW 的针脚为高电平,COL的针脚为低电平时候,我们的LED即全部点亮。 为了方便操作行和列,我们可以将ROW的8个引脚接到我们TPYBoard v102的X1-X8,COL的8个引脚接到我们TPYBoard v102的Y1-Y8。这样我们通过控制X引脚和Y引脚的高低电平就可以控制每一个LED的亮与不亮,这样就可以设计想显示的任何字符和图形,快来试试吧。

若不知道怎么判断点阵屏的针脚编号,请阅读上一篇《跳动的心》内有详细介绍

将温度显示在8*8LED点阵上

接线成功以后,我们将测试出温度通过分割函数将十位,个位显示在点阵屏上,代码如下:

import pyb
from pyb import Pin
from ds18b20 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 v102 驱动LCD5110显示6x8字符

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

实验目的
  • 学习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

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]TPYBoard v102 PM2.5检测仪制作

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

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检测仪吧。

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

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 严重污染 红灯亮
TPYBoard v102的硬件特点:

√ 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 引脚。

材料准备
制作PM2.5检测仪所需材料如下:
  • PM2.5粉尘传感器 1个
  • TPYBoard v102开发板 1块
  • Lcd5110显示屏 1个
  • 杜邦线 若干
  • micro USB数据线 1条
http://old.tpyboard.com/ueditor/php/upload/image/20160823/1471943991787031.png
硬件接线方法
传感器的针脚
传感器上一共六根线,从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://old.tpyboard.com/ueditor/php/upload/image/20160823/1471941893958432.png
LCD5110的针脚

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

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
3.3V VCC VCC
Y12 LIGHT Light (0=on, 1=off)
GND GND GND
PM2.5检测仪整体接线方法
按照图1、图2所示将PM2.5粉尘传感器以及5110显示屏与TPTYBoard v102连接起来,硬件连接完毕,如图3:
http://old.tpyboard.com/ueditor/php/upload/image/20160823/1471942098496980.png
PM2.5粉尘传感器工作原理及数据处理
PM2.5粉尘传感器工作原理

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

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

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

http://old.tpyboard.com/ueditor/php/upload/image/20160823/1471942150331605.png

内部结构仿真图

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

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

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

http://old.tpyboard.com/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。)

PM2.5粉尘传感器的采样频率及程序编码
PM2.5粉尘传感器的采样频率
PM2.5粉尘传感器的采样频率是非常高的,一般3~4ms发送一个16进制的采样数据,也就是说传感器通电(接通VCC和GND)后,每隔3~4ms发送一个16进制的采样数据,这么高的采样频率作为一个检测仪来说显然是没有必要的。 TPYBoard通过串口接收粉尘传感器数据,使用串口当然先定义串口,通过打开就可以接收串口数据,关闭串口就停止接收数据的特点,来自由控制PM2.5粉尘传感器的采样频率。
程序编码
我们main.py中,采用首先定义串口,其次是打开串口接收采样数据,最后关闭串口,并且处理采样数据及显示,依次循环。
运行测试
接线OK后,导入font.py文件和upcd8544.py文件(主要用于5110显示数据),再运行main.py即可看到当前的空气质量等级以及PM2.5的浓度值了。
源代码
把我写的程序的源码分享给大家,有需要的可以参考一下。
# 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.read()
        #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)
[Micropython]TPYBoard v102 DIY超声波测距仪

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习超声波模块的测距原理。
  • 学习LCD5110接线方法
  • 学习TPYboard控制超声波模块测距。
所需元器件
  • 超声波模块 1个
  • TPYBoard v102板子 1块
  • LCD5110显示屏 1个
  • micro USB数据线 1条
  • 杜邦线 若干
超声波模块工作原理

(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。

(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回。

(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。

如下图接线,VCC 供 5V电源, GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四个接口端。

http://old.tpyboard.com/ueditor/php/upload/image/20161116/1479286451773829.png
控制LCD5110显示屏显示6x8字符

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

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
3.3V VCC VCC
Y12 LIGHT Light (0=on, 1=off)
GND GND GND

接线ok后,并且导入font.py文件和upcd8544.py文件,编写main.py将测到的距离显示在5110显示屏上,运行main.py就ok了。(font.py和upcd8544.py可以从官网上下载,最后会告诉下载地址)。

源代码
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
[Micropython]TPYBoard v102 DIY电子时钟

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 什么是SPI接口。
  • 学习TPYBoard I2C接口的用法。
  • 学习LCD5110接线方法。
  • 设定时钟并将当前时间显示在LCD5110上。
所需元器件
  • DS3231模块 1个
  • TPYBoard v102开发板 1块
  • LCD5110显示屏 1个
  • 数据线 1条
  • 杜邦线 若干
TPYBoard v102的SPI接口

LCD5110需要SPI接口与TPYBoard v102进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,TPYBoard v102有两个SPI接口,我们用的为SPI1接口。

http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150621179364.png
TPYBoard v102的I2C接口

DS3231是I2C接口通信的,它通过I2C接口与TPYBoard v102进行数据通讯,DS3231通过这个接口与TPYBoard v102进行双向通讯,进行数据传输,TPYBoard v102有两个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 v102的针脚X9,针脚SDA接TPYBoard v102的针脚X10。

http://www.tpyboard.com/ueditor/php/upload/image/20161126/1480150682569300.png
控制5110显示屏显示6x8字符

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

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
3.3V VCC VCC
Y12 LIGHT Light (0=on, 1=off)
GND GND GND
源代码

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

# main.py -- put your code here!
import pyb
import upcd8544
from machine import SPI,Pin
from DS3231 import DS323
ds=DS3231(1)
ds.DATE([16,11,26])
ds.TIME([16,14,6])
while True:
    ds.TEMP()
    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('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('Date',0,0)
    lcd_5110.lcd_write_string(str(ds.DATE()),0,1)
    lcd_5110.lcd_write_string('Time',0,2)
    lcd_5110.lcd_write_string(str(ds.TIME()),0,3)
    lcd_5110.lcd_write_string('Tem',0,4 )
    lcd_5110.lcd_write_string(str(ds.TEMP()),0,5)
    pyb.delay(1000)
[Micropython]TPYBoard v102 学习使用OLED显示屏

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习TPYBoard控制OLED显示字符。
所需元器件
  • TPYBoard v102板子 1块
  • micro USB数据线 1条
  • 杜邦线 若干
  • OLED液晶屏 1块
什么是OLED显示屏
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(已集成在屏中)。

实际显示效果 http://old.tpyboard.com/ueditor/php/upload/image/20170211/1486776004559236.png
OLED接口定义

1> GND= 电源地

2> VCC= 电源地(2.8V~5.5V)

3> D0 = 时钟线

4> D1 = 数据线

5> RES= 复位线

6> DC = 数据/命令

7> CS = 片选

硬件的接线方法
在这OLED需要SPI接口与TPYBoard v102进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,TPYBoard v102自带两个SPI接口,本实验中我们用的TPYBoard v102的SPI1接口。
接线图 _images/oled.png
实物接线图 http://old.tpyboard.com/ueditor/php/upload/image/20170211/1486776112995233.png

接线OK后,并且导入font.py文件和ssd1306.py文件,再可运行main.py了。

源代码
#main.py
import pyb
from ssd1306_lib 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()
实现效果
http://old.tpyboard.com/ueditor/php/upload/image/20170211/1486776202255121.png
[Micropython]TPYBoard v102 控制LCD1602显示字符

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • LCD1602的硬件接线方法。
  • TPYboard控制Lcd1602显示字符 。
所需元器件
  • TPYBoard v102开发板 1块
  • LCD1602液晶屏 1块
  • 电位器3296 1个
  • 面包板 1块
  • micro USB数据线 1条
  • 杜邦线 若干
硬件接线方法

LCD1602采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如下表所示:

_images/1602.png
LCD1602液晶模块引脚说明

第1脚:VSS为地电源

第2脚:VDD接5V正电源

第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。

下面是实物图与针脚图对应的关系:

http://tpyboard.com/ueditor/php/upload/image/20161226/1482730709264212.png http://tpyboard.com/ueditor/php/upload/image/20161226/1482730716949140.png

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器

第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令

第7~14脚:D0~D7为8位双向数据线

第15脚:背光源正极

第16脚:背光源负极

http://tpyboard.com/ueditor/php/upload/image/20161226/1482730747525623.png http://tpyboard.com/ueditor/php/upload/image/20161226/1482730757499647.png

按照上面针脚对应关系接线OK后,并且导入tpyb_lcd1602.py文件和tpyb_gpio_lcd1602.py文件再可运行main.py了(tpyb_lcd1602.py和pyb_gpio_lcd1602..py可以从官网上下载,最后会告诉下载地址)。

http://www.micropython.net.cn/ueditor/php/upload/image/20161226/1482730789766757.png
main.py源代码:
    # main.py -- put your code here!
    import pyb
    from pyb import Pin
    from pyb import delay, udelay,millis
    from tpyb_lcd1602 import TPYBoardLcd1602Api
    from tpyb_gpio_lcd1602 import TPYBoardGpioLcd1602


    def main():
            lcd = TPYBoardGpioLcd1602(rs_pin=Pin.board.Y10,
                                      enable_pin=Pin.board.Y9,
                                      d4_pin=Pin.board.Y5,
                                      d5_pin=Pin.board.Y6,
                                      d6_pin=Pin.board.Y7,
                                      d7_pin=Pin.board.Y8,
                                      num_lines=2, num_columns=16)
    lcd.lcd1602_write_string("Hi,TurnipSmart!\n This TPYBoard!")
    delay(5000)
    lcd.clear()
    lcd.lcd1602_write_string("This  lcd1602!\n Start Work!")
    delay(5000)
    lcd.clear()
    count = 0
    while True:
        lcd.move_to(0, 0)
        #%1d 宽度  返回运行当前程序的累计时间,单位是毫秒
        lcd.lcd1602_write_string("%1d" % (millis() // 1000))
        delay(1000)
        count += 1
        print(count)

if __name__ == "__main__":
    main()
[Micropython]TPYBoard v102 DIY智能温控小风扇

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习DS18B20的接线方法,并利用DS18B20检测当前温度。
  • 学习三极管9014的用法。
  • 通过18B20智能控制直流电机驱动小风扇。
所需元器件
  • TPYBoard v102板子 1块
  • 直流电机 1个
  • 面包板 1块
  • 数据线 1条
  • 三极管9014(NPN)1个
  • 杜邦线 若干
学习DS18B20的接线方法
http://old.tpyboard.com/ueditor/php/upload/image/20161125/1480062707271272.png

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

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

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 ds18b20 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://tpyboard.com/ueditor/php/upload/image/20161125/1480063045583790.png

在这里我们用到三极管的开关与放大功能,给基极不同电平控制直流电机电流的通断,以达到控制电机转动的目的,根据三极管特性我们将集电极连接TPYBoard的3.3v,发射极连接电机一极,电机另一极接TPYboard的GND,通过温度传感器18B20检测温度,当温度到达指定温度时,通过TPYBoard控制三极管基极的电平,驱动直流电机转动。

效果图
http://tpyboard.com/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 v102 驱动舵机教程

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

引言

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

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

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

一是体积紧凑,便于安装; 二是输出力矩大,稳定性好; 三是控制简单,便于和数字系统接口。

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

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

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

_images/test_31.png
  • 舵机的接线

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

  • 舵机的控制原理

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

占空比:

1.指高电平在一个周期之内所占的时间比率。

2.正脉冲的持续时间与脉冲总周期的比值。例如:正脉冲宽度1μs,信号周期10μs的脉冲序列占空比为0.1。即:脉冲的宽度除以脉冲的周期称为占空比。标准PWM(脉冲宽度调制)信号的周期固定为20ms(50Hz),理论上脉宽分布应在1ms到2ms之间,但是,事实上脉宽可由0.5ms到2.5ms之间,脉宽和舵机的转角0°~180°相对应。

TPYBoard v10x驱动舵机
  • 实验目的

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

  • 实验材料
  1. TPYBoard v10x 开发板 1块
  2. SG90舵机 1个
  3. 杜邦线 若干
  • 连接图:

在micropython中已经有封装好的Servo模块用于伺服控制。设定了4个引脚X1、X2、X3和X4。我这里接的是X1引脚。

TPYBoardv10x 舵机
X1 橙色
VIN 红色
GND 棕色
http://www.tpyboard.com/ueditor/php/upload/image/20160722/1469172305445497.jpg

当然,大家也可以使用其他的GPIO引脚,但是需要自己编写驱动程序,看参考此教程:http://old.tpyboard.com/support/studyexample14/214.html

  • 实验代码

我们将三轴加速度传感器和舵机进行结合,实现当开发板转动时,舵机也随之转动。

main.py 内容如下:

from pyb import *

accel = Accel()
servo = Servo(1)
while True:
    x = accel.x()
    servo.angle(-x*3,300)
    delay(200)
效果演示

观看视频

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

高手专场

经过前面两个阶段的练习,想必你已经成为一名TPYBoard的高手了。那就来挑战下高手专场的实例训练吧!

[Micropython]TPYBoard v102 USB-HID应用

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

本部分重点讲述如果将TPYBoard v10x作为USB-HID来应用。

引言

USB-HID是Human Interface Device的缩写,属于人机交互操作的设备,如USB鼠标,USB键盘,USB游戏操纵杆,USB触摸板,USB轨迹球、电话拨号设备、VCR遥控等等设备。 TPYBoard v10x除了具有usb host功能以外,还可作为USB-HID设备来应用,这里重点讲述如果作为鼠标和键盘使用。

TPYBoard v10x作为鼠标应用

TPYBoard v10x作为鼠标的应用可以参考micropython官方实例中的usb-mouse应用。这里以官方实例为例。

编辑 boot.py 文件以更改 usb_mouse 的确认方式。具体如下:

import machine
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('CDC+HID')前的注释符。这里pyb.usb_mode(),定义了HID的设备,默认为mouse,也可以用pyb.usb_mode('CDC+HID',hid=pyb.hid_mouse)。 如果是键盘,应改为pyb.usb_mode('CDC+HID',hid=pyb.hid_keyboard)。

REPL调试鼠标事件

这里依然用PuTTY进行REPL调试。修改完boot.py文件后复位一下,会发现原本会出现的U盘没有了,此时设备的串口也可能发生了改变,因此在连接PuTTY前要先确认一下串口。 在PuTTY中,输入:

pyb.hid((0,10,0,0))  #注意这里两层括号

回车后,会发现鼠标向右移动了10个像素。pyb.hid()的具体用法:

pyb.hid((buttons, x, y, z))

这里buttons取0,1,2,3分别表示0移动,1按下左键,2按下中键,3按下右键。这句也可以用pyb.USB_HID().send((buttons, x, y, z)),效果是一样的。

鼠标左右摇晃

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

这段代码也可以写到main.py中,这时大家可能会问,u盘没了,main.py怎么编辑啊。这里需要进入TPYBoard v10x的安全模式。 按住USR键,按一下RST,此时led2与led3交替亮,当led3亮起,led2没亮时,松开usr,此时led3快闪后,可以发现u盘挂载出来了,这时可以修改main.py文件:

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

保存后,按RST重启后,就可以看到效果了。

加速度传感器的鼠标

用加速度传感器制作一个能根据TPYBoard开发板角度移动而移动的鼠标。相关的代码可以直接在交互式解释器里边完成,或者放入 main.py 文件中。在这里我们选择放入 main.py 文件。

在 main.py 中代码:

import pyb
switch = pyb.Switch()
accel = pyb.Accel()
while not switch():
    pyb.hid((0, accel.x(), accel.y(), 0))
    pyb.delay(20)

保存文件,退出或卸载TPYBoard设备。通过复位按键重置,其将再次成为鼠标,且根据板的倾斜角度移动鼠标。 你应该能注意到 y轴方向是颠倒的。这个问题很容易解决:在上述的pyb.hid()行里,y 轴方向前边加上负号即可。

TPYBoard v10x作为键盘应用

编辑 boot.py 文件,定义usb_keyboard:

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

import machine
import pyb
#pyb.main('main.py') # main script to run after this one
#pyb.usb_mode('CDC+MSC') # act as a serial and a storage device
pyb.usb_mode('CDC+HID',hid=pyb.hid_keyboard) # act as a serial device and a keyboard

按键测试

这里为了便于查看,我们修改main.py文件:

# main.py -- put your code here!
hid=pyb.USB_HID()
def release_key_once():
    buf = bytearray(8) # report is 8 bytes long
    buf[2] = 0
    hid.send(buf) # key released
    pyb.delay(10)
def press_key_once(key):
    buf = bytearray(8) # report is 8 bytes long
    buf[2] = key
    hid.send(buf) # key released
    pyb.delay(10)
def press_2key(key1,key2):
    buf = bytearray(8) # report is 8 bytes long
    buf[2] = key1
    buf[3] = key2
    hid.send(buf) # key released
    pyb.delay(10)
def release_2key():
    buf = bytearray(8) # report is 8 bytes long
    buf[2] = 0
    buf[3] = 0
    hid.send(buf) # key released
    pyb.delay(10)
pyb.delay(1000)
press_key_once(0x04)
release_key_once()
pyb.delay(1000)
press_key_once(0x05)
release_key_once()
pyb.delay(1000)
press_key_once(0x2B)
release_key_once()
pyb.delay(1000)
press_key_once(0x28)
release_key_once()
pyb.delay(1000)
press_key_once(0x06)
release_key_once()
pyb.delay(1000)
press_key_once(0x07)
release_key_once()
pyb.delay(1000)
press_2key(0x08,0x09)
release_2key()

pyb.delay(1000)

这个程序定义了按下一个键press_key_once(key),抬起一个键 release_key_once(),按下两个键press_2key(key1,key2),抬起两个键release_2key()的方法。 具体运行效果,可先打开一个记事本,然后按一下RST键,或者插拔一次usb口,最后可以看到在记事本里,先打入ab,接着是tab,回车,接着cdef,除了ef几乎同时出现,前面的输入间都间隔了1秒。

按键值的定义

为什么上面的0x04是a,0x05是b呢,这里的定义具体如下:

#define KEY_NONE                               0x00
#define KEY_ERRORROLLOVER                      0x01
#define KEY_POSTFAIL                           0x02
#define KEY_ERRORUNDEFINED                     0x03
#define KEY_A                                  0x04
#define KEY_B                                  0x05
#define KEY_C                                  0x06
#define KEY_D                                  0x07
#define KEY_E                                  0x08
#define KEY_F                                  0x09
#define KEY_G                                  0x0A
#define KEY_H                                  0x0B
#define KEY_I                                  0x0C
#define KEY_J                                  0x0D
#define KEY_K                                  0x0E
#define KEY_L                                  0x0F
#define KEY_M                                  0x10
#define KEY_N                                  0x11
#define KEY_O                                  0x12
#define KEY_P                                  0x13
#define KEY_Q                                  0x14
#define KEY_R                                  0x15
#define KEY_S                                  0x16
#define KEY_T                                  0x17
#define KEY_U                                  0x18
#define KEY_V                                  0x19
#define KEY_W                                  0x1A
#define KEY_X                                  0x1B
#define KEY_Y                                  0x1C
#define KEY_Z                                  0x1D
#define KEY_1_EXCLAMATION_MARK                 0x1E
#define KEY_2_AT                               0x1F
#define KEY_3_NUMBER_SIGN                      0x20
#define KEY_4_DOLLAR                           0x21
#define KEY_5_PERCENT                          0x22
#define KEY_6_CARET                            0x23
#define KEY_7_AMPERSAND                        0x24
#define KEY_8_ASTERISK                         0x25
#define KEY_9_OPARENTHESIS                     0x26
#define KEY_0_CPARENTHESIS                     0x27
#define KEY_ENTER                              0x28
#define KEY_ESCAPE                             0x29
#define KEY_BACKSPACE                          0x2A
#define KEY_TAB                                0x2B
#define KEY_SPACEBAR                           0x2C
#define KEY_MINUS_UNDERSCORE                   0x2D
#define KEY_EQUAL_PLUS                         0x2E
#define KEY_OBRACKET_AND_OBRACE                0x2F
#define KEY_CBRACKET_AND_CBRACE                0x30
#define KEY_BACKSLASH_VERTICAL_BAR             0x31
#define KEY_NONUS_NUMBER_SIGN_TILDE            0x32
#define KEY_SEMICOLON_COLON                    0x33
#define KEY_SINGLE_AND_DOUBLE_QUOTE            0x34
#define KEY_GRAVE ACCENT AND TILDE             0x35
#define KEY_COMMA_AND_LESS                     0x36
#define KEY_DOT_GREATER                        0x37
#define KEY_SLASH_QUESTION                     0x38
#define KEY_CAPS LOCK                          0x39
#define KEY_F1                                 0x3A
#define KEY_F2                                 0x3B
#define KEY_F3                                 0x3C
#define KEY_F4                                 0x3D
#define KEY_F5                                 0x3E
#define KEY_F6                                 0x3F
#define KEY_F7                                 0x40
#define KEY_F8                                 0x41
#define KEY_F9                                 0x42
#define KEY_F10                                0x43
#define KEY_F11                                0x44
#define KEY_F12                                0x45
#define KEY_PRINTSCREEN                        0x46
#define KEY_SCROLL LOCK                        0x47
#define KEY_PAUSE                              0x48
#define KEY_INSERT                             0x49
#define KEY_HOME                               0x4A
#define KEY_PAGEUP                             0x4B
#define KEY_DELETE                             0x4C
#define KEY_END1                               0x4D
#define KEY_PAGEDOWN                           0x4E
#define KEY_RIGHTARROW                         0x4F
#define KEY_LEFTARROW                          0x50
#define KEY_DOWNARROW                          0x51
#define KEY_UPARROW                            0x52
#define KEY_KEYPAD_NUM_LOCK_AND_CLEAR          0x53
#define KEY_KEYPAD_SLASH                       0x54
#define KEY_KEYPAD_ASTERIKS                    0x55
#define KEY_KEYPAD_MINUS                       0x56
#define KEY_KEYPAD_PLUS                        0x57
#define KEY_KEYPAD_ENTER                       0x58
#define KEY_KEYPAD_1_END                       0x59
#define KEY_KEYPAD_2_DOWN_ARROW                0x5A
#define KEY_KEYPAD_3_PAGEDN                    0x5B
#define KEY_KEYPAD_4_LEFT_ARROW                0x5C
#define KEY_KEYPAD_5                           0x5D
#define KEY_KEYPAD_6_RIGHT_ARROW               0x5E
#define KEY_KEYPAD_7_HOME                      0x5F
#define KEY_KEYPAD_8_UP_ARROW                  0x60
#define KEY_KEYPAD_9_PAGEUP                    0x61
#define KEY_KEYPAD_0_INSERT                    0x62
#define KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE    0x63
#define KEY_NONUS_BACK_SLASH_VERTICAL_BAR      0x64
#define KEY_APPLICATION                        0x65
#define KEY_POWER                              0x66
#define KEY_KEYPAD_EQUAL                       0x67
#define KEY_F13                                0x68
#define KEY_F14                                0x69
#define KEY_F15                                0x6A
#define KEY_F16                                0x6B
#define KEY_F17                                0x6C
#define KEY_F18                                0x6D
#define KEY_F19                                0x6E
#define KEY_F20                                0x6F
#define KEY_F21                                0x70
#define KEY_F22                                0x71
#define KEY_F23                                0x72
#define KEY_F24                                0x73
#define KEY_EXECUTE                            0x74
#define KEY_HELP                               0x75
#define KEY_MENU                               0x76
#define KEY_SELECT                             0x77
#define KEY_STOP                               0x78
#define KEY_AGAIN                              0x79
#define KEY_UNDO                               0x7A
#define KEY_CUT                                0x7B
#define KEY_COPY                               0x7C
#define KEY_PASTE                              0x7D
#define KEY_FIND                               0x7E
#define KEY_MUTE                               0x7F
#define KEY_VOLUME_UP                          0x80
#define KEY_VOLUME_DOWN                        0x81
#define KEY_LOCKING_CAPS_LOCK                  0x82
#define KEY_LOCKING_NUM_LOCK                   0x83
#define KEY_LOCKING_SCROLL_LOCK                0x84
#define KEY_KEYPAD_COMMA                       0x85
#define KEY_KEYPAD_EQUAL_SIGN                  0x86
#define KEY_INTERNATIONAL1                     0x87
#define KEY_INTERNATIONAL2                     0x88
#define KEY_INTERNATIONAL3                     0x89
#define KEY_INTERNATIONAL4                     0x8A
#define KEY_INTERNATIONAL5                     0x8B
#define KEY_INTERNATIONAL6                     0x8C
#define KEY_INTERNATIONAL7                     0x8D
#define KEY_INTERNATIONAL8                     0x8E
#define KEY_INTERNATIONAL9                     0x8F
#define KEY_LANG1                              0x90
#define KEY_LANG2                              0x91
#define KEY_LANG3                              0x92
#define KEY_LANG4                              0x93
#define KEY_LANG5                              0x94
#define KEY_LANG6                              0x95
#define KEY_LANG7                              0x96
#define KEY_LANG8                              0x97
#define KEY_LANG9                              0x98
#define KEY_ALTERNATE_ERASE                    0x99
#define KEY_SYSREQ                             0x9A
#define KEY_CANCEL                             0x9B
#define KEY_CLEAR                              0x9C
#define KEY_PRIOR                              0x9D
#define KEY_RETURN                             0x9E
#define KEY_SEPARATOR                          0x9F
#define KEY_OUT                                0xA0
#define KEY_OPER                               0xA1
#define KEY_CLEAR_AGAIN                        0xA2
#define KEY_CRSEL                              0xA3
#define KEY_EXSEL                              0xA4
#define KEY_KEYPAD_00                          0xB0
#define KEY_KEYPAD_000                         0xB1
#define KEY_THOUSANDS_SEPARATOR                0xB2
#define KEY_DECIMAL_SEPARATOR                  0xB3
#define KEY_CURRENCY_UNIT                      0xB4
#define KEY_CURRENCY_SUB_UNIT                  0xB5
#define KEY_KEYPAD_OPARENTHESIS                0xB6
#define KEY_KEYPAD_CPARENTHESIS                0xB7
#define KEY_KEYPAD_OBRACE                      0xB8
#define KEY_KEYPAD_CBRACE                      0xB9
#define KEY_KEYPAD_TAB                         0xBA
#define KEY_KEYPAD_BACKSPACE                   0xBB
#define KEY_KEYPAD_A                           0xBC
#define KEY_KEYPAD_B                           0xBD
#define KEY_KEYPAD_C                           0xBE
#define KEY_KEYPAD_D                           0xBF
#define KEY_KEYPAD_E                           0xC0
#define KEY_KEYPAD_F                           0xC1
#define KEY_KEYPAD_XOR                         0xC2
#define KEY_KEYPAD_CARET                       0xC3
#define KEY_KEYPAD_PERCENT                     0xC4
#define KEY_KEYPAD_LESS                        0xC5
#define KEY_KEYPAD_GREATER                     0xC6
#define KEY_KEYPAD_AMPERSAND                   0xC7
#define KEY_KEYPAD_LOGICAL_AND                 0xC8
#define KEY_KEYPAD_VERTICAL_BAR                0xC9
#define KEY_KEYPAD_LOGIACL_OR                  0xCA
#define KEY_KEYPAD_COLON                       0xCB
#define KEY_KEYPAD_NUMBER_SIGN                 0xCC
#define KEY_KEYPAD_SPACE                       0xCD
#define KEY_KEYPAD_AT                          0xCE
#define KEY_KEYPAD_EXCLAMATION_MARK            0xCF
#define KEY_KEYPAD_MEMORY_STORE                0xD0
#define KEY_KEYPAD_MEMORY_RECALL               0xD1
#define KEY_KEYPAD_MEMORY_CLEAR                0xD2
#define KEY_KEYPAD_MEMORY_ADD                  0xD3
#define KEY_KEYPAD_MEMORY_SUBTRACT             0xD4
#define KEY_KEYPAD_MEMORY_MULTIPLY             0xD5
#define KEY_KEYPAD_MEMORY_DIVIDE               0xD6
#define KEY_KEYPAD_PLUSMINUS                   0xD7
#define KEY_KEYPAD_CLEAR                       0xD8
#define KEY_KEYPAD_CLEAR_ENTRY                 0xD9
#define KEY_KEYPAD_BINARY                      0xDA
#define KEY_KEYPAD_OCTAL                       0xDB
#define KEY_KEYPAD_DECIMAL                     0xDC
#define KEY_KEYPAD_HEXADECIMAL                 0xDD
#define KEY_LEFTCONTROL                        0xE0
#define KEY_LEFTSHIFT                          0xE1
#define KEY_LEFTALT                            0xE2
#define KEY_LEFT_GUI                           0xE3
#define KEY_RIGHTCONTROL                       0xE4
#define KEY_RIGHTSHIFT                         0xE5
#define KEY_RIGHTALT                           0xE6
#define KEY_RIGHT_GUI                          0xE7
恢复正常模式

TPYBoard v10x退出CDC+HID模式的方法有两个,一个是进入安全模式,将boot.py文件的pyb.usb_mode('CDC+HID')注释掉,另一种是恢复出厂设置,这种方法是按住usr键,按一下rst,然后led2和led3交替亮,当两个灯交替亮到三次,且均亮起时,松开usr,两个灯会快闪多次,然后TPYBoard v10x恢复到出厂设置,此时main.py里的内容也都清空了。

[Micropython]TPYBoard v102 DIY照相机

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

所需元器件
  • TPYBoard v102板子 1块
  • PTC06 串口摄像头模块1个
  • 杜邦线 若干
  • 5110显示屏1个
  • 按键模块2个
  • USB数据线1条
什么是摄像头模块
PTC06 串口摄像头模块简介

PTC06 串口摄像头模块是一款集图像采集、拍摄控制、数据压缩、串口传输于一体的图像采集 处理模块。其内置的高性能数字信号处理芯片实现了对原始图像的高比例压缩。产品图像输 出采用标准 JPEG 格式,方便地兼容各种图像处理软件;采用 3 线制TTL 电平 UART 通 信接口,可以方便地实现与单片机或其他微处理器连接。默认波特率为 115200,其它可选波特率有9600,19200,38400 和 57600。 其中对于串口控制拍照,读取静态图片的应用中,只需要用到 GND,RX,TX,VCC 这4 个信号线。 如果是要输出模拟视频的应用,才需要将 CVBS 信号。 注意: TX 和 RX 是 3.3v 的 TTL 电平信号。

硬件的接线方法
TPYBoard v102 --摄像头模块

VIN ----------------5V

GND ------------ - GND

X1(UART 4 TX)------ RX

X2(UART 4 RX) ------TX

TPYBoard v102------按键模块黑色(复位键)

3.3V----------------GND

GND-----------------VCC

RST-----------------OUT

TPYBoard v102---------按键模块黄色(拍摄键)

GND-------------------VCC

3.3V------------------GND

X17-------------------OUT

TPYBoard v102---------5110显示屏

Y12-------------------RST

Y11-------------------CE

Y10-------------------DC

Y9--------------------LIGHT

Y8--------------------DIN

Y6--------------------CLK

3.3V------------------VIN

GND-------------------GND

接线图 _images/qoq.png
实物接线图

此时所有器件已连接完毕,只需要给我们核心板TPYBoard v102 编写代码,并 导入fond.py 和upcd8544.py就可以运行了。

源代码
import pyb
from pyb importUART,Switch
import upcd8544

#-----command---------#
initcmd=b'\x56\x00\x26\x00'#复位
clearcmd=b'\x56\x00\x36\x01\x02'#清除缓存
photocmd=b'\x56\x00\x36\x01\x00'#拍照
lengthcmd=b'\x56\x00\x34\x01\x00'#获取图片长度
readcmd=b'\x56\x00\x32\x0C\x00\x0A\x00\x00'#获取图片数据
responseCmd=b'\x76\x00\x32\x00\x00'#返回的图片数据固定头和尾
#---------------------------------#
isFlag=0#标识是否初始化
isPhoto=0#标识是否发送拍照命令
num=0
f_name='/sd/photo%s.jpeg'
nBytes=2048#每次读取的字节数
#---------------------------------#
uart=UART(4,115200,timeout=100)#X1(UART4 TX) X2(UART 4 RX)
#-------十进制转16进制------------#
defconvert_Data(num):
   if num>255:
           num_h=hex(num)
           if len(num_h)<6:
                   num_h_a=num_h[:3]
                   num_h_b='0x'+num_h[3:]
           else:
                   num_h_a=num_h[:4]
                   num_h_b='0x'+num_h[4:]
          byte_num=bytes([int(num_h_a,16),int(num_h_b,16)])
   else:
           byte_num=b'\x00'+bytes([num])
   return byte_num
defget_photo(add,readlen):
   global readcmd,responseCmd

  cmd=readcmd+add+b'\x00\x00'+readlen+b'\x00\xFF'
   uart.write(cmd)
   while uart.any()<=0:
           continue
   data=uart.read()
   #print('data:',data)
   #print('data[0:5]:',data[0:5])
   #print('data[-5:]:',data[-5:])
   if data[0:5]==responseCmd anddata[-5:]==responseCmd:
           revdata=data[5:-5]
           print('revdata:',revdata)
   else:
           revdata=0
   return revdata
def test():
   global num,isPhoto
   pyb.delay(30)
   if(sw()):
           sw.callback(None)
           isPhoto=0
           num+=1
           pyb.LED(3).on()
           #清除缓存
           uart.write(clearcmd)
#-------LCD5110Init-----------#
SPI    = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
RST    = pyb.Pin('Y12')
CE     = pyb.Pin('Y11')
DC     = pyb.Pin('Y10')
LIGHT  = pyb.Pin('Y9')
lcd_5110 =upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
lcd_5110.lcd_write_bmp()
#------------------------------#
print('wait......')
pyb.delay(2800)
print('initstart.......')
uart.write(initcmd)
sw=Switch()
sw.callback(test)
while True:
   if uart.any()>0:
           data=uart.read()
           print('revdata:',data)
           if isFlag==0:
                   #说明接收的是复位后的信息
                   if data==b'Init end\r\n':
                           #复位完毕
                           print('init ok.......')
                           pyb.delay(2000)
                           isFlag=1
                           pyb.LED(2).on()
                           lcd_5110.lcd_write_bmp(0)
           else:
                   if len(data)>=5:
                           if data[0]==118:#0x76
                                   if data[2]==54:#0x36
                                           if isPhoto==0:
                                                   #清除缓存返回
                                                   print('-----clearbuffer ok----')
                                                   isPhoto=1
                                                  uart.write(photocmd)
                                                   lcd_5110.clear()
                                                  lcd_5110.lcd_write_bmp(1)
                                           else:
                                                   #拍照返回
                                                   print('-----takingpictures ok----')
                                                  uart.write(lengthcmd)
                                   if data[2]==52:#0x34
                                           print('photolength:',data[7],'-',data[8])
                                          tlen=data[7]*256+data[8]
                                           t_c=tlen//nBytes
                                           t_y=tlen%nBytes
                                           add=0
                                           #256=[0x01,0x00]512=[0x02,0x00]
                                          length=convert_Data(nBytes)
                                           name=f_name % str(num)
                                           print('filename:',name)
                                           offset=0
                                           for i in range(0,t_c):
                                                   offset_a=i//4
                                                   ifoffset<offset_a:
                                                           offset=offset_a
                                                           lcd_5110.clear()
                                                          lcd_5110.lcd_write_bmp(1,offset)
                                                  add=convert_Data(i*nBytes)
                                                  revdata=get_photo(add,length)
                                                   if revdata!=0:
                                                          f=open(name,'a')
                                                          f.write(revdata)
                                                           f.close()
                                                   pyb.LED(4).toggle()
                                                   print('-------------',i)
                                                   pyb.delay(100)
                                          add=convert_Data(t_c*nBytes)
                                          revdata=get_photo(add,convert_Data(t_y))
                                           if revdata!=0:
                                                   f=open(name,'a')
                                                   f.write(revdata)
                                                   f.close()
                                           pyb.LED(3).off()
                                           pyb.LED(4).off()
                                           pyb.delay(100)
                                           print('*========================================*')
                                           lcd_5110.clear()
                                          lcd_5110.lcd_write_bmp(2)
                                           sw.callback(test)
                   else:
                           print('-----data lengtherror-----')
[Micropython]TPYBoard v102 控制LCD5110显示温度时间(中文版)

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法
  • 什么是SPI接口
  • 学习TPYBoard I2C接口的用法
  • 学习LCD5110接线方
  • DS3231的接线方法
  • 16*16汉字显示温度与当前时间
所需元器件
  • DS3231模块 1个
  • TPYBoard v102板子 1块
  • LCD5110显示屏 1个
  • micro USB数据线 1条
  • 杜邦线 若干
TPYBoard v102的SPI接口

LCD5110需要SPI接口与TPYBoard v102进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输。TPYBoard v102有两个SPI接口,本次使用SPI1接口。

http://old.tpyboard.com/ueditor/php/upload/image/20161229/1482973399550325.png
TPYBoard v102的I2C接口

DS3231是I2C接口通信的,它通过I2C接口与TPYBoard v102进行数据通讯,DS3231通过这个接口与TPYBoard v102进行双向通讯,进行数据传输。TPYBoard有两个I2C接口,本次使用I2C1接口。

http://old.tpyboard.com/ueditor/php/upload/image/20161229/1482973431559379.png
DS3231的使用方法
http://tpyboard.com/ueditor/php/upload/image/20161229/1482973477928543.png

本次教程使用DS3231的SCL,SDA,VCC,GND四个针脚进行时间的读取和设定,接线方式如下:

TPYBoard DS3231
X9 SCL
X10 SDA
3.3V VCC
GND GND
LCD5110显示屏的使用方法

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

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
3.3V Vcc Vcc
X4 LIGHT Light (0=on, 1=off)
GND GND GND

接线OK后,将font.py、upcd8544.py、chinsese.py和DS3231.py复制到TPYBoard v102加载的可移动磁盘中,然后编写main.py并保存。 等待保存完毕后,重启TPYBoard v102后(等待红灯(LED1)熄灭后,再进行重启操作),当前温度与时间会显示在LCD5110显示屏上,见下图:

http://old.tpyboard.com/ueditor/php/upload/image/20161229/1482973647210289.png
main.py源代码
# 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()
[Micropython]TPYBoard v102 红外防坠落小车

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

引言

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

http://old.tpyboard.com/ueditor/php/upload/image/20161104/1478249731266844.png

查看视频

实验目的
研究智能小车结合红外探头寻迹前进。
实验材料
  • TPYBoard开发板1块(能跑python语言的开发板,小车的大脑)
  • 四路红外感应探头(小车的眼睛)
  • 数据线一根
  • 充电宝一个(给整个系统供电)
  • 智能小车底盘(包括驱动模块)
  • 杜邦线若干
TPYBoard v102开发板
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电机驱动模块,使用方法很简单,不多做介绍。
寻迹原理
红外探头的安装
小车寻迹的原理其实就光的吸收,反射和散射。在小车的前端有安装孔,使用螺丝把红外传感器固定在安装孔上。保持发射端和接收端都保持竖直向下。
返回信号的判断
在上面已经说了,红外探头在检测到物体存在的时候,在OUT端会持续的输出低电平。那么调节调距电阻,调节到一个适合的检测距离。在小车行驶路面检测到物体的时候,说明是前面是有路的,不是悬空的。那么小车 保持直行。如果前方检测到没有返回,没返回说明没有检测到物体,妈就说明前面是没有路的,是悬空的,那么小车就先进行后退,在进行右转(也可以左转,也可以一次右转一次左转,这个比较随意。)。
硬件接线

接线其实很简单四路红外探头接线很简单,虽然有十八根线,但是有十二根是三根三根的分成四组的,对应着很好接线,剩下的六根,VCC和GND不多说了,还有四根是直接接到单片结IO口上就可以的。L298N的接线更简单了,这里不多介绍。 上个简单的帮助理解的原理图 (其实我们做实验都是插线,不做PCB图和原理图的)。

http://tpyboard.com/ueditor/php/upload/image/20161104/1478249487231057.png

再上个实物图给大家看看

http://tpyboard.com/ueditor/php/upload/image/20161104/1478249515240750.jpg
运行与调试

制作完成后,剩下的就是该调试了,调试中应该注意细节和小车稳定性的优化。

代码编写

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

源代码:

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]TPYBoard v10x 红外寻迹无线小车
版权声明:翻译整理属于TPYBoard,转载时请以超链接形式标明文章原始出处和作者信息及本声明
引言

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

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

http://old.tpyboard.com/ueditor/php/upload/image/20161031/1477877141332316.png

查看视频

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

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

实验目的

研究智能小车结合红外探头寻迹前进。

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

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

TPYBoard v102开发板

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电机驱动模块,使用方法很简单,不多做介绍。

寻迹原理

红外探头的安装

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

返回信号的判断

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

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

硬件接线

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

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

http://old.tpyboard.com/ueditor/php/upload/image/20161029/1477732081757742.png

再上个实物图给大家看看。

http://old.tpyboard.com/ueditor/php/upload/image/20161031/1477877362324105.jpg
运行与调试

制作完成后,剩下的就是该调试了,调试中应该注意细节和小车稳定性的优化。

代码编写

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

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)
[Micropython]TPYBoard v102 无线蓝牙智能小车

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习蓝牙模块的接线方法及其工作原理。
  • 学习 L298N电机驱动板模块的接线方法。
  • 学习蓝牙控制小车的工作原理。
所需元器件
  • TPYBoard v102板子 1块
  • 蓝牙串口透传模块(HC-06) 1个
  • L298N电机驱动板模块 1个
  • 智能小车底盘 1个
  • 数据线 1条
  • 杜邦线 若干
http://www.tpyboard.com/ueditor/php/upload/image/20161215/1481791277901030.jpg
蓝牙串口模块原理

(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
学习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,给TPYBoard通电就ok了,下面是源代码。

源代码
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 , timeout = 100)

while True:
        pyb.LED(2).on()
        pyb.LED(3).on()
        pyb.LED(4).on()
        _dataRead=u2.read()
        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 v102 加速度无线小车

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

引言

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

所有器材
  • TPYBoard v102开发板 2块
  • 小车底盘 1个
  • LORA无线模块 1块
  • 充电宝 1个
  • 9014三极管两个(为什么用到它呢,后面再说)

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

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

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

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

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

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

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

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

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

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

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

控制器

http://tpyboard.com/ueditor/php/upload/image/20160815/1471255048558130.png

被控制端

http://tpyboard.com/ueditor/php/upload/image/20160815/1471255085467193.png

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

成品图:

http://old.tpyboard.com/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,timeout=100)
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')
            print('\x00\x01\x18YOU')
        elif x < -10:
            xlights[1].on()
            xlights[0].off()
            u2.write('\x00\x05\x18ZUO')
            print('\x00\x01\x18ZUO')

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

        y = accel.y()
        print("y=")
        print(y)
        if y > 15:
            ylights[0].on()
            ylights[1].off()
        elif y < -15:
            ylights[1].on()
            ylights[0].off()
            u2.write('\x00\x05\x18QIAN')
            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,timeout = 100)
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]TPYBoard v102 线程与锁

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

线程的介绍

线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

在micropython官方网站的 DOWNLOAD 下载页中,pyboard的固件中有一个"threading"版本的固件,里面包含了_thread模块允许多线程操作。

线程的使用

接下来为大家演示一下,在micropython的平台上如何实现多线程的操作。

  • 烧写threading版本的固件

    本次我用的是TPYBoard v102(蓝色版),所以烧写的是PYBv1.0版本的,简约版的也是这个版本。如果是TPYBoard v102(黑色版),就要烧写PYBv1.1版本的了。

  • <_thread>模块的了解

    我用Putty连接TPYBoard v102,先大体了解一下_thread模块。

import _thread
help(_thread)
help(_thread.LockType)
_images/thread_1.png
  • 源代码
# main.py -- put your code here!
import _thread
import time

lock=_thread.allocate_lock()

def myThread_A():
    print('我是 thread A-')
    _thread.exit()


def myThread_B(time_):
    time.sleep(time_)
    print('我是 thread B-')
    print('我是 thread B- Sleep 5s')
    time.sleep(5)
    print('我是 thread B-Wake up')
    _thread.exit()

def myThread_C(time_):
    time.sleep(time_)
    print('我是 thread C-')
    _thread.exit()

_thread.start_new_thread(myThread_A, ())
_thread.start_new_thread(myThread_B, (2,))
_thread.start_new_thread(myThread_C, (3,))

while True:
    pass
  • 效果图
_images/thread_2.png
多线程中锁的使用

多线程同时运行时,是共享内存、共享数据和资源的,当你需要独占某一个资源时,你就可以使用锁来把这个资源锁住,只有等你释放打开这个锁后,其它线程才能使用。

  • 源代码
# main.py -- put your code here!
import _thread
import time

lock=_thread.allocate_lock()

def myThread_A():
    print('我是 thread A-')
    _thread.exit()


def myThread_B(time_):
    time.sleep(time_)
    if lock.acquire():#锁住资源
        print('我是 thread B-')
        print('我是 thread B- Sleep 5s')
        time.sleep(5)
        print('我是 thread B-Wake up')
        lock.release()#打开锁 释放资源
    _thread.exit()

def myThread_C(time_):
    time.sleep(time_)
    if lock.acquire():#B先抢到了资源 需等待B释放后才能占有
        print('我是 thread C-')
        lock.release()
    _thread.exit()

_thread.start_new_thread(myThread_A, ())
_thread.start_new_thread(myThread_B, (2,))
_thread.start_new_thread(myThread_C, (3,))

while True:
    pass
  • 效果图
_images/thread_3.png
[Micropython]TPYBoard v102 读取芯片上的温度传感器
TPYBoard读取芯片上的温度传感器
STM32内部温度传感器概要

STM32 芯片内部一项独特的功能就是内部集成了一个温度传感器, 因为是内置, 所以测试的是芯片内部的温度, 如果芯片外接负载一定的情况下, 那么芯片的发热也基本稳定, 相对于外界的温度而言, 这个偏差值也是基本稳定的. 也就是说用 STM32 内部传感器来测量外界环境的温度。 在一些恶劣的应用环境下面, 可以通过检测芯片内部而感知设备的工作环境温度, 如果温度过高或者过低了 则马上睡眠或者停止运转. 可以保证您的设备工作的可靠性。

STM32内部温度传感器参数
    1. STM32内部温度传感器与ADC的通道16相连,与ADC配合使用实现温度测量。
  • 2.测量范围–40~125℃,精度±1.5℃。
  • 3.温度传感器产生一个随温度线性变化的电压,转换范围在2V < VDDA < 3.6V之间。转换公式如下图所示:
_images/test_211.png

手册中对于公式中的参数说明:

_images/test_221.png
读取温度的实现原理

写代码的时候, 在测量要求不怎么高的情况下, 公式可以简化。简化的公式:

Temperature= (1.42 - ADC_Value*3.3/4096)*1000/4.35 + 25

程序编写:

    1. 初始化ADC , 初始化DMA

      注意:内部温度传感器是使用了 ADC1 的第 16 通道哦.

    1. ADC_TempSensorVrefintCmd(ENABLE);

      使能温度传感器和内部参考电压通道

    1. 按照刚才列出的公式计算

      Temperature= (1.42 - ADC_Value*3.3/4096)*1000/4.35 + 25;

_images/test_231.png
TPYBoard读取温度例程

main:

# main.py -- put your code here!
import pyb
import time
import stm
from pyb import Pin

def adcread(chan):                              # 16 temp 17 vbat 18 vref
        assert chan >= 16 and chan <= 18, 'Invalid ADC channel'
        start = pyb.millis()
        timeout = 100
        stm.mem32[stm.RCC + stm.RCC_APB2ENR] |= 0x100 # enable ADC1 clock.0x4100
        stm.mem32[stm.ADC1 + stm.ADC_CR2] = 1       # Turn on ADC
        stm.mem32[stm.ADC1 + stm.ADC_CR1] = 0       # 12 bit
        if chan == 17:
                stm.mem32[stm.ADC1 + stm.ADC_SMPR1] = 0x200000 # 15 cycles
                stm.mem32[stm.ADC + 4] = 1 << 23
        elif chan == 18:
                stm.mem32[stm.ADC1 + stm.ADC_SMPR1] = 0x1000000
                stm.mem32[stm.ADC + 4] = 0xc00000
        else:
                stm.mem32[stm.ADC1 + stm.ADC_SMPR1] = 0x40000
                stm.mem32[stm.ADC + 4] = 1 << 23
        stm.mem32[stm.ADC1 + stm.ADC_SQR3] = chan
        stm.mem32[stm.ADC1 + stm.ADC_CR2] = 1 | (1 << 30) | (1 << 10) # start conversion
        while not stm.mem32[stm.ADC1 + stm.ADC_SR] & 2: # wait for EOC
                if pyb.elapsed_millis(start) > timeout:
                        raise OSError('ADC timout')
        data = stm.mem32[stm.ADC1 + stm.ADC_DR]     # clear down EOC
        stm.mem32[stm.ADC1 + stm.ADC_CR2] = 0       # Turn off ADC
        return data

def v33():
        return 4096 * 1.21 / adcread(17)

def vbat():
        return  1.21 * 2 * adcread(18) / adcread(17)  # 2:1 divider on Vbat channel

def vref():
        return 3.3 * adcread(17) / 4096

def temperature():
        return 25 + 400 * (3.3 * adcread(16) / 4096 - 0.76)

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

sw=pyb.Switch()
def test():
        pyb.LED(1).on()
        pyb.LED(2).on()
        pyb.LED(3).on()
        pyb.LED(4).on()
        pyb.delay(2000)
sw.callback(test)

for l in leds:
        l.off()

n = 0

try:
   while True:
          n = (n + 1) % 4
          leds[n].toggle()
          pyb.delay(50)
          print('v33:',v33())
          print('vbat:',vbat())
          print('vref:',vref())
          print('temperature:',temperature())
finally:
        for l in leds:
                l.off()
[Micropython]TPYBoard v10x 智能蓝牙+红外循迹小车

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习蓝牙模块的接线方法及其工作原理。
  • 学习 L298N电机驱动板模块的接线方法。
  • 学习蓝牙控制小车的工作原理。
所需元器件
  • TPYBoard v102板子 1块
  • 蓝牙串口透传模块(HC-06) 1个
  • L298N电机驱动板模块 1个
  • 智能小车底盘 1个
  • 数据线 1条
  • 杜邦线 若干
  • 智能蓝牙小车APP(Android版) 点击下载
_images/car.png
蓝牙串口模块原理
http://www.tpyboard.com/ueditor/php/upload/image/20161215/1481791173622577.png

(1)引出接口包括EN,5V,GND,TX,RX,STATE,我们小车只用到RX,TX,GND,5V四个针脚

(2)模块默认波特率位9600,默认配对密码为1234,默认名称位为HC-06

(3)led指示蓝牙连接状态,闪烁表示没有蓝牙连接,常亮表示蓝牙已连接并打开了端口,当我们用安卓手机软件发送指令时,通过串口给TPYBoard发送指令,TPYBoard收到指令通过L298BN模块来驱动小车前进,后退,向左,向右或者停止。

如下表接线:

蓝牙模块(HC-06) TPYBoardv10x
5V VIN(+5V)
GND GND
RX Y9(UART(3)-TX)
TX Y10(UART(3)-RX)
四路红外循迹模块
_images/red.jpg

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

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

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

(4)比较器采用LM339,工作稳定。

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

四路红外感应探头的安装

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

判断反馈的信号

如果要是正前方的探头接收不到光,那么说明小车此时走在黑色的寻迹带上。可以使小车直线行走。如果左面的探头接收不到光,那么说明小车左面出现了黑色寻迹带,此时小车应该执行左转弯。右转弯同左转弯原理。 如果要是小车前面,左面,右面三个方向全都接收不到光,或者是两个方向上的探头都接收不到光,到底是左转弯,右转弯还是继续直行,这个就要看你自己在程序里怎么做判断了。

探头的安装与接线

四路红外探头接线很简单,虽然有十八根线,但是有十二根是三根三根的分成四组,一一对应接线,其余的六根,是VCC和GND。还有四根是接到TPYBoard v10x开发板的IO口上的,用于接收四路红外循迹模块反馈的信号。

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

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

N1 = Pin('X1', Pin.OUT_PP)
N2 = Pin('X2', Pin.OUT_PP)
N3 = Pin('X3', Pin.OUT_PP)
N4 = Pin('X4', Pin.OUT_PP)

M1 = Pin('Y1', Pin.IN)
M2 = Pin('Y2', Pin.IN)
M3 = Pin('Y3', Pin.IN)
M4 = Pin('Y4', Pin.IN)

blue=UART(3,9600)
mode='1'#1:表示蓝牙模式 2:循迹模式

def Stop():
    N1.low()
    N2.low()
    N3.low()
    N4.low()
def Back():
    N1.high()
    N2.low()
    N3.high()
    N4.low()
def Go():
    N1.low()
    N2.high()
    N3.low()
    N4.high()
def Left():
    N1.high()
    N2.low()
    N3.low()
    N4.high()
def Right():
    N1.low()
    N2.high()
    N3.high()
    N4.low()
while True:
    if blue.any()>0:
        data=blue.read().decode()
        print(data)
        if data.find('0')>-1:
            #stop
            Stop()
            mode="1"
            print('stop')
        if data.find('1')>-1:
            Go()
            print('go')
        if data.find('2')>-1:
            Back()
            pyb.delay(500)
            Stop()
        if data.find('3')>-1:
            Left()
            pyb.delay(250)
            Stop()
        if data.find('4')>-1:
            Right()
            pyb.delay(250)
            Stop()
        if data.find('5')>-1:
            mode="1"
            Stop()
        if data.find('6')>-1:
            mode="2"
    else:
        if mode=="2":
            print('循迹模式')
            if(M1.value() and M2.value() and M3.value()):
                Stop()
                mode="1"
            if(M2.value() or M3.value()):
                pyb.LED(2).on()
                pyb.LED(3).off()
                pyb.LED(4).off()
                Go()
            if M1.value():
                pyb.LED(3).on()
                pyb.LED(2).off()
                pyb.LED(4).off()
                Right()
                pyb.delay(10)
            if M4.value():
                pyb.LED(4).on()
                pyb.LED(2).off()
                pyb.LED(3).off()
                Left()
                pyb.delay(10)
智能蓝牙小车APP的使用

下载安装后,打开[蓝牙智能小车]APP,进入操作界面。如下:

_images/11.png

点击左下角的桃心图标,进入自定义编码界面。通过这个界面,我们可以自定义操作界面中各个按键发出去的指令内容。如下:

_images/02.png

点击页面下方的关于我们,可以加入我们的技术交流群和关注微信公众号。如下:

_images/31.png

接下来,回到一开始的操作界面,点击右下角的设置图标,进行蓝牙模块的连接。首先先点击[搜索蓝牙设备],界面会自动加载搜索到的蓝牙设备,当出现HC-06时,点击进行连接。

_images/41.png

如果是第一次连接,需要进行配对,配对的密码默认1234。

_images/5.png

提示连接成功后,我们就可以通过四个方向键来操纵智能蓝牙小车了。

大家可以看到,右上角的图标,可以进行蓝牙模式和循迹模式的切换。当按下时,两种模式来回切换。当处于循迹模式时,界面如下。

_images/6.png
[Micropython]TPYBoard v102 结合ESP8266模块实现TCP通信

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

实验目的
  • 学习ESP8266模块(ESP-01)的使用。
  • 进一步学习TPYBoardv10x中UART模块的使用。
  • 结合ESP-01模块完成局域网内的TCP通信实验。
所需元器件
  • ESP-01 WIFI模块 1个
  • TPYBoard v102板子 1块
  • USB转TTL 1个
  • micro USB数据线 1条
  • 杜邦线 若干

本实验采用TPYBoardv102串口AT指令的方式,去连接控制ESP8266模块(型号ESP-01)。

第一步:烧写AT指令的固件

下载AT指令相应固件

这里我下载了一个AiCloud 2.0 AT (512+512map)版本的,版本号:v0.0.0.6。 点击下载

安信可科技关于ESP8266相关模组的资料地址。点击进入

AT指令固件其他版本下载。点击下载

下载烧写工具ESPFlashDownloadTool

点击下载

硬件连接

ESP-01模块的引脚图:

_images/pin.jpg _images/pin1.jpg

烧写固件还需用到USB转TTL,ESP-01模最好使用其他外部器件进行供电。这里,我用的TPYBoardv102开发板。但是,别忘记了开发板与TTL之间需要共地。

接线图:

ESP-01模块 TPYBoard v102 USB TO TTL
VCC 3V3 --
GND GND --
CH_PD 3V3 --
-- GND GND
TXD -- RX
RXD -- TX
GPIO 2 悬空 --
GPIO 0 GND --
GND GND --

开始烧写

USB转TTL插上电脑,设备管理器查看端口号。

_images/12.png

打开ESPFlashDownloadTool工具,选择【ESP8266 DownloadTool】。

_images/2.png

我这里下载的是合成的固件,所以地址直接设置为0x00000,其他设置参考如下:

_images/32.png

选择好端口,点击【START】开始烧写。

_images/42.png

出现等待上电同步,这时给ESP-01模块上电,或者复位一下,等待下载成功。

_images/51.png _images/61.png
测试AT指令

烧写固件完成之后,将GPIO 0 连接的线拔掉,使其悬空,ESP-01模块会进入正常模式。 打开串口助手工具 点击下载 ,默认波特率115200。 ESP-01模块启动时,会输出一堆乱码。(其实不是乱码,是一些内部信息)如下:

_images/7-00.png

出现乱码的原因,如下:

_images/7-0.png

输出的内部信息,我们可以忽略掉,只要输出ready,就说明模块一切正常。

进入AT指令模式

AT指令说明文档、AT固件、烧写工具。点击下载

发送指令:AT

(注意:后面需跟一个回车换行,选择在工具中勾选加回车换行) 模块返回AT\r\nOK,说明模块已经成功进入AT指令模式。

_images/7.png

查询固件版本

发送指令:AT+GMR

_images/8.png
第三步:局域网TCP通信测试

1、首先,让ESP-01接入我们的路由器。

_images/9.png
AT指令 功能
AT+CWMODE_CUR?
查询当前WIFI模式
1 : station 模式 2 : softAP 模式 3 : softAP+station 模式
AT+CWMODE_CUR=1 设置WIFI为station 模式
AT+CWJAP_CUR="essid","password" 连接AP

2、接下来,我们做一个局域网内TCP通信的测试。本地用网络调试助手建立一个TCP Server如下:

_images/10.png

ESP-01作为TCP Client连接Server。发送指令AT+CIPSTART="TCP","192.168.101.116",80

_images/111.png

TCP链接建立,开始发送数据。单路链接时发送指令为AT+CIPSEND=x,x为发送的字节数。出现符号">"后就可以发送数据了。

_images/121.png

模块会把收到的数据自动通过串口透传过来。

_images/13.png

以上,我们都是结合USB转TTL实现的AT指令转发。接下来,我们通过TPYBoardv102开发板实现上面的功能。

接线图:

ESP-01模块 TPYBoard v102
VCC 3V3
GND GND
CH_PD 3V3
GPIO 0 悬空
GPIO 2 悬空
TXD X2(UART 4 )
RXD X1(UART 4 )

程序源码:

from pyb import UART
from pyb import LED

#等待ESP-01模块初始化,忽略启动时的内部信息
pyb.delay(1000)

ESP_UART = UART(4,115200,timeout=100)

def sendToUart(msg):
        ESP_UART.write(msg+'\r\n')

CWMODE_CUR = 'AT+CWMODE_CUR=1'
CWJAP_CUR = 'AT+CWJAP_CUR="TurnipSmart","turnip2016"'
CIPSTART = 'AT+CIPSTART="TCP","192.168.1.116",80'
CIPSEND = 'AT+CIPSEND=%s'
msg = 'Hello,I am TPYBoard.'

if __name__  == '__main__':
        sendToUart('AT')
        while True:
                if ESP_UART.any()  > 0:
                        buf = ESP_UART.read().decode().replace('\r','').replace('\n','').replace(' ','')
                        print(buf)
                        if buf.find('busyp') > -1 or buf.find('ERROR') > -1:
                                # AT指令执行失败
                                # 结束程序排查原因
                                break
                        elif buf.find('ATOK') > -1:
                                # 说明AT指令执行成功
                                # 成功进入AT指令模式
                                # 设置WIFI模式为sta模块
                                sendToUart(CWMODE_CUR)
                        elif buf.find(CWMODE_CUR) > -1:
                                # 设置sta模式成功,连接AP
                                sendToUart(CWJAP_CUR)
                                LED(1).on()
                        elif buf.find('WIFIGOTIP') > -1:
                                # 连接AP成功
                                # 开始连接TCP Server
                                pyb.delay(150)
                                sendToUart(CIPSTART)
                                LED(2).on()
                        elif buf.find(CIPSTART) > -1:
                                # 连接TCP Server成功,发送数据
                                CIPSEND = CIPSEND % str(len(msg))
                                sendToUart(CIPSEND)
                                LED(3).on()
                        elif buf.find('>') > -1:
                                # 发送数据
                                sendToUart(msg)
                                LED(4).on()
_images/14.png

注意:ESP-01模块上电启动时电流比较大,会导致板子的REPL无反应。关闭putty等工具,按板子的RST复位一下,再连接就好。最好方式采用外部电源给ESP-01模块供电,注意要与板子共地。

综上,TCP的测试实验完毕。本实验只是做了一些简单的示例,大家可根据自己的想法结合文档开发出更有意思的作品,比如智能控制开关、智能WIFI小车等。

[Micropython]TPYBoard v102 结合ESP8266模块实现HTTP请求实例

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

实验目的
  • 学习ESP8266模块(ESP-01)的使用。
  • 进一步学习TPYBoardv10x中UART模块的使用。
  • 结合ESP-01模块完成HTTP请求实例。
所需元器件
  • ESP-01 WIFI模块 1个
  • TPYBoard v102板子 1块
  • USB转TTL 1个
  • micro USB数据线 1条
  • 杜邦线 若干

上一篇文档《TPYBoard v10x 结合ESP8266模块实现TCP通信》中,实现了局域网中的TCP通信。本次,我们来实现简单的HTTP请求。

1、硬件连接

ESP-01模块的引脚图:

_images/pin.jpg
ESP-01模块 TPYBoard v102
VCC 3V3
GND GND
CH_PD 3V3
GPIO 0 悬空
GPIO 2 悬空
TXD X2(UART 4 )
RXD X1(UART 4 )
2、程序编写

ESP8266使用AT指令开发示例:点击进入

打开上面的AT指令开发示例,查看【二. HTTP通信示例】。根据上面的示例,完成HTTP请求的实验。

2.1 发送GET请求

程序如下:

from pyb import UART
from pyb import LED

#等待ESP-01模块初始化,忽略启动时的内部信息
pyb.delay(1000)

ESP_UART = UART(4,115200,timeout=100)

def sendToUart(msg):
        ESP_UART.write(msg+'\r\n')

CWMODE_CUR = 'AT+CWMODE_CUR=1'
CWJAP_CUR = 'AT+CWJAP_CUR="TurnipSmart","turnip2016"'
CIPSTART = 'AT+CIPSTART="TCP","183.230.40.33",80'
CIPSEND = 'AT+CIPSEND=%s'

post = """POST /devices/5835707/datapoints HTTP/1.1
api-key: xUrvOCDB=iRuS5noq9FsKrvoW=s=
Host:api.heclouds.com
Content-Length:60\r\n
{"datastreams":[{"id":"switch","datapoints":[{"value":1}]}]}
"""
if __name__  == '__main__':
        #退出透传
        ESP_UART.write('+++')
        pyb.delay(500)
        sendToUart('AT')
        isConn = 0
        while True:
                if ESP_UART.any()  > 0:
                        buf = ESP_UART.read().decode().replace('\r','').replace('\n','').replace(' ','')
                        print(buf)
                        pyb.delay(200)
                        if buf.find('busyp') > -1 or buf.find('ERROR') > -1:
                                # AT指令执行失败
                                # 结束程序排查原因
                                break
                        elif buf.find('ATOK') > -1:
                                # 说明AT指令执行成功
                                #if 'ATOK' in buf:
                                # 成功进入AT指令模式
                                # 设置WIFI模式
                                sendToUart(CWMODE_CUR)
                        elif buf.find(CWMODE_CUR) > -1:
                                # 设置sta模式成功,连接AP
                                sendToUart(CWJAP_CUR)
                                LED(1).on()
                        elif buf.find(CWJAP_CUR) > -1:
                                isConn = 1
                        elif buf.find('OK') > -1 and isConn:
                                # 连接AP成功
                                # 连接TCP Server
                                sendToUart(CIPSTART)
                                LED(2).on()
                                isConn = 0
                        elif buf.find('WIFIGOTIP') > -1:
                                # 连接AP成功
                                # 连接TCP Server
                                sendToUart(CIPSTART)
                                LED(2).on()
                        elif buf.find('CONNECTOK') > -1:
                                # 连接TCP Server成功,发送数据
                                LED(3).on()
                                sendToUart('AT+CIPMODE=1')#透传
                        elif buf.find('AT+CIPMODE=1') > -1:
                                sendToUart('AT+CIPSEND')#启动传输
                        elif buf.find('>') > -1:
                                # 发送数据
                                sendToUart(get)
                                LED(4).on()
                        elif buf.find('HTTP') > -1:
                                #退出透传
                                ESP_UART.write('+++')
                                pyb.delay(500)
                                break

实现效果:

_images/15.png
2.2 发送POST请求

主要就是增加了一个post请求的字符串,具体内容如下:

post = """POST /devices/5835707/datapoints HTTP/1.1
api-key: xUrvOCDB=iRuS5noq9FsKrvoW=s=
Host:api.heclouds.com
Content-Length:60\r\n
{"datastreams":[{"id":"switch","datapoints":[{"value":1}]}]}
"""

实现效果:

_images/15.png
[MicroPython]TPYBoard v102 制作表白女神神器(基于MAX7219点阵模块)

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

前言

又是一年毕业季,只有到了毕业季才会意识到自己又离青春远了一大步。毕业后,大家都各奔东西了,如果这个时候有喜欢的人还是藏在心底的话,不免会给人生留下遗憾。为了不留遗憾,不老套,制作一款表白神器,是不是会更容易表白成功呢?前面使用8*8LED点阵模块做过一款跳动的心,因为是直接用的点阵模块,所以控制就用了16个IO,未免有些繁琐,浪费资源。最近发现了一个好东西——MAX7219多位LED 显示驱动器。使用该驱动器加上点阵屏或者数码管,驱动起来特别方便简单,而且加上电源脚也不过就5根线而已。

MAX7219介绍

MAX7219 是美国MAXIM 公司推出的多位LED 显示驱动器,采用3 线串行接口传送数据,可直接与单片机接口连接,用户能方便修改其内部参数,以实现多位LED 显示。它内含硬件动态扫描电路、BCD译码器、段驱动器和位驱动器。此外,其内部还含有8X8 位静态RAM,用于存放8个数字的显示数据。显然,它可直接驱动64 段LED点阵显示器。当多片MAX7219 级联时,可控制更多的LED点阵显示器。显示的数据通过单片机数据处理后,送给MAX7219 显示。

引脚图:

_images/引脚图.jpg

当然了,直接拿到这个驱动器一时也不知道该怎么用,于是就直接买了现成的MAX7219驱动器结合8*8LED点阵屏模块。

_images/实物图.jpg _images/反面.jpg

看反面图可以看出,该模块不仅有DIN输入端口还有DOUT输出端口,用于多个模块级联。使用的单个模块时,开发板只接入模块的输入端口即可;当多个模块级联时,第一个模块的输出端口接第二个模块的输入端口,第二个输出端口接第三个输入端口,依次类推。

制作过程

话不多说了,马上动手实践起来。接线很简单,见下表:

TPYBoard v102 MAX7219点阵模块
VIN VIN
GND GND
X3 DIN
X2 CS
X1 CLK

源码呈上

主程序 main.py。

import MAX7219 #导入模块

#CLK -> X1,CS -> X2,DIN -> X3
#num级联的模块数量
led = MAX7219.Lattice('X1','X2','X3',num=1)
#要显示的内容,显示的内容根据字库文件而定,见font_max7219.py。
#大家也可以自定义图案添加上。
msg = 'LOVE大小'

while True:
    #显示
    led.display(msg)

字库文件 font_max7219.py。

FONT8_8= {
'0':[0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C],#0
'1':[0x10,0x18,0x14,0x10,0x10,0x10,0x10,0x10],#1
'2':[0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E],#2
'3':[0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0],#3
'4':[0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x8],#4
'5':[0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C,0x0],#5
'6':[0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x0],#6
'7':[0x3E,0x22,0x4,0x8,0x8,0x8,0x8,0x8],#7
'8':[0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E],#8
'9':[0x3E,0x22,0x22,0x3E,0x2,0x2,0x2,0x3E],#9
'A':[0x8,0x14,0x22,0x3E,0x22,0x22,0x22,0x22],#A
'B':[0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C,0x0],#B
'C':[0x3C,0x40,0x40,0x40,0x40,0x40,0x3C,0x0],#C
'D':[0x7C,0x42,0x42,0x42,0x42,0x42,0x7C,0x0],#D
'E':[0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C],#E
'F':[0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40],#F
'G':[0x3C,0x40,0x40,0x40,0x40,0x44,0x44,0x3C],#G
'H':[0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44],#H
'I':[0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x7C],#I
'J':[0x3C,0x8,0x8,0x8,0x8,0x8,0x48,0x30],#J
'K':[0x0,0x24,0x28,0x30,0x20,0x30,0x28,0x24],#K
'L':[0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C],#L
'M':[0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81],#M
'N':[0x0,0x42,0x62,0x52,0x4A,0x46,0x42,0x0],#N
'O':[0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C],#O
'P':[0x3C,0x22,0x22,0x22,0x3C,0x20,0x20,0x20],#P
'Q':[0x1C,0x22,0x22,0x22,0x22,0x26,0x22,0x1D],#Q
'R':[0x3C,0x22,0x22,0x22,0x3C,0x24,0x22,0x21],#R
'S':[0x0,0x1E,0x20,0x20,0x3E,0x2,0x2,0x3C],#S
'T':[0x0,0x3E,0x8,0x8,0x8,0x8,0x8,0x8],#T
'U':[0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1C],#U
'V':[0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18],#V
'W':[0x0,0x49,0x49,0x49,0x49,0x2A,0x1C,0x0],#W
'X':[0x0,0x41,0x22,0x14,0x8,0x14,0x22,0x41],#X
'Y':[0x41,0x22,0x14,0x8,0x8,0x8,0x8,0x8],#Y
'Z':[0x0,0x7F,0x2,0x4,0x8,0x10,0x20,0x7F],#Z
'大':[0x00,0x66,0xFF,0xFF,0x7E,0x3C,0x18,0x00],#大心
'小':[0x00,0x00,0x66,0x7E,0x3C,0x18,0x00,0x00],#小心
'中':[0x8,0x7F,0x49,0x49,0x7F,0x8,0x8,0x8],#中
'国':[0xFE,0xBA,0x92,0xBA,0x92,0x9A,0xBA,0xFE],#国
}

模块驱动程序max7219.py就不在这里呈现了,文章末有链接,大家可以去下载。

无线遥控升级版

这样虽然已经很炫了,不过加上无线遥控的效果是不是就更棒了。于是,找来了以前买的HC-05(HC-06也一样)蓝牙模块,结合一下整上。

TPYBoard v102 HC-05/06蓝牙模块
VIN +5V
GND GND
Y1 RXD
Y2 TXD

其他文件不用动,改动下main.py,增加上串口读写操作即可。

import MAX7219 #导入模块
from pyb import UART
#初始化串口参数,使用串口6 波特率9600 超时时间50毫秒
#串口6 TX->Y1 RX->Y2
#其他串口对应的引脚编号详见针脚图:http://old.tpyboard.com/document/documents/10x/TPYBoardv10xPCBpng.pdf
uart = UART(6,9600,timeout=50)

#CLK -> X1,CS -> X2,DIN -> X3
#num级联的模块数量
led = MAX7219.Lattice('X1','X2','X3',num=1)
led.display('大')                   #默认显示大心图案
while True:
    if uart.any() > 0:              #any()返回串口缓存区的数据长度,返回值大于0即表示有数据
        DATA = uart.read().decode() #读取缓存区全部数据,返回值为bytes,decode()转为字符串
        led.display(DATA)           #进行显示

蓝牙串口调试助手(Android) 点击下载

[MicroPython]TPYBoard v102 心率监测器(基于MAX30102模块)

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

前言

这几年智能穿戴设备大火,尤其是手环类,从AppleWatch到荣耀手环,再到不知名的某些品牌,智能穿戴设备是铺天盖地的来了。而其中心率监测基本上是所有穿戴设备的“标配”,为啥会如此重视心率监测?心率监测到底有必要吗?

1.持续的心率监测有助于诊断疾病

人每一次脉搏的搏动,都代表一次有效的心脏跳动,每分钟心脏跳动的次数就是心率。心率是最直接反映我们心脏健康的标志。心脏是血液泵出的动力,也是各器官系统以及整个身体正常运行的保证。

2.心率是最好的运动"导师"

如果是经常做运动的朋友应该都知道,平时运动时可以根据心率数据更好地控制运动强度,因为心率和吸氧量及最大摄氧量呈线性关系,而且最大心率百分比也和最大摄氧量的百分比呈线性关系,所以在跑步过程中,使用心率控制运动强度是最简单易行的方法。

心率监测的方法

1、PPG光电容积法

由于人体的皮肤、骨骼、肌肉、脂肪等对于光的反射是固定值,而毛细血管和动脉、静脉由于随着脉搏容积不停变大变小,所以对光的反射值是波动值,而这个波动值正好与心率一致,所以光电容积法正是通过这个波动的频率来确定使用者的心率数据。

目前市面上绝大多数的智能手环/手表都采用这种方式监测心率,而且这种方式的技术方案已经比较成熟,所以价格也相对较低。

2、心电信号测量法

还有一种就是心电信号测量法,它通过智能穿戴设备上搭载的传感器捕捉人每次心跳时微小的电极变化,再经过算法还原出心率跳动的频率,原理和心电图类似原理。目前已经很少有智能穿戴设备采用这种方式了。

TPYBoard心率监测器的制作过程

上面叨叨了这么多,接下来就进入正题。开始心率监测器的制作。首先先来介绍,里面最重要的器件-MAX30102心率模块。

MAX30102心率模块介绍

MAX30102是一个集成的脉搏血氧仪和心率监测仪生物传感器的模块。它集成了一个红光 LEO 和一个红外光 LEO 、光电检测器、光器件,以及带环境光抑制的低噪声电子电路。MAX30102采用一个 1.8V电源和一个独立的 5.0V 用于内部 LEO 的电源,应用于可穿戴设备进行心率和血氧采集检测,佩戴于手指、耳垂和手腕等处。标准的I2C兼容的通信接口可以将采集到的数值传输给Arduino、STM32 等单片机进行心率和血氧计算。此外,该芯片还可通过软件关断模块,待机电流接近为零,实现电源始终维持供电状态。

_images/1.jpg

参考了各种资料,用micropython写了个MAX30102模块的驱动,这里不就不贴源码,给个地址(文章末)大家自己去下载学习,里面也有各种手册、STM32单片机以及Arduino实现的源码。现在可以监测心率数据,但是还需要一个显示屏来进行显示,这里我选择用OLED显示屏。先参照下面信息,把硬件连接起来。

TPYBoard v102 MAX30102模块
3V3 VIN
Y10 SDA
Y9 SCL
GND GND
Y12 INT
TPYBoard v102 OLED显示屏
3V3 VCC
GND GND
D0 X6
D1 X8
RES X4
DC X5

接好线了之后,把MAX30102模块的相关驱动文件拷贝到TPYBFLASH磁盘中,然后编写main.py。保存完毕,使用PuTTY软件启动运行程序,确认程序无错误。

演示效果
  1. 程序运行后,显示屏会显示一个心形的图案,同时MAX30102模块上的红色LED灯会亮起;
_images/31.jpg
  1. 将手指放置模块红色LED处,按下板载的USR按键启动测量,显示屏会提示测量中;
_images/4.jpg
  1. 确保手指接触良好的情况下,大约等待40秒左右,显示屏会显示测量出的心率值,此时就可以把手拿开了。
_images/5.jpg
总结

使用MAX30102测量的心率值与荣耀手环4测量的心率值接近(大概有2-3值的差别)。程序中也有对血氧饱和度的测试,大家可以从程序中提取出来显示在显示屏上。但是需要注意的是,因为是基于查找表来确定血氧含量,所以每个血氧传感器都需要和专业仪器进行标定才准确。此外,RED LED的波长尤其容易受到环境温度影响,所以程序上要考虑到温度对血氧精确度的影响,这也是MAX30102本身带有温度传感器功能的主要原因。所以程序中的血氧饱和度是仅供参考,并不准确。

[Micropython]TPYBoard v102 温湿度短信通知器(SIM900A模块)
实验器件
  • TPYBoard v102 1块
  • SIM900A模块 1个
  • DHT11温湿度模块 1个
  • micro USB 数据线 1根
  • USB转TTL模块或RS232(用于调试) 1块
  • 杜邦线 若干
SIM900A模块使用说明

1.SIM900A模块需要单独外部供电,供电电压5V,电流1A。提供的用户手册中说调试初期短时间内电脑USB供电也可以。一开始用TTL模块(CH340)调试,发送AT指令模块无返回,TTL模块是可用的,不知道啥原因, 最好用CP2012芯片的。调试时最好用RS232接口。我这里用板子写了一个串口中间转发的程序才解决掉调试问题的。

2.给SIM900A模块上电前,请将SIM卡正确放入卡槽,接上GSM天线。通电后,可以通过观察D5和D6的工作状态来大致判断模块的工作状态。具体内容详见资料下载中的【12,调试教程 必看资料/全球鹰sim900 V3.8.1用户手册.pdf】。

3.SIM900A模块支持移动、联通2G网络,不支持电信。

4.模块上的5VR和5VT串口兼容3.3V和5V的TTL电平,如果你的单片机的TTL电平电压为3.3V时,可将单片机的TXD连接到模块上的5VR,RXD连接5VT,单片机的GND连接到模块的GND,模块上的VCC_MCU接到直流3.3V上。 同理若是5V电平,则VCC_MCU接到5V上。

以上说明在用户手册中都能找到,大家在使用时仔细阅读手册基本上遇到的问题都能解决。

接线说明
TPYBoard v102 SIM900A模块
3V3 VCC_MCU
GND GND
Y1(UART6-TX) 5VR
Y2(UART6-RX) 5VT

当然还需要我们的DHT11温湿度模块,用它来采集当前环境下的温湿度信息。关于DHT11模块的内容这里就不具体介绍了,没有了解过的小伙伴可以看一下本篇之前的教程中,有专门介绍DHT11模块。

TPYBoard v102 DHT11温湿度模块
VIN VCC(+)
Y12 DATA(out)
GND GND(-)
源代码

在写开发板的程序之前,建议先用PC与SIM900A模块进行调试,调试成功后,再将AT指令的收发功能移植到开发板的程序上。

main.py文件内容如下,可供参考。

import pyb
from pyb import UART
from dht11 import DHT11

SIM = UART(6,9600,timeout=50)  #与SIM900A模块通信串口的初始化
dht = DHT11('Y12')             #Y12是开发板上为DHT11数字输出引脚连接的引脚

CMD = [
'AT',
'AT+CPIN?',     #查询SIM卡的状态
'AT+CSQ',       #查询信号强度
'AT+COPS?',     #查询当前运营商
'AT+CMGF=1',    #设置为文本模式
'AT+CSCS="GSM"',#设置字符集
'AT+CNMI=2,1',  #设置新消息提示
'AT+CMGR=',     #读取指定短信
'AT+CMGS="18088889999"' #接收短信的手机号码
]

def sendToSIM(m,f=True):
    print('CMD:',m)
    if f:
        SIM.write(m + '\r\n')#每条AT指令后必须带\r\n
    else:
        SIM.write(m)         #编辑短信内容时不需要加\r\n

if __name__ == '__main__':
    NUM = 0                  #计数,用来指定接下来要发送的AT指令
    Wait = False             #True 不发送AT指令 等待新短息指令
    msg = 'Temp:{}-Hum:{}'   #发送短信的内容
    sendToSIM(CMD[NUM])      #发送AT测试与模块通信是否正常
    while True:
        if SIM.any() > 0:    #any返回的是缓存区的字节数,判断大于0即表示有数据
            revData = SIM.read().replace(b'\r\n',b'')#读取缓存区的全部数据,返回的是bytes类型,replace去除\r\n
            print('rev:',revData)
            if revData.find(b'OK') > -1:
                if len(revData) == 2:#模块返回OK,说明通信正常
                    if NUM == 0:
                        NUM = 1
                    elif 4 <= NUM <6:
                        NUM += 1
                        if NUM == 6:
                            Wait = True
                            print('等待新短息的到来......')
                            pyb.LED(2).on()
                elif revData.find(b'+CPIN: READY') > -1: #表明SIM卡状态正常
                    NUM = 2
                    print('SIM卡状态正常')
                elif revData.find(b'+CSQ') > -1:             #返回信号强度值
                    if int(revData.split(b',')[0][-2:]) > 10:#信号强度值大于10才能正常收发短信
                        NUM = 3
                        print('信号质量正常')
                    else:
                        print('信号质量异常,请检查模块!')
                        break
                elif revData.find(b'+COPS: 0,0,"CHN-UNICOM"') >-1:
                    #这里测试用的是联通卡返回为CHN-UNICOM,移动返回+COPS:0,0,"CHINAMOBILE"
                    NUM = 4
                    print('查询当前运营商成功')
                elif revData.find(b'+CMGR:') > -1:    #短信的内容
                    if revData.find(b'tpyboard') > -1:#判断短信内容是否有tpyboard,有则短信回复温湿度信息
                        NUM = 8
                        print('指定短信接收成功')
                elif revData.find(b'+CMGS:') > -1:
                    print('短信发送成功')
                    pyb.LED(4).on()
            elif revData.find(b'+CMTI') > -1:#有新短息来了
                    Wait = False
                    ID = revData.split(b',')[-1]  #获取新短息在SIM卡的位置编号
                    NUM = 7
                    CMD[NUM] = 'AT+CMGR=' + ID.decode()
                    print('来了条新短息')
                    pyb.LED(3).on()
            elif revData.find(b'>') > -1:
                    print('编辑短信并发送')
                    dhtData = dht.read_data() #采集温湿度信息
                    while 0 in dhtData:
                        dhtData = dht.read_data()
                    D = msg.format(*dhtData)
                    print(D)
                    sendToSIM(D,False)
                    pyb.delay(10)
                    #发送16进制0x1A 执行短信发送
                    sendToSIM(b'\x1A',False)
                    Wait = True
            if Wait == False:
                sendToSIM(CMD[NUM])
程序调试

1、程序一开始运行会进行一些初始化配置,比如获取信号质量、运营商等;

2、当PuTTY输出等待新短息到来,板载LED2亮起,说明初始化完毕;

_images/19.png

3、手机发送短息给模块上安装的SIM卡号码,内容为tpyboard;

_images/23.png

4、接收到新短信后LED3亮起,读取内容判断是否存在tpyboard;

5、存的话,开始采集DHT11模块的温湿度信息,编辑短息发送出去;

_images/33.png

6、这时LED4亮起,手机就会收到带有温湿度信息的短息了。

_images/44.png
[MicroPython]TPYBoard v102 无线红外遥控舵机(基于红外解/编码模块)

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

红外解码/编码模块介绍
_images/11.jpg

模块上搭载了红外接收头、红外发射器以及编码芯片。主要功能:

1、具备红外发射功能。

2、具备红外编码功能。

3、带红外发射头扩展接口。

4、具备串口通信功能,通信电平为TTL。

5、可控制红外格式设备,包括电视机、电风扇等电子电器设备。

6、支持编码芯片

7、可作为红外无线数据通信、数据传输、红外控制等功能

该模块使用方法非常简单,只需要掌握基本的单片机TTL串口通信知识即可。将模块与开发板进行串口连接,通过串口发送指定的指令进行控制模块发射;通过串口接收方式进行红外解码操作,获取遥控编码信息。

解码

解码时不需要发送任何指令,只需要拿起遥控对准模块的接收头按下某一个键,这时模块的串口就会输出该键的红外编码值给开发板,开发板只要从串口里读取到数据,进行分析就会得出按下的是哪一个键。

编码(发射)

编码时需要根据一定格式发送指令,通过串口发送5个字节的指令,就可以将对应编码的红外信号发送出去。利用这红外的收发功能,我们可以做红外数据传输和控制,使用2个就可以完成收发操作了。

红外解码/编码模块相关资料 下载

本次教程仅来学习解码功能。开发板写个串口读取的程序,先来看下遥控器按下之后,我们到底能接收到什么样的数据。这里,我们选取开发板UART3(TX-Y9,RX-Y10)。

接线图

TPYBoard v102 红外解/编码模块
VIN 5V
GND GND
Y10 TXD
Y9 RXD

程序保存后运行,打开PuTTY工具,按下遥控器左上角的第一个键CH-。

_images/32.jpg

PuTTY打印:

b'\x00\xffE'

micropython进行串口读取时,返回的是bytes类型,是一种不可变序列,跟字符串类似。返回了3个字节的内容,多按几个键你就会发现,前面2个字节是用户码固定不变,也就是说我们只要判断第3个字节就可以找到对应的键。bytes中可以直接通过索引来获取元素,也支持负数的索引。比如-1,就是从右向左数的第一个,依次类推。这里需要注意一点,获取某个元素时,他返回的是对应的十进制的数值。

例如:

>>> b = b'\x00\xffE'
>>> b[1]
255
>>> b[-1]
69

咦?最后一个元素E为什么是69呢?这是因为在bytes保存的就是原始的字节(二进制格式)数据,它会将一些16进制的值转换为对应的ascii字符。ascii中大写的E对应的十进制就是69。如果你用电脑接红外解编码模块的话,串口调试助手里打印的就应该是 00 FF 45。

根据上面的经验,总结了键值对应关系表,大家可以直接拿到程序中用。

按键 16进制/ascii字符 10进制
CH- 0x45(E) 69
CH 0x46(F) 70
CH+ 0x47(G) 71
|<< 0x44(D) 68
>>| 0x40(@) 64
>|| 0x43(C) 67
0x07 7
"+" 0x15 21
EQ 0x09(t) 9
0 0x16 22
100+ 0x19 25
200+ 0x0D(r) 13
1 0x0C 12
2 0x18 24
3 0x5E(^) 94
4 0x08 8
5 0x1C 28
6 0x5A(Z) 90
7 0x42(B) 66
8 0x52(R) 82
9 0x4A(J) 74

接下来,结合舵机做个实例。用遥控器上的|<<快进键和快退键>>|,控制舵机进行正反方向的转动。micropython中Servo类使用参考 点击查看

TPYBoard v102 舵机
VIN 电源正(红色线)
GND 电源负(棕色线)
X1 信号线(橙色线)

首先,将舵机通过程序设置到0角度的状态,安上个小翅子方便查看转动效果。

from pyb import Servo

#舵机信号线接X1,可以创建4个Servo,分别是1~4,对应的引脚是X1~X4
s1 = Servo(1)
#调整舵机转动到0角度的位置
s1.angle(0)
_images/2.jpg

程序增加上对按键的判断,每按一次转动15度,整体代码如下。

from pyb import UART,Servo

#舵机信号线接X1,可以创建4个Servo,分别是1~4,对应的引脚是X1~X4
s1 = Servo(1)
#调整舵机转动到0角度的位置
s1.angle(0)

uart = UART(3,9600,timeout=10)

def setServoTurn(flag):
    turn_angle = s1.angle()
    if flag:
        #逆时针 值递增 最大值90度
        turn_angle += 15 #每按一次转15度
        if turn_angle <= 90:
            s1.angle(turn_angle)
    else:
        #顺时针 值递减 最小值-90度
        turn_angle -= 15
        if turn_angle >= -90:
            s1.angle(turn_angle)
while True:
    if uart.any() > 0:
        val = uart.read()[-1]
        if val == 68:
            setServoTurn(True)
        elif val == 64:
            setServoTurn(False)
[MicroPython]TPYBoard v102 串口触摸屏的使用

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

准备器件
  • TPYBoard v102开发板 1块
  • 串口触摸屏(USART HMI) 1块
  • USB转TTL模块 1个
  • USB数据线 1条
  • 杜邦线 若干
串口触摸屏(USART HMI)
_images/0.png

功能特征

  • 16位真彩色RGB显示。
  • 支持多种组态控件:按钮控件、进度条控件、文本控件、指针控件。
  • 带字库:可以自定义任怠WINDOWS字库。
  • 支持基本的GUI指令(画点、画线、画矩形等)。
  • 支持图片格式BMP、JPG、JPEG、PNG。
  • 支持上位软件自动升级、设备固件自动升级。
  • 100级背光调光,有休眠模式,休眠电流20MA ,支持触摸喚醒功能。
  • 支持串口下载和SD卡下载两种方式,支持PC端模拟调试,支持模拟器和设备同步调试。
串口触摸屏的界面设计

在使用串口屏之前,我们需要先通过它的上位机软件创建一个工程,工程中进行串口屏界面的设计,包括文本控件、按钮控件等。

串口屏相关资料下载

创建工程

首先,在电脑上安装串口屏的上位机软件,安装包在上面的资料中有。安装完成后,双击打开。点击菜单栏中的新建,创建一个新的工程。

_images/16.png

点击之后会弹框让你选择保存的路径以及工程名,这个根据自己喜好设置即可,没有要求。我这里的工程名设置为test。

_images/21.png

接着会让你选择产品型号,串口屏对应的型号在背面可以看到。

_images/3.jpg

我手里的这款就是基本型的,型号为TJC3224T024_011,在软件中选择对应的型号即可。

_images/43.png

我个人比较喜欢横屏显示,所以在显示选项中选择了横屏90度,大家也可以根据喜好自行设置。设置完点击OK完成创建。

_images/52.png

制作工程

软件左侧可以看到工具箱选区,这里我们添加一个滚动文本控件。点击滚动文本,该控件会自动添加到软件中间的界面区域中。

_images/62.png _images/71.png

接下来我们需要设置要显示的文本,找到软件的右下角控件属性区,修改txt属性的值就是要显示的文本。

_images/81.png

但是改了之后,发现界面中还是没有文字显示,这是因为我们还需要添加字库。第一次用的话,需要我们制作一个新的字库。若不是,软件左下角字库区点击“+”即可添加现有字库。 这里我们制作一个新字库,点击菜单栏工具->字库制作。

_images/101.png

选择字体、字高,其它默认,输入字库名称,点击生成字库。选择保存的本地目录。

_images/112.png

保存后,提示是否添加刚才生成的字库,点击是进行添加。

_images/122.png

添加后,你会看到字库区多了一条字库信息,第一个字符0表示字库唯一ID,后面是刚才输入的字库名称,括号内是一些我们设置的参数。

_images/131.png

这时我们回到控件的属性区,修改的文字就可以在界面中显示了。这里我把txt改为Hello TPYBoard。提示超出字符长度的话,把txt_maxl改大点就行。

_images/141.png _images/151.png

如果你想更换字库的话,在控件属性修改font的值,这个值填写的是字库的ID,默认为0。

串口触摸屏的下载

界面设置完成后,点击编译进行编译,软件左下角输出框会显示编译信息,确保工程无错误无警告。

_images/16-0.png

编译成功后,将串口屏与USB转TTL连接起来,购买串口屏时,里面都有配的线。

串口屏 USB转TTL模块
+5V 5V
TX RXD
RX TXD
GND GND

确保接线正确后,将USB转TTL模块插入电源,可以在设备管理器中看到增加的端口。

_images/16-1.png

若提示没有驱动的话,根据USB转TTL模块上的芯片下载驱动进行安装。比如,我用的就是CH340芯片的。点击这里直接下载

接下来准备下载,点击软件菜单栏中的下载,弹出下载界面,选择与设备管理器中一致的端口号,波特率默认。

_images/161.png _images/17.png

点击联机并开始下载,软件和串口屏上都可以看到下载进度。

_images/18.png _images/19.jpg

等待下载完毕,观察串口屏会看到滚动显示的Hello TPYBoard。

_images/20.jpg
串口触摸屏与TPYBoard的交互实验

通过上面的学习,我们已经学会了串口屏的使用。接下来,我们将串口屏与TPYBoard v102结合起来,通过点击串口屏来发送命令给开发板。设计了一个简单的界面如下,两个文本框和两个按钮。

_images/211.png

控件的背景或字体颜色都可以在属性里设置。使用按钮时,需要勾选按下事件中的发送键值选项,这样的话,我们就可以判断按下的是哪个按钮了。

_images/22.png

设置完成后,进行编译下载。下载完成后,将串口屏与开发板进行相连。

串口屏 TPYBoard v102
+5V VIN
TX X4(UART2-RX)
RX X3(UART2-TX)
GND GND

TPYBoard v102程序如下,关于串口屏的指令集在资料中都有,可以参考。

from pyb import LED
from pyb import UART

END_CMD = b'\xFF\xFF\xFF' #发给串口屏指令的结束符,不可更改
txt = 't1.txt="{}"'       #改变文本框文字的命令

uart = UART(2,9600,timeout=50) #串口屏通信波特率默认9600
#通过开关按钮控制板载LED4亮灭,LED4默认情况下为灭
#那程序一开始就把文本改为关
CMD = txt.format('关').encode() + END_CMD
uart.write(CMD)

while True:
    if uart.any() > 0:
        data = uart.read()
        print('revFromHMI:',data)
        #开:65 00 03 01 FF FF FF 点击开按钮时 我们从串口读取到的十六进制数据
        #关: 65 00 04 01 FF FF FF 点击关按钮时 我们从串口读取到的十六进制数据
        #需要注意一点micropython从串口读取数据时返回的是bytes类型的数据,它会把一些16进制数据转为相应的ascii字符
        #也就是说我们在程序中实际接收到的开按钮的数据是这样的,b'e\x00\x03\x01\xff\xff\xff'
        if data[:2] == b'e\x00' and data[4:] == END_CMD:
            if data[2] == 3: #bytes在通过索引获取元素值时会默认转为十进制数
                CMD = txt.format('开').encode() + END_CMD
                uart.write(CMD)
                print('sendToHMI:',CMD)
                pyb.LED(4).on()
            elif data[2] == 4:
                CMD = txt.format('关').encode() + END_CMD
                uart.write(CMD)
                print('sendToHMI:',CMD)
                pyb.LED(4).off()
            else:
                print('Error:',data)

如果串口屏显示中文为乱码,把main.py文件编码改成ANSI编码格式即可

TPYBoard v201 典型实例

TPYBoard v201开发板是在v102基础上增加了以太网的功能,基本使用完全兼容v102的教程,所以这里,我们就直接引用了v102的教程

新手入门

帮助初学者快速掌握TPYBoard v201开发板的使用技巧。

进阶训练

学习使用TPYBoard v201开发板进行一些基础的实例训练。

高手专场

经过前面两个阶段的练习,想必你已经成为一名TPYBoard的高手了。那就来挑战下高手专场的实例训练吧!

[Micropython]TPYBoardV201 K2网口配置使用文档

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

超级网口 V201网口 用于实现串口到以太网口的数据的双向透明转发,用户无需关心具体细节,模块内部完成协议转换,通过简单设置即可设定工作细节。参数可以通过模块内部的网页进行设置,也可以通过设置软件进行设置,一次设置永久保存。

下面简单介绍一下软件配置的方法。

用户需要预设的参数有:

1.工作模式:TCP Client、TCP Server、UDP Client、UDP Server

2.默认 TCP/UDP连接参数

3.连接类型(Server或Client)

4.目标端口

5.目标IP地址

6.本地端口

7.串口参数

8.波特率

9.数据位

10.检验位

11.停止位

12.RS485等功能的选择

13.IP地址和模块密码等

14.IP地址获取方式

15.模块名称、用户名和密码的设置

用户配置完所有参数后重启,模块就可以按照设置的参数工作了。

使用软件配置分为网络操作和串口操作两种,下面分别介绍。

我们使用的配置软件为USR-M0-Series_V2.0.1.521。点击下载

图标如图。

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219608161569.png
一、通过网络配置

1.第一步是给整个开发板供电,使用双头usb数据,连接电脑和开发板;

2.第二步从路由器上引出一根网线插在开发板的网口上;

3.打开配置软件,界面如图

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219619821144.png

4.点击搜索设备,出现如图,这里可以在设备名称的地方看到V201网口这个设备,

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219666274759.png

5.点击选择V201网口这个设备,如图

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219680890988.png

6.这里我们需要在端口设置里面进行各个参数的设置,然后点击保存参数,结果如图

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219702772241.png
二、串口设置

1.使用串口设置前需要有一个TTL转串口模块,并按如下表格对应接线

_images/c2.png

2.在完成以上接线后,使用杜邦线把Y3与GND短接;

3.给开发板供电;

4.在TTL转串口模块正确连接电脑与开发板之后,打开配置软件;

5.选择通过串口操作,如图

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219789194685.png

6.按照上图中进行项目选择,结果如图

http://www.tpyboard.com/ueditor/php/upload/image/20170415/1492219808554216.jpg

7.这样就可以进行目的IP和本地端口等参数的设置了,具体设置参照网络设置;

8.设置完成后,点击保存即可。

[Micropython]TPYBoard v201 建立云加法器

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

引言

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

实验器件
  • TPYBoard v201开发板 1块
TPYBoard v201开发板简介

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

环境搭建

上面介绍了所需器件,下面我们来说一下实验所需的环境。这里只需要能给开发板供电,以及可以支持有线网络连接(可以给开发板接上网线)即可。 开发板接通电源插入网线后,可以看到v201网口上的绿色指示灯亮起来,说明已经连接上网络。

配置v201网口

这一步是为了设置v201网口模块的目的地址,本地端口,波特率,数据位,校验位等一系列信息,具体配置方向详见: TPYBoard相关下载(USR-K2)

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

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

2.确认网络完好,接下来就是进行传输和处理,在保证网络通畅的前提下,设置串口6,也就是Y1(TX)和Y2(RX),波特率与设置的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, timeout = 100)#定义连接网口的串口
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]TPYBoard v201 温湿度数据上传

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

引言

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

所需器材
  • TPYBoard v201开发板 1块
  • DHT11温湿度模块 1个
  • 面包板 1个
  • 杜邦线 若干

DHT11 简介

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

接线说明
DHT11模块 TPYBoard v201
GND(-) GND
VCC(+) VIN(5V)
DATA(OUT) X12
配置 v201网口

详细的配置说明详见上一篇教程 http://docs.tpyboard.com/zh/latest/tpyboard/tutorial/v201/cloudadder.html#v201

实物图

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,timeout = 100)#定义串口,我的网口设置了115200的波特率
K=1
#*******************************主程序**********************************
print('while')
while (K>0):
    #init DHT11
    dht=DHT11('X8')
    data_=dht.read_data()#读取温湿度的值
    temp=str(data_[0])#温度
    hum=str(data_[1])#湿度
    print('temp:'+temp)
    print('hum:'+hum)
    ulan.write('temperature is:'+temp+'\r\n')#上传温度
    pyb.delay(2000)#做延时是为了让给模拟服务器一个反应时间
    ulan.write('wet is:'+hum+'%'+'\r\n')#上传湿度
    pyb.delay(12000)
[Micropython]TPYBoard v201 简易的WEB服务器

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

前言

TPYBoard v201开发板上搭载了以太网转TTL串口模块(USR-K2),从而实现了TCP通信的功能。既然可以TCP通信,自然也可以实现HTTP协议通信。于是,就萌发了本教程。本教程很简单,仅是实现了一个简单的静态页面,希望可以给大家带来不一样的启发。

TPYBoard v201开发板实物图

_images/v201.jpg
准备工作

硬件&工具

  • TPYBoard v201 开发板 1块
  • TPYBoard v201 网络参数配置的工具
  • 路由器、电脑、网线等

知识储备

  • 了解基本的TCP、HTTP通信协议等相关的知识。不知道的可自行去百度,相关教程很多。
TPYBoard v201网络参数配置

USR-K2资料和工具下载 下载地址是在GitHub上,如果下载速度很慢的话,你也可以加TPYBoard技术交流群:157816561 群文件里下载。

首先,将TPYBoard v201开发板通过网线与你使用的电脑接入同一个局域网内。双击运行<USR-M0_V2.2.1.272.exe>,点击搜索设备,成功的情况下会在上面的列表中显示搜索到的设备。

_images/01.png

点击搜素到的设备,可以读取到该设备的相关参数。同时也可以进行修改并保存。接下来,我们要进行IP地址、端口等设置。IP地址我这里设置了静态IP<192.168.0.99>,防止每次重新启动时会改变IP。

_images/110.png

接下来端口设置,模块工作方式选择TCP Server。大家可以注意到基础设置中有一个HTTP服务端口的设置,是因为USR-K2中本身就有一个内嵌的网页用于参数的设置,默认是启用了80端口,那我们下面开启的TCP Server的服务端口就使用81端口吧。

_images/25.png

设置完毕后,点击软件最下方的保存设置。左侧的操作日志显示框会显示保存的进度和状态。

_images/34.png

这时再重新搜索设备,验证下模块的IP地址是否和我们设置的一致。

_images/46.png
程序实现

TPYBoard v201通过板子上的串口6与USR-K2模块之间通信。我们不用去管TCP链接等问题,只需要将想要发送的数据通过串口6发送给K2模块即可。其实我们的程序主要就是读取和写入串口的工作, 当我们从串口读取到HTTP请求报文时,组成一个简单的响应报文写入到串口发送回去就可以了。

main.py 源码:

import pyb
from pyb import UART

#串口6初始化
uart = UART(6,115200,timeout = 100)
#响应报文
header = """
HTTP/1.1 200 OK
Content-Type:text/html
Content-Length:{0}

{1}
"""
#HTML页面
html = """<!DOCTYPE html>
<html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <head> <title>TPYBoard</title> </head>
    <body>
      <h1>TPYBoard v201</h1><br />
      <h2>Simple HTTP server</h2>
    </body>
</html>
"""

while True:
    if uart.any() > 0:
        request = uart.read().decode()
        print('request:',request)
        #当接收到GET请求头时,进行响应
        if request.find('GET') > -1:
            data = header.format(len(html),html)
            uart.write(data)

保存代码。打开浏览器,输入URL进行访问。URL=ip:81,例如我的URL就是192.168.0.99:81。

_images/53.png

PuTTY中打印了接收到的请求头的数据,如下:

request: GET / HTTP/1.1
Host: 192.168.0.99:81
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.7 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

我用的是谷歌浏览器,不同浏览器可能会有些不同,但是大同小异,只要符合HTTP请求报文格式即可,有兴趣的朋友可以多去了解些。细心的朋友会注意到,每次访问时浏览器会发送两次请求,其中有一个 GET /favicon.ico HTTP/1.1,这是因为浏览器想找favicon.ico文件作为访问网页的图标,这个可以忽略掉,不影响功能。也可以在程序中进行过滤。

[Micropython]TPYBoard v201 简易家庭气象站的实现过程

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

前言

上一篇教程中我们实现了一个简单网页的显示。本篇呢,增加上温湿、时间等信息的展示,实现一个简单的家庭气象站。

TPYBoard v201开发板实物图

_images/v201.jpg
准备工作

硬件&工具

  • TPYBoard v201 开发板 1块
  • TPYBoard v201 网络参数配置的工具
  • 路由器、电脑、网线等
  • DHT11温湿度模块 1个
  • DS3231时钟模块 1个

知识储备

  • 了解基本的TCP、HTTP通信协议等相关的知识。不知道的可自行去百度,相关教程很多。
  • 掌握DHT11温湿度模块的使用方法。
  • 掌握DS3231时钟模块的使用方法。
TPYBoard v201网络参数配置

USR-K2资料和工具下载 下载地址是在GitHub上,如果下载速度很慢的话,你也可以加TPYBoard技术交流群:157816561 群文件里下载。

首先,将TPYBoard v201开发板通过网线与你使用的电脑接入同一个局域网内。双击运行<USR-M0_V2.2.1.272.exe>,点击搜索设备,成功的情况下会在上面的列表中显示搜索到的设备。

_images/01.png

点击搜素到的设备,可以读取到该设备的相关参数。同时也可以进行修改并保存。接下来,我们要进行IP地址、端口等设置。IP地址我这里设置了静态IP<192.168.0.99>,防止每次重新启动时会改变IP。

_images/110.png

接下来端口设置,模块工作方式选择TCP Server。大家可以注意到基础设置中有一个HTTP服务端口的设置,是因为USR-K2中本身就有一个内嵌的网页用于参数的设置,默认是启用了80端口,那我们下面开启的TCP Server的服务端口就使用81端口吧。

_images/25.png

设置完毕后,点击软件最下方的保存设置。左侧的操作日志显示框会显示保存的进度和状态。

_images/34.png

这时再重新搜索设备,验证下模块的IP地址是否和我们设置的一致。

_images/46.png
接线说明

进行器件接线时,请先断开开发板的电源,防止接错导致器件烧坏。

DHT11模块 TPYBoard v201
GND(-) GND
VCC(+) VIN(5V)
DATA(OUT) X12
DS3231模块 TPYBoard v201
GND GND
VCC 3V3(3.3V)
SDA Y10(IIC 2)
SCL Y9(IIC 2)
程序实现

TPYBoard v201通过板子上的串口6与USR-K2模块之间通信。我们不用去管TCP链接等问题,只需要将想要发送的数据通过串口6发送给K2模块即可。 其实我们的程序主要就是读取和写入串口的工作,当我们从串口读取到HTTP请求报文时,开始采集DHT11和DS3231的数据,采集完成后组成一个完整的响应报文写入到串口发送回去就可以了。

这里只展示main.py文件,其中里面还需要DHT11和DS3231的驱动文件,文章末有下载链接大家可自行下载参考。

main.py 源码:

import pyb
from pyb import Timer,UART
from ds3231 import DS3231
from dht11 import DHT11

#串口6初始化
uart = UART(6,115200,timeout = 100)
#响应报文
header = """
HTTP/1.1 200 OK
Content-Type:text/html
Content-Length:{0}

{1}
"""
#HTML页面
html = """
<html>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <head> <title>TPYBoard v201</title> </head>
    <body>
        <h1>TPYBaord 家庭气象站</h1><br />
        <p>时间:{}</p>
        <p>温度:{}</p>
        <p>湿度:{}</p>
    </body>
</html>
"""

#------------------------DS3231----------------------------------#
ds=DS3231(2) #设置DS3231为I2C2接口,对应SCL-Y9,SDA-Y10
#初始日期和时间,设置一次即可
#ds.DATE([19,7,27])   #设置初始日期年、月、日
#ds.TIME([14,50,0])   #设置初始时间时、分、秒
#------------------------DHT11----------------------------------#
d = DHT11('X12')

def updateDisplay():

    DATE = [str(i) for i in ds.DATE()] #将返回的时间数据int转str
    TIME = [str(i) for i in ds.TIME()]
    time = '-'.join(DATE) + ' ' + ':'.join(TIME) #读取日期和时间,拼接成正常的时间格式
    data = d.read_data()             #读取温湿度的值
    return time,data

while True:
    if uart.any() > 0:
        request = uart.read().decode()
        print('request:',request)
        #当接收到GET请求头时,进行响应.同时把favicon.ico请求过滤掉
        if request.find('GET') > -1 and request.find('favicon.ico') < 0:
            time,data = updateDisplay()
            print(data)
            HTML = html.format(time,data[0],data[1])
            #print(HTML)
            uart.write(header.format(len(HTML),HTML))

保存代码。打开浏览器,输入URL进行访问。URL=ip:81,例如我的URL就是192.168.0.99:81。

_images/53.png

如果访问时页面出现了乱码,主要有以下地方需要注意下:

  • 1.main.py文件的编码格式修改为UTF-8 无BOM格式;
  • 2.代码中的HTML字符串中需要添加<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  • 3.通过浏览器开发者工具查看,接收到的Response体是否完整。

大家可以依照本实验的基础加上自己喜欢的显示屏,然后用纸盒等包装起来,DIY一个超棒的家庭气象站。同时也可以做一个路由器映射,这样就可以 随时随地查看家里的环境信息了。

注意:
  • v201开发板上并没有板载的三轴加速度传感器。
  • 以太网模块占用了开发板上的UART 6(TX = Y1, RX = Y2)。

TPYBoard v202 典型实例

新手入门

帮助初学者快速掌握TPYBoard v202开发板的使用技巧。

[Micropython]TPYBoard v202 快速入手教程

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

前言

当你第一次接触TPYBoard v202时,或许有些疑惑,不知道该如何使用它。不用担心,当你认真阅读完本篇文章后,保证你用起来游刃有余。

初次见面
  • 正面指示图
_images/001.png
  • 反面实物图
_images/002.png

初次见到TPYBoard v202(以下简称v202)时,我们首先通过micro接口的USB数据线(android手机数据线)将v202接入电脑。

一般情况下,电脑会自动安装v202所需的驱动(以windows系统为例),安装完毕后,我们可以在设备管理器中,看到如下:

_images/118.png

也有可能有的小伙伴的电脑,不能自动安装时,请点击连接自行安装。

CH34x驱动下载

深入了解

TPYBoard v202与TPYBoard v102有所不同,v202没有USB驱动器,所以在电脑上我们看不到像v102似得加载的可移动磁盘。

我们需要一些工具,将程序下载到v202 的Flash中并运行。本次主要介绍MicroPython File Uploader 工具(以下简称MFU)。

MFU下载

双击运行MicroPython File Uploader.exe

_images/29.png

此软件需要.NET Framework 4.2 及以上版本,若打开失败,请安装.NET Framework后再使用。

.NET Framework 4.5下载

通过设备管理器可以看到COM编号,我的是COM44,所以选择COM44,点击【Open】打开串口。

_images/38.png

按一下v202上的RST键进行复位。

_images/49.png

我们看到了一些打印的信息,不过都是乱码,这是v202内部的编码格式与工具有些不兼容,不过不用担心,一点都不影响我们的开发调试。

我们v202出厂时,会自带一个呼吸灯的程序,大家此时可以仔细观察一下板子上的小蓝灯,它会是暗到亮,亮到暗一直循环变化。

接下来我们在电脑上新建一个main.py 文件,将main.py下载到v202中。

main.py 源码

import network

#将v202设置成AP模式
ap_if = network.WLAN(network.AP_IF)
#激活接口
ap_if.active(True)
#开放WIFI。名称:TPYBoard v202 密码:12345678
ap_if.config(essid='TPYBoard v202',password='12345678')

点击右侧菜单区的文件夹图标按钮,选择我们刚才新建的main.py文件。然后点击【Send】按钮,下载程序完毕后,自动运行。(Autorun取消选择则不自动运行)

大家这时就可以搜索到名为“TPYBoard v202”的WIFI,并可以成功连接。

相处与调试

MFU工具的调试菜单栏中每个按钮的功能介绍

  • Send:将选中的文件下载到模块的Flash中
  • Stop:中止程序运行
  • Run/Reset:开始运行或复位重启
  • Clear:清空输出区打印的信息

当程序停止运行时,信息输出区会出现>>>的符号。

_images/56.png

这时我们可以在命令输入区内输入单句代码,进行单步调试。我们先输入一句简单的print (‘Hello v202’) 回车发送执行。

_images/65.png
文件查看

接下来我们来看一下v202的Flash中存储了哪些文件,接着上一步,我们继续输入。

import os

首先我们导入文件操作类os。

_images/74.png
os.listdir()

列举当前目录下所有的文件

_images/84.png
f=open('main.py','r')
f.read()
f.close()

以只读的方式打开main.py文件,读取全部内容。(文件操作时记得close关闭资源)

_images/93.png
help(os)

help函数可以查看os类库中包含的所有函数,方便开发使用。

_images/104.png

到此就介绍完毕了,大家可以继续学习参考接下来的文章,里面有详细的类库介绍和有趣的实验例程。

[Micropython]TPYBoard v202 快速入门

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

TPYBoard v202简介

TPYBoard v202是遵照MIT协议,以MicroPython为基础,研发的一款支持Python和lua语言的Wifi通信开发板,TPYBoard v202有9个通用GPIO口,1费ADC接口,1个SPI接口,1个I2C 接口,1个USART接口。

通用方法 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]TPYBoard v202 文件查看与修改

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

前言

TPYBoard(Micropython)开发板上有搭建的文件系统,但是TPYBoard v202与TPYBoard v102有所不同,v202没有USB驱动器,所以只能通过串口或者Wifi方式访问。

简单命令的介绍

显示文件列表 通过串口访问文件的方法,通过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()
查看和修改文件

打开设备管理器,查看TPYBoard v202对应的端口号,这里的为COM15。

_images/010.png

首先打开MicroPython File Uploader(简称MFU)工具,选择对应的端口号,点击Open。

_images/117.png

这时,点击Stop按钮停止现有程序的运行,当出现>>>提示符时,就说明未运行程序,可手动输入代码执行。 (若点击一次未出现,再点击一次即可)

_images/28.png

工具底部输入框中输入查看文件的代码,回车执行。每次输入一行后执行即可。

_images/37.png

想要修改文件的话,就直接Send相同文件名的即可,它会覆盖掉之前的文件。

[Micropython]TPYBoard v202 GPIO的使用

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

实验目的
  • 学习在PC机系统中GPIO(General Purpose I/O Ports,即通用输入/输出端口)的使用方法
  • 学会用TPYBoard v202开发板读取GPIO的电平值,控制板载的LED点亮/熄灭
准备工作
  • TPYBoard v202开发板 1块
  • micro USB数据线 1条
  • 电脑 1台(本次实验以win7为例)
  • 所需软件 MicroPython File Uploader
GPIO的介绍

GPIO(General Purpose I/O Ports)意思为通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。

_images/tpyboardv2021.png

通过上图大家可以看到开发板上的ESP8266模块上有一个蓝色的LED灯,它与板子的G2引脚相连。当控制G2输出低电平时,LED点亮,反之熄灭。开发板上有两个按键,RST按键和FLASH按键。

  • RST按键 :复位按键,用于开发板的硬复位
  • FLASH按键 :FLASH按键,主要与RST按键搭配使用,使开发板进入烧录模式,与G0引脚相连。

TPYBoard v202开发板支持MicroPython开发,同时也只支持Lua语言开发。为了方便大家使用,下表列举了TPYBoard v202开发板上的引脚编号与NodeMCU、MicroPython之间的对应关系。

TPYBoard v202 MicroPython ESP8266模块 GPIO NodeMCU GPIO
G0 0 GPIO 0 3
G2/SDA/LED 2 GPIO 2 4
G4 4 GPIO 4 2
G5 5 GPIO 5 1
G9 9 GPIO 9 11
G10 10 GPIO 10 12
G15 15 GPIO 15 8
G16 16 GPIO 16 0
MO 13 GPIO 13 7
MI 12 GPIO 12 6
SCK/SCL 14 GPIO 14 5
TXD(REPL UART0) UART0 TXD TXD 10/TX
RXD(REPL UART0) UART0 RXD RXD 9/RX

可用于GPIO操作的引脚有:G0,G2,G4,G5,G12,G13,G14,G15,G16,其中G16是一个特殊的引脚,用于从深度睡眠模式唤醒模块。还需要注意一点,开发板上只有一个串口,将其引出为USB虚拟串口用于REPL操作,当你需要使用串口时,应注意避免冲突。

实验方法

第一步:下载安装所需的软件--MicroPython File Uploader 工具(以下简称MFU)

MFU下载

第二步:连接TPYBoard v202开发板

通过USB数据线将电脑和TPYBoard v202开发板连接起来,查看设备管理器,是否正确创建端口号。打开MFU工具,选择对应的端口号,点击Open。

第三步:下载程序

在本地新建一个main.py文件,在main.py文件中输入以下源代码的内容,使用MFU工具将程序下载到TPYBoard v202开发板中。 下载前,请先停止运行程序。

源代码
from machine import Pin
import time

p2 = Pin(2, Pin.OUT)    # 创建一个引脚对象p2,使用GPIO2(G2)引脚,输出模式
p2.value(1)             # 设置引脚输出高电平,即板载蓝色LED熄灭

while True:
  p2.value(0)           # 设置引脚输出低电平,即板载蓝色LED点亮
  print(p2.value())     # 读取引脚的电平值,并打印
  time.sleep(3)         # 延时3秒
  p2.value(1)
  print(p2.value())
  time.sleep(3)

第四步:运行程序查看效果

点击MFU工具的Run/Reset,重新运行程序,或者按下板载的RST按键都可以。运行新程序后,你会看到板载的蓝色LED灯会每隔3秒亮灭一次,并一直循环下去。

[Micropython]TPYBoard v202 Network连接网络

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

实验目的
  • 学习在PC机系统中网络(network)的使用方法
  • 学习TPYBoard V202连接网络的使用
准备工作
  • TPYBoard v202 1块
  • micro USB数据线 1条
  • 电脑 1台(本次实验以win7为例)
  • 所需软件 MicroPython File Uploader(MFU) 点击下载

Network库的使用方法

网络模块用于配置WiFi连接。一共两种模式,模式一:是TPYBoard v202当STA节点,即连接路由器的节点。模式二,是TPYBoard v202做为AP,充当路由。

TPYBoard v202 STA节点模式

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.value(0)
        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()

只需要将上面代码写入到开发板中,复位重新运行程序后,就会看到蓝灯常亮(正在连接网络),然后蓝灯交替闪烁两次,打印connect success,证明已经连接到本地网络。

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

TPYBoard v202 AP模式

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

也可以设置无密码开放模式,如下:

ap.config(essid='ESP-AP',authmode=0) # 设计接入点的ESSID,开放无密码模式

AuthMode有五种模式:

  • 0 : OPEN
  • 1 : WEP
  • 2 : WPA-PSK
  • 3 : WPA2-PSK
  • 4 : WPA/WPA2-PSK
实验一

实验要求

当TPYBoard v202未连接到网络时,LED亮起警示,当连接成功后,熄灭。

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.value(0)
        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.value(1)
        print('network config:', sta_if.ifconfig())

实验效果

当我们复位,把程序写进去的时候会看到TPYBoard V202板载的蓝灯亮起来,当连接成功后蓝灯熄灭,打印connect success。

实验二

实验要求

当TPYBoard v202连接网络成功后,通过get方式向网址 http://old.tpyboard.com/esp8266/test.php 发起请求,带有一个参数val。 网站接收到请求后,判断参数val的值是否等于字符A,等于的话返回begin,反之返回error。TPYBoard v202收到begin后LED快闪2次。

发起HTTP GET请求的简单方法

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()

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.value(0)
                print('connecting to network...')
                sta_if.active(True)
                sta_if.connect('essid', 'pwd')
                while not sta_if.isconnected():
                        pass
        if sta_if.isconnected():
                print('connect success')
                p2.value(1)
                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://old.tpyboard.com/esp8266/test.php?val=A')
[Micropython]TPYBoard v202 连接Putty教程

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

实验目的
  • 学习在PC机系统中通过putty连接开发板教程
所需器件
  • TPYBoard v202开发板 1块
  • micro USB数据线 1条
所需软件
Putty连接方法

安装驱动

通过数据线将TPYBoard v202开发板连接电脑。打开桌面,右键点击我的电脑选择设备管理器。单击端口选项,会出现如下效果:

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

注意事项

如果在端口中没有出现红色方框中的选项,请确认以下几点:

  • 检查驱动程序(CH341SER)是否安装成功。
  • 安装驱动精灵且将TPYBoard v202开发板连接电脑的同时自动搜索与其匹配的驱动进行安装。
  • 检查TPYBoard v202开发板与电脑的连接是否有误。

通过PUTTY连接TPYBoard v202开发板

双击下载后的PuTTY_0.67.0.0.exe软件,点击运行。红色方框中Host Name 填写端口中新加入的端口名字(这里可以写括号中的COM4)Port中填写115200。Connection type 中选择Serial选项。

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

点击下图左方框,在右侧Flow control 选项中选择None。

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

点击Open按钮,会弹出如下界面:

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

点击TPYBoard v202开发板中的RST键,会出现如下界面:

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

当界面出现红色方框中的内容时说明TPYBoard v202开发板已经安装成功。现在可以编写python代码,如图:

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

还可以使用快捷键Ctrl+C 停止运行程序,Ctrl +D 重新运行程序。

[Micropython]TPYBoard v202 定时器

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

实验目的
  • 学习使用定时器功能
所需元器件
  • TPYBoard v102开发板 1块
  • micro USB数据线 1条
实现方法

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

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

增加一个循环定时器

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

硬件实物图

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

硬件接线图

TPYBoard v202 DHT11温湿度模块
5V VCC
G4 DATA
GND GND

连接完成后,将下面代码写进TPYBoard v202即可读取当前温湿度的值,下面是源代码:

    from machine import Timer
    import dht
    import machine

d=dht.DHT11(machine.Pin(4))

    def f(t):
      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)

使用TPYBoard v202开发工具-MFU,就可以看到每隔2秒钟就会打印一次温湿度数据。

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

[Micropython]TPYBoard v202 常见问题及使用技巧

为了大家更好的使用TPYBoardv202开发板,下面总结了在使用TPYBoardV202(简称v202)过程中的一些常见问题和使用技巧,方便以后大家更好的使用。

常见问题:
TPYBoard v202的主控模块是什么?

TPYBoard v202采用ESP8266-12E/12F作为主控模块。

ESP8266-12E/12F 技术参数:

  • Flash大小:32Mbit(4MBit)
  • 温度范围:-20~80°C
  • 天线封装:PCB
  • 工作电压:3.0~3.6V(建议3.3V)
  • 指示灯IO口:GPIO2
  • 默认波特率:115200
TPYBoard v202支持什么语言开发?

TPYBoard v202完美支持MicroPython使用Python语言开发,同时兼容NodeMCU也可以使用Lua语言。

TPYBoard v202有几个串口?

TPYBoard v202只有一个串口,就在丝印为[FLASH]的按键旁边。

TPYBoard v202都有那么接口?

TPYBoard v202接口类型有:SPI接口1个、IIC接口1个、ADC接口1个、UART 接口 1个。

TPYBoard v202如何使用串口?

源码:

from machine import UART
u2=UART(0,115200)#串口初始化
u2.readall()#读取串口全部数据
u2.write(‘hello’)#写入串口数据
TPYBoard v202的例程资料

可直接访问TPYBoard的官方资料网站http://docs.tpyboard.com/zh/latest/tpyboard/tutorial/v202/

TPYBoard v202串口使用的一些问题总结
  • MicroPython官方固件中除了v1.8.3版本外,其余版本的固件都能正常使用串口。
  • ESP8266-12E上只有一个串口,主要功能是进行调试和文件的上传和下载。如果你在程序中使用串口接入外设通信时,需先将与外设之前的连接断开,才能对v202进行调试或文件上传的工作。
使用技巧
TPYBoard v202固件的烧写与擦除

若因为一些操作或意外,导致v202不能正常工作时,可尝试重新烧写固件试试,如果不起作用的话,可以先进行擦除在烧写。

点击查看固件擦除教程

点击查看固件烧写教程

TPYBoard v202的调试工具

v202通过数据线接入电脑后,会安装一个COM串口,这个可以在电脑的设备管理器中看到,如:

因为在v202开发板上加载了CH340(USB转串口)芯片,所以我们只要使用一个支持串口功能终端的软件即可。本人比较推荐的调试工具是Putty。

Putty下载地址:

http://tpyboard.com/download/tool/3.html

若有的小伙伴的电脑不能自动安装CH340驱动的话,这里提供一个下载地址,可自行进行安装。下载地址:http://tpyboard.com/download/drive/163.html

Putty的使用技巧
  • 组合键 Ctrl+C 停止运行
  • 组合键 Ctrl+D 重新运行
  • 输入help(object) 可以查看相关类库对象的说明
TPYBoard v202下载程序的工具
  • TPYBoard v202不像是TPYBoard v102系列的一样,可以自动在电脑上加载一个磁盘,代码文件直接拷贝到磁盘中就可以运行。
  • TPYBoard v202需要文件下载工具才能将代码下载到Flash内运行。

`` 网上比较流行有两种工具 ``

1、ESPlorer 它是用Java开发的,使用前需要安装Java运行库,支持Windows、Linux和Mac OS多种系统平台;

ESPlorer 下载地址:http://tpyboard.com/download/tool/170.html

2、MicroPython File Uploader 它是用doNET开发的,只支持Windows系统平台。

本人比较推荐MicroPython File Uploader,虽然他没有ESPlorer的功能强大,但它是一个小巧快速的ESP8266文件上传工具,上传文件快,同时也支持Putty中调试的功能。

MicroPython File Uploader下载地址:http://tpyboard.com/download/tool/170.html

进阶训练

学习使用TPYBoard v202开发板进行一些基础的实例训练。

[Micropython]TPYBoard v202 PWM控制舵机

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

实验目的
  • 学习舵机的工作原理和使用方法(舵机型号:SG90)
  • 学习TPYBoard v202中PWM控制舵机
准备工作
  • TPYBoard v202 1块
  • micro USB数据线 1条
  • SG90舵机 1个
  • 所需软件 MicroPython File Uploader 点击下载
舵机的基本介绍
  • 舵机的组成与参数

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

    _images/test_311.png
  • 舵机的接线

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

  • 舵机的控制原理

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

    占空比:

    1.指高电平在一个周期之内所占的时间比率。

    2.正脉冲的持续时间与脉冲总周期的比值。例如:正脉冲宽度1μs,信号周期10μs的脉冲序列占空比为0.1。即:脉冲的宽度除以脉冲的周期称为占空比。标准PWM(脉冲宽度调制)信号的周期固定为20ms(50Hz),理论上脉宽分布应在1ms到2ms之间,但是,事实上脉宽可由0.5ms到2.5ms之间,脉宽和舵机的转角0°~180°相对应。

硬件的连接
  • 示意图

    TPYBoard V202 SG90舵机
    +5V 正极(红色线)
    GND 负极(棕色线)
    G5 信号(橙色线)
  • 实物图

    _images/sg90.jpg
源代码

温馨提示:TPYBoard v202开发板上的引脚G9、G10、G16 不支持PWM功能。

main.py程序代码

import machine
import time

#设置PWM 引脚G5,频率50Hz
servo = machine.PWM(machine.Pin(5), freq=50)

servo.duty(40)#舵机角度的设定
time.sleep(2)#延时2秒
servo.duty(115)
time.sleep(2)
servo.duty(180)
[Micropython]TPYBoard v202 I2C操作DS3231时钟模块

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

实验目的
  • 学习TPYBoard v202中I2C接口的使用方法
  • 学习使用DS3231制作简易的电子时钟
准备工作
  • TPYBoard v202 1块
  • DS3231时钟模块 1个
  • 所需软件 MicroPython File Uploader 点击下载
I2C的基本介绍
  • I2C(Inter-Integrated Circuit(集成电路总线))

    I2C总线类型是由飞利浦半导体公司在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来连接整体电路(ICS)。

    I2C是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。

MicroPython中I2C类库介绍
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

请参考:http://docs.micropython.org/en/latest/esp8266/esp8266/quickref.html?highlight=i2c

TPYBoard v202的I2C接口中SCL=Pin(14),SDA=Pin(2),I2C初始化修改为如下:

i2c = I2C(scl=Pin(14), sda=Pin(2), freq=100000)
DS3231时钟芯片的基本介绍

DS3231是低成本、高精度I2C实时时钟(RTC),具有集成的温补晶振(TCXO)和晶体。该器件包含电池输入端,断开主电源时仍可保持精确的计时。

集成晶振提高了器件的长期精确度,并减少了生产线的元件数量。DS3231提供商用级和工业级温度范围,采用16引脚300mil的SO封装。

DS3231内部集成了一个非常精确的数字温度传感器,可通过I2C接口对其进行访问(同读取时间一样),精度为±3°C。

硬件的连接
  • 示意图

    TPYBoard v202 DS3231时钟模块
    3.3V VCC
    GND GND
    SDA SDA
    SCL SCL
源代码

main.py程序代码

import machine
import time
from ds3231 import DS3231

ds=DS3231()
ds.DATE([17,9,1])
ds.TIME([10,10,10])

while True:
    print('Date:',ds.DATE())
    print('Time:',ds.TIME())
    print('TEMP:',ds.TEMP())
    time.sleep(5)

ds3231.py 点击预览

[Micropython]TPYBoard v202 通过HTTP协议上传温湿度数据

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

一、什么是TPYBoardV202

TPYBoard_V202是以遵照MIT许可的MicroPython为基础,由TurnipSmart公司制作的一款MicroPython开发板,它基于ESP8266,通过USB接口进行数据传输,可在3.5V-6V之间的电压正常工作。让您零基础也能灵活掌握8266模块通信技术!支持Python语言的WiFi通信开发板。

二、利用TPYBoardV202完成检测温湿度并上传
1、具体要求

利用TPYBoardV202连接DHT11温湿度传感器,通过此传感器检测所在地温度和湿度,并通过无线网络上传至服务器,这里借助萝卜电子公司提供的测试网页进行测试。

2、所需器件
  • TPYBoardV202开发板 一块
  • DHT11模块 一个
  • 杜邦线 若干
3、DHT11介绍

  DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,使其成为该类应用中,在苛刻应用场合的最佳选择。

对DHT11做了简要介绍,下面再介绍一个这个器件在V202开发板上的使用方法,这个器件的使用方法就简单了

主要是因为v202开发板里面集成了DHT的类库,你在使用DHT11的时候,直接声明一下类库,调用函数,读取数值就可以了。

三、制作主要过程

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

http://old.tpyboard.com/ueditor/php/upload/image/20170428/1493349856713838.png

V202实物图

http://old.tpyboard.com/ueditor/php/upload/image/20170428/1493349883148588.png

V202数据打印截图

http://old.tpyboard.com/ueditor/php/upload/image/20170428/1493349916351620.png

V202温湿度上传测试网页

1、制作流程

(1)DHT11模块上面有三根针脚,分别为GND,VCC,OUT,接线对应如下表:

_images/DHT1111.png

(1)按照上表接好线后,我们开始编辑main.py的代码;

(2)首先需要声明我们所用到的类库,例如引脚,时间,接口,这个实验里面我们好用到了网络,机制等等;

(3)在我们声明类库完成之后,我们需要进行类库函数的调用,这里我们需要调用的是DHT11读取数据的函数;

(4)完成上面的基本准备工作后,需要定义两个我们会用到的函数,简单的说就是开发板连接路由器函数和开发板数据上传函数;

(5)完成开发板连接路由器的函数后,调用一下这个函数,这个函数在这次的代码中仅使用一次;

(6)接下来建立起整个代码的主循环;

(7)在循环中,调用DHT类库中数据测量的函数,随后在函数中读取出温度和湿度的数值,并保存;

(8)获取到温湿度后,开始调用之前定义好的开发板数据上传函数,把数据上传至服务器;

(9)延时一段时间,在整个循环中不断的读取温湿度,就完成了实时的温湿度监控。

2、具体代码:

import dht
import machine
import network
from machine import Pin
import socket
import urllib
import time#声明用到的类库,尤其是dht的类库

d = dht.DHT11(machine.Pin(5))#声明用到类库中的函数,并设置参数
led = Pin(2, Pin.OUT)
count=0
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').upper()
            #print(str(data, 'utf8'), end='')
            if(recive.find('YES')>-1):
                print('Send Data OK')
        else:#数据发送完成,退出while
            break
    s.close()#关闭数据连接
def do_connect():#定义开发板连接无线网络的函数
    wlan = network.WLAN(network.STA_IF)#设置开发板的网#络模式
    wlan.active(True)#打开网络连接
    if not wlan.isconnected():#判断是否有网络连接
        print('connecting to network...')
        wlan.connect('无线名称', '密码')#设置想要连接的无线名称和密码
        while not wlan.isconnected():#等待连接上无线网络
            pass
    print('network config:', wlan.ifconfig())

do_connect()#调用一次开发板连接无线网络的函数
while True:#开始整个代码的大循环
    d.measure()#调用DHT类库中测量数据的函数
    temp_=str(d.temperature())#读取measure()函数中的温度数据
    hum_=str(d.humidity())#读取measure()函数中的湿度数据
    count+=1#计数变量+1
    print('eg:',temp_,'-',hum_)
    http_get('http://old.tpyboard.com/esp8266/SensorTest.php?t='+temp_+'&h='+hum_+'')
    #调用数据上传函数,把最新测量得到的数据进行上传
    print('Count:',count)
    time.sleep(5)
[Micropython]TPYBoard v202 自制微信远程智能温湿度计

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

智能时代一夜间什么都能远程了。创业者想着如何做智能产品,如何做远程控制。DIY爱好者也想着如何自制各种奇妙的工具。这里和大家一起学习制作一款廉价的智能温湿度计。说它廉价是因为共计花费不过40元,说它智能是因为你可以通过手机微信时时知道该设备所在位置的温湿度。

一、申请微信推送服务

能否实现微信推送服务的平台有很多,这里我就不一一解释了。我选用了「Server酱」,英文名「ServerChan」。你完全可以选用你认为比较好用的平台。「Server酱」的申请方法:

打开该网址 http://sc.ftqq.com/3.version 开通并使用。

  • 1.登入:用GitHub账号登入网站,点击进入“发送消息”页面,就能获得一个SCKEY。具体见:http://sc.ftqq.com/?c=code
  • 2.绑定:点击“微信推送”页面,扫码关注同时即可完成绑定
  • 3.发消息:往 https://sc.ftqq.com/SCKEY.send 发GET请求,就可以在微信里收到消息啦。
二、让我们开始DIY温湿度计
1、选择合适的主控板

更喜欢python编程的我,这里选用支持micropython的TPYBoard v202(esp8266)开发板。该开发板能够直接用python进行编程,功能还是比较强大的,甚至可用来作web服务器。这里我们主要是用其进行温湿度传感器的控制及网络请求。

_images/2021.png
2、DHT11温湿度传感器

DHT11是常用的温湿度传感器,网上可以很轻易就买到。简单的讲,就是可以用这个传感器获取的当前环境的温度和湿度。

_images/DHT111.png

该传感器使用非常简单,有的有3个引脚,有的有4个引脚。我们在使用时,只用三个,分别为VCC(电源脚,接5V)、DATA(数据引脚)、GND(接地)。

3、正确的连线方法

TPYBoard v202与DHT11的具体接线对应及实物图

_images/DHT1111.png _images/2022.png
三、少不了的编程

TPYBoard v202主要有两个文件来控制,一个是boot,py,一个是main.py。我们只需要修改这两个文件就可以完成程序的编写。如果你对如何使用TPYBoard v202还不清楚,可以参照此教程:http://docs.tpyboard.com/zh/latest/tpyboard/tutorial/v202/start/

1、编写boot脚本

boot.py:

import network
import utime

pdcn = network.WLAN(network.STA_IF)
pdcn.active(True)
pdcn.connect('wifi账号', 'wifi密码')
utime.sleep(5)
if pdcn.isconnected():
    print("WiFi is connected %s."%pdcn.ifconfig()[0])
else:
    pdcn.active(False)
    utime.sleep(5)
    print("WiFi cannot connect.")
2、编写main.py脚本

main.py:

import urequests
import dht
import machine
from machine import Pin
import time

class AlarmSystem:
    def __init__(self):
        self.d = dht.DHT11(machine.Pin(5))

    def dht11(self):
        try:
            self.d.measure()
            return 'Temp:'+str(self.d.temperature())+'°C---Hum:'+str(self.d.humidity())+'%'

        except:
            return '0'

    def push(self, result):
        title = "TPYBoardv202提示您:注意天气变化保持健康心情"
        content = 'text='+title+'&'+'desp='+result
        url="https://sc.ftqq.com/你的密钥.send?%s" % content
        r = urequests.get(url)
        r.close()

p2=Pin(2,Pin.OUT)
a = AlarmSystem()

def SendData():
    p2.value(not p2.value())
    data_= a.dht11()
    if(data_!='0'):
        print(data_)
        a.push(data_)
    else:
        print('GET Data Fail')

if __name__ == '__main__':

    while True:
        SendData()
        time.sleep(300)
四、成果分享

到这里,工作完成,方糖就会给你,你就会看到显示的温湿度了。

_images/2023.png
[Micropython]TPYBoard v202 MQTT协议1:接入OneNET云平台

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

随着移动互联网的发展,MQTT由于开放源代码,耗电量小等特点,将会在移动消息推送领域会有更多的贡献,在物联网领域,传感器与服务器的通信,信息的收集,MQTT都可以作为考虑的方案之一。在未来MQTT会进入到我们生活的各各方面,本篇文章教大家利用TPYBoard v202使用MQTT协议接入OneNET平台,并且远程控制LED灯。

什么是MQTT协议

早在1999年,IBM的Andy Stanford-Clark博士以及Arcom公司ArlenNipper博士发明了MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)技术 。MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。

实验准备
硬件材料
  • TPYBoard v202
  • 面包板
  • 数据线
  • LED发光二极管
_images/2021.png
软件准备
  • MicroPython File Uploader 用于与开发板的文件传输

下载地址:http://www.tpyboard.com/download/tool/170.html

  • 第三方库文件:micropython-libumqtt.simpleumqttsimple.py

下载地址:http://www.tpyboard.com/download/data/184.html

OneNET平台创建MQTT协议的产品并添加设备。 OneNET平台官网地址:https://open.iot.10086.cn/,登录成功进入开发者中心,添加一个新产品。

_images/addp.gif

在新建的产品下新建一个设备tpyboardv202。

_images/addd.gif

实物接线图

_images/O3.png

我用的TPYBoard v202的G4引脚,这个引脚可以随便定义,主要看程序里你想用哪个。

编写程序

点击下载程序源码

首先,需要修改一下boot.py文件,连接上无线网络。

boot.py源码:

#连接本地网络
def do_connect():
    import network
    sta_if = network.WLAN(network.STA_IF)
    ap_if = network.WLAN(network.AP_IF)
    if ap_if.active():
        ap_if.active(False)
    if not sta_if.isconnected():
        print('connecting to network...')
    sta_if.active(True)
    sta_if.connect('WIFI名称','密码') #wifi的SSID和密码
    while not sta_if.isconnected():
        pass
    print('network config:', sta_if.ifconfig())
do_connect()

修改mqtt.py中设备ID、产品ID和APIKEY参数的信息。

_images/set.gif

mqtt.py源码:

from simple import MQTTClient
from machine import Pin
import machine
import micropython
#选择G4引脚
g4 = Pin(4, Pin.OUT, value=0)
# MQTT服务器地址域名为:183.230.40.39,不变
SERVER = "183.230.40.39"
#设备ID
CLIENT_ID = "deviceID"
#随便起个名字
TOPIC = b"TurnipRobot"
#产品ID
username='productID'
#产品APIKey:
password='APIKey'
state = 0
def sub_cb(topic, msg):
    global state
    print((topic, msg))
    if msg == b"on":
        g4.value(1)
        state = 1
        print("1")
    elif msg == b"off":
        g4.value(0)
        state = 0
        print("0")
    elif msg == b"toggle":
        state = 1 - state
        g4.value(state)

def main(server=SERVER):
    #端口号为:6002
    c = MQTTClient(CLIENT_ID, server,6002,username,password)
    c.set_callback(sub_cb)
    c.connect()
    c.subscribe(TOPIC)
    print("Connected to %s, subscribed to %s topic" % (server, TOPIC))
    try:
        while 1:
            c.wait_msg()
    finally:
        c.disconnect()

main.py源码:

import mqtt
mqtt.main()

simple.py文件不用更改。依次将这4个文件下载到TPYBoard v202开发板中。

效果展示

当我们给TPYBoard v202通电或执行开始运行程序。

_images/X1.png

这个时候我们OneNET云平台上设备就会显示在线了

_images/online.png

当我们通过页面发送指令的时候,就会看到控制台的输入。面包板上的LED状态也会相应的改变。

_images/cmd.gif

在这只是给大家演示了TPYBoard v202怎么用MQTT协议接入OneNET云平台,并教大家如何控制一个外围电路点亮一个LED,大家可以利用TPYBoard v202接入更复杂,更好玩的东西。

[Micropython]TPYBoard v202 MQTT协议2:上传数据点到OneNET平台

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

前言

在之前的教程中,学习过如何使用MQTT协议接入OneNET平台,同时获取该平台下发的命令实现远程控制的功能。若之前没有接触过MQTT协议和OneNET平台的朋友,建议先学习之前的教程,点击链接进入:http://docs.tpyboard.com/zh/latest/tpyboard/tutorial/v202/V2024/

本次教程,将要学习如何在OneNET平台上新建数据流,同时使用MQTT协议中publish报文格式上传数据点。

准备工作
  • TPYBoard v202开发板
  • USB数据线
  • NotePad ++ 软件(其他编辑工具也可以)
  • MicroPython File Uploader(MFU)软件
OneNET平台新建数据流

OneNET平台官网地址:https://open.iot.10086.cn/。 若没有使用过的该平台的,可以参考上面前言中的教程,先进行产品和设备的添加。

在数据点上报之前,我们需要在OneNET云平台上添加一个数据流模板。步骤如下:

1、进入[开发者中心]的[设备管理]页面,在左侧菜单栏中选择[数据流模板],点击[添加数据流]。

_images/011.png

2、会弹出一个添加数据流的对话框,必填项名称,其他可以选填,填完之后点击[添加]。

_images/021.png

3、添加成功后,对话框会自动关闭。数据流展示列表会自动增加刚才新添加的数据流信息。

_images/031.png

到此,数据流模块就建立完成了。

向OneNET平台上传数据点

接下来就要进行数据点的上传了。上传数据点时需要参考协议规则说明,大家可以去OnetNET平台文档中心上下载,OnetNET平台文档中心地址:https://open.iot.10086.cn/doc/art431.html#118。 找到[1.1 说明文档]找到关于MQTT项目中的设备终端接入协议-MQTT进行下载。

_images/041.png

下载的是一个word文档,打开之后找到[5.2消息发布]-[5.2.1 数据点上报]。

_images/051.png

数据类型采用JSON格式,主要看[数据类型1(type == 1)格式说明]。

_images/061.png

了解完publish报文格式后,找到之前[接入OneNET平台]教程的程序,添加上上传数据点的功能即可。点击下载源程序

修改mqtt.py文件,如下:

from simple import MQTTClient
from machine import Pin
import machine
import micropython
import json

#选择G4引脚
g4 = Pin(4, Pin.OUT, value=0)
# MQTT服务器地址域名为:183.230.40.39,不变
SERVER = "183.230.40.39"
#设备ID
CLIENT_ID = "deviceID"
#随便起个名字
TOPIC = b"TurnipRobot"
#产品ID
username='productID'
#产品APIKey:
password='APIKey'
state = 0
#要上报的数据点
message = {'datastreams':[{
'id':'temperature',
'datapoints':[{'value':35}]}
]}

def pubdata(data):
    j_d = json.dumps(data)
    j_l = len(j_d)
    arr = bytearray(j_l + 3)
    arr[0] = 1 #publish数据类型为json
    arr[1] = int(j_l / 256) # json数据长度 高位字节
    arr[2] = j_l % 256      # json数据长度 低位字节
    arr[3:] = j_d.encode('ascii') # json数据
    return arr

def sub_cb(topic, msg):
    global state
    print((topic, msg))
    if msg == b"on":
        g4.value(1)
        state = 1
        print("1")
    elif msg == b"off":
        g4.value(0)
        state = 0
        print("0")
    elif msg == b"toggle":
        state = 1 - state
        g4.value(state)

def main(server=SERVER):
    #端口号为:6002
    c = MQTTClient(CLIENT_ID, server,6002,username,password)
    c.set_callback(sub_cb)
    c.connect()
    c.subscribe(TOPIC)
    print("Connected to %s, subscribed to %s topic" % (server, TOPIC))
    #publish报文上传数据点
    c.publish('$dp',pubdata(message))
    print('publish message:',message)

    try:
        while 1:
            c.wait_msg()
    finally:
        c.disconnect()

程序解析

def pubdata(data):
    j_d = json.dumps(data)
    j_l = len(j_d)
    arr = bytearray(j_l + 3)
    arr[0] = 1 #publish数据类型为json
    arr[1] = int(j_l / 256) # json数据长度 高位字节
    arr[2] = j_l % 256      # json数据长度 低位字节
    arr[3:] = j_d.encode('ascii') # json数据
    return arr

我们自定义一个pubdata方法,该方法的功能是组合成协议要求的报文格式。

c.publish('$dp',pubdata(message))

设备使用publish报文来上传数据点。$dp为系统上传数据点的指令(2个字节的字符串)。

效果展示

点击运行TPYBoard v202的程序

_images/071.png

找到设备管理页面,在tpyboardv202设备信息的操作列中,点击[查看详情]。

_images/081.png

选择[数据展示],

_images/091.png

选择数据流[temperature]信息行的最右侧展开小三角,查看详细数据点。

_images/103.png _images/116.png

大家可根据上面学习到的内容进行扩展,比如接DHT11温湿度模块等各类传感器,上传温湿度、气压、光照等信息。 OneNET云平台除了支持MQTT协议外,还支持HTTP、TCP透传等多种协议,大家可以尝试添加其他协议的产品进行智能物联的开发。

高手专场

经过前面两个阶段的练习,想必你已经成为一名TPYBoard的高手了。那就来挑战下高手专场的实例训练吧!

[Micropython]TPYBoard v202 家庭气象站
一、实验器件
  • TPYBoard v102 1块
  • TPYBoard v202 1块
  • Nokia 5110LCD显示屏 1块
  • DHT11温湿度传感器 1个
  • micro USB 数据线 2根
  • 面包板 1块
  • 杜邦线 若干
二、实验步骤
  • TPYBoard v102连接DHT11,采集温湿度信息;
  • TPYBoard v102将采集到的温湿度信息显示在LCD5110上;
  • TPYBoard v102通过串口将温湿度信息发送给TPYBoard v202;
  • TPYBoard v202 将串口的数据读取出来,同时传递到服务器上。
三、实验方法
1、Nokia 5110 LCD显示屏说明

LCD5110是一款84x48 的点阵LCD,可以显示4 行汉字。采用串行接口与主处理器进行通信,支持多种串行通信协议(如AVR 单片机的SPI、MCS51 的串口模式0等),传输速率高达4Mbps,可全速写入显示数据。

_images/5110.png

Nokia 5110 LCD共有8个引脚,不同的板子可能标注的英文略有不同,具体参照如下:

_images/51101.png
2、DHT11温湿度说明

DHT11是一款有已校准数字信号输出的温湿度传感器。 精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃。

_images/DHT111.png

DHT11温湿度共有3个引脚,具体参照如下:

_images/DHT1121.png
四、接线方式
1、针脚对应图

DHT11和LCD5110的使用方法上面都介绍过了,接下来,就要动手和我们的TPYBoard v102 接起来了。

TPYBoard v102连接LCD5110

_images/5110+102.png

TPYBoard v102连接DHT11

_images/102+DHT111.png

TPYBoard v102连接TPYBoard v202

_images/202+102.png

注意: TPYBoard v202只有一个串口,在使用时比较麻烦。因为REPL也是通过串口输出的,有些字符会导致v202的程序停止,或者支持REPL(puuty)等工具会无法使用。使用时,应多注意冲突。

2、实物连接图
_images/5110+102+202.png
五、源代码

TPYBoard v102 源代码

_images/V102.png

TPYBoard v102 main.py文件内容如下:

#main.py
import pyb
import upcd8544
from machine import SPI,Pin
from dht11 import DHT11
def main(lcd_5110,dht,uart6):
    data_=dht.read_data()
    lcd_5110.lcd_write_string(' ',0,1)#添加一个分隔行
    lcd_5110.lcd_write_string('Temp:'+data_[0],2,2)
    lcd_5110.lcd_write_string(' ',0,3)
    lcd_5110.lcd_write_string(' Hum:'+data_[1],2,4)
    uart6.write(data_[0]+','+data_[1])#通过串口将数据发送给v202
if __name__ == '__main__':
    #init UART
    u6=pyb.UART(6,115200)
    #init DHT11
    dht=DHT11('X12')
    #init LCD5110
    SPI    = pyb.SPI(1)
    RST    = pyb.Pin('Y11')
    CE     = pyb.Pin('Y10')
    DC     = pyb.Pin('Y9')
    LIGHT  = pyb.Pin('X4')
    #DIN=>X8-MOSI/CLK=>X6-SCK
    #DIN =>SPI(1).MOSI 'X8' data flow (Master out, Slave in)
    #CLK =>SPI(1).SCK  'X6' SPI clock
    lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
    lcd_5110.lcd_write_string('TPYBoard v102',1,0)
    while True:
        main(lcd_5110,dht,u6)
        pyb.delay(2000)

TPYBoard v202 main.py文件内容,如下:

import machine
import network
import socket
from machine import Pin
from machine import UART
import time
u2=UART(0,115200)#串口初始化
led = Pin(2, Pin.OUT).value(1)#板载小蓝灯 默认关闭
def http_get(temp,hum):
    url='http://old.tpyboard.com/esp8266/SensorTest.php?t='+temp+'&h='+hum+''
    _, _, 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').upper()
            #print(str(data, 'utf8'), end='')
            if(recive.find('YES')>-1):
               print('Send Data OK')
        else:
            break
    s.close()
def do_connect():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect( 'ssid', 'pwd')
        while not wlan.isconnected():
            pass
    print('network config:', wlan.ifconfig())
do_connect()
led = Pin(2, Pin.OUT).value(0)#连接wifi成功 点亮LED
while 1:
    data_=u2.readall()
    if data_!=None:
        data_=data_.decode('utf8')#数组转成字符串
        data_a=data_.split(',')#分割
        temp_=str(data_a[0])#温度
        hum_=str(data_a[1])#湿度
        http_get(temp_,hum_)#发送给服务器
                    time.sleep(2)

服务器源码

SensorTest.php 用于接收TPYBoard v202提交的数据。

SensorData.php 用于显示TPYBoard v202上传的数据。

页面下方点击下载源码,获取SensorData.php和SensorTest.php文件。

六、效果图
1、实物效果图 _images/SW1.png
[Micropython]TPYBoard v202 邪恶改装:TPYBoard制作廉价WIFI干扰器
引言

想不想搞个WIFI干扰器?网上搜集了一下资料,发现用esp8266可以实现简单的干扰功能,包括断网、复制、欺骗等等。刚好手上有块Tpyboard V202(30元),也是esp8266芯片的,也是想换个固件是不是也可完成呢?周末动手试一下。

搭建开发环境
  • 网上下载了一个使用esp8266制作Deauth无线攻击的开源固件,是arduino开发的。

github下载地址:https://github.com/PakchoiFood/ESP8266_deauther

里面包含了arduino IDE(arduino-1.8.2-windows.exe)和固件源码(esp8266_deauther-master.rar)。另外,还需要esp8266开发包(Arduino15.rar)可以从下面链接:http://pan.baidu.com/s/1bpnJMkn 下载。

  • 下载完毕后,解压如下:
_images/113.png
  • 双击arduino-1.8.2-windows.exe 安装arduino IDE。(如果你已经安装过arduino IDE,这步可以省略)
  • 安装完毕后,打开arduino,菜单找到 文件—》首选项,点击红色区域进入SDK目录
_images/26.png

我的路径是:C:\Users\Administrator\AppData\Local\Arduino15

将从网盘下载的Arduino15.rar 解压,把里面全部的文件直接覆盖C:\Users\Administrator\AppData\Local\Arduino15下文件。

_images/35.png
硬件器件的准备

将tpyboard V202与电脑连接,找到arduino IDE菜单里工具—》开发板 在右侧出来的菜单中向下找,会找到一个TPYBoard v202点击选中。

_images/47.png
编译烧写固件
  • 解压esp8266_deauther-master.rar,arduino IDE菜单栏 文件-》打开esp8266_deauther-master源码包esp8266_deauther\esp8266_deauther.ino
  • TPYBoard v202 使用micro USB数据线接入电脑。查看安装的usb转串的端口。打开电脑的设备管理器(这里是COM11)
_images/54.png
  • 工具-》端口,选择COM11(根据自己的实际端口号选择)
_images/63.png
  • 菜单栏下面的绿色图标菜单区,选择上传,开始编译,烧写固件
_images/72.png
  • 查看最下方的日志区域
_images/82.png

等待编译完成,出现下图信息(状态:变为“上传”)时,按住FLASH的同时,按一下RST按键并松开,让TPYBoard v202复位一下,进入烧写模式。继续按着FLASH,出现下面的信息时就可以松开FLASH按键了。

_images/811.png _images/91.png

烧写固件时,板子上的蓝色小LED灯会一直快速闪烁。

_images/10.jpg

烧写完毕后,显示上传成功,板子上的蓝色小LED会停止闪烁。

_images/114.png
测试攻击效果
  • 成功烧写固件后,打开无线会搜索到名称为TPYBoard v202 的热点,密码默认tpyboard,进行连接。
_images/123.png
  • 连接成功后,打开浏览器输入192.168.4.1 。点击[我已阅读并理解上面的通知](本次实验只用于测试实验,请谨慎使用)。

网页原版是英文的,为了方便使用,我简单的翻译了一下(wifi SSID和密码也做了修改),下载的压缩包里也有英文原版的。

_images/132.png
  • 点击进来以后,首先扫描一下附近的wifi。点击[扫描]。
_images/142.png
  • 接下来我们选择一个wifi做一下攻击的测试,为了方便测试是否成功,选择平时经常使用的wifi,我的列表中选择boda。
_images/156.png
  • 选择好后,点击最上方菜单栏[攻击],进入攻击页面。
_images/162.png
  • 攻击方式有3种,Deauther、Beacon和Probe-Request。页面最下方有对这3种方式的介绍,Probe-Request实在不知道怎么翻译,大神们可以指点一下。
_images/171.png
  • 我们这次使用Deauther方式,阻止客户端连接,点击[START]开始攻击。
_images/181.png
  • 找一个手机做一下实验,看是否还能连上boda。
_images/191.png

如果是第一次连接的话,会一直停在正在连接的界面上,无法连接成功。

如果原本连接着,会被强迫断线。

  • 点击[STOP],停止攻击。停止后,手机成功连接上boda了。
_images/20.png
  • esp8266_deauther里面还带了wifi复制等其他攻击方式,大家可以自己尝试一下。

免责声明

请不要在非合法情况下利用TPYboard实施攻击,这种行为将会被视作非法活动。由本软件所造成的任何不良后果,作者将不承担任何责任,请各位谨慎使用。

[Micropython]TPYBoard v202 邪恶改装2:用单片机实现一次完整的wifi攻击
前言

前段时间用TPYBoard v202 做了一个简单的WIFI干扰攻击器(ps:没有看过的小伙伴,可以看一下:http://www.freebuf.com/column/136985.html),最近几天,一直在想,如何用单片机实现一次完整的wifi攻击。于是想在干扰后,是否能成功拿到wifi的登陆密码。

攻击构思

利用tpyboard v202将wifi干扰的同时,将v202的ssid和信道改为与受干扰wifi相同的SSID及信道。此时,受干扰用户极有可能去连接虚假的WIFI,当用户连接后,无论用户访问哪个网络都会跳出伪装的输入密码的页面,从而诱导其写入密码。当密码写入后,v202后尝试验证密码的正确性,如果正确将停止干扰,并将密码存入TF卡,否则再次进行干扰。

搭建开发环境
  • 首先你的需要TPYBoard v202和TPYBoard V102开发板各一块。
  • 网上下载了一个使用esp8266制作Deauth无线攻击的开源固件,是arduino开发的。

github下载地址:https://github.com/PakchoiFood/TPYBoard-v202-v102-EvilPlans

里面包含了arduino IDE(arduino-1.8.2-windows.exe)、固件源码(esp8266_wifi.rar)、TPYBoard v102的源码(TPYBoard v102.rar)和串口调试工具(XCOM V2.0.rar)。另外,还需要esp8266开发包(Arduino15-2.rar)可以从下面链接:http://pan.baidu.com/s/1pLnwz7l 下载。

  • 下载完毕后,解压如下:
_images/115.png

esp8266_wifi.rar的固件是在上一篇【邪恶改装:TPYBoard制作廉价WIFI干扰器】的实验基础上增加了骗取WIFI密码的功能。同时使用串口和TPYBoard v102进行连接,将获取到的WIFI密码传递给v102,v102接收到正确的密码后,进行TF卡的存储,同时也记录下攻击日志。

  • 双击arduino-1.8.2-windows.exe 安装arduino IDE。(如果你已经安装过arduino IDE,这步可以省略)。
  • 安装完毕后,打开arduino,菜单找到 文件—》首选项,点击红色区域进入SDK目录。我的路径是:C:\Users\Sen\AppData\Local\Arduino15。
_images/27.png
  • 解压Arduino15-2.rar,将里面的全部内容直接覆盖C:\Users\Sen\AppData\Local\Arduino15下的文件。
_images/36.png
编译烧写固件
  • 1、如果你对V102及V202的使用方法不熟悉,可以参考TPYBoard 官方docs网站。

http://docs.tpyboard.com/zh/latest/tpyboard/tutorial/

TPYBoard v102 源代码(main.py)

import pyb
from pyb import UART

u4=UART(4,115200)
mkdir_='/sd/log.txt' #需先插入TF卡 新建log.txt
pyb.LED(2).on()
while True:
    if(u4.any()>0):# 判断串口是否有数据
        _mag=''
        pyb.LED(3).toggle()
        f=open(mkdir_,'a')
        _data=u4.readline()#读取一行数据
        _dataMsg=_data.decode('utf-8')#将字节数据转码成utf-8 编码的字符串
        print('_dataMsg:',_dataMsg)
        #解析数据
        _index_h=_dataMsg.find('tpyboardpwd')
        _index_e=_dataMsg.find('*')
        if _index_h>-1 and _index_e>-1 and (_index_e-_index_h)>11:
            _dataMsg=_dataMsg.replace('tpyboardpwd','').replace('*','')
            print('GetPwd:',_dataMsg)
            _mag=_mag+'---------------attack log------------\r\n'
            _mag=_mag+'SSID:'+_dataMsg.split('+')[0]+'--'+'PWD:'+_dataMsg.split('+')[1]
            print('-------------------------\r\n')
            pyb.LED(4).toggle()
        if _mag!='':
            f.write(_mag)#将获取到的SSID和PWD 保存在日志文件中
        f.close()

2、本文重点讲解TPYBoard v202的使用方法

  • (1)解压esp8266_wifi.rar,arduino IDE菜单栏 文件-》打开esp8266_wifi源码包下的esp8266_deauther\esp8266_deauther.ino
  • (2)TPYBoard v202 使用micro USB数据线接入电脑。查看安装的usb转串的端口。打开电脑的设备管理器(这里是COM44)
_images/48.png
  • (3)工具-》端口,选择COM44(根据自己的实际端口号选择)
_images/55.png
  • (4)菜单栏下面的绿色图标菜单区,选择上传,开始编译,烧写固件
_images/64.png
  • (5)查看最下方的日志区域
_images/73.png _images/83.png

等待编译完成,出现上图信息(状态:变为“上传”)时,按住FLASH的同时,按一下RST按键松开,让TPYBoard v202复位一下,继续按着FLASH,出现下面的信息时就可以松开FLASH按键了。

_images/92.png
硬件的连接

代码和程序都完成了,接下来需要将TPYBoard v102和TPYBoard v202 的串口连接起来。

连接示意图:

_images/172.png

连接实物图:

_images/实物1.jpg _images/实物2.jpg
测试效果
  • 1、首先用我自己家的WIFI做测试,我先用手机接入WIFI(Tend_01CB30)。
  • 2、解压XCOM V2.0.rar,解压双击运行XCOM V2.0.exe 串口助手。打开串口根据自己的选择,我的是COM44 波特率115200 其余默认,打开串口,就可以看到v202打印的信息了。

ps:刚才v202烧写完固件后会马上自启动,所以这里先复位一下v202,按一下RST,这样我们就可以看到从开始到最后的整个过程了。

_images/121.jpg
  • 3、大家可以看到,v202启动会搜索到了很多附近的WIFI,然后它就判断出那一个信号最强,我这里肯定是我家的最强了,于是v202开始攻击[Tend_01CB30] 这个WIFI,同时也会建立一个开放的[Tend_01CB30]热点。攻击时,v202上的小蓝灯会常亮。
_images/133.png
  • 4、此时我的手机已经连接不到我原有路由器的[Tend_01CB30]的WIFI。这时,如果换成完全不知情的别人,极有可能会去手机设置里面看,怎么连接不上网络了?
  • 5、这时他就会手动去点击连接[Tend_01CB30],当然他会发现有两个一样名字的WIFI,因为我们是Open的,所以他再连接他原有WIFI失败后,会连入到伪装的WIFI上来。
  • 6、当我们成功骗取他连接我们的WIFI后,只要打开浏览器,输入任何网址,都会自动跳转到虚假网络密码确认页面。
_images/143.png
  • 7、测试输入12345678点击确认,串口调试助手中可以看到获取到的WIFI密码,然后停止攻击,小蓝灯会熄灭。
  • 8、同时,v202会自己先去尝试连接,来验证密码的准确性,如果连接成功的话,会自动将密码传送给v102 进行保存;如果连接失败,v202会继续进行干扰攻击。
_images/157.png
  • 9、查看一下TF卡中的log.txt文件,是否记录了刚才破解的密码。

(TPYBoard v102使用TF卡时,数据不会实时更新,你需要重新复位才能看到刚才更新的log.txt 的内容)

_images/163.png

本实验仅供学习参考。

[Micropython]TPYBoard v202 利用单片机快速实现家庭智能控制平台

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

0x00 前言

一提到智能家庭,大家可能首先想到的是各种大佬级公司搞的牛逼产品,或者说是创新产品。想想就觉得很复杂,有的用工控机,有的用树莓派,还有的用arduino,不管用什么,都绕不过服务器进行控制,比如yeelink平台,腾讯的智能硬件平台等等。其实,真实实现起来,并没有想想中这么复杂,我们甚至只用一个小的单片机就能实现。

0x01 单片机实现web服务器

探讨用单片机来实现web服务器的文章通过baidu也能找到几篇,但比较详实的实现方法并没有找到,这里考虑有两种思路可以完成,一种是有线的lan模块,如w5500,这种模块本身就带有web服务的部分功能,使用起来比较简单,但是只能基于lan进行访问。另一种是通过stm32等单片机,配合网络模块来完成。当前我能想到的最简单的方法就是用stm32+esp8266来实现。

基于第一种方法,我觉得受模块性能影响比较大,受限于模块,没有开发感。于是考虑用第二种方法。这个方法里,有人用arduino来完成,这要基于c进行编程。另外,就是考虑用micropython,这样直接可以用python来实现。这里依然使用tpyboard V202。

0x02 模拟实现家庭智能家居控制平台

因为没有想好要做一个多么复杂的实验,只是想能模拟一下效果,所有在整个的模块过程中,我选用了tpyboard v202开发板做主控制板,用一个发光二极管来模拟一个台灯(现实中,这里其实可以用一个继电器来控制其它设备的通断电),用一个直流小电机加迷你风扇叶表示模拟电风扇。整个实现还用到了一个三极管(S9014,NPN)来控制直流电机。

0x03 硬件的搭建与连接
发光二极管的使用

发光二极管使用比较简单,直接看它的两条“腿”,长的那个是正极,反之是负极。

_images/01.jpg
直流小电机的使用方法 _images/02.jpg

上图直流小电机中,红色框内的两个接线端A和B,无论那个接正极或负极都可以,只不过转动的方向不一样而已。本次我是用B端接入正极,正好是顺时针转动。

三极管S9014(NPN)的使用方法 _images/03.png

本次我们使用S9014的放大和开关功能,集电极接入v202的3.3V引脚,发射极接入电机某一端,通过给基极高低电平来控制发射极和集电极之间是否导通,从而控制直流电机转动或停止。

下面来介绍一下接线方法

_images/144.png
0x04 利用micropython实现web服务器

首先,编辑一个main.py文件。v202 开机自启动main.py 文件。

try:
    import usocket as socket
except:
    import socket
import network
from machine import UART
from machine import Pin

led_flag=Pin(2, Pin.OUT)#esp8266模块上的小灯 高电平:灭 低电平:亮
led = Pin(4, Pin.OUT)#发光二极管的控制引脚
motor = Pin(5, Pin.OUT)#直流电机的控制引脚
#初始化
led.value(0)
motor.value(0)
led_flag.value(1)
def do_connect(ssid,pwd):
    sta_if = network.WLAN(network.STA_IF)#STA 模式
    sta_if.active(False)
    if not sta_if.isconnected():#判断是否连接
        sta_if.active(True)
        sta_if.connect(ssid,pwd)#ssid:WIFI名称 pwd:WIFI 密码
        while not sta_if.isconnected():
            pass
    if sta_if.isconnected():
        return sta_if.ifconfig()[0]
def main(ip_,dev_data,login_data,name,pwd):

    s = socket.socket()
    ai = socket.getaddrinfo(ip_, 80)
    addr = ai[0][-1]
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(addr)
    s.listen(5)
    led_flag.value(0)
    #s_data=login_data
    while True:
        res = s.accept()
        client_s = res[0]
        client_addr = res[1]
        led_flag.value(1)
        req =client_s.readline()
        while True:
            h = client_s.readline()
            if h == b"" or h == b"\r\n":
                break
            #print(h)
            req+=(h.decode('utf-8'))
        print("Request:")
        req=req.lower()
        req=req.decode('utf-8').split('\r\n')
        #http header 解析
        req_data=req[0].lstrip().rstrip().replace(' ','')
        print(req_data)
        if req_data.find('favicon.ico')>-1:
            client_s.close()
            continue
        else:
            if len(req_data)<=12:
                #说明是第一次访问,输入login.html
                s_data=login_data
            else:
                req_data=req_data.replace('get/?','').replace('http/1.1','')
                _name=req_data.find('name')
                _pwd=req_data.find('pwd')
                if _name>-1 and _pwd>-1:
                    #判断是否是用户登录
                    if req_data.find(name)>-1 and req_data.find(pwd)>-1:
                        s_data=dev_data
                        print('Login Success!')
                    else:
                        f=open('fail.html','r')
                        s_data=f.read()
                        f.close()
                        print('Login Fail!')
                else:
                    #判断是否是控制LED
                    _index=req_data.find('led=')
                    if _index>-1:
                        s_data=dev_data
                        led_val=req_data[_index+4:_index+6].lstrip().rstrip()
                        print('led:',led_val)
                        if led_val=='on':
                            led.value(1)
                        else:
                            led.value(0)
                        print('led:',led.value())
                    #判断是否是控制电机
                    _index=req_data.find('motor=')
                    if _index>-1:
                        s_data=dev_data
                        motor_val=req_data[_index+6:_index+8].lstrip().rstrip()
                        print('motor_val:',motor_val)
                        if motor_val=='on':
                            motor.value(1)
                        else:
                            motor.value(0)
                        print('motor:',motor.value())
            print('-----------')
            client_s.send(s_data)
            client_s.close()
        led_flag.value(0)

f=open('device.html','r')
dev_html=f.read()
f.close()
f=open('login.html','r')
login_html=f.read()
f.close()
f=open('info.txt','r')
info=f.read()
f.close()
name=info.split(',')[0].lstrip().rstrip()
pwd=info.split(',')[1].lstrip().rstrip()
print('name:',name)
print('pwd:',pwd)
myip_=do_connect('essid','password')#家中网络的WIFI名称和密码
print(myip_)
main(myip_,dev_html,login_html,name,pwd)

其他文件login.html、fail.html、device.html,点击下面的下载源码进行下载。

info.txt 这里是用文件存放的用户名和密码(英文逗号分隔),前面是用户名,后面是密码。

这里的用户名和密码是用来登录我们 智能家居控制平台的。

admin,123456

0x05 程序下载测试

使用MicroPython File Uploader 工具,将源代码下载到v202中。

工具下载地址: http://tpyboard.com/download/tool/170.html

  • 1、使用usb数据线将v202接入到电脑,打开设备管理器,查看加载的端口。我的是COM44
_images/04.png

※如果驱动安装失败,可以下载CH340的驱动,手动安装。

CH340驱动下载地址:http://tpyboard.com/download/drive/163.html

打开MicroPython File Uploader 选择端口,点击[Open]。

_images/05.png

取消[Autorun]的打钩,点击红框的文件夹图标,选择源码,点击[Send]等待发送成功。

_images/06.png

下载完毕后,点击[Run/Reset]就会开始执行代码。 开始运行后,红色框内打印的是我们存放在info.txt里的用户名和密码,这个可以自定义。 下面桃红色框内打印的是我们v202从路由器那里获取到的IP地址,只要打印了IP地址,说明就成功接入网络了。我的v202获取的IP地址是192.168.1.192。

_images/07.png

到此,我们的web服务器就搭建完成了。

0x06 智能家庭网络平台的使用

1、在家庭局域网内,我们可以选用pc或者手机,通过浏览器,打开192.168.1.192 就可以看到登录界面。

_images/08.png

2、默认用户名 admin 密码123456 ,大家可以通过修改info.txt 文件来进行修改。

(1)输入错误的用户名和密码会进入错误界面。

_images/09.png

(2) 输入正确的,进入控制平台。

_images/102.png

3、接下来,我们就可以通过网页开控制灯光和小风扇了。

这里,我只是做了一个实例,受时间限制,没有再做更深入的开发。大家可以自己结合自己的创意再深入去做。如果能够通过路由器给tpyboard v202设一个外网Ip,这样就可以从外网进行访问,从而完成外网对家内设备的控制。

[Micropython]TPYBoard v202 智能WIFI远控小车
前言

之前有过用TPYBoard v102制作的各种各样功能的智能小车,比如自动寻迹、自动避障、手机蓝牙遥控等。想着还缺个WIFI控制的,那就用TPYBoard v202做一个吧。

设计思路

WIFI是目前最有广泛运用的一项无线网络传输技术,覆盖范围广,可远程。本次实现了远程WIFI控制,不仅可以在家里操作,还可以接入一些云平台,实现远程操控。具体思路如下:

1、TPYBoard v202作为整个小车的核心控制部分,连接L298N电机驱动模块,实现小车的基本方向控制;

2、TPYBoard v202接入网络,开启Socket服务实现web服务器功能;

3、手机接入同一局域网,可通过浏览器访问控制页面,进行小车控制。

所需器件
  • TPYBoard v202开发板 1块
  • USB数据线(MicroUSB) 1条
  • L298N电机驱动模块 1个
  • 小车套件包(底板、电机等) 1个
  • 18650电池 2节
  • 18650电池盒 1个
程序源码

TPYBoard v202 源代码(main.py)

import socket                 #导入socket通信库
import machine
from machine import Pin

g4 = Pin(4,Pin.OUT)
g5 = Pin(5,Pin.OUT)
g12 = Pin(12,Pin.OUT)
g13 = Pin(13,Pin.OUT)

def Go():
    g4.value(1)
    g5.value(0)
    g12.value(1)
    g13.value(0)
def Back():
    g4.value(0)
    g5.value(1)
    g12.value(0)
    g13.value(1)

def Left():
    g4.value(1)
    g5.value(0)
    g12.value(0)
    g13.value(0)
def Right():
    g4.value(0)
    g5.value(0)
    g12.value(1)
    g13.value(0)
def Stop():
    g4.value(0)
    g5.value(0)
    g12.value(0)
    g13.value(0)
#-----------------------HTTP Server-----------------------#
#ap模式下,默认ip地址为192.168.4.1
addr = ('192.168.4.1',80) #定义socket绑定的地址,ip地址为本地,端口为80
s = socket.socket()     #创建一个socket对象
s.bind(addr)            #绑定地址
s.listen(5)             #设置允许连接的客户端数量
print('listening on:', addr)
while True:
    cl, addr = s.accept() #接受客户端的连接请求,cl为此链接创建的一个新的scoket对象,addr客户端地址
    print('client connected from:', addr)
    cl_file = cl.makefile('rwb', 0) #返回与socket对象关联的文件对象。rwb:支持二进制模式的读写操作 0:默认值,不支持缓存
    req = b''
    while True:
        line = cl_file.readline() #读取发送过来的数据,直到\r\n换行结束
        if not line or line == b'\r\n':
            break
        req += line
    print("Request:")
    req=req.decode('utf-8').split('\r\n')
    #http header 解析
    req_data=req[0].lstrip().rstrip().replace(' ','').lower()
    print(req_data)
    if req_data.find('favicon.ico')>-1:
        cl.close()
        continue
    else:
        req_data=req_data.replace('get/?','').replace('http/1.1','')
        index = req_data.find('key=')
        value = req_data[index+4:index+6].lstrip().rstrip()
        print('key:',value)
        if value == 'go':
            Go()
        elif value == 'ba':
            Back()
        elif value == 'le':
            Left()
        elif value == 'ri':
            Right()
        else:
            Stop()
    with open("control.html", 'r') as f:
        for line in f:
            cl.send(line)
    #cl.send(response)   #返回html网页的数据
    cl.close()          #关闭socket
硬件的连接
TPYBoard v202 L298N电机驱动模块
VIN +5V
GND GND
G5 IN1
G4 IN2
G13(MO) IN3
G12(MI) IN4
两侧电机 L298N电机驱动模块
车头朝前,右侧电机 OUT1,OUT2
车头朝前,左侧电机 OUT3,OUT4

注:电机不分正负极,怎么接都可以,只不过就是正转和反转的问题。若在调试中电动转动方向不对,你可以修改程序或者将接线调换

L298N电机驱动模块 电池盒
+12V 正极(红线)
GND 负极(黑线)

注:可在电池正极与电机驱动之间外接一个按键开关模块,这样可以增加一个总开关功能。

网页效果
_images/html.png
演示效果

点击观看视频

源码下载

下载源码

[Micropython]TPYBoard v202 固件的检查与擦除

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

实验目的
  • 学会TPYBoard v202开发板的固件完整性检查
  • 学会flash的擦除方法
准备工作
  • TPYBoard v202板子 1块
  • micro USB数据线 1条
  • 电脑 1台(本次实验以win7为例)
  • PuTTY(工具)
固件完整性检查

第一步:下载安装所需的软件--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

第六步:按下图命令操作

运行命令:

import esp
esp.check_fw()
http://www.tpyboard.com/ueditor/php/upload/image/20170315/1489557784930344.png

如果最后显示True,代表固件是完整的,否则可能存在问题。如果显示False,最好重新刷一次固件。 详情可参考下一篇文档进行固件的烧写。

固件的擦除

第一步:安装Python环境

从Python的官方网站http://www.python.org下载最新的2.7版本

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

第二步:安装esptool和pyserial

在CMD命令行里运行:pip install esptool和pip install pyserial

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

第三步:擦除flash

打开CMD命令行,运行指令:

esptool.py --port COM3 erase_flash

(注意:执行擦除的指令前,需要像烧录固件一样,让esp8266进入烧写模式)即按住板上的FLASH键不放,按下RST键松开,当界面显示出MAC地址后,即可松开FLASH按键等待擦除完毕。如果在超时时间内没有让板子进入烧写模式的话 ,就会出现如下的错误提示:A fatal error occurred: Failed to connect to ESP8226

固件成功擦除后,可参考下一篇文档进行固件的烧写。

[Micropython]TPYBoard v202 固件烧写

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

前言

今天,带大家一起玩一下最新的开发板TPYBoard v202开发板,这是一款基于esp8266模块的micropython开发板。

准备工作
  • TPYBoard v202开发板 1个
  • micro USB数据线 1条
  • 电脑 1台(嘻嘻,本篇文章以windows7系统为例)
烧写固件

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

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

flash_download_tools_v3.3.4_win.zip

第二步:连接TPYBoard v202开发板

通过USB数据线将电脑和TPYBoard-esp8266开发板连接起来,会自动安装USB转串的驱动。安装完毕后,查看设备管理器,是否正确创建串口(我的电脑是COM44)

http://www.tpyboard.com/ueditor/php/upload/image/20170222/1487749376138909.png

打开ESPFlashDownloadTool_v3.3.4软件,根据下图进行设置。 选择bin格式的固件文件,固件可以去micropython官网下,点击进入。 地址设置为0x00000,串口根据自己的实际情况选择,小编我的是COM44,波特率115200(必须设置为115200)

http://www.tpyboard.com/ueditor/php/upload/image/20170222/1487750143795401.png

设置完毕后,点击START。提示上电同步。

http://micropython.net.cn/ueditor/php/upload/image/20170222/1487750496548782.png

这时你需要让板子进入烧写模式。按住板子上的SW2(FLASH)按键不松,同时按一下SW1(RST)按键松开。

界面显示下载中... 同时右边区域显示设备的MAC地址,此时松手只需要等待下载完成即可。

http://www.tpyboard.com/ueditor/php/upload/image/20170222/1487750528571423.png

TPYBoard v702 典型实例

TPYBoard v702开发板是在v102基础上增加了GPS/GPRS的功能,基本使用完全兼容v102的教程,所以这里,我们就直接引用了v102的教程

新手入门

帮助初学者快速掌握TPYBoard v702开发板的使用技巧。

进阶训练

学习使用TPYBoard v702开发板进行一些基础的实例训练。

高手专场

经过前面两个阶段的练习,想必你已经成为一名TPYBoard的高手了。那就来挑战下高手专场的实例训练吧!

[Micropython]TPYBoard v702 LCD5110显示环境信息

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

什么是TPYBoard v702

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

TPYBoard v702实物图

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188183717935.png
TPYBoard v702获取温度、湿度及光照度

具体要求

利用TPYBoard v702获取温度、湿度及光照度

所需器件

  • TPYBoard v702开发板 1块
  • 温湿度传感器和光敏系统均属于板载器件,无需外接

板载温湿度传感器介绍

TPYBoard v702板子温湿度传感器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%)

光敏系统介绍

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

制作主要过程

实物效果图

http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493091201375274.png

制作过程

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

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

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

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

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

(6)把我们需要用到的接口进行声明和定义,这里我们主要用到了spi和adc这两类接口;

(7)下面开始主函数的编写,首先我们把调用到的SHT20的类库中的函数的返回值读取出来,这样我们就获取到了温度和湿度的数值,其次我们定义ADC的的引脚和模式,上面我们介绍了我们这边的这个光敏系统我们使用的引脚是Y12引脚,我们这里需要把引脚数定义成Y12,其他的我们缺省处理;

(8)完成以上工作后,我们读取ADC引脚的返回值,这样我们获取到温度,湿度和亮度这三个数值;

(9)在完成温度湿度和亮度这三个数值的获取后,我们需要做的就是把这三个数值相应的在5110显示屏上显示出来,在5110显示屏的类库中控制5110显示的函数,可以直接调用;

(10)完成步骤9后,就完成了一个循环,这样往复的循环下去,我就可以实时的检测温湿度以及亮度了,在例程设计的时候,我们还设计了当亮度小于十的时候,蜂鸣器会发出响声。

具体代码

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


ds = SHT20(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('X20')
CE     = pyb.Pin('X19')
DC     = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
N2 = Pin('Y3', Pin.OUT_PP)
N1 = Pin('Y6', Pin.OUT_PP)
N1.low()
pyb.delay(2000)
N1.high()
while True:
    ads = pyb.ADC(Pin('Y12'))
    a=ads.read()
    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<17):
        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]TPYBoard v702 LCD5110显示当前经纬度

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

什么是TPYBoard v702

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

TPYBoard v702实物图

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188183717935.png
TPYBoard v702获取经纬度信息

具体要求

利用TPYBoard v702完成所在地经纬度采集,并在LCD5110显示屏上显示

所需器件

  • TPYBoard v702开发板 1块
  • LCD5110显示屏一块

板载定位功能及使用介绍

TPYBoard v702的开发板的整体整体亮点就是能进行定位,可以获取到当前所在地的经纬度,高度,时间等等的一些信息。在这个实验里面我们就要用到获取经纬度这一功能。这个开发板上主要的硬件功能已嵌入到了开发板上,使用起来非常方便,我们只需要进行简单的设置操作就能获取到经纬度,然后再进行数据解析,分割以及数据转换等处理,就可以得到我们想要的经度和纬度了,之后我们在使用显示屏把经纬度显示出来就完成了在开发板上显示经纬度了。

制作主要过程

效果图

http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493097993618155.png

制作过程

(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发送相应的指令,获取相应的数据,再把相应的数据进行数据转换,并显示到显示屏上即可。

具体代码

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART

leds = [pyb.LED(i) for i in range(1,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('X20')
CE     = pyb.Pin('X19')
DC     = pyb.Pin('X18')
LIGHT  = pyb.Pin('X17')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
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,timeout=100)

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()
    u2.write('AT+GPSLOC=1\r\n')
    pyb.delay(3000)
    _dataRead=u2.read()
    print('搜星=',_dataRead)
    pyb.delay(1000)
    u2.write('AT+GPSLOC=0\r\n')
    pyb.delay(200)
    print('BEIDOU')
    _dataRead=u2.read()
    if _dataRead!=None:
        print('原始数据=',_dataRead)
        print('原始数据长度:',len(_dataRead))
        if 60<len(_dataRead)<70:
            _dataRead = _dataRead.decode('utf-8')
            _dataRead1=_dataRead.split(',')
            print('数据=',_dataRead1)
            print(len(_dataRead1),'***')
            if len(_dataRead1)>4:
#*******************纬度计算********************
                weidu=_dataRead1[1]
                WD=DataConver(weidu,0)
#*******************经度计算********************
                jingdu=_dataRead1[2]
                JD=DataConver(jingdu,1)
                if jingdu.find('0.0000')<0:
                    N2.high()
#***********************时间************************
    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)
[Micropython]TPYBoard v702 GPRS功能测试

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

什么是TPYBoard v702

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

TPYBoard v702实物图

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

具体要求

利用TPYBoard v702使用GPRS功能把数据上传至服务器

所需器件

  • TPYBoard v702开发板 1块
  • SIM卡 1张(支持移动、联通)

板载通信功能及使用介绍

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

制作主要过程

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

Putty数据监控图

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

示例定位图

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

制作步骤

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

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

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

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

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

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

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

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

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

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

具体代码

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART

#lcd5110初始化
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)
lcd_5110.clear()
lcd_5110.lcd_write_string('Getting Ready',0,1)
#GU620模块初始化
N1 = Pin('Y6', Pin.OUT_PP)#定义通信系统启动引脚
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)#拉高拉低引脚,启动通信系统
u2 = UART(4,115200,timeout = 100)#定义串口4,设置 波特率为115200
#报文详细格式说明参照萝卜电子服务平台示例报文格式。
#www.turnipsmart.com:8080
message = 'TPGPS,1234567890abcde,36.67191670,119.17200000,201701120825,25,50,END'
if __name__ == '__main__':
    #连接TCP服务器
    u2.write('AT+CIPSTART="TCP","139.196.110.155",30000\r\n')
    while True:
        if u2.any() > 0:
            _dataRead = u2.read()
            print('_dataRead:',_dataRead)
            if _dataRead.find(b'CONNECT OK') > -1:
                #说明已经和服务器成功建立连接
                lcd_5110.lcd_write_string('CONNECT OK',0,2)
                print('CONNECT OK')
                pyb.LED(2).on()
                #发送指令进入透传模式
                u2.write('ATO0\r\n')
            if _dataRead.find(b'ATO0\r\n\r\nOK\r\n') > -1:
                #成功进入透传模式,退出透传模式发送+++,注意前后1秒内不能输入任何字符
                #发送数据给服务器
                u2.write(message)
            if _dataRead.find(b'TPGPSOK') > -1:
                #该数据为服务器返回
                #在向服务器发送了数据后,服务器会对数据进行判断,并返相应的报文
                pyb.LED(3).on()
                lcd_5110.lcd_write_string('SEND OK',0,3)
                break
[Micropython]TPYBoard v702 短信功能

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

什么是TPYBoard v702

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

TPYBoard v702实物图

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188183717935.png
短信发送原理

手机的信号频率很高,一般在900Mhz左右,靠电离层反射传播,打电话的手机信号传到最近的基站,也就是移动或者连通的信号塔,再由基站把高频信号频率降低,由基站和基站之间通信,这个信号是直线传播,遇到高的建筑物会被挡住,所以那些塔都竖的很高,传到接电话的手机附近的基站,再转成高频信号发给手机。

短消息业务(SMS-Short Message Service)的实现原理很简单:

  • 存储转发机制。SMS传送数据包的工作由移动网络中的短消息中心而不是终端用户来完成,如果用户不在服务区内,短消息就被存储在短消息中心,等用户出现之后,再转发给他,这是GPRS等业务所不具备的。
  • 传递确认机制。在电路交换数据环境中,连接是端到端的,所以用户能够知道连接是否完成,以及数据传递的情况。

基站永远是在发射信号的,其中很重要的一部分就是广播消息,广播消息中的一类是寻呼消息(含电话号码),每个手机都在时刻监听寻呼消息,当它发现一个寻呼消息是给它的话(即有人正打它电话),它就会和基站建立连接,通过基站和打你电话的人联系。

http://www.tpyboard.com/ueditor/php/upload/image/20170316/1489665696262351.png
了解GU620的短信发送流程

通过上面的描述,我们了解到了短信发送的基本原理和流程,下面我来了解一下GU620模块在应对这些流程时需要怎么做。 首先的我们需要把模块设置到短信发送的模式,这个通过AT指令AT+CMGF=1,来设置,这条指令是设置模块为打开短信发送格式,且以文本的格式发送。 上面一条我们说了,把短信以文本的模式发送,但是文本有很多种格式,这里我们再执行一条指令,把文本的格式设置成我们手机能稳定且正确识别的文本格式,AT+CSCS=“GB2312”,这条指令是把短信收发的文本格式设置为简体中文。 上面两条介绍了设置发送短信的模式和文本格式,这里说一个意外事件(在想要执行的流程之外发生的事件)发生的处理方法,要是在你正要发短信的时候,有一条新的短信进来了,那这个怎么办?要是新的短信一接收到,马上显示出来,显然不是很合理,会打断我们的流程,在这里我们使用AT+CNMI=2,1指令把接收到的新消息存储到SIM卡中,然后再给出提示,在我们想读的时候再读出来,这样比较符合常理。 在我们设置好以上的这些基本的设置步骤后,我们需要把发短信的一个重要因素,接收方的手机号码写进模块去,我们使用指令AT+CMGS=“手机号码”,这条指令是告诉模块想要通信的目的号码。 在发送了正确的指令和手机号后模块会有提示正确的返回值,当得到这个返回值的时候,我们就可以把我们想要发送的内容(不支持汉字)编辑进去,这样模块就会把编辑的短信内容发送给前面输入的手机号码上去。 当发送成功后,会返回发送的内容,以及相应的提示内容。

程序流程设计

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

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.模块返回发送的文本内容及相应的发送成功的提示后,结束程序。

源代码

下面是我写的简单的一个代码,提供给大家参考。

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART

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)
N1 = Pin('Y6', Pin.OUT_PP)
N1.low()
lcd_5110.lcd_write_string('Getting Ready',0,1)
pyb.delay(2000)
N1.high()
pyb.delay(10000)
u2 = UART(4, 115200,timeout = 100)
Message = 'Hello,I am TPYBoard v702'#输入你想要发送的短信的内容;
number = '1800000000'#输入想要发送的手机号

lcd_5110.lcd_write_string('Send Message',0,1)
lcd_5110.lcd_write_string(str(Message),0,2)
u2.write('AT+CMGF=1\r\n')#设置以文本方式发送短信
while True:
    if u2.any() > 0:
        _dataRead = u2.read()
        print('dataRead:',_dataRead)
        if _dataRead.find(b'AT+CMGF=1\r\n\r\nOK\r\n') > -1:
            u2.write('AT+CSCS="GB2312"\r\n')#设置文本编码
            lcd_5110.lcd_write_string('..',0,4)
        elif _dataRead.find(b'AT+CSCS="GB2312"\r\n\r\nOK\r\n') > -1:
            u2.write('AT+CNMI=2,2\r\n')#收到短信直接给出提示
            lcd_5110.lcd_write_string('...',0,4)
        elif _dataRead.find(b'AT+CNMI=2,2\r\n\r\nOK\r\n') > -1:
            u2.write('AT+CMGS="'+number+'"\r\n')#输入对方手机号
            lcd_5110.lcd_write_string('....',0,4)
        elif _dataRead.find(b'AT+CMGS="'+number+'"\r\n\r\n> ') > -1:
            u2.write(Message+'\r\n')#输入短信内容
            lcd_5110.lcd_write_string('.....',0,4)
        elif _dataRead.find(b'\r\n+CMGS') > -1 and _dataRead.find(b'OK') > -1:
            print('Send success')
            lcd_5110.lcd_write_string('Send success!',0,4)
        elif _dataRead.find(b''+Message+'') > -1:
            lcd_5110.lcd_write_string('......',0,4)
        else:
            print('error')
短信群发机制作

1.短信群发机是建立在上面的程序代码的基础上的;

2.在上面的代码中,我们是建立了一个字符变量来存储电话号码,这里我们建立一个数组来 存放电话号码;

3.在电话号码全部录入后;

4.我们来查询一下这个数组里面有几个电话号码(也就是告诉芯片你要给几个手机发短信);

5.然后我们对这个数组里面的数据进行依次调用;

6.并对这个数据执行发送短信的流程;

7.并获取到这是数组中的第几个数据;

8.如果数组中的数据全部调用了一次后,结束程序的发送;

7.短信群发机例程

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

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART

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)
N1 = Pin('Y6', Pin.OUT_PP)
N1.low()
lcd_5110.lcd_write_string('Getting Ready',0,1)
pyb.delay(2000)
N1.high()
pyb.delay(10000)
u2 = UART(4, 115200,timeout = 100)
Message = 'Hello,I am TPYBoard v702'#输入你想要发送的短信的内容;
number_list =['号码1','号码2','号码3','号码4']#手机号列表
count = 0
number = number_list[count]
lcd_5110.lcd_write_string('message sending',0,1)
u2.write('AT+CMGF=1\r\n')#设置以文本方式发送短信
while True:
    if u2.any() > 0:
        _dataRead = u2.read()
        print('dataRead:',_dataRead)
        if _dataRead.find(b'AT+CMGF=1\r\n\r\nOK\r\n') > -1:
            u2.write('AT+CSCS="GB2312"\r\n')#设置文本编码
            lcd_5110.lcd_write_string('..',0,4)
        elif _dataRead.find(b'AT+CSCS="GB2312"\r\n\r\nOK\r\n') > -1:
            u2.write('AT+CNMI=2,2\r\n')#收到短信直接给出提示
            lcd_5110.lcd_write_string('....',0,4)
        elif _dataRead.find(b'AT+CNMI=2,2\r\n\r\nOK\r\n') > -1:
            u2.write('AT+CMGS="'+number+'"\r\n')#输入对方手机号
        elif _dataRead.find(b'AT+CMGS="'+number+'"\r\n\r\n> ') > -1:
            u2.write(Message+'\r\n')#输入短信内容
            lcd_5110.lcd_write_string('......',0,4)
        elif _dataRead.find(b'\r\n+CMGS') > -1 and _dataRead.find(b'OK') > -1:
            print('Send success')
            if count < len(number_list) - 1:
                count += 1
                number = number_list[count]
                u2.write('AT+CMGS="'+number+'"\r\n')#输入对方手机号
            else:
                lcd_5110.lcd_write_string('Send success!',0,4)
        elif _dataRead.find(b''+Message+'') > -1:
            j = ((count+1)/len(number_list)*100)
            lcd_5110.lcd_write_string('......' + str(j) +'%',0,4)
        else:
            print('error')
[Micropython]TPYBoard v702 来电显示功能

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

什么是TPYBoard v702

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

TPYBoard v702实物图

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188183717935.png
TPYBoard v702实现来电显示

具体要求

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

所需器件

  • TPYBoard v702开发板 1块
  • LCD5110显示屏 1块
  • SIM卡 1张(支持移动、联通)
板载通信功能及使用介绍

TPYBoard v702的开发板的整体整体亮点置一就是能板载通信功能,只要在开发板的卡槽上插上一张可以使用的手机卡(不支持电信),即可使用该功能。开发板板载的通信功能包括了电话,短信,GPRS等功能,在这个实验里面我们只使用电话这个功能。 开发板板载的通信功能已经设计的很完善,在接到来电的时候,会主动的把来电的信息通过串口4发送进来,这样一来作为用户的我们就是需要把数据进行相应的处理加显示就可以了。

制作主要过程

效果图

http://www.tpyboard.com/ueditor/php/upload/image/20170425/1493092006716181.png

观看演示视频

制作过程

(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有数据发送过来,对数据进行相应的判断及处理,并显示到显示屏上即可。

具体代码

import pyb
import upcd8544
from machine import SPI,Pin
from pyb import UART

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)
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,timeout=100)

while True:
    N2.low()
    if u2.any()>0:
        _dataRead=u2.read()
        if _dataRead!=None:
            print('原始数据=',_dataRead)
            print('原始数据长度:',len(_dataRead))
            print('123',_dataRead[2:6])
            RING=_dataRead[2:6]
            print('111',_dataRead[18:29])
            HM=_dataRead[18:29]
            if(RING==b'RING'):
                N2.high()
                lcd_5110.lcd_write_string('Phone Number:',0,0)
                lcd_5110.lcd_write_string(HM.decode("utf8"),2,1)
        pyb.delay(1000)
[Micropython]TPYBoard v702 HTTP应用功能

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

什么是TPYBoard v702

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

TPYBoard v702实物图

http://www.tpyboard.com/ueditor/php/upload/image/20170426/1493188183717935.png
TPYBoard v702实现HTTP应用功能

具体要求

利用TPYBoard v702完成HTTP应用功能的测试,分别进行GET请求和POST请求。

所需器件

  • TPYBoard v702开发板 1块
  • LCD5110显示屏 1块
  • SIM卡 1张(支持移动、联通)
板载通信功能及使用介绍

TPYBoard v702的开发板的整体整体亮点置一就是能板载通信功能,只要在开发板的卡槽上插上一张可以使用的手机卡(不支持电信),即可使用该功能。开发板板载的通信功能包括了电话,短信,GPRS等功能,在这个实验里面我们只使用电话这个功能。 开发板板载的通信功能已经设计的很完善,在接到来电的时候,会主动的把来电的信息通过串口4发送进来,这样一来作为用户的我们就是需要把数据进行相应的处理加显示就可以了。

实现过程

为了方便测试,这里用PHP写了一个接收GET和POST请求的程序,代码非常简单,可以直接放到自己服务器上测试,也可以直接用,访问地址在下面源码中有。

PHP测试程序

<?php

$backstr = "error";
$getStr = $_GET["t"];
if($getStr!=""){
    $backstr = "{\"status\":\"0\",\"method\":\"GET\",\"data\":\"".$getStr."\"}";
}else{
    $postStr = file_get_contents("php://input");
    if($postStr!=""){
        $backstr = "{\"status\":\"0\",\"method\":\"POST\",\"data\":\"".$postStr."\"}";
    }
}
echo $backstr;
?>

编写v702上的程序

HTTP应用是通过板载的GU620模块来实现的,所以我们需要知道该模块HTTP应用的相关AT指令,才能去编写程序实现功能。 点击下载AT指令说明文档

GET请求实现代码

import pyb
from machine import SPI,Pin
from pyb import UART
import json

#GU620模块初始化
N1 = Pin('Y6', Pin.OUT_PP)#定义通信系统启动引脚
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)#拉高拉低引脚,启动通信系统
u2 = UART(4,115200,timeout = 50)#定义串口4,设置 波特率为115200
#初始化 HTTP 应用
u2.write('AT+HTTPINIT\r\n')
getURLCMD = 'AT+HTTPPARA=1,"http://old.tpyboard.com/v702/httptest.php?t=123456"\r\n'
#getURLCMD = 'AT+HTTPPARA=1,"https://www.baidu.com"\r\n'
while True:
    if u2.any() > 0:
        dataRead = u2.read()
        print('_dataRead:',dataRead)
        print('-'*30)
        if dataRead.find(b'OK') > -1:
            #AT命令执行成功
            #判断是执行的哪一步操作
            if dataRead.find(b'AT+HTTPINIT') > -1:
                #初始化HTTP成功
                #设置 HTTP 参数值 设置url
                u2.write(getURLCMD)
            elif dataRead.find(b'AT+HTTPPARA=1') > -1:
                #HTTP参数设置成功
                #发起GET请求获取数据
                u2.write('AT+HTTPACTION=0\r\n')
            elif dataRead.find(b'AT+HTTPREAD\r\n\r\n+HTTPREAD') > -1:
                #返回可用的数据信息,进行解析 获取到数据长度
                datalen = dataRead.decode().split(':')[1].split(',')[0]
                print('datalen:',datalen)
                #从第0位开始 读取指定长度的数据
                u2.write('AT+HTTPREAD=0,{}\r\n'.format(datalen))
            elif dataRead.find(b'HTTP/1.1 200 OK') > -1:
                #成功读取数据后 停止HTTP应用
                u2.write('AT+HTTPTERM')
                #进行数据解析 提取出我们需要的信息
                b = dataRead.decode()
                c = "{"+b.split('{')[-1].split('}')[0]+"}"
                #转成json对象 查看是否请求成功
                jsonobj = json.loads(c)
                print(jsonobj["status"])
                pyb.delay(100)
                break
        elif dataRead.find(b'ERROR') > -1:
            #AT命令执行失败
            if dataRead.find(b'AT+HTTPINIT') > -1:
                #初始化HTTP失败 有可能是之前的没有停止等原因
                #发送停止HTTP命令 再重新初始化
                u2.write('AT+HTTPTERM\r\n')
                pyb.delay(300)
                u2.write('AT+HTTPINIT\r\n')
        else:
            if dataRead.find(b'\r\n+HTTPACTION: 0, 200') > -1:
                #收到的数据提示 说明请求成功
                #查询当前可用数据
                u2.write('AT+HTTPREAD\r\n')

运行效果

_images/119.png

POST请求实现代码

import pyb
from machine import SPI,Pin
from pyb import UART
import json

#GU620模块初始化
N1 = Pin('Y6', Pin.OUT_PP)#定义通信系统启动引脚
N1.low()
pyb.delay(2000)
N1.high()
pyb.delay(10000)#拉高拉低引脚,启动通信系统
u2 = UART(4,115200,timeout = 50)#定义串口4,设置 波特率为115200
#初始化 HTTP 应用
u2.write('AT+HTTPINIT\r\n')
getURLCMD = 'AT+HTTPPARA=1,"http://old.tpyboard.com/v702/httptest.php"\r\n'
sendData = "I am TPYBoard v702!"
while True:
    if u2.any() > 0:
        dataRead = u2.read()
        print('_dataRead:',dataRead)
        print('-'*30)
        if dataRead.find(b'OK') > -1:
            #AT命令执行成功
            #判断是执行的哪一步操作
            if dataRead.find(b'AT+HTTPINIT') > -1:
                #初始化HTTP成功
                #设置 HTTP 参数值 设置url
                u2.write(getURLCMD)
            elif dataRead.find(sendData.encode()+b'\r\nOK\r\n') > -1:
                #POST需要发送的数据设置成功
                #发起POST请求
                u2.write('AT+HTTPACTION=1\r\n')
            elif dataRead.find(b'AT+HTTPPARA=1') > -1:
                #HTTP参数设置成功
                #输入HTTP数据AT+HTTPDATA=<size>,<time>
                #<size>:发送的数据字节数
                #<time>:最大输入数据的时间以毫秒为单位
                u2.write('AT+HTTPDATA={},100\r\n'.format(len(sendData)))
            elif dataRead.find(b'AT+HTTPREAD\r\n\r\n+HTTPREAD') > -1:
                #返回可用的数据信息,进行解析 获取到数据长度
                datalen = dataRead.decode().split(':')[1].split(',')[0]
                print('datalen:',datalen)
                #从第0位开始 读取指定长度的数据
                u2.write('AT+HTTPREAD=0,{}\r\n'.format(datalen))
            elif dataRead.find(b'HTTP/1.1 200 OK') > -1:
                #成功读取数据后 停止HTTP应用
                u2.write('AT+HTTPTERM')
                #进行数据解析 提取出我们需要的信息
                b = dataRead.decode()
                c = "{"+b.split('{')[-1].split('}')[0]+"}"
                #转成json对象 查看是否请求成功
                jsonobj = json.loads(c)
                print(jsonobj["status"])
                pyb.delay(100)
                break
        elif dataRead.find(b'ERROR') > -1:
            #AT命令执行失败
            if dataRead.find(b'AT+HTTPINIT') > -1:
                #初始化HTTP失败 有可能是之前的没有停止等原因
                #发送停止HTTP命令 再重新初始化
                u2.write('AT+HTTPTERM\r\n')
                pyb.delay(300)
                u2.write('AT+HTTPINIT\r\n')
        else:
            if dataRead.find(b'\r\n+HTTPACTION: 1, 200') > -1:
                #收到的数据提示 说明POST请求成功
                #查询当前可用数据
                u2.write('AT+HTTPREAD\r\n')
            elif dataRead.find(b'AT+HTTPDATA') > -1 and dataRead.find(b'>') > -1:
                #提示>符号 串口直接发送POST数据
                u2.write(sendData)
_images/210.png
注意:
  • v702开发板增加了板载的SHT20温湿度传感使用开发板上的I2C 1(SCL = X9, SDA = X10)。
  • v702开发板上的LCD5110的接口连接的是SPI 1。
    • DIN = X8(MOSI)
    • CLK = X6(SCK)
    • RST = X20
    • CE = X19
    • DC = X18
    • LIGHT = X17
  • v702开发板上的GU620模块使用了UART 4(TX = X1, RX = X2)。
  • v702开发板上的光敏电阻连接的是引脚Y12。
  • v702开发板上的蜂鸣器模块连接的是引脚Y3。

TPYBoard Basic 典型实例

[Micropython][TPBasic F103]PWM电机控制

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

一、什么是TPBasicF103


TPYBasicF103是由TurnipSmart公司制作的一款STM32开发板,它基于STM32F103单片机,通过USB接口进行数据传输。该开发板可在3V-10V之间的电压正常工作。

TPYBasicF103让用户可以通过C语言轻松控制微控制器的各种外设,比如LED等,读取管脚电压等等.

二、利用TPBasicF103完成PWM电机控制


1、具体要求

利用TPBasicF103完成PWM电机控制

(1)学习stm32芯片I/O配置

(2)学习stm32芯片定时器设置

(3)学习三极管9014的用法

(4)学习PWM智能控制直流电机驱动小风扇

2、熟悉所需器件


  • TPBasicF103开发板一块
  • 直流电机一个
  • s9014三极管一个
  • 100R电阻一个
  • 杜邦线三条

3、所需器件1介绍


将板子boot0与GND用跳线帽短接,s9014集电极接3.3V电源,基极接100R后接接板子C7引脚(具体电路可根据程序自行选择引脚),发射极接直流电机一端,直流电机另一端接板子GND

三、制作主要过程


1、制作流程

PWM控制电机原理:直流电机在MCU的控制之下转动,PWM占空比控制直流电机的转速,每个周期的保持同样大小可确保电机转动速度均匀。占空比-高电平所占时间/周期T,我们就是通过控制占空比来控制的转速情况,整定一个固定的周期,然后让高低电平延时的时间之和跟这个周期相等就好了。

通过调制器给电机提供一个具有一定频率的脉冲宽度可调的脉冲电。脉冲宽度越大即占空比越大,提供给电机的平均电压越大,电机转速就高。反之脉冲宽度越小,则占空比越越小。提供给电机的平均电压越小,电机转速就低。

PWM控制led实现呼吸灯实际是模拟正弦波的过程。

这是STM32数据手册上对TIM3通用定时器复用功能重映象的描述,假设让PA6作为PWM输出,从图中可以看出PA6对应TIM3的通道1,使能TIM3通道1的函数为:TIM_OC1Init();同样的,如果想要使能PA7,它对应的是TIM3的通道2,那么使能通道2的函数便是:TIM_OC2Init();以此类推,需要注意,使能不同定时器不同通道的函数是有一点小差别的,防止在程序中调用TIM_OC1Init()函数来使能TIM3通道2这种情况的发生。

2、具体代码:

#include "public.h"
#include "pwm.h"
#include "systick.h"
int main()
{
          u8 fx-1;
          u32 ti-0;
          pwm_init();

                   TIM_SetCompare2(TIM3, 20);
          }
}

..LINK:http://www.tpyboard.com/ueditor/php/upload/file/20170502/1493725726707079.zip

[Micropython][TPBasic F103]18B20温度测量

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

一、什么是TPBasicF103


TPYBasicF103是由TurnipSmart公司制作的一款STM32开发板,它基于STM32F103单片机,通过USB接口进行数据传输。该开发板可在3V-10V之间的电压正常工作。

TPYBasicF103让用户可以通过C语言轻松控制微控制器的各种外设,比如LED等,读取管脚电压等等.

二、利用TPBasicF103完成18B20温度测量


1、具体要求

利用TPBasicF103完成18B20温度测量

(1)学习stm32芯片I/O配置

(2)学习stm32芯片定时器设置

(3)学习DS18B20的用法

(4)学习串口调试用法

2、熟悉所需器件


  • TPBasicF103开发板一块
  • DS18B20三极管一个
  • 10K电阻一个
  • 杜邦线三条
  • USB转串口器件

3、所需器件介绍


将板子boot0与GND用跳线帽短接,3脚集电极接3.3V电源,2脚接板子C5引脚(具体电路可根据程序自行选择引脚),1脚接GND,2脚与3脚间接一个10K电阻。

三、制作主要过程


1、制作流程

DS18B20简介

DS18B20是由DALLAS半导体公司推出的一种的“一线总线”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的数字化温度传感器。一线总线结构具有简洁且经济的特点,可使用户轻松地组建传感器网络,从而为测量系统的构建引入全新概念,测量温度范围为-55~+125℃,精度为±0.5℃。

现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~l2位的数字值读数方式。它工作在3—5.5V的电压范围,采用多种封装形式,从而使系统设计灵活、方便,设定分辨率及

用户设定的报警温度存储在EEPROM中,掉电后依然保存。其内部结构如图所示:

ROM中的64位序列号是出厂前被光记好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。64位ROM的排列是:前8位是产品家族码,接着48位是DS18B20的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5

+X4+1)。ROM作用是使每一个DS18B20都各不相同,这样就可实现一根总线上挂接多个。

所有的单总线器件要求采用严格的信号时序,以保证数据的完整性。DS18B20共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。这里我们

简单介绍这几个信号的时序:

1)复位脉冲和应答脉冲

单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少

480us,,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~

60us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240us,以产生低电平应答脉冲,

若为低电平,再延时480us。

2)写时序

写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。写0时序:主机输出低电平,延时60us,

然后释放总线,延时2us。

3)读时序

单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。

2、具体代码:

#include "public.h"
#include "printf.h"
#include "ds18b20.h"
#include "systick.h"
int main()
{
          double temp;
          printf_init();
          ds18b20_init();
          while(1)
          {
                   temp=readtemp();
                   printf("当前温度为:%0.4lf°C\r\n",temp);
          }
}

..LINK:http://www.tpyboard.com/ueditor/php/upload/file/20170502/1493725443257212.zip

[Micropython][TPBasic F103]LCD1602显示实例

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

一、什么是TPBasicF103


TPYBasicF103是由TurnipSmart公司制作的一款STM32开发板,它基于STM32F103单片机,通过USB接口进行数据传输。该开发板可在3V-10V之间的电压正常工作。

TPYBasicF103让用户可以通过C语言轻松控制微控制器的各种外设,比如LED等,读取管脚电压等等.

二、利用TPBasicF103完成LCD1602显示


1、具体要求

利用TPBasicF103完成LCD1602显示

(1)学习stm32芯片I/O配置

(2)学习LCD1602显示的用法

(3)学习数据输出程序的设计方法

2、熟悉所需器件


  • TPBasicF103开发板一块
  • 10K电位器一个
  • 杜邦线22条

3、所需器件介绍


将板子boot0与GND用跳线帽短接,PC0-PC7接D0-D7,PA0接E,PA1接RW,PA2接RS。Vss和K接GND,Vdd和A接5V电源。Vo接电位器中间脚,电位器其余两脚分别接5V和GND。

http://www.tpyboard.com/ueditor/php/upload/image/20170502/1493724662218164.png http://www.tpyboard.com/ueditor/php/upload/image/20170502/1493724672460581.png

三、制作主要过程


1、制作流程

控制命令表

1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。(说明:1为高电平、0为低电平)

指令1:清显示,指令码01H,光标复位到地址00H位置。

指令2:光标复位,光标返回到地址00H。

指令3:光标和显示模式设置I/D:光标移动方向,高电平右移,低电平左移S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。

指令4:显示开关控制。D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:控制光标的开与关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。

指令5:光标或显示移位S/C:高电平时移动显示的文字,低电平时移动光标。

指令6:功能设置命令DL:高电平时为4位总线,低电平时为8位总线N:低电平时为单行显示,高电平时双行显示F:低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。

指令7:字符发生器RAM地址设置。

指令8:DDRAM地址设置。

指令9:读忙信号和光标地址BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。

指令10:写数据。

指令11:读数据。

2、具体代码:

#include "stm32f10x.h"
#include "math.h"
#include "delay.h"
ErrorStatus HSEStartUpStatus;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
unsigned char word1[]="TPBasic f103";
u8 alarm_on=0;
/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void TIM_Configuration(void);
void EXTI_Configuration(void);
void Delay(vu32 nCount);

void Init_LCD1602(void);
void w_cmd(u8 cmd);

void w_dat(u8 dat);
void w_string(u8 addr_start, unsigned char *p);
void w_number(u8 addr_start, u8 num);
void w_array(u8 addr_start, unsigned char *p,u8 nn);
int main()
{
        delay_init(8);
   /* System Clocks Configuration */
  RCC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();
  NVIC_Configuration();
  TIM_Configuration();
  EXTI_Configuration();

   Init_LCD1602();
   w_string(0x82,word1);

[Micropython][TPBasic F103]呼吸灯实例

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

一、什么是TPBasicF103


TPYBasicF103是由TurnipSmart公司制作的一款STM32开发板,它基于STM32F103单片机,通过USB接口进行数据传输。该开发板可在3V-10V之间的电压正常工作。

TPYBasicF103让用户可以通过C语言轻松控制微控制器的各种外设,比如LED等,读取管脚电压等等.

二、利用TPBasicF103完成呼吸灯


1、具体要求

利用TPBasicF103完成呼吸灯

(1)学习stm32芯片I/O配置

(2)学习stm32芯片定时器设置

(3)学习PWM智能控制led灯

2、熟悉所需器件


  • TPBasicF103开发板一块
  • LED灯一个
  • 杜邦线两条

3、所需器件1介绍


将板子boot0与GND用跳线帽短接,LED灯正极接3.3V电源,负极接板子C7引脚(具体电路可根据程序自行选择引脚)

三、制作主要过程



呼吸灯原理:LED灯光在MCU的控制之下完成由亮到暗的逐渐变化,感觉像是在呼吸。呼吸灯分为两个过程:亮度有暗到亮(模拟吸气过程),在由亮到暗(模拟呼气过程)

占空比=高电平所占时间/周期T。我们就是通过控制占空比来控制的灯亮灭情况,看起来就像人在呼吸的样子。整定一个固定的周期,然后让高低电平延时的时间之和跟这个周期相等就好了。

PWM控制led实现呼吸灯实际是欺骗人眼和模拟正弦波的过程。

PWM波的频率是某一个固定的值,但是高低电平所占比例(占空比)会根据用户设定而变化。假设高电平灯点亮,低电平熄灭,那么在PWM波一个周期内灯点亮的时间就等于周期*占空比。调整占空比,就可以控制LED在一个周期内的点亮时间。由于PWM波频率很高,超出人眼分辨速度,那么在人眼中就是连续的灯光,按照渐变占空比变化,在人眼中就可以表现为亮度的变化。

这是STM32数据手册上对TIM3通用定时器复用功能重映象的描述,假设让PA6作为PWM输出,从图中可以看出PA6对应TIM3的通道1,使能TIM3通道1的函数为:TIM_OC1Init();同样的,如果想要使能PA7,它对应的是TIM3的通道2,那么使能通道2的函数便是:TIM_OC2Init();以此类推,需要注意,使能不同定时器不同通道的函数是有一点小差别的,防止在程序中调用TIM_OC1Init()函数来使能TIM3通道2这种情况的发生。

2、具体代码:

#include "public.h"
#include "pwm.h"
#include "systick.h"


int main()
{
          u8 fx=1;
          u32 ti=0;
          pwm_init();
          while(1)
          {
                   delay_ms(10);
                   if(fx==1)
                   {
                                 ti++;
                                 if(ti>300)
                                 {
                                          fx=0;
                                 }
                   }
                   else
                   {
                                 ti--;
                                 if(ti==0)
                                 {
                                          fx=1;
                                 }
                   }
                   TIM_SetCompare2(TIM3, ti);
          }
}

..LINK: http://www.tpyboard.com/ueditor/php/upload/file/20170502/1493724451470181.zip

TPBasic_STM32F405RGT6的GPIO使用

一、什么是TPBasic_STM32F405RGT6最小系统板

TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。

二、利用TPBasic_STM32F405RGT6最小系统板完成串口的收发


1、具体要求

利用TPBasic_STM32F405RGT6最小系统板完成STM32通过串口1和上位机对话,STM32在收到上位机发过来的字符串(以回车换 行结束)后,原原本本的返回给上位机。同时每隔一定时间,通过串口1输出一段信息到电脑。

2、所需器件


  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根

三、制作主要过程


1、制作流程

PA9/PA10通过杜邦线连接在RXD/TXD上.

串口输入字符串以回车换行结束.

电脑端串口调试助手波特率必须是115200.

2、主要代码


#include "stm32f4xx.h"

#define ON  0
#define OFF 1

#define key (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4))


void LED_Configuration(void);
void delay(unsigned long int time);


void LED(a)
{
        if(a)
        GPIO_SetBits(GPIOC,GPIO_Pin_11);
        else
        GPIO_ResetBits(GPIOC,GPIO_Pin_11);
}

/*
 * 函数名:main
 * 描述  :主函数体
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
int main(void)
{

        SystemInit();
        LED_Configuration();
        LED(ON);
                delay(6000000);
        LED(OFF);
 //   delay(6000000);
                while(1)
                {
                        if(!key)
                                {
                                         LED(ON);
                                }
                        else
                                {
                                         LED(OFF);
                                }


        }
}


/*
 * 函数名:LED_Configuration
 * 描述  :LED GPIO口配置
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void LED_Configuration(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;  //声明一个 初始化GPIO口时候用的 结构体
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC , ENABLE); //使能PI口的时钟,否则端口是不工作的
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ; //对结构体的GPIO_Pin对象赋值,声明要操作的是11端口
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//对结构体的GPIO_Mode对象赋值,声明IO口的模式是输出
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//对结构体的GPIO_OType对象赋值,声明IO口的结构是推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//对结构体的GPIO_Speed对象赋值,声明速度是100MHz
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //对结构体的GPIO_PuPd对象赋值,声明不上拉
        GPIO_Init(GPIOC, &GPIO_InitStructure);//将结构体带入初始化函数中,执行初始化,否则之前设置都是无效的

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ; //对结构体的GPIO_Pin对象赋值,声明要操作的是4端口
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//对结构体的GPIO_Mode对象赋值,声明IO口的模式是输入
        //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//对结构体的GPIO_Speed对象赋值,声明速度是100MHz
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //对结构体的GPIO_PuPd对象赋值,声明内部上拉
        GPIO_Init(GPIOC, &GPIO_InitStructure);//将结构体带入初始化函数中,执行初始化,否则之前设置都是无效的



}


void delay(unsigned long int time)
{
        while(time--);
}

TPBasic_STM32F405RGT6的IIC使用

一、什么是TPBasic_STM32F405RGT6最小系统板

TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。

二、利用TPBasic_STM32F405RGT6最小系统板完成24C02的读写操作


1、具体要求

按键KEY0接在PC0上/按键KEY1接在PC1

24C02(IIC连接在PB8/PB9上面)

通过KEY1按键来控制24C02的写入,通过另外一个按键KEY0来控制24C02的读取。

2、所需器件


  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • USB转TTL串口转换模块 一块

三、制作主要过程


1、制作流程

按键KEY0接在PC0上/按键KEY1接在PC1

通过KEY1按键来控制24C02的写入,通过另外一个按键KEY0来控制24C02的读取。

2、主要代码


#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "24cxx.h"
#include "key.h"

//要写入到24c02的字符串数组
const u8 TEXT_Buffer[]={"Explorer STM32F4 IIC TEST"};
#define SIZE sizeof(TEXT_Buffer)

int main(void)
{
        u8 key;
        u16 i=0;
        u8 datatemp[SIZE];
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);    //初始化延时函数
        uart_init(115200);      //初始化串口波特率为115200
        KEY_Init();                             //按键初始化
        AT24CXX_Init();                 //IIC初始化
        while(1)
        {
                key=KEY_Scan(0);
                if(key==KEY1_PRES)//KEY1按下,写入24C02
                {
                        AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);
                }
                if(key==KEY0_PRES)//KEY0按下,读取字符串
                {
                        AT24CXX_Read(0,datatemp,SIZE);
                }
                i++;
                delay_ms(10);
                if(i==20)
                {
                        LED0=!LED0;//提示系统正在运行
                        i=0;
                }
        }
}

TPBasic_STM32F405RGT6的串口使用

一、什么是TPBasic_STM32F405RGT6最小系统板

TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。

二、利用TPBasic_STM32F405RGT6最小系统板完成串口通讯


1、具体要求

利用TPBasic_STM32F405RGT6最小系统板完成通过串口1和上位机对话,STM32在收到上位机发过来的字符串(以回车换 行结束)后,原原本本的返回给上位机。同时每隔一定时间,通过串口1输出一段信息到电脑。

2、所需器件


  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • USB转TTL串口转换模块 一块

三、制作主要过程


1、制作流程

将按键用杜邦线接在PC4与地之间,是按下按键IO口变为低电平

将LED的正极接在3.3V电源处,负极接在PC11上,当IO口变为低电平时LED灯亮起,当IO口为高电平时LED灯灭。

2、主要代码


#include "sys.h"
#include "delay.h"
#include "usart.h"

int main(void)
{

        u8 t;
        u8 len;
        u16 times=0;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);                //延时初始化
        uart_init(115200);      //串口初始化波特率为115200
        while(1)
        {
                if(USART_RX_STA&0x8000)
                {
                        len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
                        printf("\r\n您发送的消息为:\r\n");
                        for(t=0;t<len;t++)
                        {
                                USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
                                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
                        }
                        printf("\r\n\r\n");//插入换行
                        USART_RX_STA=0;
                }else
                {
                        times++;
                        if(times%5000==0)
                        {
                                printf("\r\nTPBASIC STM32F407最小系统板 串口实验\r\n");
                        }
                        if(times%200==0)printf("请输入数据,以回车键结束\r\n");
                        delay_ms(10);
                }
        }
}

TPBasic_STM32F405RGT6的ADC和DAC使用

一、什么是TPBasic_STM32F405RGT6最小系统板

TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。

二、利用TPBasic_STM32F405RGT6最小系统板利用按键控制W25Q128的写入和读取,并通过串口显示


1、具体要求

通过KEY1按键来控制W25Q128的写入,通过另外一个按键KEY0来控制W25Q128的读取。 可以通过USMART控制读取W25QXX的ID或者整片擦除。

2、所需器件


  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • 按键 两个
  • W25Q128 一片

三、制作主要过程


1、制作流程

PA9/PA10通过杜邦线连接在RXD/TXD上. 按键KEY1(PA3)/KEY_UP(PA0,也称之为WK_UP) SPI1(PB3/4/5/14) W25Q128(SPI FLASH芯片,连接在SPI1上)

2、主要代码


code-block:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
#include "dac.h"
#include "key.h"

int main(void)
{
        u16 adcx;
        float temp;
        u8 t=0;
        u16 dacval=0;
        u8 key;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);      //初始化延时函数
        uart_init(115200);              //初始化串口波特率为115200

        LED_Init();                                     //初始化LED
        Adc_Init();                             //adc初始化
        KEY_Init();                             //按键初始化
        Dac1_Init();                            //DAC通道1初始化
        DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0
        while(1)
        {
                t++;
                key=KEY_Scan(0);
                if(key==WKUP_PRES)
                {
                        if(dacval<4000)dacval+=200;
                        DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
                }else if(key==2)
                {
                        if(dacval>200)dacval-=200;
                        else dacval=0;
                        DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
                }
                if(t==10||key==KEY1_PRES||key==WKUP_PRES)       //WKUP/KEY1按下了,或者定时时间到了
                {
                        adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值
                        adcx=Get_Adc_Average(ADC_Channel_5,10);         //得到ADC转换值
                        temp=(float)adcx*(3.3/4096);                            //得到ADC电压值
                        adcx=temp;
                        printf("%5.0",temp);              //显示电压值整数部分
                        temp-=adcx;
                        temp*=1000;
                        printf(".%0.3d",temp);    //显示电压值的小数部分
                        t=0;
                }
                delay_ms(10);
        }
}

TPBasic_STM32F405RGT6的PWM使用

一、什么是TPBasic_STM32F405RGT6最小系统板

TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。

二、利用TPBasic_STM32F405RGT6最小系统板完成PWM对LED呼吸灯控制


1、具体要求

1,DS0 LED灯(连接在PA7) 2,定时器14(TIM14),使用TIM14的通道1(CH1),将TIM14_CH1输出到PF9. 从而实 现PWM输出控制DS0亮度.

2、所需器件


  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • LED灯 一个

三、制作主要过程


1、制作流程

定时器14(TIM14),使用TIM14的通道1(CH1),将TIM14_CH1输出到PF9. 从而实 现PWM输出控制DS0亮度. DS0由暗到亮,再由亮到暗,再由暗到亮,依次循环.

2、主要代码


code-block:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"

int main(void)
{
        u16 led0pwmval=0;
        u8 dir=1;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);  //初始化延时函数
        TIM14_PWM_Init(500-1,84-1);     //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
   while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
        {
                delay_ms(10);
                if(dir)led0pwmval++;//dir==1 led0pwmval递增
                else led0pwmval--;      //dir==0 led0pwmval递减
                if(led0pwmval>300)dir=0;//led0pwmval到达300后,方向为递减
                if(led0pwmval==0)dir=1; //led0pwmval递减到0后,方向改为递增

                TIM_SetCompare1(TIM14,led0pwmval);      //修改比较值,修改占空比
        }
}

TPBasic_STM32F405RGT6的SPI口使用

TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。

二、利用TPBasic_STM32F405RGT6最小系统板利用按键控制W25Q128的写入和读取,并通过串口显示


1、具体要求

通过KEY1按键来控制W25Q128的写入,通过另外一个按键KEY0来控制W25Q128的读取。 可以通过USMART控制读取W25QXX的ID或者整片擦除。

2、所需器件


  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • 按键 两个
  • W25Q128 一片

三、制作主要过程


1、制作流程

PA9/PA10通过杜邦线连接在RXD/TXD上. 按键KEY1(PA3)/KEY_UP(PA0,也称之为WK_UP) SPI1(PB3/4/5/14) W25Q128(SPI FLASH芯片,连接在SPI1上)

2、主要代码


code-block:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "spi.h"
#include "w25qxx.h"
#include "key.h"

const u8 TEXT_Buffer[]={"Explorer STM32F4 SPI TEST"};
#define SIZE sizeof(TEXT_Buffer)

int main(void)
{
        u8 key;
        u16 i=0;
        u8 datatemp[SIZE];
        u32 FLASH_SIZE;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
        delay_init(168);     //初始化延时函数
        uart_init(115200);      //初始化串口波特率为115200
        KEY_Init();                             //按键初始化
        W25QXX_Init();                  //W25QXX初始化
        POINT_COLOR=RED;
        while(W25QXX_ReadID()!=W25Q128)                                                         //检测不到W25Q128
        {
                printf("W25Q128 Check Failed!\n");
                printf("Please Check!      \n");
        }
        printf("W25Q128 Ready!\n");
        FLASH_SIZE=16*1024*1024;        //FLASH 大小为16字节
        while(1)
        {
                key=KEY_Scan(0);
                if(key==KEY1_PRES)//KEY1按下,写入W25Q128
                {
                        printf("Start Write W25Q128....\n");
                        W25QXX_Write((u8*)TEXT_Buffer,FLASH_SIZE-100,SIZE);             //从倒数第100个地址处开始,写入SIZE长度的数据
                        printf("W25Q128 Write Finished!"\n);    //提示传送完成
                }
                if(key==KEY0_PRES)//KEY0按下,读取字符串并显示
                {
                        printf("Start Read W25Q128....\n");
                        W25QXX_Read(datatemp,FLASH_SIZE-100,SIZE);                                      //从倒数第100个地址处开始,读出SIZE个字节
                        printf("The Data Readed Is:   ");       //提示传送完成
                        printf("%s"\n,datatemp);                                        //显示读到的字符串
                }
                delay_ms(10);
        }
}

TPBasic_STM32F405RGT6的捕获功能使用

一、什么是TPBasic_STM32F405RGT6最小系统板
TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。
二、利用TPBasic_STM32F405RGT6最小系统板完成通过捕获功能捕获按键模拟的高电平时间并通过串口发送出来
1、具体要求

1,KEY_UP按键(PA0) 2,定时器5(TIM5),TIM5的通道1(TIM5_CH1,连接在PA0上面),使用定时器的输入捕获功能来

捕捉PA0上面的高电平脉宽.
2、所需器件
  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
三、制作主要过程
1、制作流程
本实验利用TIM5_CH1来做输入捕获,我们将捕获PA0上的高电平脉宽,并将脉宽时间通过串 口打印出来
2、主要代码

#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "timer.h"

extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态 extern u32 TIM5CH1_CAPTURE_VAL; //输入捕获值

int main(void) {

long long temp=0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 uart_init(115200);//初始化串口波特率为115200

TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1); //以1Mhz的频率计数 while(1) {

delay_ms(10); if(TIM5CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平 {

temp=TIM5CH1_CAPTURE_STA&0X3F; temp*=0XFFFFFFFF; //溢出时间总和 temp+=TIM5CH1_CAPTURE_VAL; //得到总的高电平时间 printf("HIGH:%lld usrn",temp); //打印总的高点平时间 TIM5CH1_CAPTURE_STA=0; //开启下一次捕获

}

}

}

TPBasic_STM32F405RGT6的定时器使用

一、什么是TPBasic_STM32F405RGT6最小系统板
TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。
二、利用TPBasic_STM32F405RGT6最小系统板完成定时器对LED的闪烁快慢控制
1、具体要求
1,DS0 LED灯(连接在PB9)

2,DS1 LED灯(连接在PB10)

2、所需器件
  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • LED灯 二个
三、制作主要过程
1、制作流程
DS0用来指示程序运行,400ms为一个周期。DS1用于定时器中断取反,指示 定时器中断状态,1000ms为一个周期。下载完后,可以看到DS0快闪,DS1慢闪。
2、主要代码

#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "timer.h"

int main(void) {

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 LED_Init(); //初始化LED端口

TIM3_Int_Init(5000-1,8400-1); //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms while(1) {

LED0=!LED0;//DS0翻转 delay_ms(200);//延时200ms

};

}

TPBasic_STM32F405RGT6的外部中断使用

一、什么是TPBasic_STM32F405RGT6最小系统板
TPBasic_STM32F405RGT6最小系统板是基于STM32F405RGT6芯片开发制作的最小系统板,方便开发与集成使用。
二、利用TPBasic_STM32F405RGT6最小系统板学习外部中断的使用
1、具体要求
1,DS0 LED灯(连接在PB9)
2,DS1 LED灯(连接在PB10)
2,蜂鸣器(连接在PB8) 3,按键KEY0(PA3)/KEY1(PA4)/KEY2(PA5)/KEY_UP(PA0,也称之为WK_UP)
2、所需器件
  • TPBasic_STM32F405RGT6最小系统板 一块
  • 杜邦线 若干根
  • 按键 四个
  • 蜂鸣器 一个
  • LED灯 二个
三、制作主要过程
1、制作流程
通过开发外接的4个按 钮(KEY_UP、KEY0、KEY1和KEY2),来控制外接的2个LED(DS0、DS1)和蜂鸣器 ,其中WK_UP控制蜂鸣器,按一次叫,再按一次停;KEY2控制DS0,按一次亮,再按 一次灭;KEY1控制DS1,效果同KEY2;KEY0则同时控制DS0和DS1,按一次,他们的 状态就翻转一次。
2、主要代码

#include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "beep.h" #include "key.h" #include "exti.h"

int main(void) {

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数

LED_Init(); //初始化LED端口 BEEP_Init(); //初始化蜂鸣器端口 EXTIX_Init(); //初始化外部中断输入 LED0=0; //先点亮红灯 while(1) { }

}

TPYBoard F407(最小系统板) 典型实例

[Micropython]TPYBoard F407 快速入手教程

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

前言

当你第一次接触TPYBoard F407时,或许有些疑惑,不知道该如何使用它。不用担心,当你认真阅读完本篇文章后,保证你用起来游刃有余。

初次见面
  • 实物图
tpyboard/tutorial/v407_New/img/f407.png

初次见到TPYBoard F407(以下简称F407)时,我们首先通过micro接口的USB数据线将F407接入电脑。这时,你会看到开发板上的4个LED呈现流水灯的效果,这是我们的出厂默认程序。

一般情况下,电脑会自动出现一个类似U盘的可移动磁盘 TPYBFLASH 如下:

_images/flash2.png

也有可能有的小伙伴的电脑,不能自动安装时,可安装驱动人生进行USB驱动的修复。

可参考教程

深入了解

打开 TPYBFLASH 可以看到里面默认有4个文件:

  • boot.py 开发板启动配置文件,例如可以设置开发板USB设备的模式(CDC、MSC、HID)或者指定第一个运行的脚本等。
  • main.py 默认第一个运行的脚本,可在boot.py中进行设置。
  • README.txt 一些帮助信息。
  • tpybcdc.inf 开发板的USB转虚拟串口的驱动,可用于repl调试。(下一篇讲解如何使用REPL调试)
编辑器的选择

在后面的开发中,主要是在main.py文件中进行编程实现功能。那我们该如何挑选合适的编辑器呢?

其实对于一个脚本文件来说,任何一个编辑工具都可以。但最好别直接使用文本文档,这样会使代码格式乱掉。你要明白Python是通过缩进来区分代码块的,有的人会使用空格缩进,而大部分的人会使用tab键缩进,不同的编辑器会有不同的tab缩进规则,所以就会导致直接拷贝过来的程序运行会出错等。无论是哪一种缩进方式,只要保证整体一致即可。

如果出现“SyntaxError: invalid syntax“错误:可能就是tab和空格没对齐的问题。 如果出现“IndentationError: unindent does not match any outer indentation level”错误:可能就是使用的缩进方式不一致。

不在REPL调试模式下,我们是看不到错误信息的,但是当你发现开发板上出现D2和D3两个LED交替闪烁几次后熄灭的情况,就说明程序出现了错误。

代码编辑器

推荐Visual Studio Code、Notepad++、PyCharm、Python IDLE。VSCode和PyCharm都可以安装micropython的插件,支持代码提示补全和REPL调试。Notepad++在win10下会出现文件损坏的BUG。

和谐相处

为了防止代码丢失,养成良好的编程习惯,建议在电脑本地编写好main.py后直接覆盖 TPYBFLASH 中的main.py文件,不要直接在 TPYBFLASH 中编辑。

接下来,我们写一段代码,点亮板载的第2个LED。新建一个main.py文件,输入下面的代码。

import pyb
pyb.LED(2).on()

将编写好的main.py文件拷贝替换到 TPYBFLASH 里的mian.py文件。

_images/copy2.gif

注意:文件覆盖、修改保存时,板载的红色LED(D2)会亮起,说明正在写入板子内部FLASH,需等待熄灭后再进行其他操作。

保存完毕后,按下板载的RST按键进行复位,板载的红色LED(D3)就会亮起。

[Micropython]TPYBoard F407 获取REPL提示

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

前言

REPL(交互式解释器)全称是 Read Evaluate Print Loop,TPYBoard 允许用户和 MicorPython 的交互式连接。 使用REPL是迄今为止来测试你的代码、获取程序错误信息和运行命令的最简单的方法。

REPL调试

使用REPL需安装USB转串口的驱动,不同的系统不同的安装方式。

Windows

大部分win10系统会自动安装驱动。安装完成后,打开【设备管理器】就可以看到安装的端口号。

_images/win102.png

其他情况下,会出现下面的提示。

_images/q12.png

这时就需要我们去【设备管理器】进行手动安装。【其他设备】下看到一个带黄色感叹号图标的设备,右键选择更新驱动程序文件,定位到 TPYBFLASH 目录即可。

_images/qu2.gif

但是,有的朋友的电脑可能会安装失败,主要有两种情况:

  • 提示“没有INF签名的驱动程序”,这是因为有的电脑开启了驱动强制签名的设置,把此设置关闭即可。解决方案
  • 提示“系统找不到指定的文件”等类似的问题,这时因为有些电脑是通过GHOST方式装的系统,它会删减一些系统文件。解决方法

Windows下我们使用PuTTY软件进行REPL交互。 下载PuTTY软件

打开Putty软件,【Connection type】分类中选择【Serial】串口模式,输入串口端口号和波特率(默认波特率:9600)。例如端口号是COM10 (这里的端口号是指自己设备管理器对应的端口号)

_images/putty3.png

点击【Open】,进行连接。连接成功后,如下图:

_images/putty12.png

有时打开时无任何信息,按下回车键就好了。

PuTTY快捷键

  • Ctrl+C:停止运行程序
  • Ctrl+D:软复位

注意:有时必须按下RST键进行硬件复位时,需先关闭PuTTY再进行操作,否则下次连接会出错。如果出错了,就再复位一次重新打开PuTTY就好了。

Linux(Ubuntu)

执行查看端口命令

ls -a /dev/ttyA*

使用picocom,若没有安装的,请执行下面命令进行安装。

apt-get install picocom

执行命令打开picocom,连接端口。例如端口号为ttyACM1。

picocom /dev/ttyACM1

提示输入配置参数,基本配置如下:

  • 波特率:9600
  • 校验位:none
  • 数据位:8
  • 停止位:1

退出关闭-组合键Ctrl+A+Q。

MacOS

打开一个终端并运行

screen /dev/tty.usbmodem*

退出关闭-快捷键 CTRL-A CTRL-。

[Micropython]TPYBoard F407 引脚指示图

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

_images/左.png _images/右.png _images/上.png

[Micropython]TPYBoard F407 DIY声光控开关

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习光敏传感器模块的工作原理。
  • 学习声音传感器模块的工作原理。
  • 学习TPYBoard F407 Micropython开发板与声音传感器与光敏传感器的接线方法以及利用声音与光控制发光二极管亮灭。
所需元器件
  • TPYBoard F407 Micropython开发板板子一块
  • 声音传感器一个
  • 光敏传感器一个
  • 面包板一块
  • 发光二极管若干
  • 数据线一条
  • 杜邦线若干
光敏传感器模块工作原理

1.光敏电阻模块对环境光线最敏感,一般用来检测周围环境的光线的亮度,触发单片机或继电器模块等; 2.模块在环境光线亮度达不到设定阈值时,DO端输出高电平,当外界环境光线亮度超过设定阈值时,DO端输出低电平; 3.DO输出端可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的光线亮度改变; 4.DO输出端可以直接驱动本店继电器模块,由此可以组成一个光控开关。

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533629696804817.png
声音传感器模块工作原理

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

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533629713668426.png
硬件接线方法

上面我们已经知道光敏传感器跟声音传感器的工作原理,以及三根针脚的作用,那么我们只需将它们的电源正极与电源负极跟我们开发板的3.3V跟GND连接起来,然后将光敏传感器和声音传感器的信号输出针脚连接到我们开发板上的任意GPIO引脚。

本次实验将声音传感器信号输出引脚连接的是开发板的PE2针脚,光敏传感器信号输出引脚连接的PE3针脚。传感器连接完毕后,将发光数码管的正极插入面包板正极上,负极插入面包板的纵向插孔里(a,b,c,d,e,f,g,h,i,j),然后用杜邦线将负极连接到开发板的GND上,灯的正极连接到PE4针脚,然后我们声音大小以及光亮强度来控制PE4针脚输出高电平或者低电平来控制发光二极管的亮灭。

接线OK后,编写main.py,这样我们的DIY声光电控开关就完成了。

源代码
@micropython.asm_thumb
# main.py -- put your code here!
import pyb
from pyb import Pin

voice = Pin('PE2',Pin.IN)
light = Pin('PE3',Pin.IN)
led = pyb.Pin("PE4",pyb.Pin.OUT_PP)

while 1:
    if light.value()==1:
        if voice.value()==1:
            led.value(0)
        else:
            led.value(1)
            pyb.delay(5000)
    else:
        led.value(0)

[Micropython]TPYBoard F407 驱动DS18B20检测温度

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

实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。
  3. 学习DS18B20的接线方法,并利用DS18B20检测当前温度。
所需元器件
  • TPYBoard F407 micropython开发板 1块
  • 数据线 1条
  • DS18b20温度传感器 1个
  • DS18B20扩展板(带驱动电路) 1个
  • 杜邦线若干
  • PuTTY调试工具
学习DS18B20的接线方法,检测当前温度

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

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533630149265037.png

将DS18B20温度传感器直接插DS18B20模块上。如图

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533630161901981.png

DS18B20扩展板的针脚与TPYBoard F407 Micropython开发板的针脚对应关系如下:

TPYBoard F407开发板 DS18B20
3V3 VDD
GND GND
PD4 DO
源代码

接线OK后,将ds18b20.py和one_wire.py复制到PYBFLASH磁盘的根目录。将下面代码拷进main.py保存,等红灯熄灭后,RST开发板,用PuTTY可以看到当前的温度。

http://old.tpyboard.com/document/documents/tb407/18b20tem_5.png
import pyb
from pyb import Pin
from ds18b20 import DS18X20

DQ=DS18X20(Pin('PD4'))#DQ
while True:
        tem = DQ.read_temp()
        print(tem)
        pyb.delay(1000)

[Micropython]TPYBoard F407 驱动BMP180测量气压

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 学习BMP180测量气压的方法。
  • 学习TPYBoard F407 Micropython开发板中I2C接口的用法。
所需元器件
  • TPYBoard F407 Micropython开发板一块
  • BMP180气压模块一个
  • 数据线一条
  • 杜邦线若干
  • PuTTY调试工具
BMP180气压传感器的接线方法

BMP180是一直常见的气压传感器,BMP180是一款高精度、小体积、超低能耗的压力传感器,可以应用在移动设备中,它的性能卓越,精度最低可以达到0.03hPa,并且耗电极低,只有3μA;BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。

http://old.tpyboard.com/document/documents/tb407/bmp180_1.jpg

TPYBoard F407 Micropython开发板和BMP180气压模块的针脚对应关系如下: IIC接口1的接线方法(程序中bmp=BMP180(1)调用开发板的IIC接口1)

TPYBoard F407开发板 BMP180气压模块
PB6 SCL
PB7 SDA
3V3 VCC
GND GND

IIC接口2的接线方法(程序中bmp=BMP180(2)调用IIC接口2)

TPYBoard F407开发板 BMP180气压模块
PB10 SCL
PB11 SDA
3V3 VCC
GND GND
源代码

接线OK后,导入bmp180.py,编写main.py保存,等红灯熄灭后,RST开发板,用PuTTY可以看到时间和温度。

http://old.tpyboard.com/document/documents/tb407/bmp180_2.png
from bmp180 import BMP180

bmp=BMP180(1)
tem=bmp.getTemp()
press=bmp.getPress()
altitude=bmp.getAltitude()
print('tem:',tem)
print('press:',press)
print('altude:',altitude)

[Micropython]TPYBoard F407 驱动DS3231读取时间、温度

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 学习硬件接线方法。
  • 学习TPYBoard F407 Micropython开发板中I2C接口的用法。
所需元器件
  • TPYBoard F407 Micropython开发板一块
  • DS3231时钟模块一个
  • 数据线一条
  • 杜邦线若干
  • PuTTY调试工具
DS3231的接线方法

DS3231时钟模块,通信用的是IIC接口在这只用到DS3231时钟模块的SCL,SDA,VCC,GND四个针脚即可设定读出时间和温度,下面是接线方法。

http://old.tpyboard.com/document/documents/tb407/3231time_1.png

F407 Micropython开发板和DS3231时钟模块的针脚对应关系如下: IIC接口1的接线方法(程序中ds=DS3231(1)调用IIC接口1)

TPYBoard F407 DS3231时钟模块
PB6 SCL
PB7 SDA
3V3 VCC
GND GND

IIC接口2的接线方法(程序中ds=DS3231(2)调用IIC接口2)

TPYBoard F407 DS3231时钟模块
PB10 SCL
PB11 SDA
3V3 VCC
GND GND
源代码

接线OK后,导入ds3231.py,编写main.py保存,等红灯熄灭后,RST开发板,用PuTTY可以看到时间和温度。

    # main.py -- put your code here!
import pyb
from ds3231 import DS3231
ds=DS3231(1)
#设置日期
ds.DATE([19,04,01])
#设置时间
ds.TIME([15,10,10])
#延时5秒查看效果
pyb.delay(5000)
#读取秒并打印
print(ds.sec())
#读取日期
print(ds.DATE())
#读取时间
print(ds.TIME())

#读取温度
print(ds.TEMP())

[Micropython]TPYBoard F407 驱动OLED液晶屏

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习 F407 Micropython开发板控制OLED显示字符。
所需元器件
  • TPYBoard F407 Micropython开发板一块
  • 数据线一条
  • 杜邦线若干
  • OLED液晶屏一块
什么是OLED显示屏
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(已集成在屏中)。

实际显示效果

http://old.tpyboard.com/document/documents/tb407/oled_1.png
OLED接口定义
GND 电源地
VCC 电源地(2.8V~5.5V)
DO 时钟线
DI 数据线
RES 复位线
DC 数据/命令
CS 片选
硬件的接线方法

在这OLED需要SPI接口与TPYBoard F407 Micropython开发板进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在这OLED需要SPI接口与TPYBoard F407 Micropython开发板自带两个SPI接口,本实验中我们用的开发板的SPI1接口。

具体接线方法
OLED液晶屏 TPYBoardF407 开发板(SPI1)
GND GND
VCC 3v3
D0 PB3
D1 PB5
RES PB8
DC PB7
CS 悬空

接线OK后,引入font_.py文件和ssd1306.py文件,再可运行main.py了。

程序源代码
import pyb
from ssd1306 import SSD1306


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

display.poweron()
display.init_display()
display.draw_text(1,1,'Hello EveryOne',size=1,space=1)
display.draw_text(1,10,'Micropython F407',size=1,space=1)
display.draw_text(1,20,'Let Us Do it',size=1,space=1)
# 显示出你想要显示的内容
display.display()

[Micropython]TPYBoard F407 超声波测距

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习超声波模块的测距原理。
  • 学习LCD5110接线方法
  • 学习TPYBoard F407 Micropython开发板控制超声波模块测距。
所需元器件
  • 超声波模块一个
  • TPYBoard F407 Micropython开发板一块
  • LCD5110显示屏一个
  • 数据线一条
  • 杜邦线若干
超声波模块工作原理

(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。 (2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回。 (3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。 如下图接线,VCC 供 5V电源, GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四个接口端。

http://old.tpyboard.com/document/documents/tb407/supwave_1.png
硬件的连接

TPYBoard F407 Micropython开发板的针脚与LCD5110的针脚对应关系如下:

TPYBoard F407 LCD5110 memo
PB8 RST Reset pin (0=reset, 1=normal)
PB6 CE Chip Enable (0=listen for input, 1=ignore input)
PB7 DC Data/Command (0=commands, 1=data)
PB5 DIN data flow (Master out, Slave in)
PB3 CLK SPI clock
3V3 VCC  
PB9 LIGHT Light (0=on, 1=off)
GND GND  

TPYBoard F407 Micropython开发板的针脚与超声波模块的针脚对应关系如下:

F407 Micropython开发板 超声波模块
PE2 | Trig
PE3 | Echo
5V VCC
GND GND

接线OK后,并且导入font.py文件和upcd8544.py文件,编写main.py将测到的距离显示在LCD5110显示屏上,运行main.py就OK了。

源代码
import pyb
from pyb import Pin
from pyb import Timer
import upcd8544
from machine import SPI,Pin
Trig = Pin('PE2',Pin.OUT_PP)
Echo = Pin('PE3',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)
        RST    = pyb.Pin('PB8')
        CE     = pyb.Pin('PB6')
        DC     = pyb.Pin('PB7')
        LIGHT  = pyb.Pin('PB9')
        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*34299/2
            print('Distance')
            print(distance,'cm')
            lcd_5110.lcd_write_string('Distance',0,0)
            lcd_5110.lcd_write_string(str(distance),0,1)
            lcd_5110.lcd_write_string('cm',58,1)
            lcd_5110.lcd_write_string('This is a test of F407',0,2)
        flag=0
        run=0

[Micropython]TPYBoard F407 通过ADC读取光照值

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

实验目的
  • 了解光敏电阻模块的相关知识。
  • 学习使用TPYBoard F407开发板上的ADC接口获取光照值。
所需元器件
  • 光敏电阻模块 一个
  • TPYBoard F407 开发板一块
  • 数据线一条
  • 杜邦线若干
光敏电阻模块的介绍

光敏电阻模块上采用灵敏性光敏电阻传感器,通过比较器输出,具有信号干净、波形好、驱动能力强等特点。输出方式有两种:DO数字开关量和 AO模拟量。模块上配有可调电位器,可调节检测光线亮度的阈值,主要与DO端结合使用。当检测到的光照强度超过阈值时,DO端输出低电平,反之输出高电平。AO端会直接输出具体的模拟电压值。

实物图

_images/light1.png

引脚定义

引脚 功能
GND 电源地
VCC 电源正(3.3V~5V)
AO 模拟量输出
DO 数字量输出
硬件的连接

TPYBoard F407与光敏电阻模块的接线方法,如下:

TPYBoard F407 光敏电阻模块
GND GND
3V3 VCC
PA1 AO

接线OK后,编写main.py。

源代码
import pyb
from pyb import ADC,Pin
adc = ADC(Pin('PA1'))

while True:
    print(adc.read())
    pyb.delay(2000)

[Micropython]TPYBoard F407 DAC数模转换

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

DAC是数字模拟转换,将数字信号转换为模拟信号(以电流、电压或电荷的形式)。在TPYBoard F407开发板上DAC可输出介于0和3.3V之间的电压。 TPYBoard F407开发板上有两个DAC接口,分别是PA4和PA5引脚。

使用示例:

from pyb import DAC

dac = DAC(1)            # create DAC 1 on pin PA4
dac.write(128)          # write a value to the DAC (makes PA4 1.65V)

dac = DAC(1, bits=12)   # use 12 bit resolution
dac.write(4095)         # output maximum value, 3.3V

输出连续正弦波:

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)

以12位分辨率输出连续正弦波

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)
构造器
class pyb.DAC(port, bits=8)

构造一个DAC对象。

port 是一个针脚, 或整数(1 或 2)。DAC(1) 是针脚PA4 和 DAC(2) 是针脚PA5。

bits 是指定分辨率的整数,可以是8或12。

方法
DAC.init(bits=8)

重新初始化DAC。 bits 8位或12位。

DAC.deinit()

初始化DAC使其引脚可用于其他用途。

DAC.noise(freq)

产生伪随机噪声信号。一个新的随机样本写入DAC输出在给定的频率

DAC.triangle(freq)

以指定频率产生三角波。

DAC.write(value)

写入参数。在8bits时,参数范围[0-255];在12bits时,参数范围[0..4095]。

DAC.write_timed(data, freq, *, mode=DAC.NORMAL)

使用DMA方式周期写入数据

   data,缓冲区数组    freq,默认使用Timer(6),用指定频率更新。也可以指定另外的定时器,有效的定时器是[2, 4, 5, 6, 7, 8]。    modeDAC.NORMALDAC.CIRCULAR

同时利用DAC的例子:

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)

[Micropython]TPYBoard F407 定时器和呼吸灯(PWM)

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

TPYBoard F407开发板上有14个定时器,编号分别为1-14,其中编号3内部系统占用,5、6、7用于伺服控制和ADC/DAC。

程序示例:

from pyb import Timer #导入库
tim = pyb.Timer(4) #设置Timer编号
tim.init(freq=1) #设置频率,freq=1大约1秒1次。
tim.counter() # 获取计数器值
tim.callback(lambda t:pyb.LED(2).toggle()) #注册回调函数。这里使用了lambda表达式

以上程序实现的功能是,板载的D3-LED灯会每隔1秒改变一次状态,即亮/灭一次。

接下来,我们通过使用定时器的PWM功能,来实现一个呼吸灯的效果。

1、外接一个发光二极管。将发光二极管的正极接到PB10引脚上,负极接到GND引脚上。

TPYBoard F407 发光二极管
GND 正极(长腿)
PB10 负极(短腿)

程序示例:

# main.py -- put your code here!
from pyb import Pin
from pyb import Timer #导入库

#------------定时器-------------#
tim = pyb.Timer(4) #设置Timer编号
tim.init(freq=1) #设置频率,freq=1大约1秒1次。
tim.callback(lambda t:pyb.LED(2).toggle()) #注册回调函数。这里使用了lambda表达式

#------------PWM呼吸灯-------------#
p = Pin('PB10',Pin.OUT_PP)
tim = Timer(2, freq=1000)
ch = tim.channel(3, Timer.PWM, pin=p)

while True:
    for i in range(60):
        ch.pulse_width_percent(i)
        pyb.delay(20)
    for k in range(60,0,-1):
        ch.pulse_width_percent(k)
        pyb.delay(20)

程序分析

在 micropython中实现PWM功能是通过定时器来实现的。 其实PWM是Timer的一种工 模式,需要设置 Timer 的通道、频率、 PWM 模式以及输出引脚等。 首先,我们定义了一个支持 PWM 输出的引脚。

p = Pin('PB10',Pin.OUT_PP)  # X12 has TIM2, CH2

PB10 引脚连接的是定时器 2, 通道 3(其他引脚对应的定时器和通道,详见针脚图)。点击查看针脚图

tim = Timer(2, freq=1000)
ch = tim.channel(3, Timer.PWM, pin=p)

定时器 Timer 下的 channel()方法用于设置定时器的通道,需要传递 3 个参数:

   timer.channel(channel, mode,pin)

- channel:定时器通道编号
- mode: 定时器工作模式(Timer.PWM, PWM 模式)
- pin:驱动的引脚

在 PWM 模式下,可以调用 pulse_width_percent()方法,设置输出的占空比。 不传递参数是返回当前的占空比。还有一个 pulse_width()方法,用于设置输出的脉冲宽度。 不传递参数是返回当前的脉冲宽度。

[Micropython]TPYBoard F407 三线伺服舵机控制模块

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

Servo 对象用于控制标准的三线伺服舵机设备(电源地、电源正、信号)。在TPYBoard F407 开发板上有4个引脚可直接使用:PA0、PA1、PA2和PA3引脚。

程序示例:

import pyb

s1 = pyb.Servo(1)   # 在PA0引脚上创建伺服对象
s2 = pyb.Servo(2)   # 在PA1引脚上创建伺服对象

s1.angle(45)        # 转动到45度
s2.angle(0)         # 转动到0度

# 移动舵机指定角度,在1500毫秒内完成
s1.angle(-60, 1500)
s2.angle(30, 1500)

注解

舵机的驱动是通过Timer(5)产生PWM输出来实现的。使用时需注意避免冲突。

Constructors
class pyb.Servo(id)

创建一个伺服对象。 id is 1-4, 对应的引脚为 PA0~PA3.

Methods
Servo.angle([angle, time=0])

不传参数,返回当前角度。

传递参数, 设置角度:

  • angle 指定转动的角度。
  • time 达到指定角度所需的毫秒数。若忽略,将以最快的速度。
Servo.speed([speed, time=0])

不传参数,返回当前转动速度。

传递参数, 设置转动速度:

  • speed 要设置的转动速度,介于-100到100之间。
  • time 达到指定速度所需的毫秒数。若忽略,将以最短的时间。
Servo.pulse_width([value])

不传参数,返回原始的脉冲宽度值。

传递参数,设置脉冲宽度值。

Servo.calibration([pulse_min, pulse_max, pulse_centre[, pulse_angle_90, pulse_speed_100]])

不传参数,返回当前校准的数据。数据类型为元组,内含5个元素。

传递参数,设置定时校准:

  • pulse_min 允许的最小脉冲宽度。
  • pulse_max 允许的最大脉冲宽度。
  • pulse_centre 与中心/零位相对应的脉冲宽度。
  • pulse_angle_90 90度角的脉冲宽度。
  • pulse_speed_100 与速度100相对应的脉冲宽度。

[Micropython]TPYBoard F407 手机远程控制板载LED(蓝牙通信)

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 通过 TPYBoard F407开发板实现与蓝牙模块之间的串口通信。
所需元器件
  • HC-06 蓝牙模块 一个
  • TPYBoard F407 开发板一块
  • 数据线一条
  • 杜邦线若干
HC-06蓝牙模块的介绍

(HC-06蓝牙模块是主从一体的蓝牙串口模块。简单的说,当蓝牙设备与蓝牙设备配对连接成功后,我们可以忽视蓝牙内部的通信协议,直接将蓝牙当做串口用。 当建立连接,两设备共同使用一通道也就是同一串口,一个设备发送数据到通道中,另一个设备便可以接收到通道中的数据。

程序设计

我们使用TPYBoard F407的串口2连接HC-06蓝牙模块。使用手机打开蓝牙与HC-06蓝牙模块进行配对、连接。当它们之间成功建立链接后, 手机与TPYBoard F407之间就建立了一个透明的数据传输通道,HC-06蓝牙模块是手机和开发板之间的数据中转站,我们不用去管蓝牙的通信协议是什么, 只需要把想要发送的数据通过串口给HC-06蓝牙模块就可以,HC-06蓝牙模块会将数据原封不动的传递给手机;同样,手机发送的数据传递给HC-06蓝牙模块后, HC-06蓝牙模块再通过串口将数据原封不动的传递给开发板。所以对于开发板来说,我们只需要进行串口的读写操作即可。

硬件的连接

TPYBoard F407与HC-06蓝牙模块的接线方法,如下:

TPYBoard F407 HC-06
GND GND
5V +5V
PC7 TX
PC6 RX

接线OK后,编写main.py。

源代码
import pyb
from pyb import UART

#定义HC-05/06蓝牙模块连接的串口
#串口编号6 波特率9600 收发数据超时时间100ms
uart = UART(6,9600,timeout=100)

while True:
    #判断串口缓存区是否有数据
    if uart.any() > 0:
        #读取全部数据,返回的是bytes
        data = uart.read()
        #字节数组转字符串
        id = data.decode()
        #字符串转整型
        id = int(id)
        #板载的LED编号是1 or 2,判断数据是否符合,防止程序异常
        if id == 1 or id == 2:
            pyb.LED(id).toggle()
效果演示

1、开发板上电后,你会看到蓝牙模块上的LED快速闪烁,说明当前没有蓝牙设备连接。

2、手机打开【蓝牙串口调试助手】,搜索并连接蓝牙设备,HC-06蓝牙模块的蓝牙名称是HC-06,配对密码是1234。

3、连接成功后,手机发送1或2之间的数字,板载对应的LED就会进行亮/灭操作。

蓝牙串口调试助手(Android版) 点击下载

TPYBoard F407 典型实例

[Micropython]TPYBoard F407 快速入手教程

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

前言

当你第一次接触TPYBoard F407时,或许有些疑惑,不知道该如何使用它。不用担心,当你认真阅读完本篇文章后,保证你用起来游刃有余。

初次见面
  • 实物图
_images/f407.png

初次见到TPYBoard F407(以下简称F407)时,我们首先通过micro接口的USB数据线将F407接入电脑。这时,你会看到开发板上的4个LED呈现流水灯的效果,这是我们的出厂默认程序。

一般情况下,电脑会自动出现一个类似U盘的可移动磁盘 TPYBFLASH 如下:

_images/flash1.png

也有可能有的小伙伴的电脑,不能自动安装时,可安装驱动人生进行USB驱动的修复。

可参考教程

深入了解

打开 TPYBFLASH 可以看到里面默认有4个文件:

  • boot.py 开发板启动配置文件,例如可以设置开发板USB设备的模式(CDC、MSC、HID)或者指定第一个运行的脚本等。
  • main.py 默认第一个运行的脚本,可在boot.py中进行设置。
  • README.txt 一些帮助信息。
  • tpybcdc.inf 开发板的USB转虚拟串口的驱动,可用于repl调试。(下一篇讲解如何使用REPL调试)
编辑器的选择

在后面的开发中,主要是在main.py文件中进行编程实现功能。那我们该如何挑选合适的编辑器呢?

其实对于一个脚本文件来说,任何一个编辑工具都可以。但最好别直接使用文本文档,这样会使代码格式乱掉。你要明白Python是通过缩进来区分代码块的,有的人会使用空格缩进,而大部分的人会使用tab键缩进,不同的编辑器会有不同的tab缩进规则,所以就会导致直接拷贝过来的程序运行会出错等。无论是哪一种缩进方式,只要保证整体一致即可。

如果出现“SyntaxError: invalid syntax“错误:可能就是tab和空格没对齐的问题。 如果出现“IndentationError: unindent does not match any outer indentation level”错误:可能就是使用的缩进方式不一致。

不在REPL调试模式下,我们是看不到错误信息的,但是当你发现开发板上出现了红、绿色LED交替闪烁几次后熄灭的情况,就说明程序出现了错误。

代码编辑器

推荐Visual Studio Code、Notepad++、PyCharm、Python IDLE。VSCode和PyCharm都可以安装micropython的插件,支持代码提示补全和REPL调试。Notepad++在win10下会出现文件损坏的BUG。

和谐相处

为了防止代码丢失,养成良好的编程习惯,建议在电脑本地编写好main.py后直接覆盖 TPYBFLASH 中的main.py文件,不要直接在 TPYBFLASH 中编辑。

接下来,我们写一段代码,点亮板载的第4个LED。新建一个main.py文件,输入下面的代码。

import pyb
pyb.LED(4).on()

将编写好的main.py文件拷贝替换到 TPYBFLASH 里的mian.py文件。

_images/copy1.gif

注意:文件覆盖、修改保存时,板载的红色LED会亮起,说明正在写入板子内部FLASH,需等待熄灭后再进行其他操作。

保存完毕后,按下板载的RST按键进行复位,板载的蓝色LED就会亮起。

[Micropython]TPYBoard F407 获取REPL提示

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

前言

REPL(交互式解释器)全称是 Read Evaluate Print Loop,TPYBoard 允许用户和 MicorPython 的交互式连接。 使用REPL是迄今为止来测试你的代码、获取程序错误信息和运行命令的最简单的方法。

REPL调试

使用REPL需安装USB转串口的驱动,不同的系统不同的安装方式。

Windows

大部分win10系统会自动安装驱动。安装完成后,打开【设备管理器】就可以看到安装的端口号。

_images/win101.png

其他情况下,会出现下面的提示。

_images/q11.png

这时就需要我们去【设备管理器】进行手动安装。【其他设备】下看到一个带黄色感叹号图标的设备,右键选择更新驱动程序文件,定位到 TPYBFLASH 目录即可。

_images/qu1.gif

但是,有的朋友的电脑可能会安装失败,主要有两种情况:

  • 提示“没有INF签名的驱动程序”,这是因为有的电脑开启了驱动强制签名的设置,把此设置关闭即可。解决方案
  • 提示“系统找不到指定的文件”等类似的问题,这时因为有些电脑是通过GHOST方式装的系统,它会删减一些系统文件。解决方法

Windows下我们使用PuTTY软件进行REPL交互。 下载PuTTY软件

打开Putty软件,【Connection type】分类中选择【Serial】串口模式,输入串口端口号和波特率(默认波特率:9600)。例如端口号是COM10 (这里的端口号是指自己设备管理器对应的端口号)

_images/putty2.png

点击【Open】,进行连接。连接成功后,如下图:

_images/putty11.png

有时打开时无任何信息,按下回车键就好了。

PuTTY快捷键

  • Ctrl+C:停止运行程序
  • Ctrl+D:软复位

注意:有时必须按下RST键进行硬件复位时,需先关闭PuTTY再进行操作,否则下次连接会出错。如果出错了,就再复位一次重新打开PuTTY就好了。

Linux(Ubuntu)

执行查看端口命令

ls -a /dev/ttyA*

使用picocom,若没有安装的,请执行下面命令进行安装。

apt-get install picocom

执行命令打开picocom,连接端口。例如端口号为ttyACM1。

picocom /dev/ttyACM1

提示输入配置参数,基本配置如下:

  • 波特率:9600
  • 校验位:none
  • 数据位:8
  • 停止位:1

退出关闭-组合键Ctrl+A+Q。

MacOS

打开一个终端并运行

screen /dev/tty.usbmodem*

退出关闭-快捷键 CTRL-A CTRL-。

[Micropython]TPYBoard F407 DIY声光控开关

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习光敏传感器模块的工作原理。
  • 学习声音传感器模块的工作原理。
  • 学习TPYBoard F407 Micropython开发板与声音传感器与光敏传感器的接线方法以及利用声音与光控制发光二极管亮灭。
所需元器件
  • TPYBoard F407 Micropython开发板板子一块
  • 声音传感器一个
  • 光敏传感器一个
  • 面包板一块
  • 发光二极管若干
  • 数据线一条
  • 杜邦线若干
光敏传感器模块工作原理

1.光敏电阻模块对环境光线最敏感,一般用来检测周围环境的光线的亮度,触发单片机或继电器模块等; 2.模块在环境光线亮度达不到设定阈值时,DO端输出高电平,当外界环境光线亮度超过设定阈值时,DO端输出低电平; 3.DO输出端可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境的光线亮度改变; 4.DO输出端可以直接驱动本店继电器模块,由此可以组成一个光控开关。

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533629696804817.png
声音传感器模块工作原理

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

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533629713668426.png
硬件接线方法

上面我们已经知道光敏传感器跟声音传感器的工作原理,以及三根针脚的作用,那么我们只需将它们的电源正极与电源负极跟我们开发板的3.3V跟GND连接起来,然后将光敏传感器和声音传感器的信号输出针脚连接到我们开发板上的任意GPIO引脚。

本次实验将声音传感器信号输出引脚连接的是开发板的Y1针脚,光敏传感器信号输出引脚连接的Y2针脚。传感器连接完毕后,将发光数码管的正极插入面包板正极上,负极插入面包板的纵向插孔里(a,b,c,d,e,f,g,h,i,j),然后用杜邦线将负极连接到开发板的GND上,灯的正极连接到X1针脚,然后我们声音大小以及光亮强度来控制X1针脚输出高电平或者低电平来控制发光二极管的亮灭。

接线OK后,编写main.py,这样我们的DIY声光电控开关就完成了。

源代码
@micropython.asm_thumb
# 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]TPYBoard F407 驱动DS18B20检测温度

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

实验目的
  1. 学习在PC机系统中扩展简单I/O 接口的方法。
  2. 进一步学习编制数据输出程序的设计方法。
  3. 学习DS18B20的接线方法,并利用DS18B20检测当前温度。
所需元器件
  • TPYBoard F407 micropython开发板 1块
  • 数据线 1条
  • DS18b20温度传感器 1个
  • DS18B20扩展板(带驱动电路) 1个
  • 杜邦线若干
  • PuTTY调试工具
http://old.tpyboard.com/document/documents/tb407/18b20tem_0.png
学习DS18B20的接线方法,检测当前温度

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

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533630149265037.png

将DS18B20温度传感器直接插DS18B20模块上。如图

http://old.tpyboard.com/ueditor/php/upload/image/20180807/1533630161901981.png

DS18B20扩展板的针脚与TPYBoard F407 Micropython开发板的针脚对应关系如下:

TPYBoard F407开发板 DS18B20
3V3 VDD
GND GND
Y12 DO
源代码

接线OK后,将ds18b20.py和one_wire.py复制到PYBFLASH磁盘的根目录。将下面代码拷进main.py保存,等红灯熄灭后,RST开发板,用PuTTY可以看到当前的温度。

http://old.tpyboard.com/document/documents/tb407/18b20tem_5.png
import pyb
from pyb import Pin
from ds18b20 import DS18X20

DQ=DS18X20(Pin('Y12'))#DQ
while True:
        tem = DQ.read_temp()
        print(tem)
        pyb.delay(1000)

[Micropython]TPYBoard F407 驱动BMP180测量气压

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 学习BMP180测量气压的方法。
  • 学习TPYBoard F407 Micropython开发板中I2C接口的用法。
所需元器件
  • TPYBoard F407 Micropython开发板一块
  • BMP180气压模块一个
  • 数据线一条
  • 杜邦线若干
  • PuTTY调试工具
BMP180气压传感器的接线方法

BMP180是一直常见的气压传感器,BMP180是一款高精度、小体积、超低能耗的压力传感器,可以应用在移动设备中,它的性能卓越,精度最低可以达到0.03hPa,并且耗电极低,只有3μA;BMP180采用强大的8-pin陶瓷无引线芯片承载(LCC)超薄封装,可以通过I2C总线直接与各种微处理器相连。

http://old.tpyboard.com/document/documents/tb407/bmp180_1.jpg

TPYBoard F407 Micropython开发板和BMP180气压模块的针脚对应关系如下: IIC接口1的接线方法(程序中bmp=BMP180(1)调用开发板的IIC接口1)

TPYBoard F407开发板 BMP180气压模块
Y6 SCL
Y5 SDA
3V3 VCC
GND GND

IIC接口2的接线方法(程序中bmp=BMP180(2)调用IIC接口2)

TPYBoard F407开发板 BMP180气压模块
X32 SCL
X33 SDA
3V3 VCC
GND GND
源代码

接线OK后,导入bmp180.py,编写main.py保存,等红灯熄灭后,RST开发板,用PuTTY可以看到时间和温度。

http://old.tpyboard.com/document/documents/tb407/bmp180_2.png
from bmp180 import BMP180

bmp=BMP180(1)
tem=bmp.getTemp()
press=bmp.getPress()
altitude=bmp.getAltitude()
print('tem:',tem)
print('press:',press)
print('altude:',altitude)

[Micropython]TPYBoard F407 驱动DS3231读取时间、温度

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 学习硬件接线方法。
  • 学习TPYBoard F407 Micropython开发板中I2C接口的用法。
所需元器件
  • TPYBoard F407 Micropython开发板一块
  • DS3231时钟模块一个
  • 数据线一条
  • 杜邦线若干
  • PuTTY调试工具
DS3231的接线方法

DS3231时钟模块,通信用的是IIC接口在这只用到DS3231时钟模块的SCL,SDA,VCC,GND四个针脚即可设定读出时间和温度,下面是接线方法。

http://old.tpyboard.com/document/documents/tb407/3231time_1.png

F407 Micropython开发板和DS3231时钟模块的针脚对应关系如下: IIC接口1的接线方法(程序中ds=DS3231(1)调用IIC接口1)

TPYBoard F407 DS3231时钟模块
Y6 SCL
Y5 SDA
3V3 VCC
GND GND

IIC接口2的接线方法(程序中ds=DS3231(2)调用IIC接口2)

TPYBoard F407 DS3231时钟模块
X32 SCL
X33 SDA
3V3 VCC
GND GND
源代码

接线OK后,导入ds3231.py,编写main.py保存,等红灯熄灭后,RST开发板,用PuTTY可以看到时间和温度。

    # main.py -- put your code here!
import pyb
from ds3231 import DS3231
ds=DS3231(1)
#设置日期
ds.DATE([19,04,01])
#设置时间
ds.TIME([15,10,10])
#延时5秒查看效果
pyb.delay(5000)
#读取秒并打印
print(ds.sec())
#读取日期
print(ds.DATE())
#读取时间
print(ds.TIME())

#读取温度
print(ds.TEMP())

[Micropython]TPYBoard F407 驱动OLED液晶屏

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习 F407 Micropython开发板控制OLED显示字符。
所需元器件
  • TPYBoard F407 Micropython开发板一块
  • 数据线一条
  • 杜邦线若干
  • OLED液晶屏一块
什么是OLED显示屏
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(已集成在屏中)。

实际显示效果

http://old.tpyboard.com/document/documents/tb407/oled_1.png
OLED接口定义
GND 电源地
VCC 电源地(2.8V~5.5V)
DO 时钟线
DI 数据线
RES 复位线
DC 数据/命令
CS 片选
硬件的接线方法

在这OLED需要SPI接口与TPYBoard F407 Micropython开发板进行连接传输数据,SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在这OLED需要SPI接口与TPYBoard F407 Micropython开发板自带两个SPI接口,本实验中我们用的开发板的SPI1接口。

具体接线方法
OLED液晶屏 TPYBoardF407 开发板(SPI1)
GND GND
VCC 3v3
D0 X16
D1 X18
RES X35
DC X36
CS 悬空
实物接线图
http://old.tpyboard.com/document/documents/tb407/oled_2.jpg

接线OK后,引入font_.py文件和ssd1306.py文件,再可运行main.py了。

程序源代码
import pyb
from ssd1306 import SSD1306


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

led_red = pyb.LED(1)
led_red.off()
display.poweron()
display.init_display()
display.draw_text(1,1,'Hello EveryOne',size=1,space=1)
display.draw_text(1,10,'Micropython F407',size=1,space=1)
display.draw_text(1,20,'Let Us Do it',size=1,space=1)
# 显示出你想要显示的内容
display.display()

[Micropython]TPYBoard F407 超声波测距

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 学习超声波模块的测距原理。
  • 学习LCD5110接线方法
  • 学习TPYBoard F407 Micropython开发板控制超声波模块测距。
所需元器件
  • 超声波模块一个
  • TPYBoard F407 Micropython开发板一块
  • LCD5110显示屏一个
  • 数据线一条
  • 杜邦线若干
超声波模块工作原理

(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。 (2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回。 (3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。 如下图接线,VCC 供 5V电源, GND 为地线,TRIG 触发控制信号输入,ECHO 回响信号输出等四个接口端。

http://old.tpyboard.com/document/documents/tb407/supwave_1.png
硬件的连接

TPYBoard F407 Micropython开发板的针脚与LCD5110的针脚对应关系如下:

TPYBoard F407 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)
X18 DIN data flow (Master out, Slave in)
X16 CLK SPI clock
3V3 VCC  
Y12 LIGHT Light (0=on, 1=off)
GND GND  

TPYBoard F407 Micropython开发板的针脚与超声波模块的针脚对应关系如下:

F407 Micropython开发板 超声波模块
X2 Trig
X1 Echo
5V VCC
GND GND

接线OK后,并且导入font.py文件和upcd8544.py文件,编写main.py将测到的距离显示在LCD5110显示屏上,运行main.py就OK了。

http://old.tpyboard.com/document/documents/tb407/supwave_2.jpg
源代码
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=>X18-MOSI/CLK=>X16-SCK
                #DIN =>SPI(1).MOSI 'X18' data flow (Master out, Slave in)
                #CLK =>SPI(1).SCK  'X16' 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*34299/2
                        print('Distance')
                        print(distance,'cm')
                        lcd_5110.lcd_write_string('Distance',0,0)
                        lcd_5110.lcd_write_string(str(distance),0,1)
                        lcd_5110.lcd_write_string('cm',58,1)
                        lcd_5110.lcd_write_string('This is a test of F407',0,2)
                flag=0
                run=0

[Micropython]TPYBoard F407 通过ADC读取光照值

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

实验目的
  • 了解光敏电阻模块的相关知识。
  • 学习使用TPYBoard F407开发板上的ADC接口获取光照值。
所需元器件
  • 光敏电阻模块 一个
  • TPYBoard F407 开发板一块
  • 数据线一条
  • 杜邦线若干
光敏电阻模块的介绍

光敏电阻模块上采用灵敏性光敏电阻传感器,通过比较器输出,具有信号干净、波形好、驱动能力强等特点。输出方式有两种:DO数字开关量和 AO模拟量。模块上配有可调电位器,可调节检测光线亮度的阈值,主要与DO端结合使用。当检测到的光照强度超过阈值时,DO端输出低电平,反之输出高电平。AO端会直接输出具体的模拟电压值。

实物图

_images/light.png

引脚定义

引脚 功能
GND 电源地
VCC 电源正(3.3V~5V)
AO 模拟量输出
DO 数字量输出
硬件的连接

TPYBoard F407与光敏电阻模块的接线方法,如下:

TPYBoard F407 光敏电阻模块
GND GND
3V3 VCC
X23 AO

接线OK后,编写main.py。

源代码
import pyb
from pyb import ADC,Pin
adc = ADC(Pin('X23'))

while True:
    print(adc.read())
    pyb.delay(2000)

[Micropython]TPYBoard F407 DAC数模转换

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

DAC是数字模拟转换,将数字信号转换为模拟信号(以电流、电压或电荷的形式)。在TPYBoard F407开发板上DAC可输出介于0和3.3V之间的电压。 TPYBoard F407开发板上有两个DAC接口,分别是X15和X16引脚。

使用示例:

from pyb import DAC

dac = DAC(1)            # create DAC 1 on pin X15
dac.write(128)          # write a value to the DAC (makes X15 1.65V)

dac = DAC(1, bits=12)   # use 12 bit resolution
dac.write(4095)         # output maximum value, 3.3V

输出连续正弦波:

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)

以12位分辨率输出连续正弦波

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)
构造器
class pyb.DAC(port, bits=8)

构造一个DAC对象。

port 是一个针脚, 或整数(1 或 2)。DAC(1) 是针脚X15 和 DAC(2) 是针脚X16。

bits 是指定分辨率的整数,可以是8或12。

方法
DAC.init(bits=8)

重新初始化DAC。 bits 8位或12位。

DAC.deinit()

初始化DAC使其引脚可用于其他用途。

DAC.noise(freq)

产生伪随机噪声信号。一个新的随机样本写入DAC输出在给定的频率

DAC.triangle(freq)

以指定频率产生三角波。

DAC.write(value)

写入参数。在8bits时,参数范围[0-255];在12bits时,参数范围[0..4095]。

DAC.write_timed(data, freq, *, mode=DAC.NORMAL)

使用DMA方式周期写入数据

   data,缓冲区数组    freq,默认使用Timer(6),用指定频率更新。也可以指定另外的定时器,有效的定时器是[2, 4, 5, 6, 7, 8]。    modeDAC.NORMALDAC.CIRCULAR

同时利用DAC的例子:

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)

[Micropython]TPYBoard F407 定时器和呼吸灯(PWM)

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

TPYBoard F407开发板上有14个定时器,编号分别为1-14,其中编号3内部系统占用,5、6、7用于伺服控制和ADC/DAC。

程序示例:

from pyb import Timer #导入库
tim = pyb.Timer(4) #设置Timer编号
tim.init(freq=1) #设置频率,freq=1大约1秒1次。
tim.counter() # 获取计数器值
tim.callback(lambda t:pyb.LED(4).toggle()) #注册回调函数。这里使用了lambda表达式

以上程序实现的功能是,板载的第4个蓝色LED灯会每隔1秒改变一次状态,即亮/灭一次。

接下来,我们通过使用定时器的PWM功能,来实现一个呼吸灯的效果。

1、外接一个发光二极管。将发光二极管的正极接到X12引脚上,负极接到GND引脚上。

TPYBoard F407 发光二极管
GND 正极(长腿)
X12 负极(短腿)

程序示例:

# main.py -- put your code here!
from pyb import Pin
from pyb import Timer #导入库

#------------定时器-------------#
tim = pyb.Timer(4) #设置Timer编号
tim.init(freq=1) #设置频率,freq=1大约1秒1次。
tim.callback(lambda t:pyb.LED(4).toggle()) #注册回调函数。这里使用了lambda表达式

#------------PWM呼吸灯-------------#
p = Pin('X12',Pin.OUT_PP)
tim = Timer(2, freq=1000)
ch = tim.channel(2, Timer.PWM, pin=p)

while True:
    for i in range(60):
        ch.pulse_width_percent(i)
        pyb.delay(20)
    for k in range(60,0,-1):
        ch.pulse_width_percent(k)
        pyb.delay(20)

程序分析

在 micropython中实现PWM功能是通过定时器来实现的。 其实PWM是Timer的一种工 模式,需要设置 Timer 的通道、频率、 PWM 模式以及输出引脚等。 首先,我们定义了一个支持 PWM 输出的引脚。

p = Pin('X12',Pin.OUT_PP)  # X12 has TIM2, CH2

X12 引脚连接的是定时器 2, 通道 2(其他引脚对应的定时器和通道,详见针脚图)。点击查看针脚图

tim = Timer(2, freq=1000)
ch = tim.channel(2, Timer.PWM, pin=p)

定时器 Timer 下的 channel()方法用于设置定时器的通道,需要传递 3 个参数:

   timer.channel(channel, mode,pin)

- channel:定时器通道编号
- mode: 定时器工作模式(Timer.PWM, PWM 模式)
- pin:驱动的引脚

在 PWM 模式下,可以调用 pulse_width_percent()方法,设置输出的占空比。 不传递参数是返回当前的占空比。还有一个 pulse_width()方法,用于设置输出的脉冲宽度。 不传递参数是返回当前的脉冲宽度。

[Micropython]TPYBoard F407 三线伺服舵机控制模块

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

Servo 对象用于控制标准的三线伺服舵机设备(电源地、电源正、信号)。在TPYBoard F407 开发板上有4个引脚可直接使用:X11、X12、X13和X14引脚。

程序示例:

import pyb

s1 = pyb.Servo(1)   # 在X11引脚上创建伺服对象
s2 = pyb.Servo(2)   # 在X12引脚上创建伺服对象

s1.angle(45)        # 转动到45度
s2.angle(0)         # 转动到0度

# 移动舵机指定角度,在1500毫秒内完成
s1.angle(-60, 1500)
s2.angle(30, 1500)

注解

舵机的驱动是通过Timer(5)产生PWM输出来实现的。使用时需注意避免冲突。

Constructors
class pyb.Servo(id)

创建一个伺服对象。 id is 1-4, 对应的引脚为 X11~X14.

Methods
Servo.angle([angle, time=0])

不传参数,返回当前角度。

传递参数, 设置角度:

  • angle 指定转动的角度。
  • time 达到指定角度所需的毫秒数。若忽略,将以最快的速度。
Servo.speed([speed, time=0])

不传参数,返回当前转动速度。

传递参数, 设置转动速度:

  • speed 要设置的转动速度,介于-100到100之间。
  • time 达到指定速度所需的毫秒数。若忽略,将以最短的时间。
Servo.pulse_width([value])

不传参数,返回原始的脉冲宽度值。

传递参数,设置脉冲宽度值。

Servo.calibration([pulse_min, pulse_max, pulse_centre[, pulse_angle_90, pulse_speed_100]])

不传参数,返回当前校准的数据。数据类型为元组,内含5个元素。

传递参数,设置定时校准:

  • pulse_min 允许的最小脉冲宽度。
  • pulse_max 允许的最大脉冲宽度。
  • pulse_centre 与中心/零位相对应的脉冲宽度。
  • pulse_angle_90 90度角的脉冲宽度。
  • pulse_speed_100 与速度100相对应的脉冲宽度。

[Micropython]TPYBoard F407 手机远程控制板载LED(蓝牙通信)

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

实验目的
  • 学习在PC机系统中扩展简单I/O 接口的方法。
  • 进一步学习编制数据输出程序的设计方法。
  • 通过 TPYBoard F407开发板实现与蓝牙模块之间的串口通信。
所需元器件
  • HC-06 蓝牙模块 一个
  • TPYBoard F407 开发板一块
  • 数据线一条
  • 杜邦线若干
HC-06蓝牙模块的介绍

(HC-06蓝牙模块是主从一体的蓝牙串口模块。简单的说,当蓝牙设备与蓝牙设备配对连接成功后,我们可以忽视蓝牙内部的通信协议,直接将蓝牙当做串口用。 当建立连接,两设备共同使用一通道也就是同一串口,一个设备发送数据到通道中,另一个设备便可以接收到通道中的数据。

程序设计

我们使用TPYBoard F407的串口2连接HC-06蓝牙模块。使用手机打开蓝牙与HC-06蓝牙模块进行配对、连接。当它们之间成功建立链接后, 手机与TPYBoard F407之间就建立了一个透明的数据传输通道,HC-06蓝牙模块是手机和开发板之间的数据中转站,我们不用去管蓝牙的通信协议是什么, 只需要把想要发送的数据通过串口给HC-06蓝牙模块就可以,HC-06蓝牙模块会将数据原封不动的传递给手机;同样,手机发送的数据传递给HC-06蓝牙模块后, HC-06蓝牙模块再通过串口将数据原封不动的传递给开发板。所以对于开发板来说,我们只需要进行串口的读写操作即可。

硬件的连接

TPYBoard F407与HC-06蓝牙模块的接线方法,如下:

TPYBoard F407 HC-06
GND GND
5V +5V
X14 TX
X13 RX

接线OK后,编写main.py。

源代码
import pyb
from pyb import UART

#定义HC-05/06蓝牙模块连接的串口
#串口编号2 波特率9600 收发数据超时时间100ms
uart = UART(2,9600,timeout=100)

while True:
    #判断串口缓存区是否有数据
    if uart.any() > 0:
        #读取全部数据,返回的是bytes
        data = uart.read()
        #字节数组转字符串
        id = data.decode()
        #字符串转整型
        id = int(id)
        #板载的LED编号是1~4,判断数据是否符合,防止程序异常
        if id > 0 and id < 5:
            pyb.LED(id).toggle()
效果演示

1、开发板上电后,你会看到蓝牙模块上的LED快速闪烁,说明当前没有蓝牙设备连接。

2、手机打开【蓝牙串口调试助手】,搜索并连接蓝牙设备,HC-06蓝牙模块的蓝牙名称是HC-06,配对密码是1234。

3、连接成功后,手机发送1~4之间的数字,板载对应的LED就会进行亮/灭操作。

蓝牙串口调试助手(Android版) 点击下载

TPYBoard MicroPython 固件开发教程

[MicroPython]TPYBoard 使用mpy-cross工具生成mpy文件

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

接触过Python语言的人都知道,Python可以编译成.pyc文件,它是一种二进制文件,可以提高程序的加载速度,同时 也是一种保护源代码的有效方法。那么在micropython中,又该如何保护源程序呢? 贴心的micropython创始人也提供了类似的功能,可以将.py文件编译成.mpy文件。接下来,介绍一下具体的实现步骤。(本文主要以Linux Ubuntu系统为例)

搭建micropython编译环境

1.安装arm-none-eabi-gcc交叉编译工具和gcc编译器。

sudo apt-get install gcc-arm-none-eabi

sudo apt-get install gcc

2.下载micropython源码包到本地,我下载到了home目录下。

git clone --recursive https://github.com/micropython/micropython.git
生成mpy文件

3.切换到/home/micropython/mpy-cross目录执行make,编译生成mpy-cross工具。

make

4.在mpy-cross目录新建一下test.py文件,输入点亮LED4,用于测试。

import pyb

pyb.LED(4).on()

5.执行编译mpy文件的命令。

./mpy-cross test.py

其他相关功能可查看同目录下的README.md文件。

6.命令执行成功后,你就能发现同目录下出现了一个test.mpy文件。

_images/3.png

7.将test.mpy文件拷贝放到TPYBoard v10x的TPFLASH中,直接在main.py中import即可。

import test
_images/4.png

8.重置TPYBoard使其重新运行程序,大家就会看到LED4亮起来了。

注意: 如果运行时出现“ValueError: invalid .mpy file”错误的话,需要更新一下TPYboard的micropython固件(最新版本是1.9.3)。

micropython官方下载地址:http://micropython.org/download

DFU-USB接口烧写固件参考:http://tpyboard.com/support/reference11/302.html

ST-LINK烧写固件参考:http://tpyboard.com/support/reference11/239.html

虽然是进行了加密编译成了mpy文件,但是还有一些缺陷,毕竟mpy文件仍然是存放在TPFLASH或TF卡中,很容易被别人拷贝,也很有可能会被反编译出来。 是否可以直接将Python脚本文件直接编译在固件中呢?答案显然是可以!想知道的话,点击右下角Next参考下一篇《TPYBoard Micropython中增加模块》。

[MicroPython]TPYBoard v10x 在micropython中增加py模块

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

开始之前,首先要感谢一下TPYBoard技术交流群(157816561)-云之初晓网友的分享。

将自己编写的一些Python脚本的类库添加到固件中,在使用时只需import调用,就像使用内置的pyb一样简单便捷; 同时还有另外一个重要的功能,就是可以很好的保护源代码。比起生成mpy加密文件这种方式来说,显然添加到固件中会更加安全可靠。

搭建micropython编译环境

1.安装arm-none-eabi-gcc交叉编译工具和gcc编译器。

sudo apt-get install gcc-arm-none-eabi

sudo apt-get install gcc

2.下载micropython源码包到本地,我下载到了home目录下。

sudo git clone --recursive https://github.com/micropython/micropython.git
MicroPython的源码结构
_images/add1.png
docs/ micropython的说明文档(restructuredText)
drivers/ 一些外接设备的实现例程(eg:ds18b20,nrf24l01)
examples/ micropython的使用例程
extmod/ C语言实现的模块
lib/ 各类芯片的lib文件
mpy-cross/ 自带的交叉编译器,可以将.py生成.mpy加密文件
ports/ 移植到各类MCU上的源码(eg:stm32,esp8266)
tests/ 测试框架和Python脚本
tools/ 工具

进入ports目录下你会发现,micropython根据不同的MCU运行平台进行了分类,比如esp8266就是运行在esp8266-WIFI模块上的micropython,stm32是运行在stm32上的,还有cc3200等。

_images/add2.png

然后进入stm32/boards目录下,里面又根据stm32不同的系列进行了划分。

开始编译

3.回到stm32/目录下,将需要添加到固件中的Python脚本类库放到modules/目录下。编译之前,请确保程序运行无误。为了测试新建了一个test.py文件,简单写了两个函数。如下:

import pyb

def on():
    pyb.LED(4).on()
def off():
    pyb.LED(4).off()

4.执行编译命令,等待编译完成。

sudo make BOARD=PYBV10

BOARD参数为stm32/boards/目录下相应的开发板名称。 本次教程用的是TPYBoardv102(蓝色)开发板,兼容PYBV10,所以选择PYBV10开发板编译。 若是TPYBoardv102(绿色)基础板,同样选择PYBV10。 若是TPYBoardv102(黑色)开发板,需选择PYBV11。

_images/add3.png

生成的固件在stm32/build-PYBV10/目录下的firmware.dfu和firmware.hex文件。

_images/add4.png

5.将dfu和hex文件拷贝到本地,进行烧写。

dfu文件的烧写教程,请参考:http://tpyboard.com/support/reference11/302.html

hex文件的烧写需要借助ST-LINK工具,请参考:http://tpyboard.com/support/reference11/239.html

6.烧写完毕后进行测试,在main.py文件输入以下内容:

import pyb
import test
test.on()
pyb.delay(1500)
test.off()

PyCharm安装MicroPython插件

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

前言

PyCharm可以说是当今最流行的一款Python IDE了,大部分购买TPYBoard的小伙伴都会使用PyCharm编写MicroPython的程序。遗憾的是,只是把PyCharm当做了一种代码编辑器,调试依然还的需要其他辅助软件,比如PuTTY。其实最近也有不少小伙伴询问PyCharm中怎么安装MicroPython插件的问题,想着正好网站也缺少这部分的教程,不如实践一下总结下经验共享给大家,也好给爱好MicroPython的小伙伴提供便利。

准备工作

硬件要求

  • TPYBoard v102开发板 一块

电脑环境要求

  • windows系统(本教程以win10为例)
  • 已安装Python环境(本教程Python 3.6.4)
  • 已安装PyCharm软件
  • 可接入网络

PyCharm 2018专业版 安装和永久激活方法 点击下载

动手安装

安装MicroPython插件

打开“PyCharm”软件。

_images/n1.png

点击 Create New Project 创建一个新项目。选择项目保存的路径,选择 Existing interpreter 加载本地的Python环境,不使用虚拟环境。点击Create即可完成项目的创建。

_images/n2.png

菜单栏 File => Settings => Plugins ,输入 micropython 进行搜索,接着点击 Search in repositories,弹框出现MicroPython插件时点击 Install 进行安装,安装完毕后重启PyCharm软件。

_images/install.gif

启用MicroPython的设备

将TPYBoard v102开发板通过USB数据线接入电脑中,然后菜单栏 File => Settings => Languager & Frameworks => MicroPython 勾选Enable MicroPython support,Device type选择Pyboard,Device path输入自己电脑上开发板对应的端口号,比如COM19。点击Apply进行应用,点击OK关闭对话框。

_images/COM.gif

REPL调试

安装是不是很简单,接下来测试一下。点击当前项目右键选择创建一个Python File,输入名称main。这时,PyCharm提示我需要升级docopt包,点击安装后提示错误,查看详情后如下图:

_images/m1.png

若没有遇到此问题的,可自行调到下一步。复制错误信息百度查找解决方法,找到了一个可行的方法就是:找到PyCharm的安装目录下的packaging_tool.py进行修改,packaging_tool.py在JetBrainsPyCharm 2018.1helpers目录下。打开packaging_tool.py文件进行修改(别用文本文档容易出错),找到do_install和do_uninstall这两个函数(错误信息里有),改为如下内容:

def do_install(pkgs):
    try:
        try:
            from pip._internal import main
        except Exception:
            from pip import main
    except ImportError:
        error_no_pip()
    return main(['install'] + pkgs)

def do_uninstall(pkgs):
    try:
        try:
            from pip._internal import main
        except Exception:
            from pip import main
    except ImportError:
        error_no_pip()
    return main(['uninstall', '-y'] + pkgs)

修改保存后,再点安装就好了。

_images/m2.png

在main.py文件中输入以下的代码,该代码的功能就是每隔1秒反转下LED4的状态同时输出Hello字符。

from pyb import LED

LED4 = LED(4)

while True:
    LED4.toggle()
    print('Hello')
    print('-------')
    pyb.delay(1000)

输入代码时你会发现,PyCharm对于pyb模块并没有代码智能提示的功能,这是因为此micropython插件并没有实现对pyb模块的支持,不过该插件已经包含了文件下载和REPL调试的功能,也是很厉害的贡献了。该插件源码的Github地址:https://github.com/vlasovskikh/intellij-micropython

编写保存后,点击软件右上角选择 Flash main.py,点击旁边的绿色箭头开始运行,main.py文件就会下载到板子里,下载完毕后会自动运行程序,软件下方的调试区会显示相关信息。如下:

_images/m3.png _images/m4.png

菜单栏 Tools => MicroPython => MicroPython REPL 可以调出REPL调试界面,使用方法同PuTTY。每次调用时,他会先停止运行程序。

_images/m5.png

详细的操作步骤如下:

_images/repl.gif

使用Visual Studio Code进行MicroPython编程

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

Visual Studio Code

Visual Studio Code(以下简称VSCode)是一个轻量且强大的跨平台开源代码编辑器(IDE),支持Windows,OS X和Linux。内置JavaScript、TypeScript和Node.js支持,而且拥有丰富的插件生态系统,可通过安装插件来支持 C++、C#、Python、PHP等其他语言。

准备工作

  • TPYBoard v102 一块
  • 可访问网络的Windows系统的电脑(本文以win10为例)
  • 已安装VSCode编辑器

VSCode的相关地址

官网地址 https://code.visualstudio.com/

GitHub地址 https://github.com/Microsoft/vscode

VSCode IDE下载 https://code.visualstudio.com/?wt.mc_id=vscom_downloads

安装Pycom插件

Pycom插件需要node.js依赖项,所以先要安装node.js。下载地址 安装完成后,通过CMD命令查看node版本号来确定是否安装成功。

node -v
_images/1cmd.png

打开VSCode,点击左侧菜单栏 Extensions 扩展图标,进入插件搜索界面。

_images/vs0.png

输入 Pymakr 进行相关插件搜索,点击 Install 进行安装。

_images/vs1.gif

安装完毕后,关闭VSCode。将TPYBoard v102插入电脑,设备管理器中确认是否已成功加载端口。

_images/vs2.png

再次打开VSCode后,默认会自动打开 pymakr.json 配置文件,我们需要进行修改并保存。

_images/vs3.png

接下来把配置文件简化些,保留需要的部分。pymakr.json 配置文件内容如下:

Pycom插件:https://marketplace.visualstudio.com/items?itemName=dphans.micropython-ide-vscode

保存后软件右下角的 TERMINAL 终端会自动创建一个Pycom Console并自动连接板子的REPL端口。

如何使用

每次启动VSCode时Pycom Console都会自动打开并去连接你设置的端口。

_images/vs4.png

这时,插上开发板后会自动连接。REPL调试与PuTTY用法一样,CTRL+C:停止运行程序 CTRL+D:重新运行程序(软复位)。

_images/vs5.png

接下来,说明下文件下载功能的使用方法。首先,在VSCode左侧的资源管理中新建一个目录创建一个工程,新建一个main.py文件。

_images/vs6.gif

写一段简单的控制板载LED的程序用于测试。编写代码时,VSCode会提示错误,这是因为在我们本地没有pyb库,所以错误可以忽略,不影响功能。

from pyb import LED

for i in range(5):
    LED(4).toggle()
    print('-----',i,'-----')
    pyb.delay(350)

VSCode工具底部蓝色区域,有关于Pycom插件的几个快捷功能。

_images/vs7.png
  • Pycom Console:打开或关闭与板子的链接
  • Run:运行当前文件
  • Upload:上传工程文件到板子里
  • Download:下载板子里的工程文件

点击 Run 运行当前的main.py,注意这只是运行一遍而已,并不会把main.py里的代码存储到开发板的FLASH中。

_images/vs8.gif

点击 Upload 将main.py上传到板子里,上传完毕后板子会自动重启并运行新的程序。这时会提醒你端口断开,不过它会自动连接的。

_images/vs9.gif

有时会出现连接失败的情况,出现 > Failed to connect (Error: Port is not open). Click here to try again. 提示,这时点击下 Pycom Console 就可以了。

_images/vs11.gif

接下来试一下 Download 的功能,点击后它会提醒你发现了两个文件,是否只下载当前的文件还是全部下载。出现这个提示是因为板子里还有一个boot.py文件。选择那个都可以,这里我们选择全部下载点击Yes。

_images/vs10.gif

使用评价

总体来说,还是挺不错的,不仅可以上传文件还可以下载。就是每次操作后,都会进行一次硬件复位,端口断开再重连,感觉不太友好。虽然我们在使用micropython中的模块时没有代码提示补全等功能,但是可以去安装Python插件,至少使用Python语法和模块时会比较方便。

TPYBoard 相关下载

TPYBoard 资料:

TPYBoard主要数据手册

TPYBoard 固件更新记录

本文章记录了TPYBoard系列开发板的固件更新记录,方便大家查阅。

TPYBoard系列开发板

TPYBoardv10x 固件更新记录

以下更新不包括 TPYBoardv101

2019年01月12日 版本号 TPYBoardv10x-v1.9.4-0.0.7

  • MicroPython版本更新到v1.9.4
  • 增加LCD1602显示屏驱动类库
  • 增加LCD12864B显示屏驱动类库
  • 增加BMP180气压传感器驱动类库
  • 增加SYN6288语音合成模块驱动类库
  • 增加四相步进电机驱动类库
  • 增加PS2无线手柄驱动类库
  • 增加AS608指纹识别模块驱动类库
  • 增加TFT液晶显示屏驱动类库
  • 增加GY-39气象监测模块驱动类库
  • 增加NRF24L01-2.4G无线模块驱动类库
  • 增加NRF905-2.4G无线模块驱动类库
  • 修复一些BUG

2018年07月19日 版本号 TPYBoardv10x-v1.9.3-0.0.6

  • 增加AM2320驱动类库
  • 增加GY-30驱动类库
  • 修复一些BUG

2018年06月30日 版本号 TPYBoardv10x-v1.9.3-0.0.5

  • 增加LCD5110驱动类库
  • 增加DS18B20驱动类库

2018年06月25日 版本号 TPYBoardv10x-v1.9.3-0.0.4

  • 增加单个数码管驱动类库
  • 增加DS3231驱动类库

2018年06月09日 版本号 TPYBoardv10x-v1.9.3-0.0.3

  • 增加AT24C系列EEPROM存储器驱动类库

2018年05月31日 版本号 TPYBoardv10x-v1.9.3-0.0.2

  • 增加VS1838B红外接收模块的类库

2018年04月28日 版本号 TPYBoardv10x-v1.9.3-0.0.1

  • MicroPython版本更新到v1.9.3
  • 增加MFRC522-RDIF射频卡模块的类库

使用方法参照 http://docs.tpyboard.com/zh/latest/tpyboard/driver/

固件下载

TPYBoardv20x 固件更新记录

TPYBoardv70x 固件更新记录

TurnipDog 固件更新记录

2019年01月12日 版本号 TurnipDog-v1.9.4-0.0.7

  • MicroPython版本更新到v1.9.4
  • 增加LCD1602显示屏驱动类库
  • 增加LCD12864B显示屏驱动类库
  • 增加BMP180气压传感器驱动类库
  • 增加SYN6288语音合成模块驱动类库
  • 增加四相步进电机驱动类库
  • 增加PS2无线手柄驱动类库
  • 增加AS608指纹识别模块驱动类库
  • 增加TFT液晶显示屏驱动类库
  • 增加GY-39气象监测模块驱动类库
  • 增加NRF24L01-2.4G无线模块驱动类库
  • 增加NRF905-2.4G无线模块驱动类库
  • 修复一些BUG

2018年07月19日 版本号 TurnipDog-v1.9.3-0.0.6

  • 增加了AM2320驱动类库
  • 增加了GY-30驱动类库
  • 修复了一些BUG

2018年06月30日 版本号 TurnipDog-v1.9.3-0.0.5

  • 增加了LCD5110驱动类库
  • 增加了DS18B20驱动类库

2018年06月25日 版本号 TurnipDog-v1.9.3-0.0.4

  • 增加了单个数码管驱动类库
  • 增加了DS3231驱动类库

2018年06月09日 版本号 TurnipDog-v1.9.3-0.0.3

  • 增加了AT24C系列EEPROM存储器驱动类库

2018年05月31日 版本号 TurnipDog-v1.9.3-0.0.2

  • 增加VS1838B红外接收模块的类库

2018年04月28日 版本号 TurnipDog-v1.9.3-0.0.1

  • micropython版本更新到v1.9.3
  • 增加MFRC522-RDIF射频卡模块的类库

使用方法参照 http://docs.tpyboard.com/zh/latest/tpyboard/driver/

固件下载

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