1、概述
由于课题要求,需要设计一款适合于果园应用的激光雷达。因此采用单线扫描激光雷达和角度传感器来设计能采集二维数据的激光雷达。关于数据的转化的理论,我们可以查阅相关文献。在此,只讲基本的构造和程序。
2、整体外形设计
此图为设计图:硬件包括单点激光模块,无线电源模块,HC-05模块,降压模块,步进电机及驱动器,控制器arduino Mage2560(可以换其他控制器),usb数据传出模块。
下图为实际图片:
因为还未封装,走线布局可能有些乱,最后应该是这样:
因为果园路面不平,后期还要考虑怎么固定传感器。
3、软硬件调试流程
1)首先、熟悉各个硬件的基本性能和基本操作;
2)其次、各个模块调试,我首先将激光模块调试好,其次是步进电机及驱动的简单调试,然后将角度传感器模块调好,再将蓝牙模块调试好,再旋转编码器调试好。
3)然后、将硬件模块关系紧密的两两联合调试,再到三个模块,到四个模块等;
4)再然后、将硬件组合在一起,整体调试及测试;
5)最后、优化各个模块,再测试以及优化外观设计。
4、程序部分
因为代码有注释,就不再多讲,直接上代码吧。(无语,还是再说一句)但是此代码还有很多不足,需要后期的优化设计,这仅仅是为了测试而编写的。
/*以下为步进电机连接引脚
* dir -->d2
* en --> d5
* stp -->d6
* com -->5v
* V --> 12v
* GND-->GND
*/
#define dir_pin 2
#define en_pin 5
#define stp_pin 6
//激光雷达的相关变量机常量
float range = 0;//目标距离
unsigned char uart[8]={0},counter = 0;//存放雷达测量的数据
unsigned char data[3]={0};
unsigned char sign=0;
const unsigned char HEADER=0x55;//数据包帧头
const unsigned char END=0xAA;//终止序列
//将接收的数据整合到一个结构体中,使其存储到一个连续的内存中,较为高效
struct Target_Bits
{
unsigned char Target_header:8; /* 0:7 */
unsigned char Target_key:8; /* 8:15 */
unsigned char Target_value:8; /* 16:23 */
unsigned char Target_data1:8; /* 24:31 */
unsigned char Target_data2:8; /* 32:39 */
unsigned char Target_data3:8; /* 40:47 */
unsigned char Target_CRC:8; /* 48:55 */
unsigned char Target_end:8; /* 56:63 */
};
//联合表示几个变量公用一个内存位置, 在不同的时间保存不同的数据类型和不同长度的变量
typedef union{
unsigned char Byte[8];
struct Target_Bits bit;
}TargetData;
void setup()
{
Serial.begin(9600);//设置arduino与电脑连接串口的波特率
Serial1.begin(9600);//设置雷达与arduino连接串口的波特率
//set timer4
TCCR4A = 0;
TCCR4B = 0;
TCNT4 = 0;
// Mode 10: phase correct PWM with ICR4 as Top (= F_CPU/2/25000)
// OC4A OC4B OC4C as Non-Inverted PWM output
ICR4 = (F_CPU/2000)/2;
TCCR4A =_BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1) | _BV(WGM41);
TCCR4B = _BV(WGM43) | _BV(CS40);
// Set the PWM pin as output.
pinMode(6, OUTPUT);
pinMode(2,OUTPUT);
}
void loop()
{
//just set this for step motor
Pwm_out(6,1000);
digitalWrite(2,HIGH);
//for(;;); //infinite loop
if(sign)
{
sign=0;
if(uart[1]==0x07)
{
TargetData TargetData;
for (uint8_t i = 0; i < 8; i++)
{
TargetData.Byte[i] = uart[i]; // Buf指向有效数据起始
// Serial.print(TargetData.Byte[i]);
// Serial.print("\n");
}
for(int j =0;j<3;++j)
{
data[j]=TargetData.Byte[j+3];
}
range=readCharToLL(data,3);
Serial.print(range);
Serial.print("\n");
}
}
}
//激光数据采集
void serialEvent1() {
while (Serial1.available()) {
uart[counter]=(unsigned char)Serial1.read();
if(counter==0&&uart[0]!=HEADER) return; //第0号数据不是帧头
counter++;
if(counter==8) //接收到8个数据
{
counter=0; //重新赋值,准备下一帧数据的接收
sign=1;
}
}
}
/**
* 将unsigned char数组转换成long long数值
* @param str 数组
* @param len str数组长度
* @returns 0 on error
*/
int readCharToLL(unsigned char* str, int len)
{
if (str == NULL||len <= 0) //指针的判断
{
return 0;
}
int i = 0;
int value = 0;
for (i=0;i<len;i++)
{
value = value*16*16 + (str[i]/16)*16 + str[i]%16;
}
return value;
}
//motor driver
void Pwm_out(int pin ,int value)
{
switch(pin){
case 5:
OCR3A = value;
break;
case 6:
OCR4A = value;
break;
case 7:
OCR4B = value;
break;
case 8:
OCR4C = value;
break;
default:
//no other pin will work
break;
}
}
这也只是蓝牙,激光,电机的测试代码,角度传感器和旋转编码器的还需后期加上。
5、初步展示
可以这个视频
6、问题总结
1)激光雷达的初始化比较长,有时也不知为什么突然采集不到数据(还待解决)
2)蓝牙模块的传输速率应该还需设置高些
3)无线电源模块的底板很容易破裂
4)arduino Mage2560 Pro的供电有点问题