使用 MKR1400GSM 并将库中的引脚设置为高电平或低电平,使其保持低电平

问题描述 投票:0回答:1

我有一个使用 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 由于设置不正确而无法正确发送/接收。我非常肯定,一旦这个问题得到解决,图书馆就会正常工作。

arduino rs485 arduino-mkr1000
1个回答
0
投票

我没有测试你的代码,所以从技术上来说这不是一个明确的答案,但我看到了一些关于你的库的问题,而且它作为评论也太长了,所以我在这里提供我的建议和评论。

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
}
© www.soinside.com 2019 - 2024. All rights reserved.