树莓派Pico串口读取ADC值失败 求技术指导
树莓派Pico串口ADC读取失败(C++代码问题排查与修复)
已将树莓派Pico连接电脑,使用C++编写代码通过串口读取Pico的ADC值时始终无法获取数值,但Pico端Python代码运行完全正常。以下是问题代码及排查修复方案:
问题代码
#include "Adc.h" #include <iostream> #include <cstdlib> #include <thread> Adc::Adc(std::string port) { SerialPort.open(port, std::ios::in | std::ios::out); if (!SerialPort.is_open()) { std::cerr << "Error opening ADC serial port." << std::endl; std::exit(-1); } std::cout << "ADC port opened successfully." << std::endl; } Adc::~Adc() { SerialPort.close(); } std::string Adc::Request() { // Request ADC value SerialPort.write("a\r", 2); SerialPort.flush(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); // Read ADC value from serial port as a string char buffer[100]; SerialPort.getline(buffer, 5, '\n'); printf("ADC raw (%i): %s\n", SerialPort.gcount(), buffer); std::string adcValue(buffer); } return adcValue; }
核心问题排查
- 语法错误:
Request函数中,std::string adcValue(buffer);后多了一个闭合},导致return语句处于函数体外,代码无法正常编译运行。 - 串口参数不匹配:仅打开串口未配置波特率、数据位、停止位等参数,默认参数大概率与Pico端Python代码的串口配置不一致,直接导致收发失败。
- 读取逻辑缺陷:
getline(buffer, 5, '\n')限制最多读取4个有效字符,若ADC返回值长度超过此限制会读取截断;同时未考虑Pico可能返回\r\n而非单纯\n作为换行符,导致读取触发条件不匹配。
修复后的代码
#include "Adc.h" #include <iostream> #include <cstdlib> #include <thread> #include <unistd.h> #include <termios.h> Adc::Adc(std::string port) { SerialPort.open(port, std::ios::in | std::ios::out); if (!SerialPort.is_open()) { std::cerr << "Error opening ADC serial port." << std::endl; std::exit(-1); } // 配置串口参数,完全匹配Pico端Python代码的设置(示例为9600波特率、8N1) struct termios tty; if (tcgetattr(SerialPort.native_handle(), &tty) != 0) { std::cerr << "Error getting serial port attributes." << std::endl; std::exit(-1); } // 设置波特率 cfsetospeed(&tty, B9600); cfsetispeed(&tty, B9600); // 8位数据位、无奇偶校验、1位停止位 tty.c_cflag &= ~PARENB; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; // 禁用硬件流控 tty.c_cflag &= ~CRTSCTS; // 原始模式,禁用回车换行转换 tty.c_lflag &= ~ICANON; tty.c_lflag &= ~ECHO; tty.c_lflag &= ~ISIG; // 禁用软件流控 tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用输出格式转换 tty.c_oflag &= ~OPOST; tty.c_oflag &= ~ONLCR; // 设置1秒超时 tty.c_cc[VMIN] = 0; tty.c_cc[VTIME] = 10; if (tcsetattr(SerialPort.native_handle(), TCSANOW, &tty) != 0) { std::cerr << "Error setting serial port attributes." << std::endl; std::exit(-1); } std::cout << "ADC port opened and configured successfully." << std::endl; } Adc::~Adc() { SerialPort.close(); } std::string Adc::Request() { // 发送请求指令 SerialPort.write("a\r", 2); SerialPort.flush(); // 短时间等待Pico响应 std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 读取响应,适配\r\n换行格式 char buffer[100]; SerialPort.getline(buffer, sizeof(buffer), '\n'); std::string adcValue(buffer); // 移除可能残留的\r字符 size_t rPos = adcValue.find('\r'); if (rPos != std::string::npos) { adcValue.erase(rPos); } printf("ADC raw (%zu): %s\n", adcValue.size(), adcValue.c_str()); return adcValue; }
额外验证步骤
- 先修复原代码的语法错误,确保编译通过;
- 核对Python代码中的串口参数(波特率、奇偶校验等),将C++代码中的对应配置修改为完全一致;
- 用串口助手手动发送
a\r指令,确认Pico能正常返回ADC值,验证指令格式正确性。
内容的提问来源于stack exchange,提问作者jackie321
相关产品推荐
相关产品推荐

