Arduino+Python实现ADNS-3080光流传感器图像捕获与显示


在这里插入图片描述
在这里插入图片描述

引言

我在基于Arduino Uno平台开发ADNS-3080类库这篇文章中详细介绍了ADNS-3080光学传感器类的定义、实现及底层原理,并附带了ADNS3080库的下载链接,提供了相应的测试程序示例,但还是存在一些不足,比如如何调整传感器的焦距使得像素更清晰,光在控制台看数据恐怕不直观,也无从调焦。本文旨在探索Arduino+Python基于串口通信的方式,实现对ADNS-3080光流传感器图像捕获与显示。

准备

安装ADNS3080库

安装Python库

Python语言属于脚本语言,在程序可视化显示方面,与用户交互更加高级也更加方便。本文探索使用Python的pyserialtkinter这2个库,实现与Arduino Uno开发板的串口通信,并将Arduino Uno返回的像素数据转换成图像显示。若不确定你是否安装了这2个库,可以在命令行中输入如下2行命令,pip就会自动检查有无这些库,若无或者有新版本,pip会提示下载安装:
pip install pyserial
pip install tkinter

编写代码

代码包含2部分,一部分是给Arduino Uno上传的,主要功能是读取ADNS-3080光流传感器捕获的像素数据,并通过串口向上位机发送;一部分是上位机运行的python程序,用于解析像素数据并在屏幕上显示。

Arduino代码

上一篇文章提到的示例类似,主要是将像素数据按行打印到串口。部分代码如下:

// SPI pins:
#define PIN_RESET    9
#define PIN_CS       10

ADNS3080<PIN_RESET, PIN_CS> sensor; //声明传感器操作类

// Serial parameters: [Must match python script]
#define BEGIN_CHAR    'A'
#define BAUD_RATE     57600
void setup() {
  // 初始化串口
  Serial.begin(BAUD_RATE);
  Serial.flush(); //防乱码
  // 初始化ADNS-3080
  if (!sensor.setup( false, false )) { //默认LED模式、分辨率
    Serial.println(F("Error"));
    while(true); //等待用户检查和复位
  }
}
void loop() {
  // 标志帧起始
  Serial.println( BEGIN_CHAR );   
  // 取帧数据
  uint8_t frame[ADNS3080_PIXELS][ADNS3080_PIXELS];
  sensor.frameCapture( frame );

  // 串口向上位机发送数据
  for( int y = 0; y < ADNS3080_PIXELS; y += 1 ) {
    for( int x = 0; x < ADNS3080_PIXELS; x += 1 ) { //按行取数据
      Serial.println( frame[x][y] );
    }
  }
  
}

调试结果如图:
在这里插入图片描述

Python代码

主要是使用serial模块建立串口通信,使用tkinter.canvas绘制矩形,使矩形颜色对应各像素值,主要代码如下:

#---------------定义全局变量-------------------------

# 创建窗口与画布:
window = tkinter.Tk()
canvas = tkinter.Canvas( window, height = WINDOW_SIZE, width = WINDOW_SIZE ) # 窗口大小的画布

# 显示像素块及颜色:
grid = []
color = []

# 初始化图像数据
for y in range( NUM_PIXEL ): # 行
    grid.append( [] ) # 二级列表
    color.append( [] )
    for x in range( NUM_PIXEL ): # 列
        color[y].append(0) # 黑色
        grid[y].append( canvas.create_rectangle(  GRID_SIZE*x, GRID_SIZE*y, GRID_SIZE*x + GRID_SIZE, GRID_SIZE*y + GRID_SIZE, fill = "black", width = 0 ) )  # 添加矩形像素格子                            

#--------------- 函数 ------------------------
# 获取像素值
def getData() :
    return arduino.readline().decode( "utf-8" ) # 读取utf-8编码的字符

# 将8位像素值变成24位RGB值
def hexColor( byte ):
    return "#%02x%02x%02x" % (byte, byte, byte)

# 设置像素格子颜色
def setGridColor():    
    while BEGIN_CHAR not in getData():   # 空循环找第1个像素标志符'A'
        continue

    # 存储帧数据:
    for y in range( 0, NUM_PIXEL ): # 行
        for x in range( 0, NUM_PIXEL ): # 列
            try:
                color[y][x] = int( getData() )
            except:
                continue
            
    # 渲染:
    for y in range( 0, NUM_PIXEL ): 
        for x in range( 0, NUM_PIXEL ):
            canvas.itemconfig( grid[y][x], fill = hexColor( color[y][x] ) )


# 定时更新图像
def updateImage():
    setGridColor()
    canvas.after( DELAY_MSEC, updateImage )
        

#--------------- 运行脚本 ------------------
arduino = None
try:
    # 初始化串口通信
    arduino = serial.Serial( SERIAL_PORT, BAUD_RATE, timeout = float(DELAY_MSEC)/1000 )
    print( "Successful connection" )

    # 更新帧图像
    canvas.pack()
    canvas.after( DELAY_MSEC, updateImage ) # 每隔DELAY_MSEC毫秒更新一帧
    window.mainloop()
except SerialException as e:
    print( e )
except BaseException:
    print( "Connection error" )
finally:
    # 关闭串口
    if arduino is not None and arduino.isOpen():
        arduino.close()
        print ( "Close connection" )
    try:
        canvas.destroy()
        window.destroy()
    except:
        pass

成果展示

https://live.csdn.net/v/424925

相关链接

ADNS-3080测试程序(python+arduino)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值