• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP8266 hw serial не работает с XY-017 (RS485 интерфейс)

Warlib

New member
Добрый день, коллеги,

столкнулся с интересной штукой. Есть модуль XY-485 (он-же XY-017) который обеспечивает RS485 интерфейс. При подключении к RX/TX Arduino Uno заливаю sketch, все работает отлично.
Переношу на Wemos D1 или NodeMCU - не работает. Причем не то, чтобы выдавал ошибку "Response time out". Выдает неверный "Slave ID".

Визуально такая разница. При подключении к Arduino Uno светодиод RXD на XY-485 погашен и промаргивает только когда идет передача данных. При подключении к ESP8266 сразу постоянно горит.

Изрядно помаявшись подключил RX/TX платы XY-485 к двум GPIO через ESPSoftSerial. Т.е. просто перебросил RX/TX не меняя остальные подключения. Все работает таже как на Arduino Uno.

В чем отличие hardware serial порта ESP8266 от Arduino Uno?

Подробное описание подключения: Недорогой RS-485 интерфейс для Arduino/ESP8266/ESP32
 

CodeNameHawk

Moderator
Команда форума
Переношу на Wemos D1 или NodeMCU - не работает.
Так у них стоит переходник UART-USB. Второй на теже ноги вот и не работает.
Тут или родной отключить или взять голую есп, обвешать резисторами и подключить ваш переходник.
 

Warlib

New member
Так у них стоит переходник UART-USB. Второй на теже ноги вот и не работает.
Тут или родной отключить или взять голую есп, обвешать резисторами и подключить ваш переходник.
Печально. На ESP8266 ведь только один полноценый аппаратный последовательный порт?

К сожалению, если отключаю RX или TX платы XY-485 от Wemos D1, то спустя некоторое время SoftwareSerial почему-то выпадает в стек. И после не помогает даже reset, только отключение питания.
 

CodeNameHawk

Moderator
Команда форума
если отключаю RX или TX платы XY-485 от Wemos D1, то спустя некоторое время SoftwareSerial почему-то выпадает в стек
Это как?
Само собой ничего не делается, где то намудрили в коде. Даже если предположить, что не поставили подтягивающего резистора на каждую ногу RX или TX(если их нет на переходнике), то и так не ничего плохого не должно случиться.
 

Warlib

New member
Это как?
Само собой ничего не делается, где то намудрили в коде. Даже если предположить, что не поставили подтягивающего резистора на каждую ногу RX или TX(если их нет на переходнике), то и так не ничего плохого не должно случиться.
Со своим кодом вряд-ли, уж очень его мало. :) Про резисторы хорошо, что напомнили. Думал в библиотеке SoftwareSerial подключены внутренние PULLUP резисторы ESP8266, но посмотрел код, они не подключаются. Попробую добавить.

Код:
#include "ModbusMaster.h"
#include <SoftwareSerial.h>

#define Slave_ID    1
//#define RX_PIN      14  //D5
#define RX_PIN      15  //D8
//#define TX_PIN      12  //D6   
#define TX_PIN      13  //D7
  
SoftwareSerial swSer(RX_PIN, TX_PIN, false, 128);

// instantiate ModbusMaster object
ModbusMaster node;

void setup()
{
  // Modbus communication runs at 9600 baud
  Serial.begin(9600, SERIAL_8N1);
  Serial.setRxBufferSize(128); //Change default 256 to 128
 
  swSer.begin(9600);

  // Modbus slave ID 1
  //node.begin(Slave_ID, Serial);
  node.begin(Slave_ID, swSer);
}

void loop()
{
  Serial.println("Try to read data");
  // Read 2 registers starting at 0x01
  uint8_t result = node.readInputRegisters(0x01, 2);
  if (getResultMsg(result))
  {
    Serial.println();
   
    double res_dbl = node.getResponseBuffer(0)/10;
    String res = "Temperature: " + String(res_dbl) + " C\r\n";
    res_dbl = node.getResponseBuffer(1)/10;
    res += "Humidity: " + String(res_dbl) + " %";
    Serial.println(res);
}
delay(10000);
}

bool getResultMsg(uint8_t result)
{
  String tmpstr2;

  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;
}
резитсто
 

CodeNameHawk

Moderator
Команда форума
Я спрашивал про про библиотеку ModbusMaster, если еще не поняли это она вам выдает ошибку.
 

Warlib

New member
Я спрашивал про про библиотеку ModbusMaster, если еще не поняли это она вам выдает ошибку.
Библиотека не очень хорошо документирвоана, нет четкого указания про поддержку ESP8266, хотя на форуме народ использует.

Нашел другую библиотеку emelianov/modbus-esp8266 - попробую её.

Спасибо.
 

Warlib

New member
Библиотека не очень хорошо документирвоана, нет четкого указания про поддержку ESP8266, хотя на форуме народ использует.

Нашел другую библиотеку emelianov/modbus-esp8266 - попробую её.

Спасибо.
К сожалению, оказалось, что либа поддерживает только Modbus TCP. :-( В общем, похоже под ESP нет стабильных библиотек поддерживающих Modbus RTU.

Вроде как для ModbusMaster нашел workaround повышающий стабильность: отключать WDT на время считывания данных с modbus устройства.


ESP.wdtDisable();
uint8_t result = node.readInputRegisters(0x01, 2);
ESP.wdtEnable(1);

Пока, вроде, не выпадает в стек, когда отваливается один из Rx/Tx контактов.
 

CodeNameHawk

Moderator
Команда форума
выпадает в стек
Выпадает в осадок я еще слышал, а вот выпадает в стек вы наверное в каких то умных книжках прочитали.

Еще как вариант поставьте "промежуточную" атмегу.
 
Последнее редактирование:

Warlib

New member
Выпадает в осадок я еще слышал, а вот выпадает в стек вы наверное в каких то умных книжках прочитали.

Еще как вариант поставьте "промежуточную" атмегу.
Под "выпадением в стек" имел в виду вывод таблицы содержимого адресов.

Soft WDT reset

ctx: cont
sp: 3ffef4f0 end: 3ffef820 offset: 01b0

stack>>>
3ffef6a0: feefeffe feefeffe feefeffe 00000008
3ffef6b0: 00000008 00000003 3ffee4f4 402020ba
3ffef6c0: 12070301 bc640a00 006f0000 014d01de
3ffef6d0: 7f0080bc c03930ff feefefda feefeffe
3ffef6e0: feefeffe feefeffe feefeffe feefeffe
3ffef6f0: feefeffe feefeffe feefeffe feefeffe
3ffef700: feefeffe feefeffe feefeffe feefeffe
3ffef710: feefeffe feefeffe feefeffe feefeffe
3ffef720: feefeffe 00000004 3ffef78f 40202e18
3ffef730: feefeffe feefeffe feefeffe 3ffee73c
3ffef740: 00000031 0000000a 3ffee73c 40202721
3ffef750: 3ffef78b feefeffe feefeffe feefeffe
3ffef760: feefeffe feefeffe 3ffef78a 402027d5
3ffef770: feefeffe feefeffe feefeffe 00004b00
3ffef780: 0000001c 00000000 31fee73c 35343332
3ffef790: feefef00 00000001 3ffe8669 40202e18
3ffef7a0: 00000009 00000009 3ffe8459 3ffee7f0
3ffef7b0: 3ffee4f4 0000000a 3ffee73c 40202721
3ffef7c0: 0000381a 000000e2 3ffee73c 40202721
3ffef7d0: 3ffe8450 3ffee7f0 3ffee73c 3ffee7f0
3ffef7e0: 3ffee4f4 00000000 3ffee4f4 40202260
3ffef7f0: 00000000 00000000 00000001 40201d38
3ffef800: 3fffdad0 00000000 3ffee7e8 40202ba4
3ffef810: feefeffe feefeffe 3ffee800 40100708
<<<stack<<<


Промежуточную железку ставить нежелательно - девайсов надо довольно много (несоколько десятков), поэтому каждый доллар себестоимости должен быть исключен.
 
Последнее редактирование:
Сверху Снизу