Самый дешевый вариант RS485 интерфейса — плата без всякой «обвязки» для защиты чипсета MAX485. Она продается по цене около 0,3 $ Брал у поставщика оптом 5 шт, так выгоднее. Да и поскольку плата без защиты линии RS485 — возможно, чип будет периодически выгорать.
В промышленной эксплуатации лучше использовать ранее рассмотренные XY-485 или XY-017. Они более защищены от различных проблем, вроде удара молнии.
Wemos D1 mini (ESP8266) широко представлен на Aliexpress по цене менее 3 USD.
Схема соединения платы RS485 с Wemos D1 mini
WeMos D1 Mini | RS485 (MAX485 chipset) |
Rx (GPIO5, D1) | RO (receiver output) |
Tx (GPIO2, D4) | DI (driver input) |
DE_RE (GPIO4, D2) | DE (driver enable) RE (receiver enable) |
3,3V | VCC (Блок питания +3,3V) |
G | GND |
DI (driver input) — цифровой вход передатчика;
RO (receiver output) — цифровой выход приемника;
DE (driver enable) — разрешение работы передатчика;
RE (receiver enable) — разрешение работы приемника;
Пины DE И RE закорачиваем.
Модуль RS485 лучше запитывать от отдельного блока питания!
Термодатчик | RS485 (MAX485 chipset) |
A+ | A+ |
B- | B- |
GND | GND |
GND (Блок питания -) | |
VCC (Блок питания +5V) |
ESP8266 программа для работы с RS485 c DE/RE
#include "ModbusMaster.h" //https://github.com/4-20ma/ModbusMaster #include <SoftwareSerial.h> //https://github.com/plerup/espsoftwareserial /*! 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 //D2 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 5 //D1 #define TX_PIN 2 //D4 // instantiate ModbusMaster object ModbusMaster modbus; SoftwareSerial swSer(RX_PIN, TX_PIN, false, 128); 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); // Modbus slave ID 1 swSer.begin(9600); modbus.begin(Slave_ID, swSer); // 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) { ESP.wdtDisable(); uint8_t result = modbus.readInputRegisters(0x01, 2); ESP.wdtEnable(1); if (getResultMsg(&modbus, result)) { Serial.println(); double res_dbl = modbus.getResponseBuffer(0) / 10; String res = "Temperature2: " + String(res_dbl) + " C\r\n"; res_dbl = modbus.getResponseBuffer(1) / 10; res += "Humidity2: " + 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; }
Полезные ссылки