37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百八十一:Maixduino AI开发板 k210 RISC-V AI+lOT ESP32视觉听觉开发套装
知识点:勘智K210
2018年9月6日,嘉楠科技推出自主设计研发的全球首款基于RISC-V的量产商用边缘智能计算芯片勘智K210。该芯片依托于完全自主研发的AI神经网络加速器KPU,具备自主IP、视听兼具与可编程能力三大特点,能够充分适配多个业务场景的需求。
作为嘉楠科技自主研发的边缘侧AI芯片,勘智K210兼具高能耗比和灵活性。在算力方面,勘智K210可在0.3W的条件下提供1TOP的算力支持,充分适配在多数业务场景中低功耗约束下的算力需求。在芯片集成度方面,勘智K210采用视听一体化设计。在机器视觉上,芯片基于自主研发的神经网络加速器KPU,可完成基于神经网络的图像分类任务,进行人脸识别与检测,以及实时获被检测目标的分类。在听觉能力上,芯片自带APU语音处理单元,最高可支持8路音频数据及16个方向,无需占用CPU即可实现声源定向、声场成像、波束形成、语音识别与唤醒等功能。在算法定制化方面,勘智K210在可编程能力上呈现出更高的灵活性。首先,相比ARM等架构,勘智K210采用RISC-V架构,拥有更强的可定制化能力,便于开发者根据具体应用场景定制算法。其次,芯片搭载FPIOA现场可编程IO阵列,支持TensorFlow、Keras、Darknet、PaddlePaddle和Caffe等主流AI编程框架,以及全面的开发文档,对开发者十分友好。此外,芯片内置64位双核处理器架构,分为计算核与应用核,能够为开发者提供足以应对复杂业务场景的计算资源。
Maixduino AI开发板功能特性
CPU:RISC-V 双核64bit、内置FPU、400Mhz标准频率(可超频)
内置神经网络处理器
OV2640摄像头:200W像素通用24P摄像头
连接器:兼容Arduino 接口、TF卡槽、扬声器接口
无线功能:支持2.4G 802.11.b/g/n、支持Bluetooth 4.2
音频功能:MEMS 麦克风、3W扬声器输出
8 Bit(256 级) 可调颜色,5Bit (32 级)亮度调节
DVP 摄像头接口:24P 0.5mm FPC 连接器,支持OV2640、5640、7740等
LCD接口:24P 0.5mm FPC 连接器,支持8bit MCU LCD
ESP32模块:支持2.4G 802.11.b/g/n
802.11 n(2.4G)速率达到150Mbps
Bluetooth v4.2全规格,包含传统蓝牙(BR/EDR)和低功耗蓝牙(BLE)
开发环境:支持Arduino IDE、MaixPy IDE、OpenMV IDE等
技术规格
尺寸:68mm 54mm
电源输入:USB Type-C(支持6~12V输入)
温升:<20K
工作温度范围:-30~85ºC
MCU:ESP8285
无线标准:802.11 b/g/n
频率范围:2400Mhz~2483.5Mhz
发射功率:802.11.b:+15dBm
802.11.g:+10dBm(54Mbps)
802.11.n:+10dBm(65Mbps)
无线连接器:IPEX 3.03.0mm
Wi-Fi模式:Station/SoftAP/SoftAP+Station
k210 RISC-V AI+lOT ESP32视觉听觉开发套装 ,包括有
OV2640摄像头:200W像素通用24P摄像头
ST7789驱动器芯片2.4寸LCD屏(24P 320X240)
求助:标配摄像头Sipeed_OV2640驱动一直出错,无法通过验证
使用的是Sipeed_OV2640的唯一示例程序selfie.ino,Maixduino AI开发板自带的标准库Sipeed_OV2640.h
selfie.ino示例程序如下:
#include <Sipeed_OV2640.h>
#include <Sipeed_ST7789.h>
SPIClass spi(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi);
Sipeed_OV2640 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565);
void setup()
{
Serial.begin(115200);
lcd.begin(15000000, COLOR_RED);
if(!camera.begin())
Serial.printf(“camera init fail\n”);
else
Serial.printf(“camera init success\n”);
camera.run(true);
}
void loop()
{
uint8_timg = camera.snapshot();
if(img == nullptr || img==0)
Serial.printf(“snap fail\n”);
else
lcd.drawImage(0, 0, camera.width(), camera.height(), (uint16_t)img);
}
查到 github.com 上也是这个示例程序,一模一样的
https://github.com/sipeed/Maixduino/blob/master/libraries/Sipeed_OV2640/examples/selfie/selfie.ino
出错信息如下:
Arduino:1.8.12 (Windows 10), 开发板:“Sipeed Maixduino Board, Default, 400MHz CPU Clock Frequency, 1.5 Mbps, Default”
sketch_mar21a:7:15: error: cannot declare variable ‘camera’ to be of abstract type ‘Sipeed_OV2640’
Sipeed_OV2640 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565);
~~
In file included from C:\Users\Eagler8\Documents\Arduino\sketch_mar21a\sketch_mar21a.ino:1:
C:\Users\Eagler88\AppData\Local\Arduino15\packages\Maixduino\hardware\k210\0.3.11\libraries\Sipeed_OV2640\src/Sipeed_OV2640.h:36:7: note: because the following virtual functions are pure within ‘Sipeed_OV2640’:
class Sipeed_OV2640 : public Camera{
~~~~~~~~~
In file included from C:\Users\Eagler88\AppData\Local\Arduino15\packages\Maixduino\hardware\k210\0.3.11\libraries\Sipeed_OV2640\src/Sipeed_OV2640.h:4,
from C:\Users\Eagler88\Documents\Arduino\sketch_mar21a\sketch_mar21a.ino:1:
C:\Users\Eagler88\AppData\Local\Arduino15\packages\Maixduino\hardware\k210\0.3.11\libraries\Camera\src/Camera.h:79:18: note: ‘virtual void Camera::setRotation(uint8_t)’
virtual void setRotation(uint8_t rotation) = 0;
~~~~~~~
“Adafruit_GFX.h” 对应多个库
已使用: C:\Users\Eagler88\Documents\Arduino\libraries\Adafruit_GFX_Library
未使用:C:\Users\Eagler88\Documents\Arduino\libraries\arduino_956473
未使用:C:\Users\Eagler88\AppData\Local\Arduino15\packages\Maixduino\hardware\k210\0.3.11\libraries\Adafruit-GFX-Library
exit status 1
cannot declare variable ‘camera’ to be of abstract type ‘Sipeed_OV2640’
在文件 -> 首选项开启
“编译过程中显示详细输出”选项
这份报告会包含更多信息。
附录:完整的<Sipeed_OV2640.h>库文件
#ifndef __SIPEED_OV2640_H
#define __SIPEED_OV2640_H
#include “Camera.h”
#define OV9650_ID (0×96)
#define OV2640_ID (0×26)
#define OV7725_ID (0×77)
#define MT9V034_ID (0×13)
#define LEPTON_ID (0×54)
#define OV_CHIP_ID (0×0A)
#define ON_CHIP_ID (0×00)
#define GC0328_ID (0×9d)
#define GC0328_ADDR (0×42)
typedef enum {
GAINCEILING_2X,
GAINCEILING_4X,
GAINCEILING_8X,
GAINCEILING_16X,
GAINCEILING_32X,
GAINCEILING_64X,
GAINCEILING_128X,
} gainceiling_t;
typedef enum {
FRAMERATE_2FPS =0×9F,
FRAMERATE_8FPS =0×87,
FRAMERATE_15FPS=0×83,
FRAMERATE_30FPS=0×81,
FRAMERATE_60FPS=0×80,
} framerate_t;
class Sipeed_OV2640 : public Camera{
public:
Sipeed_OV2640(framesize_t frameSize = FRAMESIZE_QVGA, pixformat_t pixFormat = PIXFORMAT_RGB565);
Sipeed_OV2640(uint16_t width, uint16_t height, pixformat_t pixFormat = PIXFORMAT_RGB565);
Sipeed_OV2640();
virtual bool begin();
virtual void end();
bool reset();
bool setPixFormat(pixformat_t pixFormat);
bool setFrameSize(framesize_t frameSize);
virtual bool run(bool run);
virtual int id();
/**
* @return pixels
* If pixels format is RGB565: return RGB565 pixels with every uint16_t one pixel, e.g. RED: 0xF800
*/
virtual uint8_t* snapshot();
virtual uint16_t* getRGB565(){ return (uint16_t*)_dataBuffer; };
virtual uint8_t* getRGB888(){ return _aiBuffer; };
virtual void setRotation(uint8_t rotation);
virtual void setInvert(bool invert);
private:
uint8_t* _dataBuffer; // put RGB565 data
uint8_t* _aiBuffer; // put RGB888 data
uint8_t _resetPoliraty; // reset poliraty flag
uint8_t _pwdnPoliraty; // PWDN poliraty flag
uint8_t _slaveAddr; // camera address
uint8_t _id;
uint32_t _freq;
int dvpInit(uint32_t freq = 24000000);
int dvpInitIrq();
int cambus_scan();
int cambus_read_id(uint8_t addr,uint16_t *manuf_id, uint16_t *device_id);
int cambus_scan_gc0328(void);
int cambus_readb(uint8_t slv_addr, uint8_t reg_addr, uint8_t *reg_data);
int cambus_writeb(uint8_t slv_addr, uint8_t reg_addr, uint8_t reg_data);
int cambus_readw(uint8_t slv_addr, uint8_t reg_addr, uint16_t *reg_data);
int cambus_writew(uint8_t slv_addr, uint8_t reg_addr, uint16_t reg_data);
int cambus_readw2(uint8_t slv_addr, uint16_t reg_addr, uint16_t *reg_data);
int cambus_writew2(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data);
int sensor_ov_detect();
int sensro_gc_detect();
int ov2640_reset();
int ov2640_read_reg(uint8_t reg_addr);
int ov2640_write_reg(uint8_t reg_addr, uint8_t reg_data);
int ov2640_set_pixformat(pixformat_t pixformat);
int ov2640_set_framesize(framesize_t framesize);
int ov2640_set_framerate(framerate_t framerate);
int ov2640_set_contrast(int level);
int ov2640_set_brightness(int level);
int ov2640_set_saturation(int level);
int ov2640_set_gainceiling( gainceiling_t gainceiling);
int ov2640_set_quality(int qs);
int ov2640_set_colorbar(int enable);
int ov2640_set_auto_gain(int enable, float gain_db, float gain_db_ceiling);
int ov2640_get_gain_db(float *gain_db);
int ov2640_set_auto_exposure(int enable, int exposure_us);
int ov2640_get_exposure_us(int *exposure_us);
int ov2640_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db);
int ov2640_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db);
int ov2640_set_hmirror(int enable);
int ov2640_set_vflip(int enable);
int sensor_snapshot( );
int reverse_u32pixel(uint32_t* addr,uint32_t length);
};
#endif
标配Sipeed_OV2640摄像头
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百五十三:Maixduino AI开发板 k210 RISC-V AI+lOT ESP32视觉听觉开发套装
程序之八:I2C测试
/*
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百五十三:Maixduino AI开发板 k210 RISC-V AI+lOT ESP32视觉听觉开发套装
程序之八:I2C测试
*/
#include <Wire.h>
void setup() {
Serial.begin (115200);
// 等待串行端口连接
while (!Serial)
{
}
Serial.println ();
Serial.println ("I2C Testing ...");
byte count = 0;
Wire.begin();
Wire.beginTransmission(0x3C);
Wire.write(0x80);
Wire.write(0xAF);
Wire.endTransmission();
Serial.println ("Done.");
} // 安装结束
void loop() {}
实验串口返回情况
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百五十三:Maixduino AI开发板 k210 RISC-V AI+lOT ESP32视觉听觉开发套装
程序之九:I2C设备扫描仪
/*
【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验一百五十三:Maixduino AI开发板 k210 RISC-V AI+lOT ESP32视觉听觉开发套装
程序之九:I2C设备扫描仪
*/
#include <Wire.h>
void setup() {
Serial.begin (115200);
// 等待串行端口连接
while (!Serial)
{
}
Serial.println ();
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;
Wire.begin();
for (byte i = 8; i < 120; i++)
{
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0)
{
Serial.print ("Found address: ");
Serial.print (i, DEC);
Serial.print (" (0x");
Serial.print (i, HEX);
Serial.println (")");
count++;
//delay (1); //也许不需要?
} // 良好反应结束
} // 结束for循环
Serial.println ("Done.");
Serial.print ("Found ");
Serial.print (count, DEC);
Serial.println (" device(s).");
} // 安装结束
void loop() {}
实验串口返回情况