You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派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;

}

核心问题排查

  1. 语法错误:Request函数中,std::string adcValue(buffer);后多了一个闭合},导致return语句处于函数体外,代码无法正常编译运行。
  2. 串口参数不匹配:仅打开串口未配置波特率、数据位、停止位等参数,默认参数大概率与Pico端Python代码的串口配置不一致,直接导致收发失败。
  3. 读取逻辑缺陷: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 10:50:22