我正在编程一个c ++类,用于系统中两个设备之间的串行通信。一种设备是Linux计算机,另一种是微控制器(Arduino Uno)。该类在Linux计算机上使用。到目前为止,该类仅具有函数'Begin()'和'Available()'。
“ Available()”函数存在问题,该函数应返回可读取的字节数。 当我使用命令'Serial.print ln (“ hello world”)'(来自arduino的内置库的命令)从微控制器发送字节后,在语句中添加了'serial.Available()'语句。 Linux计算机将返回数字12。但是,当我忽略arduino一侧的换行符(“ Serial.print()”而不是“ Serial.println()”)时,serial.Available()将返回0字节可用阅读。
我的假设是我滥用了“ serial.Available()”函数中的“ ioctl()”语句,或者“ serial.Begin()”中的串行端口设置存在问题。没有人会知道为什么如果我不在arduino的一面打印换行符,为什么不认为字节可用,同样使用Arduino的'Serial.write()'命令。
任何建议,我们将不胜感激,
谢谢
编辑: 在Wiki上读到,在我使用过的termios api中,有两种模式。典范和非典范。第一个将逐行处理,第二个将返回单个字符。但是在我的配置中,我确定使用以下语句停用了规范模式:
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
serial.h
#ifndef SERIAL_H
#define SERIAL_H
#include <cstdio>
#include <cstdlib>
#include <fcntl.h> // File control definitions
#include <stdexcept>
#include <string>
#include <sys/ioctl.h> // Serial Port IO Controls
#include <termios.h> // POSIX terminal control definitions
#include <unistd.h> // UNIX standard function definitions
using namespace std;
class Serial
{
private:
int fd; // file descriptor
int configured;
public:
Serial(const char * device);
~Serial()
{
close(fd);
};
void Begin();
int Available(); // returns the number of bytes that's available for reading
};
#endif
serial.cpp
#include "serial.h"
Serial::Serial(const char * device)
{
configured = 0;
fd = open(device,O_RDWR | O_NOCTTY); // open serial port (read/write, no terminal control, blocking mode)
if (fd < 0)
{
perror("failed to open serial port");
exit(EXIT_FAILURE);
}
}
void Serial::Begin()
{
struct termios SerialPortSettings; // structure for serial port settings
tcgetattr(fd, &SerialPortSettings); // paste file descriptor's current settings to structure
cfsetispeed(&SerialPortSettings,B9600); // set input baud rate
cfsetospeed(&SerialPortSettings,B9600); // set output baud rate
SerialPortSettings.c_cflag &= ~PARENB; // disable parity
SerialPortSettings.c_cflag &= ~CSTOPB; // set number of stop bits to 1
SerialPortSettings.c_cflag &= ~CSIZE; // clear the bitmask
SerialPortSettings.c_cflag |= CS8; // set the number of data bits to 8 (byte)
SerialPortSettings.c_cflag |= CREAD | CLOCAL; // turn receiver on
SerialPortSettings.c_cc[VMIN] = 10; // read 10 characters (8 data bits and a start and stop bit)
SerialPortSettings.c_cc[VTIME] = 0; // wait indefinitely
SerialPortSettings.c_cflag &= ~CRTSCTS; // disable hardware based flow control
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software based flow control
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); // set to non-cannonical operation mode
int result = tcsetattr(fd,TCSANOW,&SerialPortSettings); // set attribute changes
if (result != 0)
{
close(fd);
perror("failed to configure serial port");
exit(EXIT_FAILURE);
}
configured = 1;
Serial::Flush(); // discard rx buffer
}
int Serial::Available()
{
if (!configured)
{
return -1;
}
int bytes = 0;
ioctl(fd, TIOCINQ, &bytes);
return bytes;
}
main.cpp
#include <iostream>
#include "serial.h"
using namespace std;
int main()
{
Serial serial = Serial("/dev/ttyUSB8");
serial.Begin();
while (true)
{
int available = serial.Available();
cout << available << " bytes available" << endl;
}
return 1;
}
Arduino代码
void setup() {
Serial.begin(9600);
}
void loop() {
delay(2000);
Serial.print("hello world");
}