前言:用arduino 和舵机和激光测距搓的,具体实现明天再写,好困啊\
Part1 什么是激光雷达
雷达很好理解(这里不讨论相控阵那种怪物),想象成旋转的测距仪。用电磁波发射与返回的时间差测得距离,而波长变化的测量甚至可以使用开普勒效应来得知被测物体的速度。
而我们因为没有能够在实验室这么小范围内还能正常定向发射的电磁波原(有也买不起,买得起也会被抓去谈话)所以退而求其次使用了激光测距的方法,原理与电磁波一模一样,都是电磁波嘛(笑。但是测量速度的功能就给砍了。
Part2 搓一个
那么对于角度的感知本来想用步进电机的,但是考虑到丢步的问题,还得用霍尔或者别的啥方法来校准,实在不太优雅,所以选择了舵机作为旋转的底座。
理论存在,实践可行,返回的数据包括角度与距离,那么只需要可视化这两个数据就可以啦,显示我们使用了一块oled的小屏幕,基本所有的东西都是自己以前做过的,所以非常好写。
#include <Wire.h>
#include <Servo.h>
#include <SparkFun_VL6180X.h>
#include <U8g2lib.h>
#include <stdlib.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
/*const float GAIN_1 = 1.01; // Actual ALS Gain of 1.01
const float GAIN_1_25 = 1.28; // Actual ALS Gain of 1.28
const float GAIN_1_67 = 1.72; // Actual ALS Gain of 1.72
const float GAIN_2_5 = 2.6; // Actual ALS Gain of 2.60
const float GAIN_5 = 5.21; // Actual ALS Gain of 5.21
const float GAIN_10 = 10.32; // Actual ALS Gain of 10.32
const float GAIN_20 = 20; // Actual ALS Gain of 20
const float GAIN_40 = 40; // Actual ALS Gain of 40
*/
#define VL6180X_ADDRESS 0x29
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0,SCL,SDA,U8X8_PIN_NONE);
VL6180xIdentification identification;
VL6180x sensor(VL6180X_ADDRESS);
Servo servo_one;
int distance = 0;
char string[16] = {0};
int digre = 0;
int flag = 1;//1 means positive
int point_x;
int point_y;
float mid;
int digg;
void setup()
{
u8g2.begin();
servo_one.attach(3);
Serial.begin(115200); // Start Serial at 115200bps
Wire.begin(); // Start I2C library
delay(100); // delay .1s
sensor.getIdentification(&identification); // Retrieve manufacture info from device memory
printIdentification(&identification); // Helper function to print all the Module information
if (sensor.VL6180xInit() != 0)
{
Serial.println("Failed to initialize. Freezing..."); // Initialize device and check for errors
while (1)
;
}
sensor.VL6180xDefautSettings(); // Load default settings to get started.
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.disableUTF8Print();
delay(1000); // delay 1s
}
void loop()
{
if(digre<180 && flag == 1){
digre = digre + 1;
}
else if(digre >= 180){
digre = digre -1;
flag = 0;
u8g2.clearDisplay();
}
else if(digre > 0 && flag ==0){
digre = digre - 1;
}
else if(digre <=0){
digre = digre + 1;
flag = 1;
u8g2.clearDisplay();
}
//servo_one.write(90);
// Get Ambient Light level and report in LUX
//Serial.print("Ambient Light Level (Lux) = ");
// Input GAIN for light levels,
// GAIN_20 // Actual ALS Gain of 20
// GAIN_10 // Actual ALS Gain of 10.32
// GAIN_5 // Actual ALS Gain of 5.21
// GAIN_2_5 // Actual ALS Gain of 2.60
// GAIN_1_67 // Actual ALS Gain of 1.72
// GAIN_1_25 // Actual ALS Gain of 1.28
// GAIN_1 // Actual ALS Gain of 1.01
// GAIN_40 // Actual ALS Gain of 40
//Serial.println(sensor.getAmbientLight(GAIN_1));
// Get Distance and report in mm
Serial.print("Distance measured (mm) = ");
distance = sensor.getDistance();
Serial.println(distance);
if(distance >= 180){
distance = 180;
}
digg = digre + 90;
if(digg > 180){
digg = digg - 180;
}
mid = sin(digg*(3.1415/180));
Serial.print(mid);
point_x = mid*(distance*64/180);
mid = abs(cos(digg*(3.1415/180)));
point_y = mid*(distance*64/180);
//Serial.print(digre);
// Serial.print(point_x);
if(digre>=90){
point_x = 64 + point_x;
}
else if(digre < 90){
point_x = 64 - point_x;
}
point_y =64 - point_y;
servo_one.write(digre);
//u8g2.clearDisplay();
//u8g2.clearBuffer(); //清除缓存
//u8g2.setCursor(0, 40);
//u8g2.print("qqq");
u8g2.drawCircle(64,64,64, U8G2_DRAW_ALL);
u8g2.drawPixel(point_x,point_y);
u8g2.sendBuffer();
//delay(1000);
};
void printIdentification(struct VL6180xIdentification *temp)
{
Serial.print("Model ID = ");
Serial.println(temp->idModel);
Serial.print("Model Rev = ");
Serial.print(temp->idModelRevMajor);
Serial.print(".");
Serial.println(temp->idModelRevMinor);
Serial.print("Module Rev = ");
Serial.print(temp->idModuleRevMajor);
Serial.print(".");
Serial.println(temp->idModuleRevMinor);
Serial.print("Manufacture Date = ");
Serial.print((temp->idDate >> 3) & 0x001F);
Serial.print("/");
Serial.print((temp->idDate >> 8) & 0x000F);
Serial.print("/1");
Serial.print((temp->idDate >> 12) & 0x000F);
Serial.print(" Phase: ");
Serial.println(temp->idDate & 0x0007);
Serial.print("Manufacture Time (s)= ");
Serial.println(temp->idTime * 2);
Serial.println();
Serial.println();
}