我有一个使用 LOLIN mini d1 的系统,该系统通过 RS485 读取电池 BMS。几周后图书馆就可以正常工作了。 现在我尝试将它与 MKR1400 一起使用,通过 GSM 发送 MQTT 数据。
我遇到了一个让我很困惑的问题。我使用的是 MAX485,我需要将 DE 和 RE 调高以发送,调低以接收。我在图书馆这样做。下面是非常简化的调试库。如果我标记延迟,则引脚变高并发送,但我无法接收,设置延迟后引脚保持低电平。我可以理解它会干扰串行,但不会将引脚设置为高电平或向上。
.h 文件
#ifndef SERIALTEST_H
#define SERIALTEST_H
#include "Arduino.h"
class ETDBms {
public:
ETDBms(); // Constructor
void begin(Uart &port);
void SerialTxControl(uint8_t pinTx);
void SerialRxControl(uint8_t pinRx);
void main_task();
void readSerial(); // New member function to read from serial port and write to serial monitor
private:
bool is_initialized;
Uart* serial;
uint8_t _pinTx;
uint8_t _pinRx;
};
#endif // SERIALTEST_H
.cpp 文件
#include "SerialTest.h"
// Constructor
ETDBms::ETDBms() {
is_initialized = false;
}
// Start processing
void ETDBms::begin(Uart &port) {
serial = &port;
is_initialized = true;
}
// Set the Rx and Tx pins
void ETDBms::SerialTxControl(uint8_t pinTx) {
_pinTx = pinTx;
}
void ETDBms::SerialRxControl(uint8_t pinRx) {
_pinRx = pinRx;
}
// Call this as fast as possible within the sketch's loop() function
void ETDBms::main_task() {
if (is_initialized) {
// SET the RS485 shield to transmit mode
digitalWrite(_pinTx, HIGH);
digitalWrite(_pinRx, HIGH);
serial->print("test"); // Sending "test" over the serial port
// SET the RS485 shield to receive mode
digitalWrite(_pinTx, LOW);
digitalWrite(_pinRx, LOW);
delay(2000); // Delay for readability
}
}
// Read from Serial1 port and write to serial monitor (Serial)
void ETDBms::readSerial() {
if (serial->available()) {
Serial.print("Received from Serial1: ");
while (serial->available()) {
char c = serial->read();
Serial.print(c);
}
Serial.println();
}
}
和草图
#include "SerialTest.h"
ETDBms bms;
int pinRX = 2;
int pinTX = 3;
void setup() {
pinMode(pinRX, OUTPUT);
pinMode(pinTX,OUTPUT);
Serial.begin(115200);
Serial1.begin(9600);
bms.begin(Serial1); //baud rate 9600
bms.SerialRxControl(pinRX);
bms.SerialTxControl(pinTX);
}
void loop() {
bms.main_task();
//bms.readSerial();
}
我是否遗漏了 MKR1400 特有的某些内容?
我尝试直接使用草图中的代码,但我仍然遇到奇怪的低/高行为。 我消除了图书馆中的所有延迟,但这没有帮助。
由于此问题,我的 MAX485 由于设置不正确而无法正确发送/接收。我非常肯定,一旦这个问题得到解决,图书馆就会正常工作。
我没有测试你的代码,所以从技术上来说这不是一个明确的答案,但我看到了一些关于你的库的问题,而且它作为评论也太长了,所以我在这里提供我的建议和评论。
int pinRX = 2;
int pinTX = 3;
首先,我假设它们分别是 DE 引脚和 RE 引脚,我个人更喜欢这样命名它们,而不是与 TX 和 RX 引脚混淆。对于下面的其余文本,我将使用
pinRE
代表 pinRX
,使用 pinDE
代表 pinTX
。
serial->print("test")
不会立即发送数据,它将数据添加到传输队列中并以相当慢的波特率发送(在您的情况下为9600波特),因此您的代码过早终止DE引脚。为了确保数据已发送出去,应先调用serial->flush()
关闭DE引脚。
delay(2000)
不是必需的,但是切换DE引脚需要时间,特别是当您有很长的RS485电缆时,建议在之前或之后有50us的延迟(或更长,请阅读数据表和RS485规范)实际的数据传输。
这是修改后的数据传输代码
digitalWrite(_pinDE, HIGH);
delayMicroseconds(50); // this delay may or may not need longer
serial->print("test"); // Sending "test" over the serial port
serial->flush(); // make sure all data are sent
delayMicroseconds(50);
digitalWrite(_pinDE, LOW);
对于接收,您只需将 MAX485 默认设置为接收模式(即 RE 引脚处于低电平),并且仅在发送期间切换 DE 引脚。
void setup() {
// your original setup code here
digitalWrite(pinRE, LOW); // in receive mode by default
}