HarvardX TinyML小笔记3(番外2:OV7670平替)(TODO)
1 缘由
教程里面用的是OV7675,不过有点贵,是国产的OV7670价格的10倍不止。所以这里打算换成国产的OV7670。两个都是OmniVision 0.3MP VGA 级CMOS图像传感器。
OV7670 用的是老一代6µm像素工艺,光敏面积大,但芯片体积大。OV7675 用的是更新的3µm工艺,在小尺寸模组里更合适,噪声和功耗控制更好。所以两者最大的差异就是制作工艺,7675体积也更小。不过两者并不是Pin2Pin兼容。
2 硬件连接
OV7670引脚说明:
- 控制接口(I2C):SCL(时钟线)、SDA(数据线)、VCC(电源)、GND(接地)。
- 数据接口(并行):D0-D7(8 位数据)、VSYNC(场同步)、HREF(行参考)、PCLK(像素时钟)、RST(复位,可选)、PWDN(省电,接低电平启用)。
有专门的一篇文章说怎么修改:https://blog.arduino.cc/2020/06/24/machine-vision-with-low-cost-camera-modules/
Nano BLE的Pins定义如下:
按照上面那篇文章,接线图如下:
但是这个Pin脚定义好像不对,因为直接初始化就挂了。
if (!Camera.begin(QVGA, RGB565, 1)) {
Serial.println("Failed to initialize camera!");
while (1);
}
看了一下代码,好像说了一下Pin脚的配置,和上面的差很多。
Test that the connection between your Arduino and Camera is able to transfer data correctly at the given speed
Circuit:
- Arduino Nano 33 BLE board
- OV7670 camera module:
- 3.3 connected to 3.3
- GND connected GND
- SIOC connected to A5
- SIOD connected to A4
- VSYNC connected to 8
- HREF connected to A1
- PCLK connected to A0
- XCLK connected to 9
- D7 connected to 4
- D6 connected to 6
- D5 connected to 5
- D4 connected to 3
- D3 connected to 2
- D2 connected to 0 / RX
- D1 connected to 1 / TX
- D0 connected to 10
This example code is in the public domain.
试了一下。我是真想吐槽的,因为引脚真的太多了。。。一共快20个了。连接这堆杜邦线都要搞好久。。。
上去起码不报错了。
3 软件配置
软件上首先要多安装一个OV765X的库。
其实还要装一个Arduino_CRC32的库,里面有例子会用到。
之后就可以看到出的图了。
但是这个图是乱码,怎么看呢。看了一下之前那个教程,说是有个Processing软件可以看。
Processing 是由麻省理工学院媒体实验室开发的开源图形设计语言与开发环境,2001 年诞生至今始终免费,支持跨平台运行。它以简化的 Java 语法为基础,无需深厚编程基础也能快速上手,核心通过
setup()
(初始化)和draw()
(循环渲染)函数实现图形绘制、动画效果与交互功能,还可借助扩展库拓展音频处理、3D 渲染等能力,广泛用于艺术创作(如视觉装置、动态图形)、设计领域(如交互设计原型)及编程教育,是连接代码与视觉表达的实用工具。
下载地址是:https://processing.org/
01年的软件,老掉牙了属于,不过还能用吧。
这个要放置一套Java代码进去。
/*This sketch reads a raw Stream of RGB565 pixelsfrom the Serial port and displays the frame onthe window.Use with the Examples -> CameraCaptureRawBytes Arduino sketch.This example code is in the public domain.
*/import processing.serial.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;Serial myPort;// must match resolution used in the sketch
final int cameraWidth = 320;
final int cameraHeight = 240;
final int cameraBytesPerPixel = 2;
final int bytesPerFrame = cameraWidth * cameraHeight * cameraBytesPerPixel;PImage myImage;
byte[] frameBuffer = new byte[bytesPerFrame];void setup()
{size(320, 240);// if you have only ONE serial port active//myPort = new Serial(this, Serial.list()[0], 9600); // if you have only ONE serial port active// if you know the serial port namemyPort = new Serial(this, "COM11", 9600); // Windows//myPort = new Serial(this, "/dev/ttyACM0", 9600); // Linux//myPort = new Serial(this, "/dev/cu.usbmodem14401", 9600); // Mac// wait for full frame of bytesmyPort.buffer(bytesPerFrame); myImage = createImage(cameraWidth, cameraHeight, RGB);
}void draw()
{image(myImage, 0, 0);
}void serialEvent(Serial myPort) {// read the saw bytes inmyPort.readBytes(frameBuffer);// access raw bytes via byte bufferByteBuffer bb = ByteBuffer.wrap(frameBuffer);bb.order(ByteOrder.BIG_ENDIAN);int i = 0;while (bb.hasRemaining()) {// read 16-bit pixelshort p = bb.getShort();// convert RGB565 to RGB 24-bitint r = ((p >> 11) & 0x1f) << 3;int g = ((p >> 5) & 0x3f) << 2;int b = ((p >> 0) & 0x1f) << 3;// set pixel colormyImage .pixels[i++] = color(r, g, b);}myImage .updatePixels();}
我是Windows,用的COM11,所以改成myPort = new Serial(this, "COM11", 9600);
打开OV767X - Camera Capture Raw Bytes这个例子,编译上传之后关掉Arduino,运行这个程序,就可以看到图了。
如果屏蔽掉// Camera.testPattern();是下面的。
可以看到,数据是能出来了,但是花屏了,明显还不对。。。
未完待续。。。