软件准备
未来板编程推荐采用小喵科技研发的纯代码Python编程软件 KittenCode。
软件下载
📥 前往下载
软件简介
- 安装好软件并初次打开时,软件资源将自动解压到目标盘符(可能会占用一些时间,请耐心等待);
- 成功开启软件后进入主界面,以下为界面功能指示图;
1 | 项目管理:新建、导出或导入项目、项目重命名 |
---|---|
2 | 模式切换:默认Python3模式(纯软件);可切换至硬件模式(支持MicroPython主控板编程) |
3 | 功能按钮:库管理、教程、示例等功能(持续优化) |
4 | 文件管理:展示项目内所包含的文件,可理解为工作空间。能够进行项目文件的各种增删操作 |
5 | 代码编辑区:文件管理中的文件在这个区域进行编辑(目前仅支持.py .md .txt .json) |
6 | 终端:运行代码后,结果会返回在终端;也可作为REPL使用 |
连接硬件
- 将Type-C USB连接未来板后,打开未来板电源开关。
- 接下来要对未来板编程,所以此处将模式切换成 硬件模式 并选择未来板。
- 连接串口(这里选择串口USB连接)
- 成功连接后,底部终端将打印消息,如下图。
- 试着输入一行指令,与未来板交互。不出意外可听到未来板蜂鸣器响起。
buzzer.tone(200, 0.5)
函数API
未来板是microPython而非Python3
- microPython是Python的精简指令集,为了在硬件上能跑,阉割了许多高性能库
- Python相关的第三方库例如pygame等是无法在未来板上运行的请悉知
- 同样的名称例如os库内的方法,在microPython与Python3中也存在差异,一切请以我们提供的教程或网络上关于microPython的相关API教程为指南进行参考
显示屏
使用screen类调用显示相关功能
- 设置同步刷新
screen.sync = val
val | 含义 |
---|---|
0(推荐) | 显示函数均不实时显示在屏幕,需要使用刷新显示方法将设置过的内容显示出来 |
1(默认) | 每显示函数都将直接显示在屏幕上,如果显示的函数太多会造成效率低 |
- 屏幕填充
screen.fill(color)
color | 含义 |
---|---|
RGB数值 | 为标准RGB色彩数值,例如白色 screen.fill((255, 255, 255)) |
明度 | 数值区间为0~255,常用screen.fill(0)填充最低明度即黑色来达到清屏效果 |
映射好的颜色 | RED、YELLOW、PINK、WHITE、GREEN、BLUE、PURPLE、CYAN、BLACK |
- 绘制像素点
screen.pixel(x, y, color=255)
参数 | 含义 |
---|---|
x, y | x和y分别是屏幕尺寸,x=160,y=128 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
- 绘制线条
screen.line(x1, y1, x2, y2, color=255)
坐标:(x1, y1)和(x2, y2)为顶点绘制线段绘制线条
参数 | 含义 |
---|---|
x1, y1 | 线段的一个端点 |
x2, y2 | 线段的另一个端点 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
📋示例程序:亮度曲线
from future import *
import time
Light = [0, 0, 0]
screen.sync = 0
while 1:
light = sensor.getLight()
if len(Light) < 160:
Light.append((125 - int(light/4095*125)))
else:
Light.pop(0)
screen.fill(0)
i_end = len(Light) - 1
for i in range(i_end): # 与 for i in range(i_end) 等效
screen.pixel(i, Light[i])
screen.line(i, Light[i], (i+1), Light[(i+1)])
screen.refresh()
time.sleep_ms(1)
- 🟥 绘制矩形
screen.rect(x, y, w, h, color=255, fill=0)
参数 | 含义 |
---|---|
x, y | 矩形左上角顶点 |
w, h | 矩形的宽和高 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
fill | 0:不填充(默认) |
1:填充 |
- 🔺绘制三角形
screen.triangle(x1, y1, x2, y2, x3, y3, color=255, fill=0)
参数 | 含义 |
---|---|
x1, y1, x2, y2, x3, y3 | 三角形的顶点坐标 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
fill | 0:不填充(默认) |
1:填充 |
- 🔴 绘制圆形
screen.circle(cx, cy, r, color=255, fill=0)
参数 | 含义 |
---|---|
x, y | 圆形坐标 |
r | 圆的半径 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
fill | 0:不填充(默认) |
1:填充 |
- 绘制圆角矩形
screen.roundRect(x,y,r,w,h,color=255,fill=0)
参数 | 含义 |
---|---|
x, y | 矩形左上角顶点 |
r | 圆角半径 |
w, h | 矩形的宽和高 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
fill | 0:不填充(默认) |
1:填充 |
- 🔷 绘制多边形
screen.polygon(x, y, sides=3, r=10, th=3, rot=0, color=255, fill=0)
参数 | 含义 |
---|---|
x, y | 多边形中心点 |
sides | 多边形边数,默认为3 |
r | 中心点到顶点到距离,默认10 |
th | 边框到厚度,默认3 |
rot | 旋转角度(正数为逆时针转),默认0 |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
fill | 0:不填充(默认) |
1:填充 |
- 绘制英文字符(字符串)
screen.text(text, x=0, y=0, ext=1, color=255)
参数 | 含义 |
---|---|
text | 英文字符串,包含英文字母、数字、简单的非输入法下的?!^等符号 |
x, y | 第一个字符左上角,不填默认为(0, 0)为屏幕左上角 |
ext | 字符字号,默认为1号——8x8像素。字号增大的规律为8*ext |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
- 绘制中文字符(字符串)
screen.textCh(text, x=0, y=0, ext=1, color=255)
参数 | 含义 |
---|---|
text | 中文字符串,包括大部分简体和繁体、数字、简单的?!℃等符号 |
x, y | 第一个字符左上角,不填默认为(0, 0)为屏幕左上角 |
ext | 字符字号,默认为1号——12x12像素。字号增大的规律为12*ext |
color | 为标准RGB色彩数值。默认不填即为白色,明度=255 |
- 显示Bmp图片 仅支持24/32位的bmp,尺寸小于等于160x128
screen.loadBmp(path, x=0, y=0)
参数 | 含义 |
---|---|
path | 绝对路径,如path='name.bmp' |
x, y | 图片的左上角坐标,不填默认为(0, 0)从屏幕左上角开始 |
- 显示PNG图片 尺寸小于等于160x128
screen.loadPng(path, x=0, y=0)
参数 | 含义 |
---|---|
path | 绝对路径,如path='name.png' |
x, y | 图片的左上角坐标,不填默认为(0, 0)从屏幕左上角开始 |
- 显示动态GIF图 尺寸小于等于160x128
screen.loadGif(path, x = 0, y = 0)
参数 | 含义 |
---|---|
path | 绝对路径,如path='name.gif' |
x, y | 图片的左上角坐标,不填默认为(0, 0)从屏幕左上角开始 |
📥 测试图片资源pic.zip
# 显示png
from future import *
screen.loadPng('hmP.png')
# 显示gif
from future import *
while 1:
screen.loadgif('hmG.gif')
# 回调方式显示gif, 可以发现在gif显示过程中你也可以通过按键A播放蜂鸣器
from future import *
def gifCb():
if sensor.btnValue('a'):
buzzer.tone(200,-1)
else:
buzzer.stop()
tft.show(fb)
fb.loadgif('boot1.gif',gifCb)
AB按键
- 按键检测
sensor.btnValue(btn)
参数 | 含义 |
---|---|
btn | 'a' / 'b' 分别代表按键A和B,对应按键按下返回True,否则为False |
可以直接使用sensor.btnValue()则返回一个数组[],当有按键按下时返回返回对应的键位
"""
REPL
"""
# 没有按下
>>>sensor.btnValue()
>>>[]
# 按住A
>>>sensor.btnValue()
>>>['a']
蜂鸣器
无源蜂鸣器是采用定时器模拟PWM驱动发声
- 使用频率驱动发声 📥频率对应音调表
buzzer.tone(freq, d = 0.5)
参数 | 含义 |
---|---|
freq | 频率,对应音调 |
d | 持续时间(单位秒),默认为0.5s;当d=-1时,设置为持续发声(通常和buzzer.stop()配合使用) |
- 播放映射好的音调
buzzer.note(note, beats=1)
参数 | 含义 |
---|---|
note | 0~130共12个八度,12的整除倍数为C调 |
beats | 持续拍数,默认不填为1拍 |
- 休音一定拍数
buzzer.rest(beats=1)
参数 | 含义 |
---|---|
beats | 持续拍数,默认不填为1拍 |
- 设置Bpm
buzzer.setBpm(bpm=120)
参数 | 含义 |
---|---|
bpm | 拍速(beat per minute),默认为120,即120拍/分钟 |
设置后,会影响带有beats参数相关的函数
- 播放旋律
buzzer.melody(m)
参数 | 含义 |
---|---|
m | m=octave:duration=音符+八度音阶[默认为4]:滴答音的次数[默认4],规定duration = 4为1个四分音符,并且滴答音单位时长是由bpm决定的,可为任意时长 |
- 当c4:4在bpm为默认情况下,效果为响1拍(即0.5s)
- 当c4:8在bpm为默认情况下,效果为c4:4时长的2倍
- 改变bpm为60,c4:4的时长变为1s
固件内保留了以下简单音效,使用方式如:buzzer.melody(CORRECT)
CORRECT = "c6:1 f6:2 "
NOTICE = "d5:1 b4:1 "
ERROR = "a3:2 r a3:2 "
DADA = "r4:2 g g g eb:8 r:2 f f f d:8 "
ENTERTAINER = "d4:1 d# e c5:2 e4:1 c5:2 e4:1 c5:3 c:1 d d# e c d e:2 b4:1 d5:2 c:4 "
PRELUDE = "c4:1 e g c5 e g4 c5 e c4 e g c5 e g4 c5 e c4 d g d5 f g4 d5 f c4 d g d5 f g4 d5 f b3 d4 g d5 f g4 d5 f b3 d4 g d5 f g4 d5 f c4 e g c5 e g4 c5 e c4 e g c5 e g4 c5 e "
ODE = "e4 e f g g f e d c c d e e:6 d:2 d:8 e:4 e f g g f e d c c d e d:6 c:2 c:8 "
NYAN = "f#5:2 g# c#:1 d#:2 b4:1 d5:1 c# b4:2 b c#5 d d:1 c# b4:1 c#5:1 d# f# g# d# f# c# d b4 c#5 b4 d#5:2 f# g#:1 d# f# c# d# b4 d5 d# d c# b4 c#5 d:2 b4:1 c#5 d# f# c# d c# b4 c#5:2 b4 c#5 b4 f#:1 g# b:2 f#:1 g# b c#5 d# b4 e5 d# e f# b4:2 b f#:1 g# b f# e5 d# c# b4 f# d# e f# b:2 f#:1 g# b:2 f#:1 g# b b c#5 d# b4 f# g# f# b:2 b:1 a# b f# g# b e5 d# e f# b4:2 c#5 "
RING = "c4:1 d e:2 g d:1 e f:2 a e:1 f g:2 b c5:4 "
FUNK = "c2:2 c d# c:1 f:2 c:1 f:2 f# g c c g c:1 f#:2 c:1 f#:2 f d# "
BLUES = "c2:2 e g a a# a g e c2:2 e g a a# a g e f a c3 d d# d c a2 c2:2 e g a a# a g e g b d3 f f2 a c3 d# c2:2 e g e g f e d "
BIRTHDAY = "c4:3 c:1 d:4 c:4 f e:8 c:3 c:1 d:4 c:4 g f:8 c:3 c:1 c5:4 a4 f e d a#:3 a#:1 a:4 f g f:8 "
WEDDING = "c4:4 f:3 f:1 f:8 c:4 g:3 e:1 f:8 c:4 f:3 a:1 c5:4 a4:3 f:1 f:4 e:3 f:1 g:8 "
FUNERAL = "c3:4 c:3 c:1 c:4 d#:3 d:1 d:3 c:1 c:3 b2:1 c3:4 "
PUNCHLINE = "c4:3 g3:1 f# g g#:3 g r b c4 "
BADDY = "c3:3 r d:2 d# r c r f#:8 "
CHASE = "a4:1 b c5 b4 a:2 r a:1 b c5 b4 a:2 r a:2 e5 d# e f e d# e b4:1 c5 d c b4:2 r b:1 c5 d c b4:2 r b:2 e5 d# e f e d# e "
BA_DING = "b5:1 e6:3 "
WAWA = "e3:3 r:1 d#:3 r:1 d:4 r:1 c#:8 "
JUMP_UP = "c5:1 d e f g "
JUMP_DOWN = "g5:1 f e d c "
POWER_UP = "g4:1 c5 e g:2 e:1 g:3 "
POWER_DOWN = "g5:1 d# c g4:2 b:1 c5:3 "
- 停止播放
buzzer.stop()
含义 |
---|
蜂鸣器停止播放,配合buzzer.tone(freq, d= -1)持续播放使用 |
亮度检测
- 返回光照强度模拟量
sensor.getLight()
含义 |
---|
返回12位模拟量,范围在0~4095 |
温度检测
- 返回温度值
sensor.getTemp()
含义 |
---|
获取esp32模组附近的温度数值,返回值为摄氏度,范围在-40~85℃(会存在误差,且可能随着wifi温度升高而偏高) |
换算华氏度:F = C * 9 / 5 + 32
加速度计
- 三轴加速度
sensor.accX()
sensor.accY()
sensor.accZ()
含义 |
---|
获取加速度计3个轴的数值,对应单位g(重力加速度9.8m/s²) |
通常静置状态下,垂直于某个轴的的数值大约为1g(由于地球重力加速度)
- 姿态角—横滚
sensor.roll()
含义 |
---|
未来板屏幕朝上想象成飞机水平姿态,翻滚则为左右倾斜 |
- 姿态角—俯仰
sensor.pitch()
含义 |
---|
未来板屏幕朝上想象成飞机水平姿态,俯仰则为上下倾斜 |
- 姿态检测信息
按照未来板屏幕朝向
sensor.gesture(ges)
参数 | 含义 |
---|---|
ges | 'shake' 摇晃、'freefall' 自由落体、'tilt_up' 后倾、'tilt_down' 前倾、'tilt_left' 左倾、'tilt_right' 右倾、'face_up' 朝上、'face_down' 朝下 |
可以直接使用sensor.gesture('face_up')来检测是否处于当前状态
"""
REPL
"""
# 平方屏幕朝上
>>>sensor.gesture('face_up')
>>>True
# 平方屏幕朝上
>>>sensor.gesture()
>>>'face_up'
- 姿态检测事件
sensor.gesTrig[ges] = fn
需要注意的是这里参数是使用 [ ]包裹
参数 | 含义 |
---|---|
ges | 'shake' 摇晃、'freefall' 自由落体、'tilt_up' 后倾、'tilt_down' 前倾、'tilt_left' 左倾、'tilt_right' 右倾、'face_up' 朝上、'face_down' 朝下 |
fn | 自定义需要触发的回调函数 |
当设定的姿态达到时会触发执行自定义的中断函数fn
自定义函数的定义需要注意:
- 这个函数内容执行应尽量短并且耗时短
- 函数不允许有任何的内存申请,如:a = i+1
- 如需要使用全局变量,除了提前定义一个全局变量外,函数内还需要用global修饰
def fn():
screen.fill(255)
sensor.gesTrig['shake'] = fn
sensor.startSchedule()
# 本身板子是黑屏状态下,摇晃一下屏幕变白
指南针
- 磁场校准
calibrateCompass()
含义 |
---|
三维缓慢转动板子,让屏幕中的3种颜色点大致形成3个区域的圆 |
至少保证开机使用前要校准1次,可以通过按A键直接完成校准,但建议持续校准直到进度条走完
校准时请远离其他磁场,比如电脑机箱,磁铁,手机
- 磁场强度
sensor.magX()
sensor.magY()
sensor.magZ()
sensor.magStrength()
含义 |
---|
分别表示x、y、z轴的磁感应强度以及矢量磁感应强度。单位为uT(微特斯拉) |
测量范围为±800μT = ±8Gs(高斯)
- 指南针朝向
sensor.heading()
含义 |
---|
当前方位,范围在0~360°,0°附近是北。指南针实际是指向地磁南极——地理北极 |
from future import *
import math
calibrateCompass()
screen.sync = 0
ds = ''
while 1:
d = sensor.heading()
screen.fill(44)
if (d<20) | (d>340):
ds = '北'
elif (d<70):
ds = '东北'
elif (d<110):
ds = '东'
elif (d<160):
ds = '东南'
elif (d<200):
ds = '南'
elif (d<250):
ds = '西南'
elif (d<290):
ds = '西'
else:
ds = '西北'
screen.text(d, 80-len(str(d))*4,113 )
screen.textCh(ds,80-len(ds)*6,5)
ax = 30 * math.sin(d / 180.0 * math.pi)
ay = 30 * math.cos(d / 180.0 * math.pi)
bx = 8 * math.sin(d / 180.0 * math.pi+ 80)
by = 8 * math.cos(d / 180.0 * math.pi + 80)
screen.circle(80,64,40,color=(233,233,99),fill=1)
screen.circle(80,64,38,color=44,fill=1)
screen.triangle((ax + 80), (ay + 64), (bx + 80), (by + 64), (-bx + 80), (-by + 64),color=(88,133,243), fill = 1)
screen.triangle((-ax + 80), (-ay + 64), (bx + 80), (by + 64), (-bx + 80), (-by + 64), fill = 1,color=(243,22,22))
screen.refresh()
RGB彩灯
- 彩灯类
NeoPixel(pin, num)
参数 | 含义 |
---|---|
pin | P引脚,板载的3颗RGB为P7 |
num | 彩灯数量 |
np = NeoPixel('P7', 3) # 初始化灯珠,未来板的3颗RGB挂在P7脚上
- 设置单颗灯
setColor(i, color)
参数 | 含义 |
---|---|
i | 灯的序号,从0开始 |
color | rgb颜色(元组) |
- 设置全部灯
setColorAll(color)
参数 | 含义 |
---|---|
color | rgb颜色(元组) |
- 刷新显示
update()
含义 |
---|
将设置的颜色刷新显示出来,不刷新是看不到效果的 |
from future import *
import time
""" 固件内已经建立的映射,可以直接使用
RED=(255,0,0)
YELLOW=(255,255,0)
PINK=(255,105,180)
WHITE=(255,255,255)
BLACK=(0,0,0)
GREEN=(0,255,0)
BLUE=(0,0,255)
PURPLE=(148,0,211)
CYAN = (0,255,255)
"""
np = NeoPixel('P7', 3)
color = [RED,GREEN,BLUE]
for i in range(3):
np.setColorAll(color[i])
np.update() # 目前需要刷新,可能之后的固件再设置所有灯的时候会优化省略掉这一步
time.sleep(1)
for i in range(3):
np.setColor(i,BLACK)
np.update()
time.sleep(1)
海龟绘图
turtle. 按下Tab查看所有方法
📋示例程序:简单的绘图
turtle.clear()
turtle.penup()
turtle.setx(80)
turtle.sety(64)
turtle.pendown()
for i in range(5):
turtle.forward(40)
turtle.right(144)
# turtle.begin_fill()
turtle.right(120)
for i in range(5):
turtle.forward(40)
turtle.right(144)
# turtle.end_fill()
硬件性能限制,填充效果将无法达到预期
引脚控制
数字读写引脚类MeowPin(pin, mode)
参数 | 含义 |
---|---|
pin | P引脚,如'P0' |
mode | 实例化引脚的时候需要给定一个模式,一般给定后在下一次复位前都不要更改 - 数字输入:'IN' - 数字输出:'OUT' - 模拟输入:'ANALOG' - 模拟输出:'PWM' |
p1 = MeowPin('P1', 'IN') # 实例化IO对象
- 引脚的读写方法请对应实例化对象的模式,如'IN'对应getDigital()
- 设置过模拟输入模式的引脚无法在下一次重新上电前被设置为其他模式使用
- 数字读
getDigital()
含义 |
---|
返回值为0和1的高低电平 |
# P4-亮度传感器 / P5-按键A /P6-蜂鸣器 / P7-RGB灯 P10-麦克风数据脚 / P11-按键B / P12-传感器输入脚,无上拉
# 数字读=['P0','P1','P2','P3','P8','P9','P12','P13','P14','P15','P16']
p0 = MeowPin('P0','IN')
print(p0.getDigital())
- 数字写
setDigital(val)
参数 | 含义 |
---|---|
val | 填入0和1分别为输出0V低电平和3.3V高电平 |
# 数字输出=['P0','P1','P2','P6','P7','P8','P10','P13','P3','P9','P14','P15','P16']
p0 = MeowPin('P0','OUT')
while 1:
p0.setDigital(1)
time.sleep(1)
p0.setDigital(0)
time.sleep(1)
- 模拟读
getAnalog(width=12)
参数 | 含义 |
---|---|
width | ADC宽度(分辨率),对应电压范围0~3.3V - width=10:返回值范围0~1023 - width=12(不填默认):返回值范围0~4095 |
# P4-亮度传感器 / P5-按键A / P11-按键B
# 两颗按键虽然可以设置为模拟度但不建议
# 模拟读=['P0','P1','P4','P12', 'P3', 'P14', 'P15', 'P16']
p0 = MeowPin('P0','ANALOG')
print(p0.getAnalog())
print(p0.getAnalog(width=10))
- 模拟写(PWM)
setAnalog()
含义 |
---|
填写0~1023可输出0~3.3V电压,多用于控制舵机、蜂鸣器及呼吸灯等 |
# 模拟输出=['P0','P1','P2','P3','P8','P13','P14','P15','P16']
p0 = MeowPin('P0','PWM')
while 1:
for i in range(1023):
p0.setAnalog(i)
time.sleep_ms(1)
for i in range(1023,0,-1):
p0.setAnalog(i)
time.sleep_ms(1)
串口引脚类UART(id, baudrate, tx, rx)
参数 | 含义 |
---|---|
id | 串口ID号,ESP32默认有0~2 三个UART,但0和2被未来板内部占用,仅可使用id=1 |
baudrate | 通讯波特率,通常的通讯波特率在9600和115200选 |
tx | 数据发送脚,填写原生IO号,硬件与通讯对象的rx引脚相连 |
rx | 数据接收脚,填写原生IO号,硬件与通讯对象的tx引脚相连 |
from machine import UART
uart1 = UART(1, 9600, tx = 33, rx = 32)
# 实例化IO对象,将tx和rx分别设置为33和32,分别对应映射引脚的P1和P0
# 其中tx=33,rx=32可分别写成tx=PINMAP['P1'], Rx=PINMAP['P0']
- 串口发送消息
write(str)
参数 | 含义 |
---|---|
str | 字符串或字节数据 |
from machine import UART
uart1 = UART(1, 115200, tx = 33, rx = 32)
while 1:
uart1.write('hello123') # 发送一行消息
sleep(1)
- 串口接收消息
readline()
读取单行信息(常用)
read()
一次读出串口内255个字节内的所有消息
from machine import UART
uart1 = UART(1, 115200, tx = 33, rx = 32)
while 1:
if uart.any(): # 检测串口是否有消息缓存
mes = uart1.readline() # 单行读取
print(mes)
📋示例程序:与microbit进行串口通讯
- 连接,注意理清rx、tx的对应关系
- microbit端在makecode写如下程序,实现每隔1s发送一个自增数字到未来板
- 未来板端程序为接收串口指令,并刷新显示到屏幕上
from future import *
from machine import UART
uart1 = UART(1, 115200, tx = 33, rx = 25)
screen.sync=0
while 1:
if uart1.any(): # 检测串口是否有消息缓存
mes = str(uart1.readline(),'UTF-8') # 单行读取,如果发送端设备上线较快,接收端在已经接受了多个数据时才开始行读取,会放生堆积现象
screen.fill(1)
screen.text(mes)
screen.refresh()
WIFI
- 连接wifi
wifi.connect(apName, apPass)
参数 | 含义 |
---|---|
apName | wifi热点名称,字符串(不要以数字或符号开头) |
apPass | wifi热点密码 |
- 检测wifi是否连接成功
wifi.sta.isconnected()
含义 |
---|
返回布尔值,当wifi连接成功,返回布尔真值 |
📋示例程序:连接wifi获取ip
未来板连接名称为Kittenbot的wifi,连接成功后,把IP显示在未来板显示屏上,此程序一般用在MQTT、NTP等网络通讯功能前。
from future import *
wifi.connect("Kittenbot", '12345678')
while not wifi.sta.isconnected():
pass
screen.text(wifi.sta.ifconfig()[0],5,10,1,(0, 119, 255))
- 获取wifi信息
wifi.sta.ifconfig()
含义 |
---|
返回 IP、Netmask、网关、DNS |
- 获取wifi信息的对应项目
wifi.sta.ifconfig()[x]
参数 | 含义 |
---|---|
x | x取值0~3,分别对应IP、netmask、网关和DNS |
- 获取MAC地址
import machine
import ubinascii
mac = ubinascii.hexlify(machine.unique_id()).decode().upper()
print('\n'+mac)
- 断开wifi
wifi.sta.disconnect()
含义 |
---|
断开wifi连接 |
MQTT
- MQTT类
c = mqttsimple.MQTTClient(server,client_id,port=0,user=None,password=None,keepalive=0,
ssl=False,ssl_params={})
参数 | 含义 |
---|---|
server | MQTT服务器地址(推荐喵家的'iot.kittenbot.cn') |
client_id | 随意自定义 |
port | 这个参数一般不需要理会,默认会自动根据是否有ssl替换成适合的端口号 带ssl:8883 不带ssl:1883 |
其他 | 不理会 |
- 连接mqtt服务器
c.connect()
含义 |
---|
与mqtt服务器建立连接(必要) |
- 断开mqtt服务器
c.disconnect()
含义 |
---|
与mqtt服务器断开连接 |
- 话题消息回调函数
c.set_callback(callback)
参数 | 含义 |
---|---|
callback | 自定义话题回调,函数名可以不叫callback,使用方式如下 |
def mqttcb(topic, msg):
print('topic=%s , msg=%s' %(topic, msg))
c.set_callback(mqttcb)
- 订阅话题
c.subscribe(topic, qos=0)
参数 | 含义 |
---|---|
topic | 话题名(字符串类型),话题需要先创建或者已知一个公共话题 |
qos | 省略不需要理会 |
- 发布消息
c.publish(topic, msg)
参数 | 含义 |
---|---|
topic | 话题名(字符串类型),话题需要先创建或者已知一个公共话题 |
msg | 消息(字符串类型) |
- 返回值类型的消息读取
c.mqttRead(topic)
参数 | 含义 |
---|---|
topic | 话题名(字符串类型),话题需要先创建或者已知一个公共话题 |
📋示例程序1:回调方式使用mqtt发送和接收消息
import mqttsimple
if not(wifi.sta.isconnected()): # 做一次wifi是否连接的判断,减少重复连接的耗时
wifi.connect('router', 'password') # 填写wifi的名称和密码,不支持5G喔。等待一下看屏幕提示是否成功
c = mqttsimple.MQTTClient("iot.kittenbot.cn", 'yourID')
c.connect()
# 成功连接
# 设置回调函数,当话题有消息更新将自动跳入该函数内执行(比如这个函数执行打印话题和消息)
def sub_cb(topic, msg):
print((topic, msg))
c.set_callback(sub_cb)
# 订阅话题/ttt,只有订阅了的话题才能接收到里面的消息
c.subscribe('/ttt')
while 1:
if sensor.btnValue('a'):
# 向话题/ttt发送消息hello
c.publish('/ttt', 'hello')
sleep(0.2)
# 执行这条函数当有消息时才会进入sub_cb的回调函数内执行(有缓存机制)
c.check_msg()
# 你也可以试试这个方法,是堵塞的效果,将等待有新的话题消息才继续执行
# c.wait_msg()
📋示例程序2:返回值方式使用mqtt发送和接收消息
import mqttsimple
if not(wifi.sta.isconnected()): # 做一次wifi是否连接的判断,减少重复连接的耗时
wifi.connect('router', 'password') # 填写wifi的名称和密码,不支持5G喔。等待一下看屏幕提示是否成功
c = mqttsimple.MQTTClient("iot.kittenbot.cn", 'yourID', port=1883)
c.connect()
# 成功连接
# 订阅话题/ttt,只有订阅了的话题才能接收到里面的消息
c.subscribe('/ttt')
t= 0
# 返回值类型的读取消息采用的是取值回收的机制,既当新的消息到来,并通过mqttRead得到后,对该话题直到下一次新消息到来前通过mqttRead出来的数据均为None
while 1:
if sensor.btnValue('a'):
t+=1
c.publish('/ttt','t'+str(t))
sleep(0.2)
# 由于机制决定,我们需要将话题存储到变量中使用,当话题消息不为None既有消息,才打印
mqttT = c.mqttRead('/ttt')
if mqttT:
print(mqttT)
📋示例程序3:按键AB向对应话题发送不同消息
from future import *
import mqttsimple
from time import sleep
if not(wifi.sta.isconnected()): # 做一次wifi是否连接的判断,减少重复连接的耗时
wifi.connect('router', 'password') # 填写wifi的名称和密码,不支持5G喔。等待一下看屏幕提示是否成功
mqtt = mqttsimple.MQTTClient("iot.kittenbot.cn", "CCFeatureboard",port=1883)
mqtt.connect()
while True:
if sensor.btnValue('a'):
# apple是我的话题,需要修改为你自己申请的!
mqtt.publish("apple", "hipeilei666")
buzzer.tone(440,1)
sleep(1)
else:
if sensor.btnValue('b'):
# apple是我的话题,需要修改为你自己申请的!
mqtt.publish("apple", "hipeilei123")
buzzer.tone(880,1)
sleep(1)
- 喵家提供的mqtt服务器
地址:https://zone.kittenbot.cn/iot/main
在Kzone的IOT页面申请你自己的话题
危险话题名称只能为英文或者数字的字符
查看话题接收结果
NTP
- 同步网络时间
ntptime.settime(zone=8)
参数 | 含义 |
---|---|
zone | 时区,默认北京时间东八区 |
需要先连接wifi
from future import *
from machine import RTC
if not(wifi.sta.isconnected()): # 做一次wifi是否连接的判断,减少重复连接的耗时
wifi.connect('Kittenbot', 'kittenbot428') # 填写wifi的名称和密码,不支持5G喔。等待一下看屏幕提示是否成功
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # 设定特定时间
rtc.datetime() # 获取时间
import ntptime
ntptime.settime() # 获取服务器时间到rtc
t = rtc.datetime() # 获取时间, 格式为(年,月,日,星期,小时,分钟,秒,微妙)
# REPL显示年月日,星期
print("\n%d年%d月%d日,星期%d" %(t[0],t[1],t[2],t[3]))
麦克风
使用语音Audio类
import audio
au = audio.Audio()
- 麦克风声音强度
au.loadness()
含义 |
---|
返回值范围在0~4095,随着声音越大数值越大 |
import time
import audio
au = audio.Audio()
# 由于I2S端口的初始化不可重复,Audio麦克风目前单次上电只能实例化一次,出现报错现象请重开电源
while 1:
time.sleep(0.1)
print(au.loudness())
- 云端语音识别
au.recognize(sec=3,vid=1537)
参数 | 含义 |
---|---|
sec | 录制语音的时长 |
vid | 语言,如下表(默认普通话) |
from future import *
if not(wifi.sta.isconnected()): # 做一次wifi是否连接的判断,减少重复连接的耗时
wifi.connect('Kittenbot', 'kittenbot428') # 填写wifi的名称和密码,不支持5G喔。等待一下看屏幕提示是否成功
au = Audio()
while 1:
if sensor.btnValue('a'):
screen.clear()
result = au.recognize(sec=3, vid=1537) # sec建议在1~3,代表着识别的语音长度,从执行这条语句开始计算
screen.textCh(result)
识别回来的字符串自动带一个句号
MESH (ESP now)
基于WIFI MESH网络的板对板通讯(精准点对点)
# 1. 启动wifi
import network
w0 = network.WLAN(network.STA_IF)
w0.active(True)
# 2. 分别获取通讯双方的的mac地址
mac = w0.config('mac')
print(mac)
# 记住各自REPL打印的mac地址,如 b'\xc4O3"\xdb\x89'
# 3. 导入espnow
from esp import espnow
e = espnow.ESPNow()
e.init()
# 4. 加入peer节点
# 注意: 这里填写的不是自己的mac地址,而是需要通讯的另一个未来板的mac地址
e.add_peer(b'\x8c\xaa\xb5\xb9\xf8\xf0')
# 5. 目标接收注册接收回调函数
def rxcb(mac, msg):
print("Recv:", mac, msg)
e.on_recv(rxcb)
# 6. 发送消息
e.send(b'\x8c\xaa\xb5\xb9\xf8\xf0', 'hello world')
# 7. 在接收端可以看到 Recv: b'\xc4O3"\xdb\x89' b'hello world'
radio(2.4g通讯)
基于WIFI MESH网络的板对板广播式通讯(类似microbit的2.4g通讯)
📋示例程序2:回调函数方式运行
from radio import *
def onmsg(msg, mac):
print('get', msg, 'from', mac)
r = Radio(onmsg)
print('channel', r.channel)
r.channel = 12 # 直接更改wifi频点,频点对不上的收不到
r.send("hello world")
📋示例程序2:返回值方式运行
import time
from radio import *
r = Radio()
print('channel', r.channel)
r.channel = 12 # 直接更改wifi频点,频点对不上的收不到
while True:
time.sleep(1)
a = r.read()
if a:
print('get', a)
OneNet(可能无用)
中国移动OneNet物联网平台,OneNet物联网平台有点复杂,需要自行研究下使用方法
控制面板地址:https://open.iot.10086.cn/
需要自己进行新建,建立自己独有的设别ID和apikey
新建设备,并把设备ID和APIKey记录下来,接入方式为HTTP
增加数据流模板temp,数据流名称由自己定义,记录下数据流的名称
import onenet
# 只需要 设备ID 和 APIKey 两个参数
onenet = onenet.OneNet(str('581610877'), "6sxkdbL8E=sv4yylQvmvjPc6kRk=")
# 写:"数据点","数据"
onenet.write("temp", 123456)
# 读: "数据点"
a = onenet.read("temp")
Robotbit扩展板驱动
使用喵家正版Robotbit扩展板
扩展板不支持能量魔块的Armourbit
- 初始化扩展板
import robotbit
robot = robotbit.RobotBit()
# 养成好习惯,先实例化再使用
- 电机控制
robot.motor(index,speed)
参数 | 含义 |
---|---|
index | 1~4分别代表M1A、M1B、M2A、M2B的电机接口(对应板子上有丝印) |
speed | 速度,范围-255~255(负数为反转) |
- 停止所有电机
robot.motorStopAll()
含义 |
---|
1~4的电机一起停止 |
- 180度蓝色小舵机
robot.servo(index, degree)
参数 | 含义 |
---|---|
index | 1~8分别代表S1~S8的舵机接口(对应板子上有丝印) |
degree | 角度,范围0~180;对应脉宽500~2500us |
- 270度Geekservo灰色9g舵机
robot.geekServo9g(index, degree)
参数 | 含义 |
---|---|
index | 1~8分别代表S1~S8的舵机接口(对应板子上有丝印) |
degree | 角度范围在-45°~225°对应500~2500us脉宽 |
- 360度Geekservo灰色2kg舵机
robot.geekServo2kg(index, degree)
参数 | 含义 |
---|---|
index | 1~8分别代表S1~S8的舵机接口 |
degree | 角度范围在0~360°对应500~2650us脉宽 |
- 28byj-48步进电机转动角度(精准相对转动)
robot.stepperDual(degree1,degree2)
参数 | 含义 |
---|---|
degree1 | M1接口的步进电机转动角度 |
degree2 | M2接口的步进电机转动角度 |
- 28byj-48步进电机转动角度(精准相对转动)
robot.stepperDegree(index, degree)
参数 | 含义 |
---|---|
index | 指定M1或M2接口的步进电机转动一定角度(对应板子上有丝印) |
degree | 转动角度,转动达到目标角度之前,程序是阻塞的 |