main
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
37
include/README
Normal file
37
include/README
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the convention is to give header files names that end with `.h'.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||
46
lib/README
Normal file
46
lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into the executable file.
|
||||
|
||||
The source code of each library should be placed in a separate directory
|
||||
("lib/your_library_name/[Code]").
|
||||
|
||||
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
Example contents of `src/main.c` using Foo and Bar:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries by scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
26
platformio.ini
Normal file
26
platformio.ini
Normal file
@ -0,0 +1,26 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:nucleo_l476rg]
|
||||
platform = ststm32
|
||||
board = nucleo_l476rg
|
||||
|
||||
; change microcontroller
|
||||
board_build.mcu = stm32l476rgt6
|
||||
|
||||
; change MCU frequency
|
||||
board_build.f_cpu = 80000000L
|
||||
|
||||
upload_protocol = stlink
|
||||
|
||||
lib_deps = mikalhart/TinyGPSPlus@^1.1.0
|
||||
|
||||
framework = arduino
|
||||
|
||||
237
src/STP-23L.c
Normal file
237
src/STP-23L.c
Normal file
@ -0,0 +1,237 @@
|
||||
#include "STP-23L.h"
|
||||
#include <Arduino.h>
|
||||
#include <stdio.h>
|
||||
|
||||
LidarPointTypedef Pack_Data[12]; /* 雷达接收的数据储存在这个变量之中 */
|
||||
LidarPointTypedef Pack_sum; /* 输出结果储存 */
|
||||
|
||||
extern uint16_t receive_cnt;
|
||||
extern uint8_t confidence;
|
||||
extern uint16_t distance,noise,reftof;
|
||||
extern uint32_t peak,intg;
|
||||
|
||||
void parseData(uint8_t temp_data) {
|
||||
static uint8_t state = 0; // 状态位
|
||||
static uint8_t crc = 0; // 校验和
|
||||
static uint8_t cnt = 0; // 用于一帧12个点的计数
|
||||
static uint8_t PACK_FLAG = 0; // 命令标志位
|
||||
static uint8_t data_len = 0; // 数据长度
|
||||
static uint32_t timestamp = 0; // 时间戳
|
||||
static uint8_t state_flag = 1; // 转入数据接收标志位
|
||||
|
||||
if(state < 4) { // 起始符验证 前4个数据均为0xAA
|
||||
if(temp_data == HEADER) state++;
|
||||
else state = 0;
|
||||
}
|
||||
else if(state < 10 && state > 3) {
|
||||
switch(state) {
|
||||
case 4:
|
||||
if(temp_data == device_address) { // 设备地址验证
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else state = 0, crc = 0;
|
||||
case 5:
|
||||
if(temp_data == PACK_GET_DISTANCE) { // 获取测量数据命令
|
||||
PACK_FLAG = PACK_GET_DISTANCE;
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else if(temp_data == PACK_RESET_SYSTEM) { // 复位命令
|
||||
PACK_FLAG = PACK_RESET_SYSTEM;
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else if(temp_data == PACK_STOP) { // 停止测量数据传输命令
|
||||
PACK_FLAG = PACK_STOP;
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else if(temp_data == PACK_ACK) { // 应答码命令
|
||||
PACK_FLAG = PACK_ACK;
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else if(temp_data == PACK_VERSION) { // 获取传感器信息命令
|
||||
PACK_FLAG = PACK_VERSION;
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else state = 0, crc = 0;
|
||||
case 6:
|
||||
if(temp_data == chunk_offset) { // 偏移地址
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else state = 0, crc = 0;
|
||||
case 7:
|
||||
if(temp_data == chunk_offset) {
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
}
|
||||
else state = 0, crc = 0;
|
||||
case 8:
|
||||
data_len = (uint16_t)temp_data; // 数据长度低八位
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
case 9:
|
||||
data_len = data_len + ((uint16_t)temp_data << 8); // 数据长度高八位
|
||||
state++;
|
||||
crc += temp_data;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if(state == 10) state_flag = 0; // 由switch跳出来时state为10,但temp_data仍为距离长度高八位数据,需跳过一次中断
|
||||
|
||||
if(PACK_FLAG == PACK_GET_DISTANCE && state_flag == 0) { // 获取一帧数据并校验
|
||||
if(state > 9) {
|
||||
if(state < 190) {
|
||||
static uint8_t state_num;
|
||||
state_num = (state - 10) % 15;
|
||||
switch(state_num) {
|
||||
case 0:
|
||||
Pack_Data[cnt].distance = (uint16_t)temp_data; // 距离数据低八位
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 1:
|
||||
Pack_Data[cnt].distance = ((uint16_t)temp_data << 8) + Pack_Data[cnt].distance; // 距离数据
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 2:
|
||||
Pack_Data[cnt].noise = (uint16_t)temp_data; // 环境噪音低八位
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 3:
|
||||
Pack_Data[cnt].noise = ((uint16_t)temp_data << 8) + Pack_Data[cnt].noise; // 环境噪音
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 4:
|
||||
Pack_Data[cnt].peak = (uint32_t)temp_data; // 接受强度信息低八位
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 5:
|
||||
Pack_Data[cnt].peak = ((uint32_t)temp_data << 8) + Pack_Data[cnt].peak;
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 6:
|
||||
Pack_Data[cnt].peak = ((uint32_t)temp_data << 16) + Pack_Data[cnt].peak;
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 7:
|
||||
Pack_Data[cnt].peak = ((uint32_t)temp_data << 24) + Pack_Data[cnt].peak; // 接受强度信息
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 8:
|
||||
Pack_Data[cnt].confidence = temp_data; // 置信度
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 9:
|
||||
Pack_Data[cnt].intg = (uint32_t)temp_data; // 积分次数低八位
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 10:
|
||||
Pack_Data[cnt].intg = ((uint32_t)temp_data << 8) + Pack_Data[cnt].intg;
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 11:
|
||||
Pack_Data[cnt].intg = ((uint32_t)temp_data << 16) + Pack_Data[cnt].intg;
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 12:
|
||||
Pack_Data[cnt].intg = ((uint32_t)temp_data << 24) + Pack_Data[cnt].intg; // 积分次数
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 13:
|
||||
Pack_Data[cnt].reftof = (int16_t)temp_data; // 温度表征值低八位
|
||||
crc += temp_data;
|
||||
state++;
|
||||
break;
|
||||
case 14:
|
||||
Pack_Data[cnt].reftof = ((int16_t)temp_data << 8) + Pack_Data[cnt].reftof; // 温度表征值
|
||||
crc += temp_data;
|
||||
state++;
|
||||
cnt++; // 进入下一个测量点
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// 时间戳
|
||||
if(state == 191) timestamp = temp_data, state++, crc += temp_data;
|
||||
else if(state == 192) timestamp = ((uint32_t)temp_data << 8) + timestamp, state++, crc += temp_data;
|
||||
else if(state == 193) timestamp = ((uint32_t)temp_data << 16) + timestamp, state++, crc += temp_data;
|
||||
else if(state == 194) timestamp = ((uint32_t)temp_data << 24) + timestamp, state++, crc += temp_data;
|
||||
else if(state == 195) {
|
||||
if(temp_data == crc) { // 校验成功
|
||||
data_process(); // 数据处理函数,完成一帧之后可进行数据处理
|
||||
receive_cnt++; // 输出接收到正确数据的次数
|
||||
}
|
||||
distance = Pack_Data[0].distance;
|
||||
crc = 0;
|
||||
state = 0;
|
||||
state_flag = 1;
|
||||
cnt = 0; // 复位
|
||||
}
|
||||
if(state == 190) state++; // state等于190的数据实际是第12个测距点的最后一位数据,数据已经取走使用
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void data_process(void) {
|
||||
static uint8_t cnt = 0;
|
||||
uint8_t i;
|
||||
static uint16_t count = 0;
|
||||
static uint32_t sum = 0;
|
||||
LidarPointTypedef Pack_sum;
|
||||
|
||||
for(i = 0; i < 12; i++) { // 12个点取平均
|
||||
if(Pack_Data[i].distance != 0) { // 去除0的点
|
||||
count++;
|
||||
Pack_sum.distance += Pack_Data[i].distance;
|
||||
Pack_sum.noise += Pack_Data[i].noise;
|
||||
Pack_sum.peak += Pack_Data[i].peak;
|
||||
Pack_sum.confidence += Pack_Data[i].confidence;
|
||||
Pack_sum.intg += Pack_Data[i].intg;
|
||||
Pack_sum.reftof += Pack_Data[i].reftof;
|
||||
}
|
||||
}
|
||||
|
||||
if(count != 0) {
|
||||
distance = Pack_sum.distance / count;
|
||||
noise = Pack_sum.noise / count;
|
||||
peak = Pack_sum.peak / count;
|
||||
confidence = Pack_sum.confidence / count;
|
||||
intg = Pack_sum.intg / count;
|
||||
reftof = Pack_sum.reftof / count;
|
||||
Pack_sum.distance = 0;
|
||||
Pack_sum.noise = 0;
|
||||
Pack_sum.peak = 0;
|
||||
Pack_sum.confidence = 0;
|
||||
Pack_sum.intg = 0;
|
||||
Pack_sum.reftof = 0;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
43
src/STP-23L.h
Normal file
43
src/STP-23L.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __STP23L_H
|
||||
#define __STP23L_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 如果是 C++ 编译器,使用 extern "C"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define HEADER 0xAA /* 起始符 */
|
||||
#define device_address 0x00 /* 设备地址 */
|
||||
#define chunk_offset 0x00 /* 偏移地址命令 */
|
||||
#define PACK_GET_DISTANCE 0x02 /* 获取测量数据命令 */
|
||||
#define PACK_RESET_SYSTEM 0x0D /* 复位命令 */
|
||||
#define PACK_STOP 0x0F /* 停止测量数据传输命令 */
|
||||
#define PACK_ACK 0x10 /* 应答码命令 */
|
||||
#define PACK_VERSION 0x14 /* 获取传感器信息命令 */
|
||||
|
||||
typedef struct {
|
||||
int16_t distance; /* 距离数据:测量目标距离单位 mm */
|
||||
uint16_t noise; /* 环境噪声:当前测量环境下的外部环境噪声,越大说明噪声越大 */
|
||||
uint32_t peak; /* 接收强度信息:测量目标反射回的光强度 */
|
||||
uint8_t confidence; /* 置信度:由环境噪声和接收强度信息融合后的测量点的可信度 */
|
||||
uint32_t intg; /* 积分次数:当前传感器测量的积分次数 */
|
||||
int16_t reftof; /* 温度表征值:测量芯片内部温度变化表征值,只是一个温度变化量无法与真实温度对应 */
|
||||
} LidarPointTypedef;
|
||||
|
||||
extern uint16_t receive_cnt;
|
||||
extern uint8_t confidence;
|
||||
extern uint16_t distance, noise, reftof;
|
||||
extern uint32_t peak, intg;
|
||||
extern LidarPointTypedef Pack_sum;
|
||||
|
||||
void parseData(uint8_t temp_data);
|
||||
void data_process(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STP_23L_H */
|
||||
116
src/i2c_communication.cpp
Normal file
116
src/i2c_communication.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
#include "i2c_communication.h"
|
||||
#include <TinyGPS++.h>
|
||||
#include "main.h"
|
||||
|
||||
extern uint16_t receive_cnt;
|
||||
|
||||
extern TinyGPSPlus gps;
|
||||
extern uint16_t distance;
|
||||
// 缓冲区用于发送结构体数据
|
||||
uint8_t i2c_tx_buffer[sizeof(hh3_slave_data)];
|
||||
|
||||
// 初始化 I2C 从机
|
||||
void init_i2c_slave() {
|
||||
Wire.setSDA(I2C_SDA_PIN);
|
||||
Wire.setSCL(I2C_SCL_PIN);
|
||||
//Wire.Pins(16,17);
|
||||
Wire.begin(SLAVE_ADDRESS); // 设置从机地址为 0x55
|
||||
Wire.onRequest(onRequestEvent); // 注册请求回调 ***改用主机命令0x01
|
||||
Wire.onReceive(onReceiveEvent); // 注册接收回调
|
||||
}
|
||||
|
||||
// 当主机请求数据时调用
|
||||
void onRequestEvent() {
|
||||
update_sensor_data(); // 确保数据是最新的
|
||||
memcpy(i2c_tx_buffer, &sensor_data, sizeof(sensor_data));
|
||||
Wire.write(i2c_tx_buffer, sizeof(sensor_data));
|
||||
}
|
||||
|
||||
void power_init(){
|
||||
pinMode(RANGING_POWER_PIN, OUTPUT);
|
||||
pinMode(GPS_POWER_PIN, OUTPUT);
|
||||
}
|
||||
|
||||
// 当主机发送命令时调用
|
||||
void onReceiveEvent(int bytes) {
|
||||
while (Wire.available()) {
|
||||
uint8_t cmd = Wire.read();
|
||||
switch (cmd) {
|
||||
case CMD_GPS_POWER_OFF:
|
||||
turn_off_gps();
|
||||
break;
|
||||
case CMD_RANGING_POWER_OFF:
|
||||
turn_off_ranging();
|
||||
break;
|
||||
case CMD_GPS_POWER_ON:
|
||||
turn_on_gps();
|
||||
break;
|
||||
case CMD_RANGING_POWER_ON:
|
||||
turn_on_ranging();
|
||||
break;
|
||||
case CMD_MASTER_GET_SLAVE_DATA:
|
||||
onRequestEvent(); // 主动调用一次数据发送
|
||||
break;
|
||||
default:
|
||||
Serial.printf("Unknown command received: 0x%02X\n", cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新传感器状态和数据
|
||||
static uint8_t last_receive_cnt = 0;
|
||||
void update_sensor_data() {
|
||||
//gps
|
||||
if (millis() > 5000 && gps.charsProcessed() < 10 && digitalRead(GPS_POWER_PIN) == HIGH) {
|
||||
sensor_data.gps_sta = 0x00; // 无设备
|
||||
sensor_data.gps_lat = 0.0f;
|
||||
sensor_data.gps_lon = 0.0f;
|
||||
} else if (digitalRead(GPS_POWER_PIN) == LOW){
|
||||
sensor_data.gps_sta = 0x01; // 关机
|
||||
sensor_data.gps_lat = 0.0f;
|
||||
sensor_data.gps_lon = 0.0f;
|
||||
}else if (!gps.location.isUpdated()) {
|
||||
sensor_data.gps_sta = 0x02; // 未搜到信号
|
||||
sensor_data.gps_lat = 0.0f;
|
||||
sensor_data.gps_lon = 0.0f;
|
||||
} else {
|
||||
sensor_data.gps_sta = 0x03; // 正常工作
|
||||
sensor_data.gps_lat = gps.location.lat();
|
||||
sensor_data.gps_lon = gps.location.lng();
|
||||
}
|
||||
|
||||
//测距
|
||||
if (receive_cnt == last_receive_cnt && digitalRead(RANGING_POWER_PIN) == HIGH) {
|
||||
sensor_data.height_sta = 0x00; // 无设备
|
||||
sensor_data.height = 0.0f;
|
||||
}else if (digitalRead(RANGING_POWER_PIN) == LOW){
|
||||
sensor_data.height_sta = 0x01; // 关机
|
||||
sensor_data.height = 0.0f;
|
||||
}else {
|
||||
last_receive_cnt = receive_cnt;
|
||||
sensor_data.height_sta = 0x02; // 有效高度
|
||||
sensor_data.height = (float)distance / 1000.0f; // mm -> m
|
||||
}
|
||||
}
|
||||
|
||||
// 电源控制
|
||||
void turn_off_gps() {
|
||||
digitalWrite(GPS_POWER_PIN, LOW);
|
||||
//Serial.println("Turning OFF GPS Power");
|
||||
}
|
||||
|
||||
void turn_on_gps() {
|
||||
digitalWrite(GPS_POWER_PIN, HIGH);
|
||||
//Serial.println("Turning ON GPS Power");
|
||||
}
|
||||
|
||||
void turn_off_ranging() {
|
||||
digitalWrite(RANGING_POWER_PIN, LOW);
|
||||
//Serial.println("Turning OFF Ranging Module");
|
||||
}
|
||||
|
||||
void turn_on_ranging() {
|
||||
digitalWrite(RANGING_POWER_PIN, HIGH);
|
||||
//Serial.println("Turning ON Ranging Module");
|
||||
}
|
||||
36
src/i2c_communication.h
Normal file
36
src/i2c_communication.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// 命令定义
|
||||
#define CMD_MASTER_GET_SLAVE_DATA 0x01
|
||||
#define CMD_GPS_POWER_OFF 0x02
|
||||
#define CMD_RANGING_POWER_OFF 0x03
|
||||
#define CMD_GPS_POWER_ON 0x04
|
||||
#define CMD_RANGING_POWER_ON 0x05
|
||||
|
||||
// 数据结构定义
|
||||
typedef struct {
|
||||
uint8_t gps_sta; // 0x00 ~ 0x03
|
||||
uint8_t height_sta; // 0x00 ~ 0x01
|
||||
float gps_lat;
|
||||
float gps_lon;
|
||||
float height;
|
||||
} hh3_slave_data;
|
||||
|
||||
extern hh3_slave_data sensor_data;
|
||||
|
||||
// 函数声明
|
||||
void power_init();
|
||||
void update_sensor_data();
|
||||
void turn_off_gps();
|
||||
void turn_on_gps();
|
||||
void turn_off_ranging();
|
||||
void turn_on_ranging();
|
||||
|
||||
// I²C 从机接口
|
||||
void init_i2c_slave();
|
||||
void onRequestEvent();
|
||||
void onReceiveEvent(int bytes);
|
||||
148
src/main.cpp
Normal file
148
src/main.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "main.h"
|
||||
|
||||
|
||||
HardwareSerial rangingSerial(RANGING_RX_PIN, RANGING_TX_PIN);
|
||||
HardwareSerial gpsSerial(GPS_RX_PIN, GPS_TX_PIN);
|
||||
HardwareSerial printSerial(PRINT_RX_PIN,PRINT_TX_PIN);
|
||||
|
||||
TinyGPSPlus gps;
|
||||
|
||||
|
||||
// 全局变量
|
||||
uint16_t receive_cnt = 0; // 计算成功接收数据帧次数
|
||||
uint8_t confidence = 0;
|
||||
uint16_t distance = 0, noise = 0, reftof = 0;
|
||||
uint32_t peak = 0, intg = 0;
|
||||
extern LidarPointTypedef Pack_sum; // 输出结果储存
|
||||
|
||||
|
||||
// 实例化共享数据结构体
|
||||
hh3_slave_data sensor_data = {0};
|
||||
|
||||
|
||||
// //每当主机请求数据时,该函数便会执行
|
||||
// //在setup()中,该函数被注册为一个事件
|
||||
// void requestEvent() {
|
||||
// Wire.write("hello "); // 用6B的信息回应主机的请求,hello后带一个空格
|
||||
// }
|
||||
|
||||
void setup() {
|
||||
|
||||
// Wire.begin(8); // Wire初始化, 并以从设备地址#8的身份加入i2c总线
|
||||
// Wire.onRequest(requestEvent); // 注册一个IIC事件,用于响应主机的数据请求
|
||||
// 初始化 I2C 从机通信
|
||||
init_i2c_slave();
|
||||
|
||||
rangingSerial.begin(RANGING_BAUDRATE); // 激光雷达
|
||||
gpsSerial.begin(GPS_BAUDRATE); //RX引脚、TX引脚
|
||||
printSerial.begin(PRINT_BAUDRATE); // 调试输出串口(RX, TX)
|
||||
|
||||
power_init();
|
||||
// pinMode(PD14, OUTPUT);
|
||||
// pinMode(PD15, OUTPUT);
|
||||
digitalWrite(RANGING_POWER_PIN, HIGH);
|
||||
digitalWrite(GPS_POWER_PIN, HIGH);
|
||||
|
||||
printSerial.println("Initialized...");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop() {
|
||||
// 处理主串口(激光雷达数据)
|
||||
while (rangingSerial.available()) {
|
||||
parseData(rangingSerial.read());
|
||||
//ranging_displayInfo();
|
||||
}
|
||||
|
||||
// 处理 GPS 数据
|
||||
while (gpsSerial.available() > 0)
|
||||
gps.encode(gpsSerial.read());
|
||||
//gps_displayInfo();
|
||||
|
||||
// If 5000 milliseconds pass and there are no characters coming in
|
||||
// over the software serial port, show a "No GPS detected" error
|
||||
// if (millis() > 5000 && gps.charsProcessed() < 10)
|
||||
// {
|
||||
// Serial.println("No GPS detected");
|
||||
// while(true);
|
||||
// }
|
||||
}
|
||||
|
||||
void ranging_displayInfo()
|
||||
{
|
||||
// 定期打印数据
|
||||
static unsigned long lastPrintTime = 0;
|
||||
if (millis() - lastPrintTime > 100) {
|
||||
lastPrintTime = millis();
|
||||
|
||||
printSerial.printf("Successfully received: %d times\n", receive_cnt);
|
||||
printSerial.printf("Distance: %d mm\n", distance);
|
||||
printSerial.printf("Environment noise: %d\n", noise);
|
||||
printSerial.printf("Received signal strength: %d\n", peak);
|
||||
printSerial.printf("Confidence: %d\n", confidence);
|
||||
printSerial.printf("Integration count: %d\n", intg);
|
||||
printSerial.printf("Temperature characterization: %d\n", reftof);
|
||||
|
||||
|
||||
|
||||
printSerial.println("----------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
void gps_displayInfo()
|
||||
{
|
||||
if (gps.location.isValid())
|
||||
{
|
||||
printSerial.print("Latitude: ");
|
||||
printSerial.println(gps.location.lat(), 6);
|
||||
printSerial.print("Longitude: ");
|
||||
printSerial.println(gps.location.lng(), 6);
|
||||
printSerial.print("Altitude: ");
|
||||
printSerial.println(gps.altitude.meters());
|
||||
}
|
||||
else
|
||||
{
|
||||
printSerial.println("Location: Not Available");
|
||||
}
|
||||
|
||||
printSerial.print("Date: ");
|
||||
if (gps.date.isValid())
|
||||
{
|
||||
printSerial.print(gps.date.month());
|
||||
printSerial.print("/");
|
||||
printSerial.print(gps.date.day());
|
||||
printSerial.print("/");
|
||||
printSerial.println(gps.date.year());
|
||||
}
|
||||
else
|
||||
{
|
||||
printSerial.println("Not Available");
|
||||
}
|
||||
|
||||
printSerial.print("Time: ");
|
||||
if (gps.time.isValid())
|
||||
{
|
||||
if (gps.time.hour() < 10) Serial.print(F("0"));
|
||||
printSerial.print(gps.time.hour());
|
||||
printSerial.print(":");
|
||||
if (gps.time.minute() < 10) Serial.print(F("0"));
|
||||
printSerial.print(gps.time.minute());
|
||||
printSerial.print(":");
|
||||
if (gps.time.second() < 10) Serial.print(F("0"));
|
||||
printSerial.print(gps.time.second());
|
||||
printSerial.print(".");
|
||||
if (gps.time.centisecond() < 10) Serial.print(F("0"));
|
||||
printSerial.println(gps.time.centisecond());
|
||||
}
|
||||
else
|
||||
{
|
||||
printSerial.println("Not Available");
|
||||
}
|
||||
|
||||
printSerial.println();
|
||||
printSerial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
37
src/main.h
Normal file
37
src/main.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include "STP-23L.h"
|
||||
#include <HardwareSerial.h>
|
||||
#include <TinyGPS++.h>
|
||||
#include "i2c_communication.h"
|
||||
|
||||
|
||||
// 全局引脚常量,// 使用 constexpr 定义编译时常量
|
||||
constexpr int RANGING_BAUDRATE = 230400;
|
||||
constexpr int GPS_BAUDRATE = 9600;
|
||||
constexpr int PRINT_BAUDRATE = 115200;
|
||||
|
||||
//测距
|
||||
constexpr int RANGING_POWER_PIN = PB0;
|
||||
constexpr int RANGING_RX_PIN = PC5; //USART3_RX
|
||||
constexpr int RANGING_TX_PIN = PC4; //USART3_TX
|
||||
//gps
|
||||
constexpr int GPS_POWER_PIN = PB1;
|
||||
constexpr int GPS_RX_PIN = PA3; //USART2_RX
|
||||
constexpr int GPS_TX_PIN = PA2; //USART2_TX
|
||||
//串口
|
||||
constexpr int PRINT_RX_PIN = PA1; //UART4_RX
|
||||
constexpr int PRINT_TX_PIN = PA0; //UART4_TX
|
||||
//IIC
|
||||
constexpr int I2C_SDA_PIN = PB7; // I2C1_SDA
|
||||
constexpr int I2C_SCL_PIN = PB6; // I2C1_SCL
|
||||
constexpr int SLAVE_ADDRESS = 0x55;
|
||||
|
||||
// 函数声明
|
||||
void ranging_displayInfo();
|
||||
void gps_displayInfo();
|
||||
|
||||
#endif // MAIN_H
|
||||
11
test/README
Normal file
11
test/README
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||
Reference in New Issue
Block a user