使用 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 的有效负载中的所有零的主要内容,如果未能解决你的问题,请参考以下文章