ESP32 + RS-485(Mudbus RTU) = работает

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Приветствую.

Собственно столкнулся с задачей, надо считать при помощи ESP32 данные из промышленного контроллера OWEN МВ110-8А(использую MAX485).

Пока что не одна библиотека даже не заставила мигнуть индикатор RS-485 на Овене. 

Пробовал считать при помощи Arduino Nano - без проблем, библиотека SimpleModbusMaster справляется на ура, под ESP32 компилится, но переводит состояние ножки RE/DE раз в 20 медленее.

Может кто-то сталкивался с подобными делами, пусть даже на ESP8266?

Чуть позже сделаю фото осциллограм, что происходит.

Araris
Araris аватар
Offline
Зарегистрирован: 09.11.2012

OFFTOP: Привіт, друже, рад видеть ))).

По теме сказать нечего, моя ESP32 где-то в дороге ещё...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Araris - здоровенькі були.

А если конкретнее - к Овену подключен промышленный термодатчик, и стоит задача получить от Овена по интерфейсу RS-485 температуру которую она измеряет.

Вот этот код на ардуино нано работает так как мне нужно:

/*
   The example will use packet1 to read a register from address 0 (the adc ch0 value)
   from the arduino slave (id=1). It will then use this value to adjust the brightness
   of an led on pin 9 using PWM.
   It will then use packet2 to write a register (its own adc ch0 value) to address 1
   on the arduino slave (id=1) adjusting the brightness of an led on pin 9 using PWM.
*/


unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1;           // interval at which to blink (milliseconds)


#include <SimpleModbusMaster.h>
//////////////////// Port information ///////////////////
#define baud        9600
#define timeout     1000
#define polling     200 // скорость опроса по модбус
#define retry_count 0
#define TxEnablePin 25   // Tx/Rx пин RS485


int16_t val1 = 0;
int16_t val2 = 0;
int16_t val3 = 0;
int16_t val4 = 0;
int32_t val5 = 0;
int32_t val6 = 0;

float VAL = 0.0;

//Общая сумма доступной памяти на ведущем устройстве, чтобы хранить данные
//Локальный регистр это регистры хранения в памяти мастера тоесть масив регистров с адресами от 0 до 29
//ВСЕГО 30 это важно иначе работать не будет всетаки это ардуино а не плк
#define TOTAL_NO_OF_REGISTERS 10


// Это самый простой способ для создания новых пакетов
// Добавить столько, сколько вы хотите. TOTAL_NO_OF_PACKETS
// обновляется автоматически.
enum
{
  PACKET1,
  //  PACKET2,
  //  PACKET3,
  TOTAL_NO_OF_PACKETS // leave this last entry
};

// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];

// Массив хранения содержимого принятых и передающихся регистров

unsigned int regs[TOTAL_NO_OF_REGISTERS];

/*
  float convert_uint_to_float(unsigned int hw, unsigned int lw) {
        union {
          float f;
          unsigned short i[2];
        } convert_float_uint;
        convert_float_uint.i[0] = lw;
        convert_float_uint.i[1] = hw;
        return (convert_float_uint.f);
        }
*/

void setup()
{
  // инициализируем протокол модбус
  //Valid modbus byte formats are:
  //     SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
  //     SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
  //     SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit
  modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

  // Настраиваем пакеты
  // Шестой параметр - это индекс ячейки в массиве, размещенном в памяти ведущего устройства, в которую будет
  // помещен результат или из которой будут браться данные для передачи в подчиненное устройство. В нашем коде - это массив reg
  // Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
  //  modbus_construct(&packets[PACKET1], 100, READ_COIL_STATUS, 48, 1, 0);
  //  modbus_construct(&packets[PACKET2], 100, READ_INPUT_STATUS, 48, 1, 1);
  //  modbus_construct(&packets[PACKET3], 100, READ_HOLDING_REGISTERS, 48, 1, 2);
  modbus_construct(&packets[PACKET1], 16, READ_HOLDING_REGISTERS, 0, 6, 0);
  //  modbus_construct(&packets[PACKET2], 50, READ_HOLDING_REGISTERS, 49, 1, 1);
  //  modbus_construct(&packets[PACKET3], 50, READ_HOLDING_REGISTERS, 50, 1, 2);

  //  modbus_construct(&packets[PACKET2], 14, READ_HOLDING_REGISTERS,    11, 1, 1);
  //  modbus_construct(&packets[PACKET3], 15, READ_HOLDING_REGISTERS,    11, 1, 1);
  //  modbus_construct(&packets[PACKET4], 16, READ_HOLDING_REGISTERS,    11, 1, 1);
  //  modbus_construct(&packets[PACKET5], 17, READ_HOLDING_REGISTERS,    11, 1, 1);

  // Пакет,SLAVE адрес,функция модбус,адрес регистра,количесво запрашиваемых регистров,локальный адрес регистра.
  //modbus_construct(&packets[PACKET3], 1, PRESET_MULTIPLE_REGISTERS, 2, 1, 2);
  //modbus_construct(&packets[PACKET4], 1, PRESET_MULTIPLE_REGISTERS, 3, 1, 3);


}

void loop()
{
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;


    modbus_update();
    //val_f_1 = regs[0]; // чтение данных slave-master (slave адрес 4, в регистр 0) (регистр 0 находится на ардуине)
    val1 = regs[0];
    val2 = regs[1];
    val3 = regs[2];
    val4 = regs[3];
    val5 = regs[4];
    val6 = regs[5];

    VAL = val2 / 10.0;

    // Вывод в сериал
    //  val2 = regs[1]; // чтение данных slave-master (slave адрес 100, регистр 1)
    //  val3 = regs[2]; // чтение данных slave-master (slave адрес 100, регистр 2)
    //  int val =  val1 + val2 + val3;
    //  if (val > 0){digitalWrite(LED1, HIGH);}
    //  else{digitalWrite(LED1, LOW);}//если пришло 255 зажигаем светодиод

    //  if (val1 > 0){digitalWrite(LED1, HIGH);}
    //  if (val2 > 0){digitalWrite(LED1, HIGH);}
    //  if (val3 > 0){digitalWrite(LED1, HIGH);}
    //  else{digitalWrite(LED1, LOW);}//если пришло 255 зажигаем светодиод


    //unsigned int temp2;
    //regs[0] = analogRead(0);       // запись данных master-slave
    //analogWrite(LED, regs[0]>>2);  // чтение данных slave-master (ограничеть количесво бит данных числом 255)
    //regs[0] = 255;   // запись данных master-slave (slave адрес 1, регистр 1)


    //temp2 = regs[3]; // чтение данных slave-master (slave адрес 1, регистр 4)

    //if (temp2 == 255){digitalWrite(LED1, HIGH);}else{digitalWrite(LED1, LOW);}
    Serial.print("val1=");
    Serial.println(val1);

    Serial.print("val2=");
    Serial.println(val2);

    Serial.print("val3=");
    Serial.println(val3);

    Serial.print("val4=");
    Serial.println(val4);

    Serial.print("val5=");
    Serial.println(val5);

    Serial.print("val6=");
    Serial.println(val6);

    Serial.print("Temperature = ");
    Serial.println(VAL);
  }
}

 


Синий луч - изменение состояния на RE/DE ножках микросхемы MAX485, жёлтый - TXD микроконтроллера.

Данный код под ESP32 компилится и работает, но ооочень медленно(обратите внимание на временную равёртку):

Мало того, ещё и переключает режим MAX485 раньше чем нужно:
 

 

Подключился к RS-485 через USB переходник и вижу что в шине нули:

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Из-за особенностей реализации Serial.flush() для ESP32 переключение ноги прием-передача происходит раньше. Естественно, никакого вменяемого пакета клиент не получает, поскольку контрольная сумма не совпадает. Нужно изменять реализацию sendPack, в файле SimpleModbusMaster.cpp

Например вот так

void sendPacket(unsigned char bufferSize)
{
  if (TxEnablePin > 1)
    digitalWrite(TxEnablePin, HIGH);

  previousTimeout = millis();  // <=тут изменить
  
  for (unsigned char i = 0; i < bufferSize; i++)
    Serial.write(frame[i]);

  unsigned int timeout=((10000UL * (bufferSize+3))/(35000000/3_5)); // <=тут изменить
  while(millis()-previousTimeout<timeout) delay(1); // <=тут изменить
    
  if (TxEnablePin > 1)
    digitalWrite(TxEnablePin, LOW);
    
  previousTimeout = millis(); // initialize timeout delay 
}

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Да, функция Serial.flush() на ESP32 работает некорректно, это факт.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Пожалуйста.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Вот этот код чётко работает на Arduino Nano:
 

/*
   The example will use packet1 to read a register from address 0 (the adc ch0 value)
   from the arduino slave (id=1). It will then use this value to adjust the brightness
   of an led on pin 9 using PWM.
   It will then use packet2 to write a register (its own adc ch0 value) to address 1
   on the arduino slave (id=1) adjusting the brightness of an led on pin 9 using PWM.
*/
#include <SimpleModbusMaster.h>
//////////////////// Port information ///////////////////
#define baud        9600
#define timeout     1000
#define polling     200 // скорость опроса по модбус
#define retry_count 0
#define TxEnablePin 13  // Tx/Rx пин RS485


int16_t val1 = 0;
int16_t val2 = 0;
int16_t val3 = 0;
int16_t val4 = 0;
int32_t val5 = 0;
int32_t val6 = 0;

float VAL = 0.0;

unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 250;           // interval at which to blink (milliseconds)


//Общая сумма доступной памяти на ведущем устройстве, чтобы хранить данные
//Локальный регистр это регистры хранения в памяти мастера тоесть масив регистров с адресами от 0 до 29
//ВСЕГО 30 это важно иначе работать не будет всетаки это ардуино а не плк
#define TOTAL_NO_OF_REGISTERS 10


// Это самый простой способ для создания новых пакетов
// Добавить столько, сколько вы хотите. TOTAL_NO_OF_PACKETS
// обновляется автоматически.
enum
{
  PACKET1,
  //  PACKET2,
  //  PACKET3,
  TOTAL_NO_OF_PACKETS // leave this last entry
};

// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];

// Массив хранения содержимого принятых и передающихся регистров

unsigned int regs[TOTAL_NO_OF_REGISTERS];

void setup()
{
  // инициализируем протокол модбус
  //Valid modbus byte formats are:
  //     SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
  //     SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
  //     SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit
  modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

  modbus_construct(&packets[PACKET1], 16, READ_HOLDING_REGISTERS, 0, 6, 0);
  /*
     modbus_construct(&packets[PACKET1], a, READ_HOLDING_REGISTERS, b, c, d);
    a - SLAVE адрес
    b - адрес регистра
    c - колличество запрашиваемых регистров
    d - номер ячейки массива куда запишутся данные
  */
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    modbus_update();

    val1 = regs[0];
    val2 = regs[1]; // возвращает температуру в формате 123 - 12.3 градуса
    val3 = regs[2]; 
    val4 = regs[3];
    val5 = regs[4];
    val6 = regs[5];

    VAL = val2 / 10.0;
    // Вывод в сериал

        Serial.print("val1 = ");
        Serial.println(val1);
         Serial.print("val2 = ");
        Serial.println(val2);
         Serial.print("val3 = ");
        Serial.println(val3);
         Serial.print("val4 = ");
        Serial.println(val4);
         Serial.print("val5 = ");
        Serial.println(val5);
         Serial.print("val6 = ");
        Serial.println(val6);
  
    Serial.print("Temoerature = ");
    Serial.println(VAL,1);
  }
}

Ссылка на библиотеку SimpleModbusMasterV2rev2:

https://drive.google.com/file/d/1AQggEa6UnQLptpZGrw3t3ZvFZ_RR3wzH/view?usp=sharing

Вот так работа выглядит на осциллографе:

Жёлтый - TX ардуины, синий - RE/DE ножка микросхемы MAX485.

Вот такое наблюдаю в RS-485 шине при помощи переходника с RS-485 на USB.

Сейчас попробую аналогичным образом всё показать как на ESP32 этот же код крутится.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

На ESP32 приведённая мною выше библиотека работает следующим образом:

В сериале ESP32 полная тишына, если подключить USB - RS-485 переходник то можно в шине увидить следующее:

 

Как видно одни нули.
На осциллографе следующая картина:

Обратите внимание на время через которее изменяется состояние на ножке RE/DE, это секунд 7-8 примерно, что наталкивает на мысль - библиотека работает значительно медленее чем ра Arduino Nano.

b707
Offline
Зарегистрирован: 26.05.2017

имхо, если на нано все работает - надо сделать из атмеги переходник для общения с ОВЕНом и все дела. Если пойдет библиотека, можно под переходник взять не атмегу328, а что-нибудь попроще, типа тини45 или 85

RizONE
Offline
Зарегистрирован: 22.03.2018

HWman пишет:

Пробовал считать при помощи Arduino Nano - без проблем

Схему подключения не скинете?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

RizONE пишет:
HWman пишет:
Пробовал считать при помощи Arduino Nano - без проблем
Схему подключения не скинете?

Да, вот:

 

Питаю микросхему от 3.3 В в случае с ESP32, и от 5-ти - Arduino.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

b707 пишет:

имхо, если на нано все работает - надо сделать из атмеги переходник для общения с ОВЕНом и все дела. Если пойдет библиотека, можно под переходник взять не атмегу328, а что-нибудь попроще, типа тини45 или 85


Я думал над этим... Но хз как-то, городить горы микроконтроллеров это вообще как-то не это... Комильфо. Хотя в данный момент ничего не вижу кроме как сделать так.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

На осциллограмме скорее всего шум. Что на шине МодБас, можно посмотреть ?

В "новой" библиотеке так же используется flush, так почему же она должна работать ? Я же дал вам пример исправления библиотеки, чем он вам не подошел ?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

brokly пишет:

На осциллограмме скорее всего шум. Что на шине МодБас, можно посмотреть ?

В "новой" библиотеке так же используется flush, так почему же она должна работать ? Я же дал вам пример исправления библиотеки, чем он вам не подошел ?


Нет, не шум это, это шлёт ЕСПшка по мудбас, как я и говорил - в шине мудбас нули одни.

Спасибо большое за код, я подставлял его, всё равно ничего корректно не отрабатывало. Скорее всего где-то есть привязка к частоте микроконтроллера, у ардуины 16, а у есп32 240 МГц.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Не, нет никаких привязок. Вы можете в цикле с поднятой ножкой передача просто отправлять что то типа 0xAA  и глянуть осциллографом что на шинах A и B ?

RizONE
Offline
Зарегистрирован: 22.03.2018

HWman пишет:

Да, вот:

Спасибо. Попробую Ваш скетч прикрутить к своей задаче, а то на библиотеке ModbusRtu.h у меня пока не получается.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

RizONE пишет:

Спасибо. Попробую Ваш скетч прикрутить к своей задаче, а то на библиотеке ModbusRtu.h у меня пока не получается.


Нет, это не мой скетч.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

brokly пишет:

Не, нет никаких привязок. Вы можете в цикле с поднятой ножкой передача просто отправлять что то типа 0xAA  и глянуть осциллографом что на шинах A и B ?


Без диференциирования интересует осциллограмма?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Лучше отдельно A-земля и B-земля... 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Цитата:
Питаю микросхему от 3.3 В в случае с ESP32, и от 5-ти - Arduino.
Это MAX485 от 3.3 В запитываешь? А почитать datasheet на неё не пробовал?

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Andy пишет:

Цитата:
Питаю микросхему от 3.3 В в случае с ESP32, и от 5-ти - Arduino.
Это MAX485 от 3.3 В запитываешь? А почитать datasheet на неё не пробовал?


Таки да, рекомендуютпитать от 5V.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

brokly пишет:

Не, нет никаких привязок. Вы можете в цикле с поднятой ножкой передача просто отправлять что то типа 0xAA  и глянуть осциллографом что на шинах A и B ?


Прошил код из этого поста в ESP32, на линии А относительно земли следующая картина(синий луч - А, жёлтый - RE/DE):

На линии В:

Вот такое с Вашей функцией, A:

На линии B:

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ножка направления явно рано  сбрасывается

Попробуйте 11 строку в моей правке изменить :

unsigned int timeout=((10000UL * (bufferSize+6))/(35000000/3_5)); // 

А по правильности данных - не понятно. Меня вообще эти осциллограммы удивляют. У вас A и B обязаны быть противофазными. А я вижу обратное. Точно знаю что чудес не бывает. А у вас - чудо.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Вообщем принял решение выгрузить работу с RS-485 на ардуинку, устроил общение посредтвом UART и AT команд.

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Надо же, нашёл библиотеку, которая завелась на ESP32, обзывается она - SimpleModbusMasterV2rev2_DUE
 

Скетч:

/*
   The example will use packet1 to read a register from address 0 (the adc ch0 value)
   from the arduino slave (id=1). It will then use this value to adjust the brightness
   of an led on pin 9 using PWM.
   It will then use packet2 to write a register (its own adc ch0 value) to address 1
   on the arduino slave (id=1) adjusting the brightness of an led on pin 9 using PWM.
*/

#include <SimpleModbusMaster_DUE.h> 
// https://github.com/jecrespo/simple-modbus

//////////////////// Port information ///////////////////
#define baud        9600
#define timeout     1000
#define polling     200 // скорость опроса по модбус
#define retry_count 0
#define TxEnablePin 13 // Tx/Rx пин RS485


int16_t val1 = 0;
int16_t val2 = 0;
int16_t val3 = 0;
int16_t val4 = 0;
int32_t val5 = 0;
int32_t val6 = 0;

float VAL = 0.0;

unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 250;           // interval at which to blink (milliseconds)


//Общая сумма доступной памяти на ведущем устройстве, чтобы хранить данные
//Локальный регистр это регистры хранения в памяти мастера тоесть масив регистров с адресами от 0 до 29
//ВСЕГО 30 это важно иначе работать не будет всетаки это ардуино а не плк
#define TOTAL_NO_OF_REGISTERS 10


// Это самый простой способ для создания новых пакетов
// Добавить столько, сколько вы хотите. TOTAL_NO_OF_PACKETS
// обновляется автоматически.
enum
{
  PACKET1,
  //  PACKET2,
  //  PACKET3,
  TOTAL_NO_OF_PACKETS // leave this last entry
};

// Масив пакетов модбус
Packet packets[TOTAL_NO_OF_PACKETS];

// Массив хранения содержимого принятых и передающихся регистров

unsigned int regs[TOTAL_NO_OF_REGISTERS];

void setup()
{
  // инициализируем протокол модбус
  //Valid modbus byte formats are:
  //     SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
  //     SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
  //     SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit
  //modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
  modbus_configure(&Serial, baud, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

  modbus_construct(&packets[PACKET1], 16, READ_HOLDING_REGISTERS, 0, 6, 0);
  /*
     modbus_construct(&packets[PACKET1], a, READ_HOLDING_REGISTERS, b, c, d);
    a - SLAVE адрес Овена
    b - адрес регистра
    c - колличество запрашиваемых регистров
    d - номер ячейки массива куда запишутся данные
  */
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    modbus_update();

    val1 = regs[0]; // смещение точки, например 1 - 123= 12.3
    val2 = regs[1]; // возвращает температуру в формате 123 - 12.3 градуса
    val3 = regs[2];
    val4 = regs[3];
    val5 = regs[4];
    val6 = regs[5];

    VAL = val2 / 10.0;
    // Вывод в сериал


    Serial.print("val1 = ");
    Serial.println(val1);
    Serial.print("val2 = ");
    Serial.println(val2);
    Serial.print("val3 = ");
    Serial.println(val3);
    Serial.print("val4 = ");
    Serial.println(val4);
    Serial.print("val5 = ");
    Serial.println(val5);
    Serial.print("val6 = ");
    Serial.println(val6);


    Serial.print("Temp = ");
    //Serial.println(VAL, 1);
    Serial.println(VAL, val1);
  }
}

Крутость этого решения заключается в том, что тут тебе и 2 ядра, и вай фай, и блютуз, АЦП и ЦАП... Я в своих наработках использую одно ядро под RS-485 а второе под простенький вебсервер, и ещё куча процессорного времени есть в запасе. ESP32 можная штука, это факт.

Ирония заключается в том, что когда вообщем всё сделал уже на ардуине в формате АТ-комманд, случайно наткнулся на эту библиотеку, месяц тупежа по сути.

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Предлагаю изменить название темы на "ESP32 + RS-485(Mudbus RTU) = работает"

 

Araris: - изменил )) ]

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Подтверждаю работу на ESP32 библиотеки SimpleModbusSlaveV10_DUE(режим Slave) из поста выше

Прикинулся Овеном по ID и отсылал содержимое нужных регистров.

Схема подключения аналогичная как в этом посте, только питаю MAX485 от 5 В и сигнал подаю на RX/TX еэспэшки.

Вообщем огромный простор для полёта фантазии учитывая колличество памяти в ESP32 ;)

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Ха, поспешил я радоваться. примерно через мину​​т 5 еспшка перестаёт отвечать на запросы по RS-485

И лечится всё только перегрузкой платы...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

 

Похоже всё решилось, слишком часто теребил функцию  modbus_update(); - прибавил делей на 50 мс и всё заработало.

kaustubhawade
Offline
Зарегистрирован: 26.09.2018

HWman пишет:

 

Похоже всё решилось, слишком часто теребил функцию  modbus_update(); - прибавил делей на 50 мс и всё заработало.

 

Hello HWMan,

can you please share the code and modifications done to run this library on ESP32

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

kaustubhawade пишет:

HWman пишет:

 

Похоже всё решилось, слишком часто теребил функцию  modbus_update(); - прибавил делей на 50 мс и всё заработало.

 

Hello HWMan,

can you please share the code and modifications done to run this library on ESP32

 

#include <SimpleModbusSlave_DUE.h> // github.com/jecrespo/simple-modbus

//Debuging settings:
#define DebugToUART false

#define ReDePin 12 // Re/De Pin

int maxNumRegisters = 6; // 6 regs

int RS485Result[] = {4, 8, 15, 16, 23, 42}; // 6

enum
{
  d0,
  d1,
  d2,
  d3,
  d4,
  d5,
  HOLDING_REGS_SIZE // leave this one
};

unsigned int holdingRegs[HOLDING_REGS_SIZE];



void setup() {
  modbus_configure(&Serial, 9600, 10, ReDePin, HOLDING_REGS_SIZE, holdingRegs);
  modbus_update_comms(9600, 10); //  register addres 10
}

void loop() {
  modbus_update();
  holdingRegs[d0] = RS485Result[0];
  holdingRegs[d1] = RS485Result[1];
  holdingRegs[d2] = RS485Result[2];
  holdingRegs[d3] = RS485Result[3];
  holdingRegs[d4] = RS485Result[4];
  holdingRegs[d5] = RS485Result[5];
#if DebugToUART
  debuging();
#endif
}


void debuging() {
  for (int dbg = 0; dbg < maxNumRegisters; dbg++) {
    Serial.print(" ");
    Serial.print(dbg);
    Serial.print(" = ");
    Serial.print(RS485Result[dbg]);
    Serial.print(",");
  }
  Serial.println("");
}

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Set
Offline
Зарегистрирован: 07.02.2017

Здравствуйте господа! Может кто знает? Библиотека SimpleModbusMaster_DUE, опрос, а также запись регистров ведется пачкой, и по циклу при помощи modbus_update();, есть ли в этой библиотеке возможность записи отдельно каждого пакета? Смысл в том, что мне необходимо запись производить только один раз, когда мне это нужно, а не в цикле вмеcте с чтением. И если есть, может примеры найдутся? В сети информацию на эту тему найти не получается.