Arduino и ModBus

Тема в разделе "Проводная и беспроводная связь", создана пользователем (Svarog), 21 май 2016.

  1. (Svarog)

    (Svarog) Нуб

    Здравствуйте! Проблема такая: я хочу осуществить передачу между двумя Ардуино Уно с помощью протокола Модбас через RS485. Нашел скетчи, собрал схему, но ничего не работает! Помогите разобраться в чем проблема, может ошибка в подключении, может в коде.....Прилагаю скетчи мастера и слейва, а также схему, которую собрал. Как должно быть: Мастер записывает в нулевой регистр единицу, а слейв эту еденицу подает на вывод с подключенным диодом (мне хотя бы для начала сделать это...).

    ВОТ МАСТЕР:
    Код (C++):
    #include <SimpleModbusMaster.h>
    //////////////////// Макроопределения портов и настройки программы  ///////////////////
    #define baud        9600 // скоростьобмена по последовательному интерфейсу. (UART)
    #define timeout     1000 // Длительность ожидание ответа (таймаут modbus)
    #define polling     200  // скорость опроса по modbus
    #define retry_count 10   // количесво запросов modbus до ошибки и останова обмена
    #define TxEnablePin 2    // Tx/Rx пин RS485


    // Общая сумма доступной памяти на master устройстве, для хранения данных
    // не забудьте изменить макроопределение TOTAL_NO_OF_REGISTERS. Если из слейва
    // запрашиваешь 4 регистра, то тогда в массиве reg должно быть не меньше 4х ячеек
    // для хранения полученных данных.

    #define TOTAL_NO_OF_REGISTERS 4

    // Масив пакетов modbus
    enum
    {
      PACKET1,
      PACKET2,

      TOTAL_NO_OF_PACKETS // эту строку неменять
    };

    // Масив пакетов модбус
    Packet packets[TOTAL_NO_OF_PACKETS];
    // Массив хранения содержимого принятых и передающихся регистров
    unsigned int regs[TOTAL_NO_OF_REGISTERS];

    void setup(){
       // Пакет,SLAVE адрес,функция модбус,адрес регистра,данные,локальный адрес регистра.
    modbus_construct(&packets[PACKET1], 1, PRESET_MULTIPLE_REGISTERS, 0, 1, 0); // запись данных master-slave (slave адрес 1, регистр 0)

    // инициализируем протокол модбус
    modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);

    }

    void loop(){
      modbus_update(); // запуск обмена по Modbus
    regs[0] = 1;  // запись данных master-slave (slave адрес 1, регистр 0), запись константы
    }
     
    А ВОТ СЛЕЙВ:
    Код (C++):
    #include <SimpleModbusSlave.h>
    //////////////////// Макроопределения портов и настройки программы  ///////////////////
    #define TxEnablePin  2     // Tx/Rx пин RS485
    #define baud         9600  // скоростьобмена по последовательному интерфейсу. (UART)
    #define timeout      1000  // Длительность ожидание ответа (таймаут modbus)
    #define polling      200   // скорость опроса по modbus
    #define retry_count  10    // количесво запросов modbus до ошибки и останова обмена
    #define Slave_ID     1     // Адрес Slave устройсва
    #define LED1 8

    //////////////// Регистры вашего Slave ///////////////////
    enum
    {  
    //Просто добавьте или удалите регистры. Первый регистр начинается по адресу 0
      master_to_slave_val_1,          //  с адресом массива 0
      master_to_slave_val_2,          //  с адресом массива 1 ---в данном случае не испол-ся(только для примера)
      HOLDING_REGS_SIZE // Это не удалять размер массива HOLDING_REGS.
      //общее количество регистров для функции 3 и 16 разделяет тотже самый массив регистров
      //т.е. то же самое адресное пространство
    };
    unsigned int holdingRegs[HOLDING_REGS_SIZE]; // функции 3 и 16 массив регистров

    void setup()
    {

       modbus_configure(&Serial, baud, SERIAL_8N1, Slave_ID, TxEnablePin, HOLDING_REGS_SIZE, holdingRegs);
       modbus_update_comms(baud, SERIAL_8N1, 1);
       pinMode(LED1, OUTPUT);
    }
    void loop()
    {
      modbus_update(); // запуск обмена по Modbus
               
      // чтение данных master-slave (регистр 0)
    digitalWrite(LED1, holdingRegs[master_to_slave_val_1]);
    }
    Безымянный.png
     
    Последнее редактирование: 21 май 2016
  2. joman

    joman Гик

    Может для начала Вам попробовать без ModBus передать информацию?
    Сделать что то вроде:
    Мастер все время (естественно с небольшой задержкой) пихает в Serial слова (на пример из какого то списка).
    Вместо слейва использовать USBtoTTL конвертер, включенный в комп с запущенным монитором порта и смотреть что в мониторе появляется. Должны получить то, что передаётся.
    Если то, что передаётся получили, то подключить слейв, читать порт и зажигать диод при какой то фразе, выключать при получении других. Убедиться, что светодиод моргает.
    Таким образом Вы сможете убедиться в том, что сообщения доходят. Дальнейшее - дело программирования.
    Тут подробное описание со скетчами:
    http://adatum.ru/podklyuchenie-konvertera-rs-485-v-ttl-k-arduino.html
     
    Последнее редактирование: 25 май 2016