B学习

添加库文件

需要确保你的Arduino IDE中已经安装了TimerOne库。具体可参考以下步骤:

  1. 打开Arduino IDE软件;
  2. 点击“工具”(Tools)菜单栏,然后点击“管理库”(Manage Libraries)选项;
  3. 在弹出的对话框中,在搜索框中输入“TimerOne”,然后进行搜索;
  4. 安装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. 降低寻迹速度可以提高寻迹精确度
  2. 冲特殊地形之前也要降速,避免碰到障碍

倒车入库寻迹

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日

命令获取并执行

函数执行需要满足

  1. 写的时候传输指令要符合格式
  2. 校验和要能对比上
  3. 两个&& && 对应下标要对应相关内容主指令

Analyze_Handle( ZigBee_comand[X] ) 是由自己决定执行哪条主指令的内容

主指令一般设置Switch as分支结构选择哪个主指令

数据上传

取高八位和低八位操作

两个ZigBee中间的if——当[9] 里面的数据>= 0x80时,[9] 就执行0xff - [9 ] 的操作

二维码数据上传

读取数据,向主车发送OpenMV识别结果

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)
    1. D7:右转90——寻迹+过寻迹线——右转90——倒车入库
    2. F7:右转90——右转90——倒车入库
    3. G6:右转90——倒车入库

摄像头

烧录
  • Kflash软件先擦除旧固件,重新烧录新的 .bin 文件,拔线、关闭软件
  • 打开烧录软件——工具——发送保存boot文件
模型代码
  • 模型需要u盘存储运行文件
  • 改模型——改两处:99437、头三样
  • 调节曝光:代码exposure 值越大曝光越高、gain_db 往下调成1或0
  • 摄像头程序执行完需要跳出自动函数,

定时器函数里面delay无效