Бюджетный RS485 модуль с ESP32 (hardware serial)

В предыдущей статье рассмотрел подключение бюджетного модуля RS485 к ESP8266. Фактически это чип MAX485 без защиты от напастей ну и стоит около 0,3 $ Лучше закупать оптом по 5 шт, так выгоднее, да и небольшая подстраховка на случай выгорания, поскольку защиты линии RS485 нет.

Бюджетный RS485 модуль

В промышленной эксплуатации лучше использовать ранее рассмотренные XY-485 или XY-017. Они более защищены от различных проблем, вроде удара молнии.

Плата ESP32 DevKit V1 широко распространена на Aliexpress по цене около 6 USD.

Схема соединения платы RS485 с ESP32 DevKit V1

На плате ESP32 DevKit V1 имеется три аппаратных UART порта
именуемые как U0UXD, U1UXD и U2UXD:

  • U0UXD используется чипом преобразователя USB интерфейса платы ESP32 DevKit V1.
  • U1UXD можно использовать для своих проектов. Некоторые платы используют этот порт на пине используемом под SPI Flash. Если не перенести на другой GPIO, то при обращении к этому пину программа выпадет в ошибку.
  • U2UXD можно использовать для своих проектов.

На большинстве плат с ESP32 U0UXD занят для работы с конвертером USB интерфейса. Остается два свободных UART порта. Схема подключения ESP32 LuaNode32 к бюджетному модулю RS485 следующая:

Подключение ESP32 к бюджетному модулю RS485

В моем примере модуль RS485 интерфейса запитывается непосредственно от пина 3,3 В платы LuaNode32. Этот вариант рабочий. Если будете использовать отдельный блок питания для RS485 платы, то основная рекомендация:

Блок питания для модулей RS485 ДОЛЖЕН БЫТЬ на 3,3V,
иначе можно сжечь GPIO ESP32!!! 
Либо используйте конвертер TTL  уровней

ESP32 LuaNode32RS485 (MAX485 chipset) 
Rx (PIN RX2, GPIO16) RO (receiver output)
Tx (PIN TX2, GPIO17) DI (driver input)
DE_RE (GPIO4, D4) DE (driver enable)
RE (receiver enable)
3,3VVCC (Блок питания +3,3V)
GNDGND

DI (driver input) — цифровой вход передатчика;
RO (receiver output) — цифровой выход приемника;
DE (driver enable) — разрешение работы передатчика;
RE (receiver enable) — разрешение работы приемника;

Пины DE И RE закорачиваем.

ТермодатчикRS485 (MAX485 chipset) 
A+A+
B-B-
GNDGND
GND (Блок питания -)
VCC (Блок питания +5V)

ESP32 программа для работы с RS485 c DE/RE

#include "ModbusMaster.h" //https://github.com/4-20ma/ModbusMaster

/*!
  We're using a MAX485-compatible RS485 Transceiver.
  Rx/Tx is hooked up to the hardware serial port at 'Serial'.
  The Data Enable (DE) and Receiver Enable (RE) pins are hooked up as follows:
*/

#define MAX485_RE_NEG  4 //D4 RS485 has a enable/disable pin to transmit or receive data. Arduino Digital Pin 2 = Rx/Tx 'Enable'; High to Transmit, Low to Receive
#define Slave_ID       1
#define RX_PIN      16 //RX2 
#define TX_PIN      17  //TX2 

// instantiate ModbusMaster object
ModbusMaster modbus;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, HIGH); //Switch to transmit data
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, LOW); //Switch to receive data
}

void setup()
{
  pinMode(MAX485_RE_NEG, OUTPUT);

  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, LOW);

  // Modbus communication runs at 9600 baud
  Serial.begin(9600, SERIAL_8N1);

  Serial2.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);
  modbus.begin(Slave_ID, Serial2);

  // Callbacks allow us to configure the RS485 transceiver correctly
  modbus.preTransmission(preTransmission);
  modbus.postTransmission(postTransmission);
}

long lastMillis = 0;
void loop() 
{
  long currentMillis = millis();
  if (currentMillis - lastMillis > 1000) 
  {
    uint8_t result = modbus.readInputRegisters(0x01, 2);
    
    if (getResultMsg(&modbus, result)) 
    {
      Serial.println();

      double res_dbl = modbus.getResponseBuffer(0) / 10;
      String res = "Temperature: " + String(res_dbl) + " C\r\n";
      res_dbl = modbus.getResponseBuffer(1) / 10;
      res += "Humidity: " + String(res_dbl) + " %";
      Serial.println(res);
    }
    lastMillis = currentMillis;
  }
}

bool getResultMsg(ModbusMaster *node, uint8_t result) 
{
  String tmpstr2 = "\r\n";

  switch (result) 
  {
  case node->ku8MBSuccess:
    return true;
    break;
  case node->ku8MBIllegalFunction:
    tmpstr2 += "Illegal Function";
    break;
  case node->ku8MBIllegalDataAddress:
    tmpstr2 += "Illegal Data Address";
    break;
  case node->ku8MBIllegalDataValue:
    tmpstr2 += "Illegal Data Value";
    break;
  case node->ku8MBSlaveDeviceFailure:
    tmpstr2 += "Slave Device Failure";
    break;
  case node->ku8MBInvalidSlaveID:
    tmpstr2 += "Invalid Slave ID";
    break;
  case node->ku8MBInvalidFunction:
    tmpstr2 += "Invalid Function";
    break;
  case node->ku8MBResponseTimedOut:
    tmpstr2 += "Response Timed Out";
    break;
  case node->ku8MBInvalidCRC:
    tmpstr2 += "Invalid CRC";
    break;
  default:
    tmpstr2 += "Unknown error: " + String(result);
    break;
  }
  Serial.println(tmpstr2);
  return false;
}

Полезные ссылки

  1. ESP32 DevKit V1 Fritzing Part

Spread the love
Запись опубликована в рубрике IT рецепты с метками , , , , , . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *