openmv基础实验


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】中断后执行的回调函数

上升沿和下降沿:

image-20210205110519548

当按键被按下再松开时,引脚先获得下降沿再获得上升沿

因此可以选择下降沿方式触发外部中断

实验目的:利用中断方式检查按键KEY状态,按键被按下(产生外部中断)后使LED(2)蓝灯的亮灭状态发转

  1. 导入模块
  2. 配置中断方式和定义回调函数
  3. 产生外部中断的时候自动执行回调函数
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() 终止定时器
  1. 导入模块
  2. 定义回调函数和配置定时器中断方式
  3. 当定时器产生中断时候自动执行回调函数
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()

文章作者: 1doctorc1
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 1doctorc1 !
  目录