Ардуино и Modbus RTU RS 485

Приветствую.
Помогите с проблемой связи Ардуино с ПК через MAX485.
Составлен скетч и проверен на взаимодействие с ПК СКАДА СИМПЛАЙТ через USB ардуино.
Все работает, производится запись/чтение Coil, input, holding регистров.
Теперь надо все это опросить через RS485, для этого стандартно подключен MAX485 со стороны ПК USB/485 (без 422 только АВ).
Вроде как написано, что в библиотеке ModbusRtu.h класс
Modbus slave(ID, 1, 2);
в таком виде поддерживает RS 485 на пинах RX/TX и сигналом направления передачи на пине 2. Не работает.

/*Проект взаимодействия датчиков со СКАДА Симплайт (проект Modbac_arduino)
4 дискретных выхода, один из них ШИМ
1 дискретный вход
1 вход датчика температуры типа ДНТ*/
#include "ModbusRtu.h"
#include <DHT.h>


#define SerialTxControl 2 // Пин 2 будет переключать режим приёмник/передатчик
#define RS485Transmit HIGH
#define RS485Receive LOW

#define DHTPIN 9             // номер входа, подключенный к датчику температуры
#define DHTTYPE DHT11        // Тип датчика температуры
#define ID   1               // адрес ведомого
#define btnPin  3            // номер входа, подключенный к кнопке
#define stlPin  13           // номер выхода индикатора работы расположен на плате Arduino 
#define ledPin1  5           // номер выхода светодиода
#define ledPin2  6           // номер выхода светодиода
#define ledPin3  7           // номер выхода светодиода
#define ledPin4  8           // номер выхода светодиода

Modbus slave(ID, 1, 2);       //Задаём ведомому адрес, последовательный порт, выход управления TX
DHT _dht1(DHTPIN, DHTTYPE);   //Запускаем датчик ДНТ
int8_t state = 0;
uint16_t au16data[11];          // массив данных modbus

unsigned long tempus = 0UL;      //Период опроса модбас
unsigned long tempus2 = 0UL;     //Период опроса датчика ДНТ
int _ledlight;                   //Яркость светодиода
float _dht1t = 0.00;
float _dht1h = 0.00;

void setup() {
  _dht1.begin();
  io_setup();                   // настраиваем входы и выходы
  slave.begin( 9600 );          // настраиваем последовательный порт ведомого
  tempus = millis() + 100;      // зажигаем светодиод на 100 мс
  digitalWrite(stlPin, HIGH );
  
}

void io_setup() {               // настраиваем входы и выходы
  digitalWrite(stlPin, HIGH ); 
  digitalWrite(ledPin1, LOW );
  digitalWrite(ledPin2, LOW );
  digitalWrite(ledPin3, LOW );
  digitalWrite(ledPin4, LOW );
  pinMode(stlPin, OUTPUT);
  pinMode(ledPin1, OUTPUT); 
  pinMode(ledPin2, OUTPUT); 
  pinMode(ledPin3, OUTPUT); 
  pinMode(ledPin4, OUTPUT); 
  pinMode(btnPin, INPUT);  
}

void loop() {
   state = slave.poll( au16data, 11);          // обработка сообщений 
   if (state > 4) {                              // если получили пакет без ошибок - зажигаем светодиод на 50 мс 
    tempus = millis() + 50;
    digitalWrite(stlPin, HIGH);
   }
   if (millis() > tempus) digitalWrite(stlPin, LOW );
   //обновляем данные в регистрах Modbus и в пользовательской программе
   io_poll();
   ai_poll();
  }

  void io_poll() {
    au16data[0] = au16data[1];                            //Копируем Coil[1] в Discrete[0]
    digitalWrite( ledPin1, bitRead( au16data[1], 1 ));      //Выводим значение регистра  на светодиоды
    //digitalWrite( ledPin2, bitRead( au16data[1], 2 )); 
    digitalWrite( ledPin3, bitRead( au16data[1], 3 ));
    digitalWrite( ledPin4, bitRead( au16data[1], 4 ));
    bitWrite( au16data[0], 5, digitalRead( btnPin ));         //Сохраняем состояние кнопки в регистр 5
    _ledlight = int(au16data[7]);                           //Яркость светодиода из 7 холдинг регистра
    au16data[8] = au16data[7]; 
    analogWrite (ledPin2, _ledlight/4);                     //Записываем яркость на светодиод
    
  }
  
  void ai_poll(){                         //Чтение датчика ДНТ и запись в регистры Модбас
    if (_isTimer(tempus2, 3000)) {
    tempus2 = millis();
    float tempDht3;
    tempDht3 = _dht1.readTemperature();
    if (!(isnan(tempDht3))) {
      _dht1t = tempDht3*100;              // Значение температуры *100 
      au16data[5] = _dht1t;               // Записываем в холдинг регистр 
     /* Serial.print("Humidity: ");       // Для контроля пишем в порт
      Serial.print(_dht1t);
      Serial.print(" %\t");*/
    }
    tempDht3 = _dht1.readHumidity();
    if (!(isnan(tempDht3))) {
      _dht1h = tempDht3*100;              // Значение температуры *100 
      au16data[6] = _dht1h;
     /* Serial.print("Temperature: ");    // Для контроля пишем в порт
      Serial.print(_dht1h);
      Serial.println(" *C "); */
    }
    }
  }


bool _isTimer(unsigned long startTime, unsigned long period ) //Таймер паузы
{
  unsigned long currentTime;
  currentTime = millis();
  if (currentTime >= startTime) {
    return (currentTime >= (startTime + period));
  } else {
    return (currentTime >= (4294967295 - startTime + period));
  }
}

Почему 1 и 2, а не 0 и 1 ?

Посмотрел библиотеку.
Там id/stream/txEn

 // >>>>> Deprecated: Use constructor: "Modbus m(0,Serial,0)" instead.  <<<<<<<<<
    Modbus(uint8_t u8id=0, uint8_t u8serno=0, uint8_t u8txenpin=0) __attribute__((deprecated));

Example:

#define TXEN	4 
...
Modbus slave(1,Serial,TXEN); // this is slave @1 and RS-485

В оригинале у меня вот так выглядит конструктор:

Modbus(uint8_t u8id, Stream& port, uint8_t u8txenpin =0);

Т.е. в коде ТС должно быть так:

Modbus slave(ID, Serial, SerialTxControl);

Спасибо, сделал так, но не работает через max485, только через УСБ,

Ну осталось только узнать как к ардуино подключена max485

Спасибо! Самое интересное что заработало на УНО, на НАНО отказывается работать
(да, я знаю что на нано ТХ РХ по другому расположены) Все равно спасибо, за правильную строку инициализацию.

На Уно и нано rx/tx расположены точно так же

Перепроверил еще раз. Логически РХ = 0 ТХ = 1 у обоих, но в НАНО ТХ с краю, нумерация 1,0,2

И что там не соответствует ?
TX-1
RX-0

На UNO точно так же.

Здравствуйте, есть предложение к вам по разработке скетча на Ардуино, не нашёл, как написать в личку, буду признателен, если напишите на vice.pr@gmail.com

К кому - коллективному бессознательному?

Прошу прощения, ошибся кнопкой, не там нажал ответ. Вообще писал именно вам)

Подскажи, плз, куда на Ардуинке заведены контакты RO, DI, DE, RE ?

DE, RE - соединить и присоединить к ноге, которую ты назначил как направление передачи. RO, DI - к ногам приёма и передачи последовательного порта, который ты выбрал.

Можно ли реализовать самоконтроль работы по модбасу? Хотелось бы, чтобы когда происходит опрос ардуинки, горел светодиод на указанном выходе. Если опроса нет, соответственно, не горел.

да. Для этого каждая команда возвращает статус.

Использую эти библиотеки:
#include <SoftwareSerial.h>
#include <ModbusRTUSlave.h>

Для обмена используется одна команда modbus.poll(); и она ничего не возвращает

Кто ж виноват что эта библиотека такая ущербная. Нормальные библиотеки возвращают. Например GitHub - smarmengol/Modbus-Master-Slave-for-Arduino: Modbus Master-Slave library for Arduino