最新案例教程点击下方链接跳转,CSDN已停止更新
点
击
跳
转
1.简介
本案例使用ULC-DSC03串口JPG摄像头(RS485接口),实现拍照功能。摄像头参数如下图所示。
2.硬件模块
-
硬件购买链接
链接: Hass506开发板.
链接: RS485-Camera. -
RS485-Camera资料
链接: RS485-camera手册. -
硬件接线
3.校验和查询
例如:获取AA 55 01 01 00 0D 的校验和
writeBuf= bytearray([0XAA,0X55,0x01,0x01,0x00,0x0D,SUM])
(1)打开在线工具
链接: 在线工具-校验和.
(2)输入数据,点击计算,获取校验和
所以AA 55 01 01 00 0D 的校验和为0E,故SUM填0x0E
writeBuf= bytearray([0XAA,0X55,0x01,0x01,0x00,0x0D,0x0E])
4.测试代码
- main.py
from driver import UART
import utime as time
import ubinascii
# JPEG图片以“FF D8”开头,“FF D9”结尾
uart=UART()
uart.open("serial3")
def syn():
readBuf=bytearray(15)
writeBuf= bytearray([0XAA,0X55,0x01,0x01,0x00,0x0D,0x0E])
'''
一、同步
1.主机同步摄像头
2.摄像头应答
3.摄像头同步主机
4.主机应答
'''
for i in range(50):
size=uart.read(readBuf)
print(size)
if size!=0:
print(readBuf)
print(ubinascii.hexlify(readBuf).decode())
print("同步成功,等待主机应答")
break
else:
uart.write(writeBuf)
print("have writed")
time.sleep(1)
writeBuf=bytearray([0xAA,0x55,0x01,0x02,0x00,0x0E,0x0D,0x1D])
uart.write(writeBuf)
print("---------------1----------------")
def set_resolution():
#设置分辨率
# 320*240
'''
主机发送: AA,55,Addr,02,00,01,N,SUM
分辨率配置:
1.N=0x01-------->325*288
2.N=0x02-------->480*272
3.N=0x03-------->800*480
4.N=0x04-------->1280*720
5.N=0x05-------->320*240
6.N=0x06-------->1440*896
7.N=0x07-------->640*480
8.N=0x08-------->1920*1080
9.N=0x09-------->800*600
10.N=0x0a-------->1024*768
'''
print("设置分辨率")
writeBuf=bytearray([0xAA,0x55,0x01,0x02,0x00,0x01,0x05,0x08])
uart.write(writeBuf)
readBuf=bytearray(8)
uart.read(readBuf)
print(readBuf)
# bytearray(b'\xaaU\x01\x02\x00\x0e\x01\x11')
# aa 55 01 02 00 0e 01 11'
print("--------------2--------------")
def set_baud():
'''
设置波特率,默认使用的是115200
主机发送:0xAA,0x55,Addr,0x02,0x00,0x07,Baud,SUM
Addr默认是0x01
SUM:0xAA,0x55,Addr,0x02,0x00,0x07,Baud的校验和
Baud配置:
1.Baud=0x0f--------->115200
2.Baud=0x1f--------->57600
3.Baud=0x2f--------->38400
4.Baud=0x3f--------->28800
5.Baud=0x5f--------->19200
6.Baud=0x7f--------->14400
7.Baud=0xBf--------->9600
例如:
writeBuf=bytearray([0xAA,0x55,Addr,0x02,0x00,0x07,Baud,SUM])
uart.write(writeBuf)
readBuf=bytearray(9)
print(readBuf)
print(ubinascii.hexlify(readBuf).decode())
-注意:设置成功之后请更换成新的波特率对摄像头进行通信,断电后重新上
电波特率会恢复到原来的比特率(如果不保存)
'''
pass
def set_pic_quality():
'''
设置图像质量
主机发送:AA 55 Addr 02 00 10 N SUM
图片质量配置:
1.N=0----->质量最高(压缩率最低,数据量最大)
2.N=1----->中等质量(压缩率中等,数据量适中)
3.N=2----->质量最差(压缩率最高,数据量最小)
'''
print("设置图片质量")
writeBuf=bytearray([0xAA,0x55,0x01,0x02,0x00,0x10,0x00,0x12])
uart.write(writeBuf)
readBuf=bytearray(8)
uart.read(readBuf)
print(readBuf)
print("-------------3-------------")
def take_pic():
'''
1.主机发送开始拍指令
2.摄像头应答
3.摄像头开始拍照
4.获取图像数据大小,决定分多少包传输
'''
print("拍照")
# 1
readBuf=bytearray(8)
writeBuf=bytearray([0xAA,0x55,0x01,0x02,0x00,0x04,0x05,0x0B])
uart.write(writeBuf)
# 2
uart.read(readBuf)
print(readBuf)
# 3
time.sleep(3)
readBuf=bytearray(10)
uart.read(readBuf)
print(readBuf)
print(ubinascii.hexlify(readBuf))
# 4
data=ubinascii.hexlify(readBuf)
data=data[-6:-2]
data_l=int(data[:2],16)
data_h=int(data[2:4],16)
package_size=(data_h*256+data_l)/512
#分包次数取整
package_size=int(package_size)+1
print(package_size)
print("----------------4-------------")
return package_size
def transfer_data(package_size):
# 分包传输
# i 个包
data=""
readBuf=bytearray(522)
print("分包传输")
for i in range(package_size+1):
print("-------------package",str(i)+"-----------------")
writeBuf=bytearray([0xAA,0x55,0x01,0x03,0x00,0x0C,0x00+i,0x00,0x0F+i])
print(ubinascii.hexlify(writeBuf))
uart.write(writeBuf)
size=uart.read(readBuf)
print(ubinascii.hexlify(readBuf[:9]))
print(ubinascii.hexlify(readBuf[9:-1]))
if i==0:
#由于第一个包是空包,故不要该包数据
time.sleep(1)
continue
if i==package_size:
#读取最后一个包数据时,需要去除ffd9之后的校验码
data_end=ubinascii.hexlify(readBuf[9:-1]).decode()
data_end=data_end[:data_end.find("ffd9")+4]
data+=data_end
break
data+=ubinascii.hexlify(readBuf[9:-1]).decode()
time.sleep(1)
print("--------------------5------------------------")
return data
def write_txt_content(path,mode,data):
# 文本保存的字符串必须是形如"c8770783a87b86d5..."的十六进制字符串,有无效字符会读取失败。
with open(path, mode) as f:
f.write(data)
print("--------------6----------------")
def read_txt_content(path,mode):
print("读取文件内容")
with open(path, mode) as f:
content = f.read()
# print(content)
print("--------------7-----------------")
return content
def end_transfer_data():
# 主机收发完最后一包,发送一个结束命令
writeBuf=bytearray([0xAA,0x55,0x01,0x03,0x00,0x0C,0xF0,0xF0,0xEF])
uart.write(writeBuf)
print("--------------8-----------------")
def txt_to_jpg():
#文本数据转图片
payload=read_txt_content('/user/test.txt','r')
write_txt_content('/user/test.jpg', "wb",payload)
print("--------------9-----------------")
def main():
# 上电至少延时3s
time.sleep(6)
#同步
syn()
#设置分辨率
set_resolution()
#设置图片质量
set_pic_quality()
#拍照
package_size=take_pic()
#数据分包传输
data=transfer_data(package_size)
#写文本
write_txt_content('/user/test.txt','w',data)
# 数据传输结束,自动转为拍照模式
end_transfer_data()
#将16进制的文本数据转化成jpg图片
txt_to_jpg()
# 由于图像数据保存在user文件夹下,不可看,故打印该数据,进行外部转换
print(data)
# type(data)
if __name__=="__main__":
main()
- board.json
{
"version": "1.0.0",
"io": {
"serial1":{
"type":"UART",
"port":0,
"dataWidth":8,
"baudRate":9600,
"stopBits":1,
"flowControl":"disable",
"parity":"none"
},
"serial2":{
"type":"UART",
"port":1,
"dataWidth":8,
"baudRate":4800,
"stopBits":1,
"flowControl":"disable",
"parity":"none"
},
"serial3":{
"type":"UART",
"port":2,
"dataWidth":8,
"baudRate":115200,
"stopBits":1,
"flowControl":"disable",
"parity":"none"
}
},
"debugLevel": "ERROR"
}
4.测试结果
代码烧录后,摄像头所拍摄的图片会被存放在user文件夹下,所以图像不可见,当然用户可以外置存储卡,将图片图放在SD卡中,使用读卡器查看所拍摄的图片。当前介绍一下如何将16进制的数据转换为图片:
(1)复制数据
代码运行完毕,会打印图片的16进制数据,该数据以ffd8开头,ffd9结尾,复制该数据。
(2)粘贴数据
先在电脑桌面上新建一个文件夹,例如txt2jpg。然后在该文件夹内创建一个txt文本,例如text.txt,将(1)中所复制的数据粘贴到test.txt内。
(3)执行python脚本
打开pythonIDE,将test.txt的路径填写到下面的代码中(注意是"/"),执行该脚本,将txt文本转化成jpg图片。
import binascii
with open('C:/Users/further/Desktop/txt2jpg/test.txt','rb') as f1, open('C:/Users/further/Desktop/txt2jpg/test.jpg', "wb") as f2:
payload=f1.read()
pic = binascii.a2b_hex(payload)
f2.write(pic)