Приветствую.
Помогите с проблемой связи Ардуино с ПК через 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));
}
}