Arduion从车
B学习
添加库文件
需要确保你的Arduino IDE中已经安装了TimerOne库。具体可参考以下步骤:
- 打开Arduino IDE软件;
- 点击“工具”(Tools)菜单栏,然后点击“管理库”(Manage Libraries)选项;
- 在弹出的对话框中,在搜索框中输入“TimerOne”,然后进行搜索;
- 安装TimerOne库。
打开文件->首选项 确认文件夹地址为对应的位置
Arduion 添加计时器
/* User include begin */
#include <TimerOne.h> //定时器
/* 变量区 */
// 定义常量,定时器时间间隔,单位为毫秒
const int TIMER_INTERVAL = 1;
// 定义变量,记录当前的时间
unsigned long timer_now = 0;
//初始化
void setup()
{
// 定时器初始化,设定时间间隔及中断函数
Timer1.initialize(TIMER_INTERVAL * 1000); // 1ms
Timer1.attachInterrupt(timerISR); //中断服务函数 timerISR
}
void timerISR() //定义一个函数
{
static uint16_t Led1_Cnt = 0; //定义变量
static bool Led1_Flag = 0; //定义标志
Led1_Cnt++; //计数
if(500 == Led1_Cnt)
{
Led1_Cnt = 0; //归零
Led1_Flag = !Led1_Flag;
if(Led1_Flag)
{
CoreLED.TurnOn(1); //警示灯 开函数
}
else
{
CoreLED.TurnOff(1); //关函数
}
}
}
关于寻迹细节
- 降低寻迹速度可以提高寻迹精确度
- 冲特殊地形之前也要降速,避免碰到障碍
倒车入库寻迹
1. 小车按时间前进寻迹
/*
小车按时间寻迹
参数:速度,时间
*/
void vCAR_track_Time(uint8_t Car_Spend,uint8_t Car_Time) {
uint8_t gd;
uint8_t tp;
uint8_t firstbit[8];
DCMotor.StartUp();
while (true) {
tp = 0;
firstbit[0] = 0;
gd = ExtSRAMInterface.ExMem_Read(0x6000);
for (size_t i = 0x01; i < 0x100; i <<= 1) {
if ((gd & i) == 0) {
firstbit[tp++] = uint8_t(i);
}
}
if (tp >= 0x05) /*循迹灯灭的个数≥5表示全灭*/
{
DCMotor.Stop();
break;
} else {
switch (firstbit[0]) {
case 0x00:
DCMotor.SpeedCtr(Car_Spend, Car_Spend);
break;
case 0x01:
DCMotor.SpeedCtr(Car_Spend + 60, Car_Spend - 120);
break;
case 0x02:
DCMotor.SpeedCtr(Car_Spend + 40, Car_Spend - 70);
break;
case 0x04:
DCMotor.SpeedCtr(Car_Spend + 30, Car_Spend - 30);
break;
case 0x08:
DCMotor.SpeedCtr(Car_Spend, Car_Spend);
break;
case 0x10:
DCMotor.SpeedCtr(Car_Spend - 30, Car_Spend + 30);
break;
case 0x20:
DCMotor.SpeedCtr(Car_Spend - 70, Car_Spend + 40);
break;
case 0x40:
DCMotor.SpeedCtr(Car_Spend - 120, Car_Spend + 60);
break;
case 0x80:
DCMotor.SpeedCtr(Car_Spend - 120, Car_Spend + 60);
break;
}
}
Car_Time--;
if(!Car_Time)
{
DCMotor.Stop();
return;
}
delay(100);
}
}
2. 前后寻迹多次找到最佳正车身
库函数
BEEP.cpp | 1. Initialization(); 2.TurnOn 3.TurnOff |
1.初始化函数 2.打开蜂鸣器 3.关闭蜂鸣器 |
---|---|---|
ExtSRAMInterface.cpp | 1. ExMem_Read(0x6100) 2. ExMem_Read_Bytes(0x6100,Rbuf,8) 3.ExMem_Write(0x6000,0x55); 4.ExMem_Write_Btyes(0x6000,Tbuf,8); |
1.读取单个数据,读取外部总线接口地址为0x6100的数据 2. 向外部总线起始地址为0x6100开始读取8个数据,存放于Rbuf中 3.向外部总线接口地址为0x6000写0x55数据 4.向外部总线写长度为8的数组数据 |
command.cpp | 1. Judgment(ZigBee_command) | 1. 检验校验和 |
Ultrasonic.cpp | 1.Ranging(cm); 2.Timing(); |
1. 设置测量距离的单位,1表示厘米,0表示英寸,返回测量距离 2.测量函数,返回测量的时间,超声波一个来回的时间 |
BH1750.cpp | 1. ReadLightLevel(); 2.Configure(mode=BH1750_CONTINUOUS_HIGH_RES_MODE) BH1750_CONTINUOUS_HIGH_RES_MODE_2 BH1750_CONTINUOUS_LOW_RES_MODE BH1750_ONE_TIME_HIGH_RES_MODE BH1750_ONE_TIME_HIGH_RES_MODE_2 BH1750_ONE_TIME_LOW_RES_MODE 3.ReadLightLevel(true/false) |
1. 读取传感器数据函数 ,设置等待测量时间:true或false,返回传感器测量值 2.配置传感器工作模式 3.读取传感器数据函数,设置等待测量时间:true或false,传感器测量值,返回传感器测量值 |
DCMotor.cop | 1.Initialization(8000) 2.Go(70); 3.Back(70) 4.TurnLeft(70) 5.TurnRight(70) 6.Stop(); 7.StarUp(); 8.ShutDown(); 9.RightMotorSpeed(70,0) 10.RightMotorFrequency(7000) 11.LeftMotorSpeed(70,50); 12.LeftMotorFrequency(7000); |
1.直流电机初始化 2.小车前进函数,前进速度70 3.小车后退函数,后退速度70 4.小车左转速度70 5.小车右转速度70 6.小车停止 7.小车启动函数 8.小车关闭函数 9.设置PWM波的占空比,频率保持最后一次设置值 通道A-----pin6,通道B-----pin7,设置通道 A 输出PWM波的占空比,设置通道 B 输出PWM波的占空比 10.置PWM波的频率,占空比保持最后一次设置值 通道A-----pin6,通道B-----pin7,设置通道 A/B 输出PWM波的频率,频率范围为245Hz~8MHz 11.设置PWM波的占空比,频率保持最后一次设置值 通道A-----pin46,通道B-----pin45,设置通道 A 输出PWM波的占空比,设置通道 B 输出PWM波的占空比 12.设置PWM波的频率,占空比保持最后一次设置值 通道A-----pin46,通道B-----pin45,设置通道 A/B 输出PWM波的频率 |
CoreBeep.cpp | 1.Initialization 2.TurnOn 3.TurnOff |
1.初始化函数 2.打开蜂鸣器 3.关闭蜂鸣器 |
CoreKEY.cpp | 1.Initialization 2.Check 3.Kwhile 4.Scan(); |
1.初始化函数 2.小车核心板按键检测函数,返回相应的键值 3.小车核心板按键执行 4.小车核心板按键扫描函数,true表示支持连按,false表示不支持 |
CoreLED.cpp | 1.Initialization 2.TurnOn(1); 3.TurnOff(1); 4.TurnOnOff(0x01) |
1.初始化 2.点亮核心板LED1/2/3/4 3.熄灭核心板LED1/2/3/4 4.同时控制4个LED,led1亮,led2、led3和led4灭 |
Infrare.cpp | 1.Transmition(uint8_t *s,int n) | 1.红外发送数据 |
LED.cpp | 1.RightTurnOn(); 2.RightTurnOFF(); 3.LeftTurnOn(); 4.LeftTurnOff(); |
1.打开右灯 2.关闭右灯 3.打开任务板左灯 4.关闭任务板左灯 |
SYN7318.cpp | 1.ResetCom(); 2.ResetCheck(); 3.ResetTest(); 4.QueryStatus(); 5.CommandSendCheck(); 6.CommandSendCheckBusy(); 7.oiceSynthesisPlayback(str,0);const char str[4] = { 0xB0,0xD9,0xC1,0xE9 };//百灵(GB2312编码) 8.VSPCom(str,0);const char str[4] = { 0xB0,0xD9,0xC1,0xE9 };//百灵(GB2312编码) 9.VSPTest(str,0); 10.CommandSendCheckACK(); 11.Start_ASR(0x00); 12.Start_ASR_return(0x04,true); 13.Start_ASR_send(4); 14.Start_ASR_rec(true); |
1.产生一次复位信号,使SYN7318复位一次 2.检测SYN7318模块复位回传命令, false:表示复位成功 3.SYN7318模块复位测试函数 4.检测SYN7318模块状态是否空闲 5.判断发送是否正确接收,true:表示命令接收成功 6.判断模块是否忙碌,false:表示模块空闲 7.语音合成播报函数,播报“百灵” 8.语音合成播报函数,播报“百灵 9. 语音合成播报综合测试函数 10.发送命令的回传检测函数,false:表示收到回传结果,识别回传标志更新 11.语音识别测试函数,识别0x00词典中的词条 12.语音识别返回测试结果,识别0x04词典中的词条,返回识别到的词条命令ID 13.开启语音识别,识别0x04词典中的词条 14.返回识别到的词条命令ID,语音识别返回测试结 |
注释 | SpeedCtr:1. SpeedCtr(int16_t L_speed, int16_t R_speed) | 1.给左轮、右轮的速度 |
arduion串口通信
串口使用在右上角:串口监视器(长得像放大镜)
Serial.begin(115200); //串口初始化 传输速率为115200bps
Serial.print('2'); //打印字符,也可以打印数字
从车与主车通信
发送指令给主车
1. 定义好结构体
将要用的命令封装好在结构体内,如果有需要,可添加变量和改变指令
// 定义数据结构体
typedef struct
{
uint8_t MainCar_send_order_open_barrier_Buff[8]; //发送给主车的命令【主车打开道闸】
uint8_t MainCar_send_order_qr_data_Buff[8]; //发送给主车的命令【发送二维码数据给主车】
uint8_t MainCar_send_order_out_garage_Buff[8]; //发送给主车的命令【主车出车库】
uint8_t MainCar_send_order_garage_rise_Buff[8]; //发送给主车的命令【主车控制车库上升】
uint8_t MainCar_send_order_RX_OK_Buff[8]; //收到主车的命令后回传OK
} DATA_TypeDef;
// 数据结构体初始化
DATA_TypeDef Data = {
.MainCar_send_order_open_barrier_Buff = { 0x55, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0xBB },
.MainCar_send_order_qr_data_Buff = { 0x55, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0xBB },
.MainCar_send_order_out_garage_Buff = { 0x55, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0xBB },
.MainCar_send_order_garage_rise_Buff = { 0x55, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0xBB },
.MainCar_send_order_RX_OK_Buff = { 0x55, 0x01, 0xAA, 0x00, 0x00, 0x00, 0x00, 0xBB }
};
其中0x55,0x01 是从车与主车的通信帧头
0x02 、0x03、0x04 ···都是与主车通信的信息,例如0x02,让主车打开道闸。
2.发送命令给主车函数
/*
发送8位命令给主车函数【0x55 0x01 0xXX 0x00 0x00 0x00 0x00 0xBB】
参数:命令数组
*/
void vMAIN_CAR_send_order(uint8_t *arr) {
Command.Judgment(arr); //一定要先计算校验和
ExtSRAMInterface.ExMem_Write_Bytes(MAIN_CAR_ADDR, arr, 8); //再向主车地址发送八位指令
}
已经封装好,直接调用
接收主车指令
1. 接收指令流程
第一个 if——(参考02协议) 先0x6100是否是Arduino 读取 ZigBee 数据地址的包头
第二、三个 if ——判断帧头:0x55,0x02(是发送给从车的,从车接收)
第4、5、6个 if ——同级判断
- 读取是0xA0 回复OK
- 0xA1 读取数组,将右边数组赋值到左边数组
- 0xA2 同上
因为一次接收不了太长的数据,所以可以分多次接收数据 例如:下面分为六组数组来接收
最后是常规清零
if (ExtSRAMInterface.ExMem_Read(0x6100) != 0x00) //从车接收ZigBee数据
{
ExtSRAMInterface.ExMem_Read_Bytes(ZigBee_command, 8); //向外部总线起始地址为0x6100开始读取8个数据,存放于中ZigBee_command中
memcpy(Zigbee_RX_Buff, ZigBee_command, sizeof(ZigBee_command));//memcpy:将com数组复制到RX数组 sizeof是数组大小
if ((0x55 == Zigbee_RX_Buff[0]) && (0xBB == Zigbee_RX_Buff[7])) //判断帧头帧尾
{
if (0x02 == Zigbee_RX_Buff[1]) //发送给自己的
{
if ((0xA0 == Zigbee_RX_Buff[2]) && Rx_MainCar_Flag) {
vMAIN_CAR_send_order(Data.MainCar_send_order_RX_OK_Buff); //回复ok
GoFlag = 1;
//memset((void*)(0x6100 + 8), 0, 80); //从0x6100+8开始,往后65528个字节清零
}
if (0xA1 == Zigbee_RX_Buff[2]) //接收主车发送前三位烽火台数据
{
rx_main_car_barrier[0] = Zigbee_RX_Buff[3];
rx_main_car_barrier[1] = Zigbee_RX_Buff[4];
rx_main_car_barrier[2] = Zigbee_RX_Buff[5];
vMAIN_CAR_send_order(Data.MainCar_send_order_RX_OK_Buff); //回复ok
}
if (0xA2 == Zigbee_RX_Buff[2]) //接收主车发送后三位烽火台数据
{
rx_main_car_barrier[3] = Zigbee_RX_Buff[3];
rx_main_car_barrier[4] = Zigbee_RX_Buff[4];
rx_main_car_barrier[5] = Zigbee_RX_Buff[5];
vMAIN_CAR_send_order(Data.MainCar_send_order_RX_OK_Buff); //回复ok
Serial.print('\n');
}
memset(Zigbee_RX_Buff, 0, sizeof(Zigbee_RX_Buff)); //清零
}
memset(ZigBee_command, 0, sizeof(ZigBee_command)); //清零
memset(Zigbee_RX_Buff, 0, sizeof(Zigbee_RX_Buff)); //清零
}
}
超声波测距
1.功能
/*
功 能:超声波测量距离,一个来回的时间
参 数:无
返 回 值:无
*/
void Ultrasonic_Dis_Time(void) {
uint8_t dis = 0;
uint8_t time_ = 0;
dis = Ultrasonic.Ranging(1); //超声波获取距离 1/cm , 0/英尺 // 1 381 ; 2 334
time_ = Ultrasonic.Timing(); //超声波来回的时间
Serial.print(dis, 1);
Serial.println(" cm"); //println 串口打印完后自动下一行
Serial.print(time_, 1);
Serial.println("ms");
return dis;
}
2. 将测量距离 通过红外 立体显示距离
功能函数 return 回一些值
将 a = 函数 赋值
然后将 a —> ID1 使用
/*距离信息显示模式*/
/*
--------------------------------------------------------------------------------
| 帧头第1位 | 帧头第2位 | 数据1 | 数据2 | 数据3 |数据4 |说明
|----------|-----------|------|----------|-----------------------------------
| 0xFF |0x11 | 距离十位| 距离个位| 0x00 | 0x00 |显示距离信息
| | |------|----------|-----------------------------------
--------------------------------------------------------------------------------
*/
void Infrare_3D(uint8_t ID1) {
Command.HW_3D[1] = 0x11;
Command.HW_3D[2] = ID1 / 10;
Command.HW_3D[3] = ID1 % 10;
Infrare.Transmition(Command.HW_3D, 6);
}
智能路灯
1.使用
通过识别路灯档位,设置到规定路灯档位
2.代码
光源档位增加一档
光源档位增加两档
光源档位增加三档
/*智能路灯标志物*/
/*
--------------------------------------------------------------------------------
| 帧头第1位 | 帧头第2位 | 数据1 | 数据反码 |说明
|----------|-----------|------|----------|-----------------------------------
| 0x00 |0xFF | 0x0C |0xF3 |光源挡位加1档
| | |------|----------|-----------------------------------
| | | 0x18 |0xE7 |光源挡位加2档
| | |------|----------|-----------------------------------
| | | 0x5E |0xA1 |光源挡位加3档
--------------------------------------------------------------------------------
智能路灯标志物*/
void Infrace_StreetLight(uint8_t ID) {
switch (ID) {
case 1: //+1
{
Command.HW_StreetLight[2] = 0x0C;
Command.HW_StreetLight[3] = 0xF3;
Infrare.Transmition(Command.HW_StreetLight, 4);
}
case 2:
{
Command.HW_StreetLight[2] = 0x18;
Command.HW_StreetLight[3] = 0xE7;
Infrare.Transmition(Command.HW_StreetLight, 4);
}
case 3:
{
Command.HW_StreetLight[2] = 0x5E;
Command.HW_StreetLight[3] = 0xA1;
Infrare.Transmition(Command.HW_StreetLight, 4);
}
}
}
冒泡排序使用:
读取值为:二档、三档、四档、一档
排序后为:一档、二档、三档、四档(从小排到大)
/*冒泡排序*/
void Yang_bubble_sort(uint16_t *arr, uint8_t len) {
uint8_t count = 1; //判断是否已经排序好
uint16_t i, j;
//一共要冒n-1次
for (i = 0; i < len - 1; i++) {
count = 0;
for (j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
uint16_t temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
count = 1;
}
}
if (count == 0) //如果已经是排好则不需要再执行后面直接退出
break;
}
}
/*
功能:根据光度判断当前档位再根据需要调到规定档位
参数---需要到达的档位(1~4)
*/
void StreetLight_Test(uint8_t num) {
uint16_t temp; //临时变量保存初始状态的光度
uint8_t i;
uint8_t Old_Gear, New_Gear = 0; //初始档位,最后档位
Command.Light_temp[0] = BH1750.ReadLightLevel(); //读取第一次光度值
temp = Command.Light_temp[0];
Infrace_StreetLight(1); //+1档
delay(500); //至少延时1s太短会接收不到
delay(500);
Command.Light_temp[1] = BH1750.ReadLightLevel(); //读取第二次光度值
Infrace_StreetLight(1); //+1档
delay(500);
delay(500);
Command.Light_temp[2] = BH1750.ReadLightLevel(); //读取第三次光度值
Infrace_StreetLight(1); //+1档
delay(500);
delay(500);
Command.Light_temp[3] = BH1750.ReadLightLevel(); //读取第四次光度值
Infrace_StreetLight(1); //+1档回到最初位置
Yang_bubble_sort(Command.Light_temp, 4); //冒泡排序从小到大
for (i = 0; i < 4; i++) //确认档位
{
if (Command.Light_temp[i] == temp) //如果相等
{
Old_Gear = i + 1; //最小档位是1最大是4
}
}
delay(500);
delay(500);
//设置到规定的档位 如果需要3档 当前在1档 则需要加二档
switch (num) {
case 1: //档位调到1档处
{
if (1 == Old_Gear) {
; //无需处理
} else if (2 == Old_Gear) {
Infrace_StreetLight(3); //+3档
New_Gear = 2;
} else if (3 == Old_Gear) {
Infrace_StreetLight(2); //+2档
} else if (4 == Old_Gear) {
Infrace_StreetLight(1); //+1档
}
New_Gear = 1;
break;
}
case 2: //档位调到2档处
{
if (1 == Old_Gear) {
Infrace_StreetLight(1); //+1档
} else if (2 == Old_Gear) {
; //无需处理
} else if (3 == Old_Gear) {
Infrace_StreetLight(3); //+3档
} else if (4 == Old_Gear) {
Infrace_StreetLight(2); //+2档
}
New_Gear = 2;
break;
}
case 3: //档位调到3档处
{
if (1 == Old_Gear) {
Infrace_StreetLight(2); //+2档
} else if (2 == Old_Gear) {
Infrace_StreetLight(1); //+1档
} else if (3 == Old_Gear) {
; //无需处理
} else if (4 == Old_Gear) {
Infrace_StreetLight(3); //+3档
}
New_Gear = 3;
break;
}
case 4: //档位调到4档处
{
if (1 == Old_Gear) {
Infrace_StreetLight(3); //+3档
} else if (2 == Old_Gear) {
Infrace_StreetLight(2); //+2档
} else if (3 == Old_Gear) {
Infrace_StreetLight(1); //+1档
} else if (4 == Old_Gear) {
; //无需处理
}
New_Gear = 4;
break;
}
default:
break;
}
}
/*
功 能:返回路灯当前挡位
参 数:无
返 回 值:路灯当前挡位 返回Old_Gear // 1 1档; 2 1档
*/
uint8_t StreetLight_gear(void) {
uint16_t temp; //临时变量保存初始状态的光度
uint8_t i;
uint8_t Old_Gear, New_Gear = 0; //初始档位,最后档位
Command.Light_temp[0] = BH1750.ReadLightLevel(); //读取第一次光度值
temp = Command.Light_temp[0];
Infrace_StreetLight(1); //+1档
delay(500); //至少延时1s太短会接收不到
delay(500);
Command.Light_temp[1] = BH1750.ReadLightLevel(); //读取第二次光度值
Infrace_StreetLight(1); //+1档
delay(500);
delay(500);
Command.Light_temp[2] = BH1750.ReadLightLevel(); //读取第三次光度值
Infrace_StreetLight(1); //+1档
delay(500);
delay(500);
Command.Light_temp[3] = BH1750.ReadLightLevel(); //读取第四次光度值
Infrace_StreetLight(1); //+1档回到最初位置
Yang_bubble_sort(Command.Light_temp, 4); //冒泡排序从小到大
for (i = 0; i < 4; i++) //确认档位
{
if (Command.Light_temp[i] == temp) //如果相等
{
Old_Gear = i + 1; //最小档位是1最大是4
return Old_Gear;
}
}
return 0;
}
使用,直接使用两个函数别管了
openMV 识别二维码
1.使用
识别——检测——接收,打印
识别二维码:arduion发送二维码数据给主车——主车读取出来发送给OpenMV,OpenMV识别二维码——O又通过串口把数据反馈给主车——
主车再将数据写入FPGA中——通过arduion在对应地址把数据读取出来
2. 驱动安装和烧录Python代码
官网:星瞳OpenMV
安卓充电线连接摄像头,软件打开U盘文件,连接+运行
[Python背景知识 · OpenMV中文入门教程]:入门
立体显示
立体显示车牌和坐标3d1和3d2直接用ASCLL码转十六进制表示
直接调用函数
语音播报
赛前准备工作
10.11日
焊接板子有所变化,有点位图和原理图——考虑打板
每周一焊接练习,期待新焊接设备能如虎添翼
程序对应library,先认清功能字符内容,现在至下周四练习立体显示和回顾小车运动
10.12日
01通信协议有增加,主从车通信协议无变化
10.14日
命令获取并执行
函数执行需要满足
- 写的时候传输指令要符合格式
- 校验和要能对比上
- 两个&& && 对应下标要对应相关内容主指令
Analyze_Handle( ZigBee_comand[X] ) 是由自己决定执行哪条主指令的内容
主指令一般设置Switch as分支结构选择哪个主指令
数据上传
取高八位和低八位操作
两个ZigBee中间的if——当[9] 里面的数据>= 0x80时,[9] 就执行0xff - [9 ] 的操作
二维码数据上传
Read函数——连续读取到Length的长度存到Data_OUABuf数组中
如果满足第二个if的条件,执行OpenMV函数
10.15日
编译上传代码之前先把小车四个开关都打开,串口波特率为115200 baud
10.18日
实现主从通信开启从车蜂鸣器
需要编写对应 主指令、副指令和校验码
第七字节是校验码
校验和 = (主指令+三个副指令)% 256
void loop()
{
if(Testflag==1) // loop 一圈下来Testflag == 判断值
{
Test();
Serial.print('2'); //发送字符
}
if (ExtSRAMInterface.ExMem_Read(0x6100) != 0x00) //调用了0x6100里面的数据,if意思为有没有收到命令格式为0x00的数据 从车接收ZigBee数据
{
ExtSRAMInterface.ExMem_Read_Bytes(ZigBee_command, 8); //向外部总线起始地址为0x6100开始读取8个字节数据,
/*是终端设备(主车)发送过来的数据,存放于中ZigBee_command中*/
memcpy(Zigbee_RX_Buff, ZigBee_command, sizeof(ZigBee_command));//sizeof()函数表示字符大小
if ((0x55 == Zigbee_RX_Buff[0]) && (0xBB == Zigbee_RX_Buff[7])) //判断帧头帧尾
{
if (0x02 == Zigbee_RX_Buff[1]) //发送给自己的
{
if ((0xA0 == Zigbee_RX_Buff[2]) && Rx_MainCar_Flag)
{
vMAIN_CAR_send_order(Data.MainCar_send_order_RX_OK_Buff); //回复ok
Testflag = 1;
}
}
}
}
}
/*
功 能:Test函数(通信test)
参 数:Testbuf
返 回 值:无
*/
void Test(void)
{
switch (Testbuf) {
case 1:
{
BEEP.TurnOn();
delay(1500);
break;
}
case 2:
{
BEEP.TurnOff();
Testbuf = 3;
break;
}
case 3:
{
//OpenMVQr_Disc_CloseUp();
break;
}
default:
break;
}
}
10.19日
单色最终例程
# Single Color RGB565 Blob Tracking Example
#
# This example shows off single color RGB565 tracking using the OpenMV Cam.
import sensor, image, time, math
threshold_index = 0 # 0 for red, 1 for green, 2 for blue
# Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
# The below thresholds track in general red/green/blue things. You may wish to tune them...
thresholds = [(30, 100, 15, 127, 15, 127), # generic_red_thresholds
(30, 100, -64, -8, -32, 32), # generic_green_thresholds
(0, 30, 0, 64, -128, 0)] # generic_blue_thresholds
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()
# Only blobs that with more pixels than "pixel_threshold" and more area than "area_threshold" are
# returned by "find_blobs" below. Change "pixels_threshold" and "area_threshold" if you change the
# camera resolution. "merge=True" merges all overlapping blobs in the image.
while(True):
clock.tick()
img = sensor.snapshot()
for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):
# These values depend on the blob not being circular - otherwise they will be shaky.
if blob.elongation() > 0.5:
img.draw_edges(blob.min_corners(), color=(255,0,0))
img.draw_line(blob.major_axis_line(), color=(0,255,0))
img.draw_line(blob.minor_axis_line(), color=(0,0,255))
# These values are stable all the time.
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
# Note - the blob rotation is unique to 0-180 only.
img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)
print(clock.fps())
10.28日
一直不敢碰的路灯,看代码这么长,又觉得自己看不懂,没想到 吧,直接用两个函数就好了。
现在缺乏逻辑的训练
要实现获取数据和传输正确数据,和处理回传信息
实现一个函数
/*
功 能:超声波返回数据并显示在立体显示
参 数:无
返 回 值:无
*/
void Ultrasonic_Dis_3D()
{
uint8_t dis = 0;
dis = Ultrasonic.Ranging(1);
Serial.print(dis, 1);
Serial.println(" cm");
b[2] = dis; // 接收两位
Serial.println(b[2]);
delay(250);
Infrare_3D3(b[2]);
}
11.02日
设传输红绿灯数据数组
11.07日
电路板巨多电阻电容,真的要疯掉了
12.13日
新车使用改变
底层驱动有所不同
摄像头软件,文件内容不同
注意事项
Command.h中要添加一些代码
12.14日
在 Arduino 开发中,同一个目录下的两个 .ino 文件彼此之间是平行关系。当你在 Arduino IDE 中打开多个 .ino 文件时,它们都可以被视为同一个项目的一部分。这意味着它们可以互相引用,并且在编译时会被合并为一个程序。对于 Arduino 开发中的 .ino 文件,#include
指令可以用来引入其他文件的内容,包括其他 .ino 文件。但是在 Arduino IDE 中,实际上不需要使用 #include "helper.ino"
来引入其他 .ino 文件。
同一个窗口下的项目可以相互联用。
12.19日
比赛1.20日——1.21日噩耗 直接一个月备赛,期末考五一、模电确实有点困难
12.21日
开干!
小车运动:90度转弯还需要调试,四十五度良好
省赛练习1
从车路径——省练习题
D7——D6(二维码)——D4(交通灯)——D2(3d显示)——F2——F4——F6(选择入库点)——入库
运动路径:
- 寻迹+过寻迹线——右转45——识别二维码——左转45
- 寻迹+过寻迹线——舵机上扬30——识别交通灯(识别发送结果验证)——舵机回正
- 寻迹+过寻迹线——左转45——3D显示——右转45——右转90——寻迹+过寻迹线——右转90
- 3D交互信息显示
- 寻迹+过寻迹线——寻迹+过寻迹线(到达F6)
- 处理二维码结果 (最后的case里面三个if对应倒数三个case)
-
- D7:右转90——寻迹+过寻迹线——右转90——倒车入库
- F7:右转90——右转90——倒车入库
- G6:右转90——倒车入库
摄像头
烧录
- Kflash软件先擦除旧固件,重新烧录新的 .bin 文件,拔线、关闭软件
- 打开烧录软件——工具——发送保存boot文件
模型代码
- 模型需要u盘存储运行文件
- 改模型——改两处:99437、头三样
- 调节曝光:代码exposure 值越大曝光越高、gain_db 往下调成1或0
- 摄像头程序执行完需要跳出自动函数,
定时器函数里面delay无效