串口操作的问题

while (respond.find(“----more----”) == std::string::npos) {
// 在循环内部处理 respond 的逻辑
// …

// 更新 respond 的值
// 假设有一些方法或逻辑来获取新的 respond 值
read(fd,buf,100);
respond(buf,len);

}

// 创建消息处理对象
MessageHandler handler;
SwitchMonitor switchMonitor(handler, “/dev/ttyUSB0”);
ClientMonitor clientMonitor(handler, “/dev/ttyUSB1”);

void function() {
std::mutex Mutex;
std::lock_guardstd::mutex lock(Mutex);
}
handler这个全局的类变量在其他类线程中使用,在每个线程中上锁,锁可以用std::mutex Mutex;局部变量的锁吗

std::string serialData;
while (isMonitoring_) {
    char buf[1024];

    std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
    ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
    if (bytes_read > 1) {
        serialData(buf, bytes_read);



while (isMonitoring_) {
    char buf[1024];
	std::string serialData;
    std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
    ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
    if (bytes_read > 1) {
        serialData.append(buf, bytes_read);
		
	这种写法每次读到的buf里面是不是有大量的空字符,比如读到username8个字符,剩下的1016个字节应该都是空字符吧,serialData.append会追加很多空字符,打印出来是空白的吧,会这样吗,如果是这样怎么改
	
	std::string serialData;
    while (isMonitoring_) {
		char buf[1024];
		
		std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
		ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
		if (bytes_read > 1) {
			serialData.append(buf, bytes_read);
			
			std::string serialData;这个是定义在while循环外面好还是里面好,每次执行到std::string serialData;定义处都会把它赋空吗,重新赋值吗,覆盖前面的
			
			
			
			std::string serialData =R"(
			username
			password:
			Repond login authentication
			)";
			
			
std::string serialData;
ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
if (bytes_read > 1) {
	serialData(buf, bytes_read);能这样用吗
	
	
	std::string serialData;
    while (isMonitoring_) {
		char buf[1024];
		
		std::unique_lock<std::mutex> lock(m_serialMutex); // 使用 unique_lock 可以手动控制锁定和解锁
		ssize_t bytes_read = read(m_serialFd, buf, sizeof(buf));
		if (bytes_read > 1) {
			serialData.append(buf, bytes_read);
			
			ssize_t bytesWritten = write(m_serialFd, serialData.c_str(), serialData.length());
			
			
			
			把读到的写入串口,串口工具回显是这样的,有阶梯,是啥原因:
			username:
			
					Error: The username times out.
					
												  username:
			
															Error: The username times out.	
															
															
		
			std::string serialData =R"(
			username
			Error: The username times out.
			Error: The username times out.
			)";
			这个字符串write写入串口会下面那样回显

			username:
					Error: The username times out.
												  username:
															Error: The username times out.	
															
															
	// 使用istringstream将字符串拆分为一行一行
std::istringstream stream(serialData);
std::string line;
while (std::getline(stream, line)) {
    // 添加换行符
    line += '\n';
    
    // 写入串口
    ssize_t bytes_written = write(serial_port, line.c_str(), line.size());
    if (bytes_written < 0) {
        std::cerr << "Error writing to serial port" << std::endl;
        close(serial_port);
        return 1;
    }
}

在串口通信中,当你发送换行符('\n')时,它通常只会将光标移动到下一行,但不会将光标移到行首。如果你希望光标移动到新的一行并且从行首开始显示,你需要发送回车符('\r')和换行符('\n')。

这是因为 ‘\r’ (回车) 将光标移动到当前行的开头,而 ‘\n’ (换行) 将光标移动到下一行。

示例代码修改
你可以在每行数据后添加 ‘\r\n’ 而不是只添加 ‘\n’。以下是修改后的代码:

cpp
#include
#include
#include
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
const char *device = “/dev/ttyS3”; // 替换为实际的串口设备名称
int serial_port = open(device, O_RDWR);

if (serial_port < 0) {
    std::cerr << "Error opening serial port" << std::endl;
    return 1;
}

// 配置串口参数
termios tty;
if (tcgetattr(serial_port, &tty) != 0) {
    std::cerr << "Error getting termios attributes" << std::endl;
    close(serial_port);
    return 1;
}

cfsetospeed(&tty, B9600); // 设置波特率
cfsetispeed(&tty, B9600);

tty.c_cflag &= ~PARENB; // 清除校验位
tty.c_cflag &= ~CSTOPB; // 设置1个停止位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 设置8个数据位

tty.c_cflag &= ~CRTSCTS; // 禁用硬件流控
tty.c_cflag |= CREAD | CLOCAL; // 启用读取和忽略调制解调器控制线

tty.c_lflag &= ~ICANON; // 禁用规范模式
tty.c_lflag &= ~ECHO; // 禁用回显
tty.c_lflag &= ~ECHOE; // 禁用回显擦除
tty.c_lflag &= ~ECHONL; // 禁用新行回显
tty.c_lflag &= ~ISIG; // 禁用信号处理

tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // 禁用特殊字符处理

tty.c_oflag &= ~OPOST; // 禁用输出处理
tty.c_oflag &= ~ONLCR; // 禁用新行转换

tty.c_cc[VTIME] = 10; // 设置读超时时间
tty.c_cc[VMIN] = 0;

if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
    std::cerr << "Error setting termios attributes" << std::endl;
    close(serial_port);
    return 1;
}

// 准备要写入串口的数据
std::string serialData = R"(

username
Error: The username times out.
Error: The username times out.
)";

// 使用istringstream将字符串拆分为一行一行
std::istringstream stream(serialData);
std::string line;
while (std::getline(stream, line)) {
    // 添加回车和换行符
    line += "\r\n";
    
    // 写入串口
    ssize_t bytes_written = write(serial_port, line.c_str(), line.size());
    if (bytes_written < 0) {
        std::cerr << "Error writing to serial port" << std::endl;
        close(serial_port);
        return 1;
    }
}

// 读取回显
char buffer[256];
memset(buffer, 0, sizeof(buffer));
ssize_t bytes_read = read(serial_port, buffer, sizeof(buffer) - 1);
if (bytes_read < 0) {
    std::cerr << "Error reading from serial port" << std::endl;
    close(serial_port);
    return 1;
}

// 将读取的数据转换为string并输出
std::string response(buffer, bytes_read);
std::cout << response << std::endl;

// 关闭串口
close(serial_port);

return 0;

}
解释
\r\n:‘\r’ 是回车符,将光标移到当前行的起始位置;‘\n’ 是换行符,将光标移到下一行。因此,“\r\n” 可以确保新的一行从行首开始显示。
通过这种方式,你可以确保在串口工具上看到的输出每行都从行首开始显示。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值