攻城狮参上 2024-08-20 12:14 采纳率: 0%
浏览 6

Arduino串口数据读取问题

Arduino编程时,读取pm2.5传感器时,串口打印数据不正常,用millis()函数定时和delay()函数延时打印出来的串口数据不同:
不正常的代码:

#include <SoftwareSerial.h>
SoftwareSerial PMSerial(7, 8); // 声明另一个软串口对象,RX接6,TX接5
//pm2.5
byte PMbuf[] = {0,0,0,0};
long ltime = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // 初始化硬串口
  PMSerial.begin(9600); // 初始化PM2.5模块的软串口
//  ZigbeeSerial.begin(9600);
//  dht13.begin();
//  pinMode(yw_get, INPUT);
}

void loop() {
  if (PMSerial.available() > 0) {
    for (int i = 0; i < 4; i = i + (1)) {
      PMbuf[i] = PMSerial.read();
    }
    PM = ((PMbuf[1] & 0x7F) * 128 + (PMbuf[2]) & 0x7F) * 0.4;
  }
  if (millis() - ltime >= 3000) {
    ltime = millis();
    for (int i = 0; i < 4; i = i + (1)) {
      Serial.println(PMbuf[i]);
    }
    Serial.print("PM2.5: ");
    Serial.println(PM);
  }
//  delay(3000);

 
}

img


正常的代码:

#include <SoftwareSerial.h>
SoftwareSerial PMSerial(7, 8); // 声明另一个软串口对象,RX接6,TX接5
//pm2.5
byte PMbuf[] = {0,0,0,0};
long ltime = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // 初始化硬串口
  PMSerial.begin(9600); // 初始化PM2.5模块的软串口
//  ZigbeeSerial.begin(9600);
//  dht13.begin();
//  pinMode(yw_get, INPUT);
}

void loop() {
  if (PMSerial.available() > 0) {
    for (int i = 0; i < 4; i = i + (1)) {
      PMbuf[i] = PMSerial.read();
    }
    PM = ((PMbuf[1] & 0x7F) * 128 + (PMbuf[2]) & 0x7F) * 0.4;
  }
 // if (millis() - ltime >= 3000) {
   // ltime = millis();
    for (int i = 0; i < 4; i = i + (1)) {
      Serial.println(PMbuf[i]);
    }
    Serial.print("PM2.5: ");
    Serial.println(PM);
  //}
 delay(3000);

img

传感器是固定每一秒发送一次串口数据,A5是识别码,中间两位是数据值,最后一位是校验位

  • 写回答

1条回答 默认 最新

  • 吃不了席 2024-08-23 22:00
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从你提供的代码和串口打印数据来看,问题出在你使用millis()函数定时和delay()函数延时的方式不同。在第一种情况下,你可能在PMSerial.available()true时读取了数据,但在下一次millis()定时器触发之前,数据已经被覆盖,导致打印出的数据不正常。

    为了解决这个问题,你可以使用一个标志位来判断是否已经读取了数据,然后在millis()定时器触发时检查这个标志位。如果已经读取了数据,则打印数据;否则,不进行任何操作。这样可以确保每次打印的数据都是完整的。以下是修改后的代码:

    #include <SoftwareSerial.h>
    SoftwareSerial PMSerial(7, 8); // 声明另一个软串口对象,RX接6,TX接5
    //pm2.5
    byte PMbuf[] = {0,0,0,0};
    bool dataRead = false; // 添加一个标志位
    long ltime = 0;
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600); // 初始化硬串口
      PMSerial.begin(9600); // 初始化PM2.5模块的软串口
    //  ZigbeeSerial.begin(9600);
    //  dht13.begin();
    //  pinMode(yw_get, INPUT);
    }
    
    void loop() {
      if (PMSerial.available() > 0) {
        for (int i = 0; i < 4; i = i + (1)) {
          PMbuf[i] = PMSerial.read();
        }
        PM = ((PMbuf[1] & 0x7F) * 128 + (PMbuf[2]) & 0x7F) * 0.4;
        dataRead = true; // 读取数据后,将标志位设为true
      }
      if (millis() - ltime >= 3000) {
        ltime = millis();
        if (dataRead) { // 检查标志位
          for (int i = 0; i < 4; i = i + (1)) {
            Serial.println(PMbuf[i]);
          }
          Serial.print("PM2.5: ");
          Serial.println(PM);
          dataRead = false; // 打印数据后,将标志位设为false
        }
      }
      delay(3000);
    }
    

    这样修改后,你的代码应该可以正常打印传感器的数据了。

    评论

报告相同问题?

问题事件

  • 创建了问题 8月20日

悬赏问题

  • ¥15 51嵌入式入门按键小项目
  • ¥30 海外项目,如何降低Google Map接口费用?
  • ¥15 fluentmeshing
  • ¥15 手机/平板的浏览器里如何实现类似荧光笔的效果
  • ¥15 盘古气象大模型调用(python)
  • ¥15 传人记程序做的plc 485从机程序该如何写
  • ¥15 已知手指抓握过程中掌指关节、手指各关节和指尖每一帧的坐标,用贝塞尔曲线可以拟合手指抓握的运动轨迹吗?
  • ¥50 libwebsockets 如何添加其他socket事件回调
  • ¥50 实现画布拖拽算子排布,通过flink实现算子编排计算,请提供思路
  • ¥15 esium自定义材质拉伸问题