[星瞳科技]OpenMV是否属于单片机?

news/2024/9/20 7:13:12/ 标签: 科技, stm32, 嵌入式硬件, python, 图像处理, 视觉检测

文件系统

MicroPyhon的文件系统是FatFS。

根目录

路径都是以根目录为起点。

当插入sd卡后,根目录就是SD卡;不插入sd卡,根目录就是内置的Flash。

如果需要,你可以在SD卡上,新建一个空文件:/flash/SKIPSD,这会避免挂载SD卡,当然,你可以使用os.mount来手动挂载SD卡。

绝对路径与相对路径

绝对路径是以根目录为起点的,相对路径是以当前目录为起点的。
比如:

image.save("/example.jpg")

中的"/example.jpg"就是绝对路径。会存放在根目录/下。
比如:

image.save("./pic/example.jpg")
image.save("pic/example.jpg")

这就是相对路径,表示当前路径下的pic文件夹下的example.jpg文件。

python的文件读写">MicroPython的文件读写

Python学习(九)IO 编程 —— 文件读写 - feesland - 博客园

python的os模块">MicroPython的OS模块

在代码中,可以使用os库,来进行新建目录,新建文件之类的操作。

  • os.listdir([dir])
    如果没有参数,列出当前目录。如果给了参数,就列出参数所代表的目录。

  • os.chdir(path)
    改变当前目录

  • os.getcwd()
    获得当前目录

  • os.mkdir(path)
    新建一个新的目录

  • os.remove(path)
    删除文件

  • os.rmdir(path)
    删除目录

  • os.rename(old_path, new_path)
    重命名文件

  • os.stat(path)
    获得文件或者路径的状态

OpenMV的默认文件

默认情况下,OpenMV的磁盘有三个文件。

  • main.py
    上电自动运行这个文件的代码。

  • openmv.inf
    windows驱动文件。

  • README.txt
    可以简单看一下。

模块的使用

什么是模块?

随着代码的增多,在一个文件里的代码会越来越长,越来越难看懂。

为了编写可维护的代码,我们把很多函数分组,放到不同的文件里。在Python中,一个.py文件就称之为一个模块(Module)。

模块有什么好处?复用代码方便!如果我写了一个模块,你也写了一个模块,我们就有了两个模块。我们把这些模块都组织起来,大家就可以少写很多代码了!

如何使用模块?

import machinered_led = machine.LED("LED_RED")red_led.on()

import machine就是引入machine这个模块。通过import语句,就可以引入模块。

还有from xxx import ooo 的语句,意思是通过xxx模块引入ooo类,或者通过xxx模块引入ooo函数。比如上面的程序可以写成:

from machine import LEDred_led = LED("LED_RED")red_led.on()

这就是通过machine的模块来引入LED类了。

如何添加自定义模块?

之前我们提到了,OpenMV是有文件系统的。

文件系统的根目录存在一个main.py,代码执行的当前目录就是根目录。

所以我们把模块的文件复制到OpenMV的“U盘”里就可以。如图:

这里的pid.py只是举一个举例。

我把pid.py复制到了U盘的根目录下。那么在程序中:

import pid

就可以引入pid模块了了。或者通过:

from pid import PID

这就是引入了PID类。

pyb各种外设

概览

作为一个单片机,控制IO口,IIC,SPI,CAN,PWM。定时器当然都是可以的。
而且,使用python语言,可以非常简单的调用它们,而不用考虑寄存器。

 

 

 

TablesOpenMV2 M4OpenMV3 M7OpenMV4 H7OpenMV4 H7 PlusOpenMV RT1062
Pin910101014
ADC11111
DAC11110
SPI11111
I2C12221
UART12221
Servo23324
CAN bus01111
电源按键00001
自定义按键00001
引脚耐受5V5V5V5V3.3V
引脚电平3.3V3.3V3.3V3.3V3.3V
ICSTM32F427STM32F765STM32H743STM32H743IMXRT1062
RAM256KB512KB1MB32MB + 1MB32MB + 1MB
Flash1MB2MB2MB32MB + 2MB16MB
频率180MHz216MHZ480MHZ480MHZ600MHZ
标配感光元件OV7725(30W像素)OV7725(30W像素)OV7725(30W像素)OV5640(500W像素)OV5640(500W像素)

注意:因为MicroPython可以在很多平台上运行。最开始在pyb模块,pyboard,是基于STM32的,但是后来又加入了esp8266和esp32,以及nrf系列,他们的架构和STM32不同。所以官方统一制定了machine模块,所以通用性更高一些,最终pyb会被淘汰。

OpenMV4 H7 Plus / OpenMV4 H7 / OpenMV3,主控为STM32,一般用pyb模块。

2024年最新款的OpenMV RT1062,主控为IMXRT1062,只支持machine模块,不支持pyb模块。请使用对应的machine代码哦~

常用的函数

pyb.delay(50) # 延时 50 毫秒
pyb.millis() # 获取从启动开始计时的毫秒数

LED

from pyb import LEDled = LED(1) # 红led
led.toggle()
led.on()#亮
led.off()#灭

LED(1) -> 红LED
LED(2) -> 绿LED
LED(3) -> 蓝LED
LED(4) -> 红外LED,两个

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import LED
import timered_led = LED("LED_RED")
green_led = LED("LED_GREEN")
blue_led = LED("LED_BLUE")
blue_led.off()
green_led.off()
red_led.off()while(1):green_led.toggle()red_led.on()time.sleep_ms(250)red_led.off()time.sleep_ms(250)

IO

from pyb import Pinp_out = Pin('P7', Pin.OUT_PP)#设置p_out为输出引脚
p_out.high()#设置p_out引脚为高
p_out.low()#设置p_out引脚为低p_in = Pin('P7', Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻
value = p_in.value() # get value, 0 or 1#读入p_in引脚的值

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import Pinp_out = Pin("P7", Pin.OUT)#设置p_out为输出引脚
p_out.high()#设置p_out引脚为高
p_out.low()#设置p_out引脚为低p_in = Pin("P8", Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻
value = p_in.value() # get value, 0 or 1#读入p_in引脚的值
Copy

Servo

视频教程34 - OpenMV控制三个舵机:OpenMV控制3个舵机 | 星瞳科技
from pyb import Servos1 = Servo(1) # servo on position 1 (P7)
s1.angle(45) # move to 45 degrees
s1.angle(-60, 1500) # move to -60 degrees in 1500ms
s1.speed(50) # for continuous rotation servos
  • Servo(1) -> P7 (PD12)
  • Servo(2) -> P8 (PD13)

OpenMV3 M7 / OpenMV4 H7上增加:

  • Servo(3) -> P9 (PD14)

注意:OpenMV4 H7 Plus P9不能使用PWM

OpenMV RT1062 有P7 P8 P9 P10 四个PWM引脚。 在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

# 舵机控制例子
#
# 这个例子展示了如何使用OpenMV来控制舵机
#
# 伺服系统需要 50 Hz PWM,脉冲宽度为 1000us 至 2000us。import time
from machine import PWM# P7 和 P8 可以共享相同的 PWM  module,它们需要具有相同的频率。
p7 = PWM("P7", freq=50, duty_ns=(2000 * 1000))
p8 = PWM("P8", freq=50, duty_ns=(2000 * 1000))# P9 和 P10 可以共享相同的 PWM  module,它们需要具有相同的频率。
p9 = PWM("P9", freq=50, duty_ns=(2000 * 1000))
p10 = PWM("P10", freq=50, duty_ns=(2000 * 1000))while True:for i in range(1000, 2000, 100):p7.duty_ns(i * 1000)p8.duty_ns(i * 1000)p9.duty_ns(i * 1000)p10.duty_ns(i * 1000)time.sleep_ms(1000)for i in range(2000, 1000, -100):p7.duty_ns(i * 1000)p8.duty_ns(i * 1000)p9.duty_ns(i * 1000)p10.duty_ns(i * 1000)time.sleep_ms(1000)

IO中断

from pyb import Pin, ExtIntcallback = lambda e: print("intr")
ext = ExtInt(Pin('P7'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback)

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import Pin
import time
pin0 = Pin("P0", Pin.IN, Pin.PULL_UP)
callback = lambda e: print("intr")
pin0.irq(callback, Pin.IRQ_FALLING)while True:time.sleep(1)

定时器

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

Timer 1 Channel 3 Negative -> P0
Timer 1 Channel 2 Negative -> P1
Timer 1 Channel 1 Negative -> P2
Timer 2 Channel 3 Positive -> P4
Timer 2 Channel 4 Positive -> P5
Timer 2 Channel 1 Positive -> P6
Timer 4 Channel 1 Negative -> P7
Timer 4 Channel 2 Negative -> P8

OpenMV M7上增加:
Timer 4 Channel 3 Positive -> P9

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import LED
from machine import Timerblue_led = LED("LED_BLUE")# 当被调用时,我们将返回timer对象
# 注意:在回调中不允许分配内存的函数
def tick(timer):blue_led.toggle()# machine模块目前仅支持-1虚拟定时器。
tim = Timer(-1, freq=1, callback=tick)  # 创建一个定时器对象—以1Hz触发

PWM

from pyb import Pin, Timerp = Pin('P7') # P7 has TIM4, CH1
tim = Timer(4, freq=1000)
ch = tim.channel(1, Timer.PWM, pin=p)
ch.pulse_width_percent(50)

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import PWM
import timep7 = PWM("P7", freq=100, duty_u16=32768)while True:for i in range(0, 65536, 256):p7.duty_u16(65535 - i)time.sleep_ms(10)p7.duty_u16(32768)

ADC

from pyb import Pin, ADCadc = ADC('P6')
adc.read() # read value, 0-4095

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import ADCadc = ADC('P6')
adc.read_u16()

DAC

from pyb import Pin, DACdac = DAC('P6')
dac.write(120) # output between 0 and 255

UART

from pyb import UARTuart = UART(3, 9600)
uart.write('hello')
uart.read(5) # read up to 5 bytes

UART 3 RX -> P5 (PB11)
UART 3 TX -> P4 (PB10)

OpenMV3 M7 / OpenMV4 H7/ OpenMV4 H7 Plus上增加:
UART 1 RX -> P0 (PB15)
UART 1 TX -> P1 (PB14)

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

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

OpenMV RT1062只有串口1,对应 P4 P5 引脚。 UART 1 RX -> P5 (PB11)
UART 1 TX -> P4 (PB10)

SPI

from pyb import SPIspi = SPI(2, SPI.MASTER, baudrate=200000, polarity=1, phase=0)
spi.send(b'hello')
spi.recv(5) # receive 5 bytes on the bus
spi.send_recv(b'hello') # send a receive 5 bytes

在 OpenMV RT 上不能用pyb模块,只能使用以下machine模块:

from machine import SPIspi = SPI(1, baudrate=int(1000000000 / 66), polarity=0, phase=0)
spi.write(b'hello')
spi.read(5) # receive 5 bytes on the bustxdata = b"12345678"
rxdata = bytearray(len(txdata))
spi.write_readinto(txdata, rxdata)  # Simultaneously write and read bytes.

I2C

from machine import I2C, Pin
i2c = I2C(sda=Pin('P5'),scl=Pin('P4'))i2c.scan()
i2c.writeto(0x42, b'123')         # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(0x42, 4)             # read 4 bytes from slave with 7-bit address 42i2c.readfrom_mem(0x42, 8, 3)      # read 3 bytes from memory of slave 42,# starting at memory-address 8 in the slave
i2c.writeto_mem(0x42, 2, b'\x10') # write 1 byte to memory of slave 42# starting at address 2 in the slave

I2C 2 SCL (Serial Clock) -> P4 (PB10)
I2C 2 SDA (Serial Data) -> P5 (PB11)

OpenMV3 M7 / OpenMV4 H7 / OpenMV4 H7 Plus上增加:
I2C 4 SCL (Serial Clock) -> P7 (PD13)
I2C 4 SDA (Serial Data) -> P8 (PD12)

machine库是软件模拟的I2C协议,所以使用任何引脚都可以,但是还是推荐使用上面所说的引脚。

在 OpenMV RT 上可以这样调用:

from machine import I2C, Pin
i2c = I2C(1)i2c.scan()
i2c.writeto(0x42, b'123')         # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(0x42, 4)             # read 4 bytes from slave with 7-bit address 42i2c.readfrom_mem(0x42, 8, 3)      # read 3 bytes from memory of slave 42,# starting at memory-address 8 in the slave
i2c.writeto_mem(0x42, 2, b'\x10') # write 1 byte to memory of slave 42# starting at address 2 in the slave

Switch Pin 自定义按键SW

# OpenMV Cam 上的用户开关可通过“SW”引脚读取。 
# 该引脚通过 RC 电路在硬件中进行去抖。 
# 因此,您只需读取引脚状态即可了解开关是否被按下。import machinesw = machine.Pin("SW", machine.Pin.IN)
r = machine.LED("LED_RED")while True:r.value(not sw.value())print(sw.value())

仅OpenMV RT具有SW自定义按键,OpenMV4 H7 / OpenMV4 H7 Plus / OpenMV3 M7 没有自定义按键。

字符串简介json/正则

介绍

在传统的单片机应用中,两个单片机串口通信,都是自己定义一些帧,包括帧头,数据帧,校验帧,帧尾。 图中 是飞控MavLink的协议。 

这种方式,稳定,高效。缺点也很明显:开发难度稍大,需要自己制定协议,编码解码需要手动编写。如果想快速尝试两个单片机通信的。我推荐使用串口传输json字符串!

优点:不需要了解底层的事情,比如:

  • 不考虑大端小端
  • 不考虑数据的byte转换
  • 支持任意长的int,float
  • 简单易懂,容易开发。

缺点:效率稍低。json的编码和解码会占用cpu。

其实传输json在网络编程中已经成为标准,比如在restful api中,前端和后端使用json来获取信息。只是在传统单片机的领域中不常见,一方面是效率稍低,嵌入式通常对成本的控制要求比较高。但是随着芯片成本的降低,很多应用对物料成本要求不是很高了,对开发效率越来越重视。

字符串

string = "hello string!"

OpenMV 是可以直接通过串口发送字符串的。

from machine import UARTuart = UART(1, 9600)
string = "hello string!"
uart.write(string)

字符串操作

Python3 字符串 | 菜鸟教程

举个例子:


blobs=[12,23,11,22,33,44]print("%d", blobs[3])

JSON

JSON是一种简洁高效的交换数据的格式。 它可以是这种简单的:

"[[12,0],[10,12],[22,10],[99,11]]"

注:我通过这种简单的字符串,把OpenMV中的色块的x,y坐标发送出去。

也可以是这种复杂的:('''在python中表示多行字符串)

'''
{"number":10,"color" :[255,0,0],"rate" :0.65
}
'''

我使用这种结构把OpenMV采集到的颜色信息发送到wifi中的服务器中。

甚至于,可以像这样:

'''
{"firstName": "John","lastName": "Smith","sex": "male","age": 25,"address": {"streetAddress": "21 2nd Street","city": "New York","state": "NY","postalCode": "10021"},"phoneNumber": [{"type": "home","number": "212 555-1234"},{            "type": "fax","number": "646 555-4567"}]
}
'''

注意:json的形式和Python很像,但是json是javascript的对象表达形式,和python的表达形式稍有不同。

python生成json">python生成json

OpenMV有json的模块,json.dumps(obj)和ujson.loads(str)可以很容的生成json字符串和解析json字符串。

import jsonobj = [[12,0],[10,12],[22,10],[99,11]]
print(json.dumps(obj))obj = {"number":10,"color" :[255,0,0],"rate" :0.65
}
print(json.dumps(obj))

会输出:

'[[12, 0], [10, 12], [22, 10], [99, 11]]''{"color": [255, 0, 0], "number": 10, "rate": 0.65}'

然后把字符串通过串口发送出去,然后在另一端,把json字符串解析成对象/数组。然后进行接下来的逻辑操作。

其他单片机的json模块

json很简单也很通用。

  • Arduino: GitHub - bblanchon/ArduinoJson: 📟 JSON library for Arduino and embedded C++. Simple and efficient.
  • STM32: 【STM32】使用keil提供的JSON库——Jansson_keil.jansson-CSDN博客
  • MicroPython(pyboard,esp8266,samd21): json – JSON encoding and decoding — MicroPython latest documentation

  • NodeMCU(esp8266): https://nodemcu.readthedocs.io/en/master/en/modules/sjson/

你可以利用这些库,把json字符串转换成对象。

电脑其他语言的json模块

基本所有的语言都支持json(连lisp都有)。。。所以可以很容易的进行通信。

正则表达式

如果是一些简单的字符串处理,使用python内置的一些功能就可以,但是对于复杂一些的需求,就需要使用正则表达式了。

比如URL处理中。(此处在OpenMV中使用不多)


http://www.ppmy.cn/news/1511869.html

相关文章

ES6随笔

ES6(ECMAScript 2015)是JavaScript的一个重大更新,它引入了许多新特性和语法糖,使得JavaScript的开发更加高效和灵活。下面是一些ES6中新增的主要特性及其代码示例: 1. 模板字符串(Template Strings&#…

stable-fast-3d的部署,在服务器Ubuntu22.04系统下——点动科技

在服务器Ubuntu22.04系统下,stable-fast-3d的部署 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表:2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有驱动2.3 安装驱动2.4 安…

【Java学习】实现图书管理系统

所属专栏:Java学习 🍁1. 功能演示 用户分为普通用户和管理员,登录进系统之后可以对图书进行一系列操作,此时我们要明白,对图书的操作是通过书架来执行的,我们平常在图书馆上借书就是在书架上 &#x1f…

单元测试、系统测试、集成测试知识总结

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、单元测试的概念 单元测试是对软件基本组成单元进行的测试,如函数或一个类的方法。当然这里的基本单元不仅仅指的是一个函数或者方法,有…

爬取豆瓣TOP250电影详解

一.分析网页DOM树结构 1.分析网页结构及简单爬取 豆瓣(Douban)是一个社区网站,创立于2005年3月6日。该网站以书影音起家,提供关于书籍、电影、音乐等作品的信息,其作品描述和评论都是由用户提供(User-Gen…

【element-ui】 统一全局配置size和z-index属性

Vue.use(Element, { size: small, zIndex: 3000 });参考: element ui 统一全局配置size和z-index属性

使用SSH协议远程连接Ubuntu

1.切换到root用户 sudo -i 2.安装openssh-server apt update apt install openssh-server 3.启动ssh服务 service ssh start 4.查看ssh状态 (q键: 退出) service ssh status 5.检查ssh服务是否启动成功 ps -e | grep ssh 6.开机自启动 systemctl enable …

Webpack高级配置(干货2)

目录 39.CodeSplit 优化代码运行性能40.CodeSplit按需加载,性能优化41.eslint 不支持动态倒入语法,需要引入import的plugin42.图片,字体等命名规则,可以提取复用43.preload/prefatch 39.CodeSplit 优化代码运行性能 entry由字符串…

libvirt bridge network configure

If you want to configure all the parameters of your virtual machine, you can issue the command like this: virsh edit ubuntu22.04-test In the GUI of NIC configuration, you can choose a configuration item from a drop box,such as “default”,‘bridged-network…

Apache Doris 中Compaction问题分析和典型案例

说明 此文档主要说明一些常见compaction问题的排查思路和临时处理手段。这些问题包括 Compaction socre高Compaction失败compaction占用资源多Compaction core 如果问题紧急,可联系社区同学处理 如果阅读中有问题,可以反馈给社区同学。 1 compaction …

机器学习--常见算法总结

有监督学习算法 1. 线性回归算法 概念:线性回归是一种统计方法,用于预测一个变量(因变量)与一个或多个自变量(特征变量)之间的关系。目标是通过线性方程建立自变量和因变量之间的关系模型。 作用&#x…

Linux执行脚本报错:-bash: ./mylife.sh: /bin/sh^M: bad interpreter: Text file busy

这个错误信息 -bash: ./mylife.sh: /bin/sh^M: bad interpreter: Text file busy 实际上包含了两个主要问题,但“Text file busy”这部分通常不是真实的错误,可能是显示错误或者与之前的操作冲突。更常见的问题是前面的 /bin/sh^M,这里的 ^M …

ZooKeeper Watcher 机制详解

ZooKeeper Watcher 机制详解 1、特点2、注册与触发3、注意事项 💖The Begin💖点点关注,收藏不迷路💖 ZooKeeper 的 Watcher 机制是分布式系统中用于事件通知的重要功能。 1、特点 一次性触发: Watcher 被触发后立即从…

Python自动化测试工具selenium使用指南

概述 selenium是网页应用中最流行的自动化测试工具,可以用来做自动化测试或者浏览器爬虫等。官网地址为:相对于另外一款web自动化测试工具QTP来说有如下优点: 免费开源轻量级,不同语言只需要一个体积很小的依赖包支持多种系统&a…

《现代情报》

《现代情报》简介 《现代情报》(原名《情报知识》)杂志是由吉林省科学技术厅主管,吉林省科学技术信息研究所、中国科学技术情报学会联合主办的信息资源管理领域综合性学术期刊。该刊于1980年创刊,每年12期。重点报道服务于国家战略…

上传文件,文件类型限制语法,各种媒体视频文件的Content-Type

各种媒体视频文件的Content-Type “application/x-apple-diskimage”: “DMG”, “application/epubzip”: “EPUB”, “application/java-archive”: “JAR”, “video/x-matroska”: “MKV”, “text/html”: “HTML|HTM”, “text/css”: “CSS”, “text/javascript…

Ps:首选项 - 单位与标尺

Ps菜单:编辑/首选项 Edit/Preferences 快捷键:Ctrl K Photoshop 首选项中的“单位与标尺” Units & Rulers选项卡允许用户根据工作需求定制 Photoshop 的测量单位和标尺显示方式。这对于保持工作的一致性和精确性,尤其是在跨设备或跨平台…

USB3.2 摘录(四)

系列文章目录 USB3.2 摘录(一) USB3.2 摘录(二) USB3.2 摘录(三) USB3.2 摘录(四) 文章目录 系列文章目录8 协议层(Protocol Layer)8.8 三个参数地址信息&…

软考高级第四版备考---第四十一天(软件工程-软件设计)

一、结构化设计 结构化设计(Structured Design,SD)是一种面向数据流的方法,它以SRS和SA阶段所产生的DFD和数据字典等文档为基础,是一个自顶向下、逐步求精和模块化的过程 二、面向对象设计 2.1面相对象设计(OOD&…

Electron 的contextBridge

contextBridge 是 Electron 框架中用于在渲染器进程(通常是 Web 页面)和主进程之间安全地暴露 API 的一种方式。它允许开发者在保持主进程和渲染器进程之间清晰分离的同时,从主进程向渲染器进程安全地传递方法和属性。这是通过创建一个单向的、只能从主进程到渲染器进程的桥…