使用 SerialTransfer 库通过 UART 接收从 nodemcu 发送到 Arduino UNO 的有效负载中的所有零

Posted

技术标签:

【中文标题】使用 SerialTransfer 库通过 UART 接收从 nodemcu 发送到 Arduino UNO 的有效负载中的所有零【英文标题】:Receiving all zeros in payload sent from nodemcu to Arduino UNO over UART using SerialTransfer library 【发布时间】:2021-08-01 07:46:51 【问题描述】:

我有一个 nodemcu master 使用 SerialTransfer.h 通过 UART 将传感器值流式传输到 Arduino Uno 从站。我已经使用SoftwareSerial.h 在 Arduino 数字引脚 2、3 上为 Rx、Tx 设置了一个额外的串行端口。我已将 nodemcu 上的 Tx 连接到 Uno 上的 Rx,并将 nodemcu 上的 Rx 连接到 Uno 上的 Tx。我有一个电平转换器来调整 3.3 V nodemcu 和 5 V Arduino。我确保提供一个共同点。

我从 nodemcu 传输一个带有传感器值(bool 和 int 类型,为演示硬编码)的结构,但在 Arduino 上仅接收零值,如串行监视器所示。我的代码如下。如有任何意见,我将不胜感激。

我尝试了以下没有任何区别。

    在使用SoftwareSerial.h 创建的 Uno 上有和没有额外的串行端口 使用 Arduino Uno master 和 nodemcu slave 反转设置 在 nodemcu Tx 和 Arduino Uno Rx 上使用和不使用电平转换器

这是nodemcu master的代码。

#include <Wire.h>
#include <SerialTransfer.h>

SerialTransfer masterMCU;

struct PAYMASTER 
  /*
  water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
  fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
  led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
  */
  bool water;
  int fan; 
  int led;
 instructions = 
  true,
  201,
  60
;

void setup() 
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(999);
  masterMCU.begin(Serial);
  delay(999);


void debug() 
  Serial.print("MASTER: ");
  Serial.print(millis());
  Serial.print("   Water: ");
  Serial.print(instructions.water);
  Serial.print(", Fan: ");
  Serial.print(instructions.fan);
  Serial.print(", LED: ");
  Serial.println(instructions.led);


void loop() 
  // put your main code here, to run repeatedly:
  masterMCU.txObj(instructions, sizeof(instructions));
  masterMCU.sendData(sizeof(instructions));
  debug();
  delay(999);


这是 Arduino Uno slave 的代码。

#include <Wire.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>

SerialTransfer slaveMCU;
SoftwareSerial extra(2, 3); // Rx 2, Tx 3

struct PAYMASTER 
  /*
  water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
  fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
  led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
  */
  bool water;
  int fan; 
  int led;
 instructions;

void setup() 
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(201);
  extra.begin(9600);
  delay(201);
  slaveMCU.begin(extra);
  delay(201);


void debug() 
  Serial.print("SLAVE: ");
  Serial.print(millis());
  Serial.print("   Water: ");
  Serial.print((bool)instructions.water);
  Serial.print(", Fan: ");
  Serial.print(instructions.fan);
  Serial.print(", LED: ");
  Serial.println(instructions.led);


void loop() 
  // put your main code here, to run repeatedly:
  if (slaveMCU.available()) 
    slaveMCU.rxObj(instructions, sizeof(instructions));
    debug();
   else if (slaveMCU.status < 0) 
    Serial.print("ERROR: ");

    if(slaveMCU.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(slaveMCU.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(slaveMCU.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  
  delay(999);

【问题讨论】:

从结构(可能有也可能没有填充)和不同大小的元素开始,你并没有真正让它变得容易。为什么不从一个简单的字节值开始,看看它是否有效?然后尝试使用 4 字节值。 @MarkSetchell 谢谢,这是一个很好的建议!今后我会牢记这一点。 【参考方案1】:

我做了一些更改,现在收到的数据具有正确的值。

    我在 master 中将 delay() 替换为 millis()。 我在 master 中用 SerialTransfer::sendDatum() 替换了 SerialTransfer::sendData()。前者用于流式传输多个对象,而后者用于流式传输单个对象。 我将结构中的 int 类型替换为 uint8_t,该结构通过主机和从机的线路发送。

现在 Arduino Uno 可以正确接收这些值。在上述 3. 之前,所有更改都没有任何区别。我保留了其他更改,因为它们对结果也很重要。这是用于正确传输和接收从 nodemcu master 到 Arduino Uno slave 的对象的最终代码。

nodemcu 主控

#include <Wire.h>
#include <SerialTransfer.h>

SerialTransfer masterMCU;
unsigned long tic = millis();
unsigned long toc = tic;

#define DELTA 1000

struct PAYMASTER 
  /*
  water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
  fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
  led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
  */
  bool water;
  uint8_t fan; 
  uint8_t led;
 instructions = 
  true,
  201,
  60
;

void setup() 
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(999);
  masterMCU.begin(Serial);
  delay(999);


void debug() 
  Serial.print("MASTER: ");
  Serial.print(millis());
  Serial.print("   Water: ");
  Serial.print(instructions.water);
  Serial.print(", Fan: ");
  Serial.print(instructions.fan);
  Serial.print(", LED: ");
  Serial.println(instructions.led);


void loop() 
  // put your main code here, to run repeatedly:
  toc = millis();
  if ((toc - tic) > DELTA) 
    masterMCU.txObj(instructions, sizeof(instructions));
    masterMCU.sendDatum(instructions), sizeof(instructions);
    debug();
    tic = toc;
  


Arduino Uno 奴隶

#include <Wire.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>

SerialTransfer slaveMCU;
SoftwareSerial Extra(2, 3); // Rx: 2, Tx: 3
unsigned long tic = millis();
unsigned long toc = tic;

struct PAYMASTER 
  /*
  water: instruction to switch pump on or off. Note the float sensor in pump's circuit will prevent overflow.
  fan: instruction to control fan speed - LO, MED, HIGH. Note PC fan requires an int between 0 and 255.
  led: instruction to control LED brightness. Note that the FastLED library requires an int between 0 and 255.
  */
  bool water;
  uint8_t fan; 
  uint8_t led;
 instructions;

void setup() 
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(201);
  Extra.begin(9600);
  delay(201);
  slaveMCU.begin(Extra);
  delay(201);


void debug() 
  Serial.print("SLAVE: ");
  Serial.print(millis());
  Serial.print("   Water: ");
  Serial.print((bool)instructions.water);
  Serial.print(", Fan: ");
  Serial.print(instructions.fan);
  Serial.print(", LED: ");
  Serial.println(instructions.led);


void loop() 
  // put your main code here, to run repeatedly:
  if (slaveMCU.available()) 
    slaveMCU.rxObj(instructions);
    debug();
   else if (slaveMCU.status < 0) 
    Serial.print("ERROR: ");

    if(slaveMCU.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(slaveMCU.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(slaveMCU.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  

【讨论】:

以上是关于使用 SerialTransfer 库通过 UART 接收从 nodemcu 发送到 Arduino UNO 的有效负载中的所有零的主要内容,如果未能解决你的问题,请参考以下文章

Mini2440裸机开发之串口UART

迅飞智能车相关开发资料

芯片级通信总线之一:SPI

Mysql加载配置默认路径

Universal asynchronous receiver transmitter (UART)

嵌入式串口控制