Files
Loongson_2k0300_SmartCar/jy62_demo/jy62_demo.cpp
T

183 lines
4.6 KiB
C++

/*
* @Author: Ilikara 3435193369@qq.com
* @Date: 2025-01-26 17:00:24
* @LastEditors: ilikara 3435193369@qq.com
* @LastEditTime: 2025-02-28 08:42:56
* @FilePath: /2k300_smartcar/jy62_demo/jy62_demo.cpp
* @Description:
*
* Copyright (c) 2025 by ${git_name_email}, All Rights Reserved.
*/
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <vector>
#include <cstdint>
#include <termios.h>
#include <atomic>
const size_t PACKET_LENGTH = 11;
const uint8_t HEADER = 0x55;
std::atomic<int16_t> accel[3], gyro[3], angle[3];
uint8_t calculateChecksum(const std::vector<uint8_t> &data)
{
uint8_t checksum = 0;
for (uint8_t byte : data)
{
checksum += byte;
}
return checksum;
}
bool parsePacket(const std::vector<uint8_t> &packet)
{
if (packet[0] != HEADER)
{
return false;
}
if (packet[1] > 0x53 || packet[1] < 0x51)
{
return false;
}
uint8_t receivedChecksum = packet.back();
uint8_t calculatedChecksum = calculateChecksum(std::vector<uint8_t>(packet.begin(), packet.end() - 1));
return receivedChecksum == calculatedChecksum;
}
bool setupSerialPort(int fd, int baudRate)
{
struct termios tty;
memset(&tty, 0, sizeof tty);
// 获取当前串口配置
if (tcgetattr(fd, &tty) != 0)
{
std::cerr << "Error getting terminal attributes" << std::endl;
return false;
}
// 设置输入输出波特率
cfsetospeed(&tty, baudRate);
cfsetispeed(&tty, baudRate);
// 设置数据位为 8 位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
// 禁用奇偶校验
tty.c_cflag &= ~PARENB;
// 设置停止位为 1 位
tty.c_cflag &= ~CSTOPB;
// 禁用硬件流控制
tty.c_cflag &= ~CRTSCTS;
// 启用接收和本地模式
tty.c_cflag |= CREAD | CLOCAL;
// 禁用软件流控制
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
// 设置原始模式(禁用规范模式)
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// 禁用输出处理
tty.c_oflag &= ~OPOST;
// 设置读取超时和最小读取字符数
tty.c_cc[VMIN] = 1; // 至少读取 1 个字符
tty.c_cc[VTIME] = 5; // 等待 0.5 秒
// 应用配置
if (tcsetattr(fd, TCSANOW, &tty) != 0)
{
std::cerr << "Error setting terminal attributes" << std::endl;
return false;
}
return true;
}
void data_handler(const std::vector<uint8_t> &packet)
{
switch (packet[1])
{
case 0x51:
accel[0].store((int16_t)packet[3] << 8 | packet[2]);
accel[1].store((int16_t)packet[5] << 8 | packet[4]);
accel[2].store((int16_t)packet[7] << 8 | packet[6]);
break;
case 0x52:
gyro[0].store((int16_t)packet[3] << 8 | packet[2]);
gyro[1].store((int16_t)packet[5] << 8 | packet[4]);
gyro[2].store((int16_t)packet[7] << 8 | packet[6]);
break;
case 0x53:
angle[0].store((int16_t)packet[3] << 8 | packet[2]);
angle[1].store((int16_t)packet[5] << 8 | packet[4]);
angle[2].store((int16_t)packet[7] << 8 | packet[6]);
break;
}
}
int main()
{
const char *device = "/dev/ttyS2";
int fd = open(device, O_RDWR | O_NOCTTY);
if (fd < 0)
{
std::cerr << "Failed to open " << device << std::endl;
return 1;
}
if (!setupSerialPort(fd, B115200))
{
std::cerr << "Failed to setup serial port" << std::endl;
close(fd);
return 1;
}
std::vector<uint8_t> buffer;
while (true)
{
uint8_t byte;
ssize_t n = read(fd, &byte, 1);
if (n > 0)
{
buffer.push_back(byte);
if (buffer.size() >= PACKET_LENGTH)
{
if (parsePacket(buffer))
{
data_handler(buffer);
buffer.erase(buffer.begin(), buffer.begin() + PACKET_LENGTH);
std::cout << "accel:" << accel[0] << " " << accel[1] << " " << accel[2] << std::endl;
std::cout << "gyro:" << gyro[0] << " " << gyro[1] << " " << gyro[2] << std::endl;
std::cout << "angle:" << angle[0] << " " << angle[1] << " " << angle[2] << std::endl;
}
else
{
std::cerr << "Invalid packet, discarding the first byte." << std::endl;
buffer.erase(buffer.begin());
}
}
}
else if (n < 0)
{
std::cerr << "Error reading from UART." << std::endl;
break;
}
}
close(fd);
return 0;
}