Microduino Pixy摄像头SPI通讯追踪颜色/zh
概述
材料清单
文档程序下载:pixyMicroduinoServo.ino Pixy上位机安装:pixymon_windows-2.0.6.exe Pixy函数库:arduino_pixy-0.1.7 搭建硬件电路
安装pixymon_windows-2.0.6.exe
清空所有标记颜色
按住(不松手)右上角白色按钮直到前面的彩灯彩虹闪烁(红,橙,黄,绿,蓝,碘,紫),这时候拿一个带有饱满颜色的物体在摄像头前晃悠,电脑屏幕会标识这个物体,标识了正确的物体后再次按下白色按钮,屏幕上会次物体标识一个标签比如S1等等,你最多可以标识7个颜色的物体,这里我们只标识一个颜色。
用SPI数据线把Pixy和Microduino连接起来,由于数据线是连接Arduino的,所以你需要用跳线来改造这个数据线 引脚图: 连接好后看起来像这样 下载pixyMicroduinoServo.ino代码到Microduino Core中 打开串口你会看到摄像头初始化... 初始化完成后,这是如果你拿一个标识过的物体在摄像头前晃悠,串口会显示物体的坐标数据 这说明Pixy和Microduino通讯成功了 整体组装安装云台 连接舵机 Microduino模块堆叠 把USB线插入Microduino-Duo-v上给Microduino供电 这时,摄像头就可以跟踪刚才那个标记过的物体了,会始终跟着物体。 接下来也可以再装一个microWrt连接一个小型摄像头方便无线看视频 具体的microWrt摄像头配置方法如下: MicroWRT 摄像头自动启动 查看是否开启wifi etc/config 下面有个wireless 连接一个USB摄像头。同时在/dev目录下会生成设备vdieo0. mjpeg-streamer 的执行程序在/etc/init.d 目录 设置开机启动摄像头就修改/etc/rc.local 配置文件 Vi /etc/rc.local # Put your custom commands here that should be executed once # the system init finished. By default this file does nothing. mjpg_streamer -i "input_uvc.so -d /dev/video0 -r 640x480 -f 20" -o "output_http.so -p 8080 -w /www/webcam" exit 0
软件调试程序说明pixyMicroduinoServo.ino #include <SPI.h>
#include <Pixy.h>
#include <Servo.h>
Pixy pixy;
#define X_CENTER ((PIXY_MAX_X-PIXY_MIN_X)/2)
#define Y_CENTER ((PIXY_MAX_Y-PIXY_MIN_Y)/2)
#define panServoPWM 8 //pwm
#define tiltServoPWM 9 //pwm
int panAngle=90, tiltAngle=90;
int oldPanAngle=90, oldTiltAngle=90;
int panDiff=0, tiltDiff=0;
int stepRange=3;
int gap=0;
int center=500;
Servo panServo,tiltServo;
class ServoLoop
{
public:
ServoLoop(int32_t pgain, int32_t dgain);
void update(int32_t error);
int32_t m_pos;
int32_t m_prevError;
int32_t m_pgain;
int32_t m_dgain;
};
ServoLoop panLoop(300, 500);
ServoLoop tiltLoop(500, 700);
ServoLoop::ServoLoop(int32_t pgain, int32_t dgain)
{
m_pos = PIXY_RCS_CENTER_POS;
m_pgain = pgain;
m_dgain = dgain;
m_prevError = 0x80000000L;
}
void ServoLoop::update(int32_t error)
{
long int vel;
char buf[32];
if (m_prevError!=0x80000000)
{
vel = (error*m_pgain + (error - m_prevError)*m_dgain)>>10;
//sprintf(buf, "%ld\n", vel);
//Serial.print(buf);
m_pos += vel;
if (m_pos>PIXY_RCS_MAX_POS)
m_pos = PIXY_RCS_MAX_POS;
else if (m_pos<PIXY_RCS_MIN_POS)
m_pos = PIXY_RCS_MIN_POS;
}
m_prevError = error;
}
void setup()
{
Serial.begin(9600);
Serial.print("Starting...\n");
initServos();
pixy.init();
}
void loop()
{
static int i = 0;
int j;
uint16_t blocks;
char buf[32];
int32_t panError, tiltError;
blocks = pixy.getBlocks();
if (blocks)
{
panError = X_CENTER-pixy.blocks[0].x;
tiltError = pixy.blocks[0].y-Y_CENTER;
panDiff=panError;
tiltDiff=tiltError;
panLoop.update(panError);
tiltLoop.update(tiltError);
pixy.setServos(panLoop.m_pos, tiltLoop.m_pos);
// Serial.print(panLoop.m_pos);
// Serial.print("\t");
// Serial.println(tiltLoop.m_pos);
controlServo();
i++;
// do this (print) every 50 frames because printing every
// frame would bog down the Arduino
if (i%50==0)
{
sprintf(buf, "Detected %d:\n", blocks);
//Serial.print(buf);
for (j=0; j<blocks; j++)
{
sprintf(buf, " block %d: ", j);
//Serial.print(buf);
//pixy.blocks[j].print();
}
}
}
}
void initServos() {
panServo.attach(panServoPWM);
tiltServo.attach(tiltServoPWM);
panServo.write(panAngle);
tiltServo.write(tiltAngle);
}
//控制舵机转动
void controlServo() {
panAngle=map(panLoop.m_pos,0,1000,0,180);
if(panAngle!=oldPanAngle) {
panServo.write(panAngle);
oldPanAngle=panAngle;
}
tiltAngle=map(tiltLoop.m_pos,0,1000,0,180);
if(tiltAngle!=oldTiltAngle) {
tiltServo.write(tiltAngle);
oldTiltAngle=tiltAngle;
}
Serial.print(panAngle);
Serial.print("\t");
Serial.println(tiltAngle);
}
程序下载
视频 |