Использование сервера Modbus TCP на Arduino

У меня есть датчик scd30, подключенный к Arduino Uno. scd30 работает по протоколу I2C. Я могу читать данные в реальном времени на последовательном мониторе в Arduino IDE. У меня есть ethernet-шилд на моем Arduino. Я хотел бы, чтобы Arduino связывался с полевым агентом, который будет загружать данные в Интернет.

Я испробовал множество библиотек Modbus TCP, и, похоже, ничего не получалось. Я могу подключить свой Arduino к полевому агенту, но всякий раз, когда он отправляет данные, я получаю код исключения 0x02 — недопустимый адрес данных. Это библиотека, которую я использую https://github.com/andresarmento/modbus- arduino/tree/master/libraries/ModbusIP/примеры

Я считаю, что правильный способ сделать это — хранить регистры, но я не знаю, как это сделать при использовании I2C. Со связью все в порядке, проблема в формате. Спасибо за любую помощь.

/*
Чтение CO2, влажности и температуры с SCD30
В этом примере печатается текущий уровень CO2, относительная влажность и температура в градусах Цельсия.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Modbus.h>
#include <ModbusIP.h>
#include <Wire.h>
#include <Streaming.h>
#include "SparkFun_SCD30_Arduino_Library.h" 

SCD30 airSensor;
//Смещения регистров Modbus (0-9999)
const int SENSOR_ISTS = 100; 
//ModbusIP-объект
ModbusIP mb;
long ts;    

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("SCD30 Example");

 // Адрес управления доступом к среде (аппаратное обеспечение Ethernet) для шилда
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  
    // IP-адрес щита
    byte ip[] = { 000 , 00,0, 00  }; 
    byte gateway[] = { 0, 0, 0, 0 };  
    byte subnet[] = { 255, 255, 255, 0 }; 
    //Конфигурация Modbus IP
    mb.config(mac, ip,gateway,subnet);
    // Добавляем регистр SWITCH_ISTS — используем addIsts() для цифровых входов
    mb.addHreg(SENSOR_ISTS);
  airSensor.begin(); // Это приведет к тому, что показания будут происходить каждые две секунды

}

void loop()
{

mb.task();
   mb.Hreg(SENSOR_ISTS, digitalRead(airSensor.getTemperature()));

}

, 👍0

Обсуждение

[Не переписываться.](https://meta.stackexchange.com/q/64068) Вы уже [спрашивали об этом на SO](https://stackoverflow.com/q/52258447)., @gre_gor


1 ответ


1

Библиотека ModbusIP ожидает от вас указания значения регистра. Библиотека AirSensor дает вам это значение.

Установите значение регистра в Hreg:

mb.Hreg(SENSOR_ISTS, airSensor.getTemperature());

Я протестировал ваш скетч без библиотеки датчиков, и он работает. Клиент был моим тестовым клиентом Java, который я использовал для проверки доступа к регистрам Modbus TCP моей фотоэлектрической системы.

Убедитесь, что клиент вызывает «0x03 — чтение регистров временного хранения» и проверяет адреса 100 и 101, поскольку смещения некоторых клиентов Modbus отсчитываются от 1.

,

Кажется, это не работает. Код компилируется хорошо, но я не думаю, что он действительно их сохраняет. Знаете ли вы какие-либо другие библиотеки, которые могут хранить данные в регистрах Modbus TCP?, @user401708

и как ты это читаешь? какой у вас клиент Modbus TCP?, @Juraj

Это делает полевой агент. Полевой агент считывает регистры Arduino или должен прочитать их, если Arduino настроен правильно., @user401708

какое программное обеспечение использует полевой агент? некоторые смещения клиентов Modbus отсчитываются от 1, поэтому регистр, настроенный как 100 в библиотеке, в этом программном обеспечении должен иметь значение 101. https://github.com/andresarmento/modbus-arduino/blob/master/README.md, @Juraj

это подчиненный модуль Modbus. не знаю точного программного обеспечения. Попробовал изменить его на 101 и все равно получаю ту же ошибку. НЕЗАКОННЫЙ АДРЕС ДАННЫХ, @user401708

и он настроен на вызов «0x03 — чтение регистров хранения»?, @Juraj

я не уверен, как это сделать, @user401708

Вы можете попробовать «0x04 — чтение входных регистров» с помощью Ireg., @Juraj