Skip to content

Commit

Permalink
Add code which works on raspberry pi
Browse files Browse the repository at this point in the history
  • Loading branch information
Chi-EEE committed Dec 9, 2023
1 parent 1816924 commit 64e97ee
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 13 deletions.
133 changes: 133 additions & 0 deletions libraries/RPLidar/test/linux_read.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// https://blog.mbedded.ninja/programming/operating-systems/linux/linux-serial-ports-using-c-cpp/

// C library headers
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdint.h>
#include <thread>
#include <iomanip>
#include <vector>
#include <sstream>

// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()
#include <sys/ioctl.h>

std::string convertToHexString(uint8_t value)
{
// Convert a uint8_t to a hexadecimal string
std::stringstream stream;
stream << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<int>(value);
return stream.str();
}

int main()
{
// Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)
int serial_port = open("/dev/ttyUSB0", O_RDWR);

// Create new termios struct, we call it 'tty' for convention
struct termios tty;

// Read in existing settings, and handle any error
if (tcgetattr(serial_port, &tty) != 0)
{
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return 1;
}

tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
tty.c_cflag |= CS8; // 8 bits per byte (most common)
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)

tty.c_lflag &= ~ICANON;
tty.c_lflag &= ~ECHO; // Disable echo
tty.c_lflag &= ~ECHOE; // Disable erasure
tty.c_lflag &= ~ECHONL; // Disable new-line echo
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes

tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
// tty.c_oflag &= ~OXTABS; // Prevent conversion of tabs to spaces (NOT PRESENT ON LINUX)
// tty.c_oflag &= ~ONOEOT; // Prevent removal of C-d chars (0x004) in output (NOT PRESENT ON LINUX)

tty.c_cc[VTIME] = 10; // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.
tty.c_cc[VMIN] = 0;

// Set in/out baud rate to be 9600
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);

// Save tty settings, also checking for error
if (tcsetattr(serial_port, TCSANOW, &tty) != 0)
{
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return 1;
}

// Write to serial port
unsigned char msg[] = {'\xA5', '\x50'};
write(serial_port, msg, sizeof(msg));

// Allocate memory for read buffer, set size according to your needs
char descriptor[7];

// Normally you wouldn't do this memset() call, but since we will just receive
// ASCII data for this example, we'll set everything to 0 so we can
// call printf() easily.
memset(&descriptor, '\0', sizeof(descriptor));

// Read bytes. The behaviour of read() (e.g. does it block?,
// how long does it block for?) depends on the configuration
// settings above, specifically VMIN and VTIME
int num_bytes = read(serial_port, &descriptor, sizeof(descriptor));

uint8_t dsize = descriptor[2];
bool isSingle = descriptor[5] == 0;
uint8_t dtype = descriptor[6];

int nread;
while (true)
{
ioctl(serial_port, FIONREAD, &nread);
if (nread >= dsize)
{
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
std::cout << "nread: " << nread << std::endl;

std::vector<uint8_t> data(dsize);
int num_bytes_2 = read(serial_port, data.data(), sizeof(data));

std::string serialNumber;
for (size_t i = 4; i < data.size(); ++i)
{
serialNumber += convertToHexString(data[i]);
}

std::cout << serialNumber << std::endl;

// // n is the number of bytes read. n may be 0 if no bytes were received, and can also be -1 to signal an error.
// if (num_bytes < 0) {
// printf("Error reading: %s", strerror(errno));
// return 1;
// }

// // Here we assume we received ASCII data, but you might be sending raw bytes (in that case, don't try and
// // print it to the screen like this!)
// printf("Read %i bytes. Received message: %s", num_bytes, read_buf);

close(serial_port);
return 0; // success
};
22 changes: 9 additions & 13 deletions libraries/RPLidar/xmake.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
add_requires("serial", "spdlog")
add_requires("tl_expected")

add_requires("pybind11", "python", {configs = {headeronly = true}})

-- target("RPLidar")
-- set_kind("static")
-- add_files("src/*.cpp")
-- add_headerfiles("include/(**.h)")
-- add_headerfiles("include/(**.hpp)")
-- add_includedirs("include")
-- add_packages("serial", "spdlog")
-- add_packages("tl_expected")
target("RPLidar")
set_kind("static")
add_files("src/*.cpp")
add_headerfiles("include/(**.h)")
add_headerfiles("include/(**.hpp)")
add_includedirs("include")
add_packages("serial", "spdlog")
add_packages("tl_expected")

target("test")
set_kind("binary")
add_files("test/*.cpp")
add_includedirs("include")
add_packages("serial", "spdlog")
add_packages("tl_expected")
-- add_deps("RPLidar")
add_packages("pybind11", "python")

add_deps("RPLidar")

0 comments on commit 64e97ee

Please sign in to comment.