c++ - 在 Linux(ubuntu) 中从 C++ 读取 arduino 串行数据
问题描述
我的设置如下:-操作系统:LINUX(ubuntu),
Arduino nano + HC-SR04 传感器。其代码是: -
const int trigPin = 5;
const int echoPin =6;
// defines variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance= duration*0.034/2;
if (distance <50) {
Serial.print("Chko Distance: ");
Serial.println(distance); }
}
现在我想从 C++ 读取串行输出,其代码是:-
// C library headers
#include <stdio.h>
#include <string.h>
// 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()
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 struc, 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, B9600);
cfsetospeed(&tty, B9600);
// 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;
}
// Allocate memory for read buffer, set size according to your needs
char read_buf [256];
// 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(&read_buf, '\0', sizeof(read_buf));
// 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, &read_buf, sizeof(read_buf));
// 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
}
代码工作正常,但它从传感器输出打印一行或几行。而我只想从传感器打印一行,据我所知,这似乎是 arduino 代码和 C++ 代码之间的连接不正确。
Distance printed twice
┌─[monisha@monisha-asus]─[~/cpp/serial] $./a.out
Read 36 bytes. Received message: Chko Distance: 0
Chko Distance: 0
Distance printed only once
┌─[monisha@monisha-asus]─[~/cpp/serial]$ ./a.out
Read 18 bytes. Received message: Chko Distance: 0
Distance printed several times
┌─[monisha@monisha-asus]─[~/cpp/serial]$ ./a.out
Read 256 bytes. Received message: Chko Distance: 0
Chko Distance: 0
Chko Distance: 0
Chko Distance: 0
Chko Distance: 0
Chko Distance: 0
请有人帮助我,谢谢莫妮莎
解决方案
推荐阅读
- clion - Environment variable as Command line argument
- spring - 获取错误状态 500 将 reactmongo 连接到 mlabs
- php - 将 php 扩展从 7.2 迁移到 7.3 时编译错误
- c++ - How to get fmt::format to work with wchar_t?
- android - Android SDK for fingerprint matching - External device
- ruby - Rubygems: You do not have permission to push to this gem
- c++ - 如何在同一行格式化左右对齐?
- ruby - 关于如何过滤 x || 的问题 y 而不是 x && y
- reactjs - 在 typescript 中扩展 AWS Amplify Auth 组件
- python - 使用 numpy.loadtxt() 加载带有制表符分隔符的 txt 文件 FAIL