openmv基础实验
感悟:
学会构造函数和使用方法,完成对相关对象的操作
功能增加就是各类函数的叠加
除了普通的按键输入和电平检测外,很大一部分输入设备,比如传感器也是通过外部中断方式来实时检测
I2C学习:使用单片机从0开发需要了解I2C总线原理,了解OLED显示屏的使用手册,编程I2C代码
历程测试
通过mircousb数据线将mircopython开发板连接到电脑
正常操作将会在电脑发现一个U盘
主要文件介绍:
main.py: 主函数代码文件,上电后首先执行
另外系统会自动安装usb转串口驱动,“我的电脑”—“属性”—“设备管理器”—“端口(com和LPT)”查看是否有openMV(cam usb com port)
点亮led
通过mircopython对象编程控制,控制led使用到led对象,主要学习led的构造函数和使用方法
led对象:
- 构造函数:pyb.LED(id) # led对象在pyb模块下
- 使用方法:
- LED.on() #点亮LED,输出“低”电平?
- LED.off() #关闭LED,输出“高”电平
- LED.toggle() #LED亮灭状态翻转,输出电平翻转
from pyb import LED #导入模块
LED(3).on() #令LED3(蓝)亮
需要加载到openmv4文件系统,无法在openmvIDE中运行,因为无while True()死循环
流水灯
要实现固定时间来亮灭,需要用到utime模块中的延时函数
utime时间对象:
- utime() #时间模块
- 使用方法:
- utime.sleep_ms(ms) # 毫秒级延时
- utime.sleep_us(us) #微妙级延时
from pyb import LED
import utime
#关闭全部LED
LED(2).off()
LED(3).off()
#while True 表示一直循环
while True:
#LED2亮1秒
LED(2).on()
utime.sleep(1)
LED(2).off()
#LED3亮1秒
LED(3).on()
utime.sleep(1)
LED(3).off()
#for形式实现上述功能
from pyb import LED
import utime
for i in range(2,4):
LED(i).off()
while True:
for i in range(2,4):
LED(i).on()
utime.sleep(1)
LED(i).off()
GPIO(按键)
General Purpose Input/Output
GPIO(Pin对象)的构造函数和使用方法:
- 构造函数:
- pyb.Pin(id,mode,pull_mode)
- Pin对象在pyb模块下
- 【id】引脚号,P0,P1
- 【mode】输入输出模式选择 Pin.IN输入模式,Pin.OUT_PP输出带推挽
- 【pull_mode】上下拉电阻配置 Pin.PULL_UP上拉电阻 Pin.PULL_DOWN下拉电阻 Pin.PULL_NONE没上下拉电阻
- 例:KEY=Pin(“P9”,Pin.IN,Pin.PULL_UP) #将按键P9配置为输入方式
- 使用方法:
- Pin.high() 引脚输出高电平
- Pin.low() 引脚输出低电平
- Pin.value() 获取当前引脚的输入电平,返回0(低电平)或者1(高电平)
from pyb import LED,Pin
#配置KEY
KEY=Pin("P9",Pin.IN,Pin.PULL_UP)
while True:
if KEY.value()==0 :
LED(2).on()
else:
LED(2).off()
外部中断
上述代码会使GPIO口一直检测IO的输入口变化
外部中断要实现:当按键被按下(产生中断)时,我们才去执行相关功能
外部中断对象:
- 构造函数:
- pyb.ExtInt(pin,mode,pull_mode,callback)
- 【pin】引脚号
- 【mode】中断触发方式 Extlnt.IRQ_RISING:上升沿触发 Extlnt.IRQ_FALLING:下降沿触发 Extlnt.IRQ_RISING_FALLING: 上升或下降沿触发
- 【pull_mode】上下拉电阻设置,同Pin对象构造函数
- 【callback】中断后执行的回调函数
上升沿和下降沿:
当按键被按下再松开时,引脚先获得下降沿再获得上升沿
因此可以选择下降沿方式触发外部中断
实验目的:利用中断方式检查按键KEY状态,按键被按下(产生外部中断)后使LED(2)蓝灯的亮灭状态发转
- 导入模块
- 配置中断方式和定义回调函数
- 产生外部中断的时候自动执行回调函数
from pyb import LED,Pin,ExtInt
callback=lambda e:LED(3).toggle()
#下降沿触发,拉开上拉电阻
ext=ExtInt(Pin('P9'),ExtInt.IRQ_FALLING,Pin.PULL_UP,callback)
定时器
通过定时器可以完成各种预设好的任务
实验通过定时器让LED(3)蓝灯周期性每秒闪烁1次
定时器对象:
- 构造函数:
- pyb.Timer(id,freq,……)
- 定时器对象Timer对象在pyb模块下
- 【id】定时器编号,1–14
- 【freq】定时器中断频率
- Timer.callback(fun) 定义执行的回调函数
- Timer.deinit() 终止定时器
- 导入模块
- 定义回调函数和配置定时器中断方式
- 当定时器产生中断时候自动执行回调函数
from pyb import Timer,LED
timer=Timer(4,freq=1) #使用定时器4创建定时器对象,频率1HZ
#定时器中断回调函数,执行LED(3)蓝灯状态反转
timer.callback(lambda t:LED(3).toggle())
I2C总线(OLED屏)
输出设备OLED
pyAI-Openmv4是通过I2C总线与OLED显示屏通讯的
I2C是不同通讯设备之间的通讯协议,在物理层面分为两条线,SCL和SDA,即时钟线和数据线
OLED与py板的连接:Y6–SCL,Y8–SDA
openmv4与py板的连接:Y6–P2,Y8–P0
即Openmv4与OLED的对应连接关系是: P0–SDA,P2–SCL
I2C对象:
- 构造函数:i2c=machine.I2C(scl,sda,freq) 构造I2C对象
- 【scl】时钟引脚
- 【sda】数据引脚
- 【freq】通信频率,即速度
- 使用方法
- i2c.scan() 扫描I2C总线的设备,返回地址
- i2c.readfrom(addr,nbytes) 从指定地址读数据 addr:指定设备地址,nbytes:读取字节数
- i2c.write(buf) 写数据 buf:数据内容
OLED对象:
- 构造函数:oled=SSD1306_I2C(width,height,i2c,addr)
- 构造OLED显示屏对象
- 【width】屏幕宽像素
- 【height】屏幕高像素
- 【i2c】定义好的I2c对象
- 【addr】显示屏设备地址
- 使用方法:
- oled.text(string,x,y) 将string字符写在指定位置,string:字符;x:横坐标,y:纵坐标
- oled.show() 执行显示
- oled.fill(RGB) 清屏,RGB:0表示黑色,1表示白色
#导入Pin,I2C,OLED模块
from pyb import Pin
from ssd1306.py import OLED
from machine import I2C
#初始化I2C和OLED
i2c=machine.I2C("P2","P0",4)
oled=SSD1306_I2C(20,20,i2c,i2c.scan())
#输入需要显示的字符
oled.text("hello world",0,0)
#执行OLED显示函数
oled.show()
from machine import I2C,Pin #从machine模块导入I2C,Pin子模块
from ssd1306 import SSD1306_I2C #从ssd1306模块中导入SSD1306_I2C子模块
#I2C初始化
i2c=I2C(sda=Pin("P0"),scl=Pin("P2"),freq==80000)
#OLED显示屏初始化:128*64分辨率,OLED的I2C地址是0x3c
oled=SSD1306_I2C(128,64,i2c,addr=0x3c)
oled.text("Hello World!",0,0) #写入第1行内容
oled.text("MircoPython",0,20) #写入第2行内容
oled.show() #oled执行显示
RTC实时时钟
学习RTC编程并制作电子时钟(读取RTC数据),使用OLED显示
pyboard集成了内置时钟函数模块
RTC实时时钟对象:
- 构造函数:pyb.RTC() RTC()是内置的实时时钟函数模块
- 使用方法:RTC().datetime(2019,4,1,1,0,0,0,0)
- 设置日期时间:顺序分别是年,月,日,星期,时,分,秒,次秒级
- 星期:1-7表示周一到周日
- 次秒级:255–0倒着计数
- RTC().datetime() 获取当前日期时间数据
先设定时间,然后获取当前芯片里的时间,通过OLED显示屏显示,如此循环
每隔一段时间获取一次数据,可以每隔300ms获取一次数据
#导入RTC,OLED模块
from pyb import RTC
from ssd1306 import SSD1306_I2C
#初始化RTC和OLED
oled=SSD1306_I2C(128,64,i2c,addr=0x3c)
rtc=RTC().datetime(2021,2,6,6,0,0,0,255)
while True():
trc=RTC().datatime()
oled.text(rtc,0,0)
oled.show()
utime.sleep(300)
#导入相关模块
from pyb import RTC
from machine import Pin,I2C
from ssd1306 import SSD13066_I2C
import utime
#定义星期和时间(时分秒)显示字符列表
week=['Mon','Tues','Wed','Thur','Fri','Sat','Sun']
time=['','','']
#初始化所有相关对象
i2c=I2C(sda=Pin('P0'),scl=Pin("P2"),freq=80000)
oled=SSD1306_I2C(128,64,i2c,addr=0x3c)
rtc=RTC()
#设置初始时间
rtc.datatime((2021,2,6,6,0,0,0,255))
while True:
datetime=rtc.datetime() #获取当前时间
oled.fill(0) #清屏显示黑色背景
#显示日期,字符串使用“+”连接
oled.text(str(datetime[0])+"-"+str(datetime[1])+"-"+str(datetime[2])+" "+" "week[(datetime[3]-1)],0,40)
#显示时间
oled.show()
utime.sleep_ms(300)
ADC
analog to digital conversion 模拟数字转换
将模拟信号转化成数字信号
应用:将外界模拟信号通过ADC转换成单片机可以识别的数字信息
将变化的电压转成数字信号
实验目的:调用mircopython内置的ADC函数,实现测量0-3.3V电压,并显示到OLED屏幕上
openmv的P6引脚连接到pyboard的X6上,通过跳线帽连接X6和X7,pyboard上的X7用于调节电压
ADC对象:
- 构造函数:
- pyb.ADC(Pin) ADC对象在pyb模块下,Pin:ADC输入引脚
- 使用方法:
- ADC.read()
- 读取AD值,返回0–4095(0V–3.3V),自带ADC的测量精度是12位,2^12=4096
from pyb import ADC,Pin
from machine import I2C
from ssd1306x import SSD1306_I2C
import utime
#初始化ADC和OLED
adc=ADC("P")
i2c=machine.I2C(scl=Pin("P2"),sda=Pin("P0"),freq=80000) #!!!!
oled=SSD1306_I2C(128,64,i2c,ox3c)
#获取ADC的值
while True(): #!!!!
vcc=adc.read()/1240
oled.text(str(vcc),0,0)
utime.sleep_ms(300)
#导入相关模块
import pyb,utime
from machine import Pin,I2C
from ssd1306x import SSD1306_I2C
#初始化相关模块
i2c=I2C(sda=Pin("P0"),scl=Pin("P2"),freq=80000)
oled=SSD1306_I2C(128,64,i2c,addr=0x3c)
adc=pyb.ADC("P6")
while True:
oled.fill(0) #每次使用前都要清屏,以显示黑色背景
oled.text(str(adc.read()),0,40)
oled.text('(4095)',40,40)
oled.text(str('%.2f'%(adc.read()/4095*3.3)),0,50)
oled.text('V',40,55)
oled.show()
utime.sleep(1)
DAC
digital to analog converter数字模拟转化器
将特定的数字信号通过DAC输出,输出的形式多种,特定电压,信号波形
实验目的:通过DAC输出不同频率的方波来驱动蜂鸣器
pybase开发板X5引脚连接无源蜂鸣器
openmv4的DAC引脚P6连接到pybase开发板的X6引脚
用跳线帽连接pybase开发板的X5和X6引脚
DAC对象:
- 构造函数:
- pyb.DAC(port,bits=8) DAC对象在pyb模块下
- 【port】对应“P6”
- 【bits】8或者12
- 使用方法:
- DAC.noise(freq) 产生特定频率的噪声信号
- DAC.triangel(freq) 产生特定频率的三角波信号
- DAC.write(value) 输出特定电压(0–VCC) 【value】范围:0–2^bits-1(例如8bits那么范围就是0–255)
- DAC.write_timed(data,freq,mode)【data】字节数组 【freq】频率输出 【mode】模式:DAC.NORMAL单次模式,DAC.CIRCULAR循环模式
#导入ADC,KEY,OLED模块
from pyb import Pin,ADC
from ssd1306x import SSD1306_I2C
from machine import I2C
#初始化相关模块
key=Pin("P6",Pin.IN.Pin.PULL_UP)
dac=DAC("P6",8)
i2c=machine.I2C(scl=Pin("P2"),sda=Pin("P0"),freq=80000)
oled=SSD1306_I2C(128,64,i2c,0x3c)
if key.value()==0:
while True:
dac.write_timed(8,0,DAC.CIRCULAR)
oled.text(str(dac.write_timed))
from pyb import ADC,ExtInt
from ssd1306x import ssd1306_I2C
from machine import I2C
i2c=I2C(scl=Pin("P2"),sda=Pin("P0"),freq=80000)
oled=SSD1306_I2C(128,64,i2c,0x3c)
dac=DAC(Pin("P6"))
freq=[1,200,1000,5000]
buf=bytearray(2)
buf[0]=0
buf[1]=255
key_node=0
i=0
def key(ext):
global key_node
key_node=1
ext=ExtInt(Pin("P9"),ExtInt.IRQ_FALLING,Pin.PULL_UP,key)1
oled.fill(0)
oled.show()
while True:
if key_node==1:
i=i+1
if i==4:
i=0
key_node=0
dac.write_timed(buf,freq[i]*len(buf),mode=DAC.CIRCULAR)
oled.text(str(freq[i])+"Hz",0,40)
oled.show()