В предыдущей статье я рассмотрел несколько Arduino RS485 shields. Некоторые стоят немало, больше 20 USD. В этой статье я рассмотрю Arduino RS485 shield стоимостью около 3 USD.
На Aliexpress заказал IO expansion shield with RS485 interface и чтобы запустить в работу пришлось немного повозится. У китайцев на Aliexpress нет никакого описания подключения платы. Описание нашел у одного из производителей. Поскольку с тестовым примером схема не заработала, пока разбирался, проверил омметром и нарисовал красным соединительные линии.
В качестве RS485 Modbus устройства используется датчик температуры и влажности из моей предыдущей статьи. Код программы для Arduino:
#include "ModbusMaster.h"
/*!
IO Expansion Shield For Arduino (V5) (SKU: DFR0088) RS485 interface.
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable (DE) and Receiver Enable (RE) pins are hooked up as follows:
*/
#define MAX485_RE_NEG 2 //RS485 has a enable/disable pin to transmit or receive data. Arduino Digital Pin 2 = Rx/Tx 'Enable'; High to Transmit, Low to Receive
#define Slave_ID 1
// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, HIGH); //Switch to transmit data
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, LOW); //Switch to receive data
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, LOW);
// Modbus communication runs at 9600 baud
Serial.begin(9600, SERIAL_8N1);
// Modbus slave ID 1
node.begin(Slave_ID, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
// Read 2 registers starting at 0x01
uint8_t result = node.readInputRegisters(0x01, 2);
if (getResultMsg(result))
{
Serial.println();
double res_dbl = node.getResponseBuffer(0)/10;
String res = "Temperature: " + String(res_dbl) + " C\r\n";
res_dbl = node.getResponseBuffer(1)/10;
res += "Humidity: " + String(res_dbl) + " %";
Serial.println(res);
}
delay(10000);
}
bool getResultMsg(uint8_t result)
{
String tmpstr2;
switch (result) {
case node.ku8MBSuccess:
return true;
break;
case node.ku8MBIllegalFunction:
tmpstr2 = "Illegal Function";
break;
case node.ku8MBIllegalDataAddress:
tmpstr2 = "Illegal Data Address";
break;
case node.ku8MBIllegalDataValue:
tmpstr2 = "Illegal Data Value";
break;
case node.ku8MBSlaveDeviceFailure:
tmpstr2 = "Slave Device Failure";
break;
case node.ku8MBInvalidSlaveID:
tmpstr2 = "Invalid Slave ID";
break;
case node.ku8MBInvalidFunction:
tmpstr2 = "Invalid Function";
break;
case node.ku8MBResponseTimedOut:
tmpstr2 = "Response Timed Out";
break;
case node.ku8MBInvalidCRC:
tmpstr2 = "Invalid CRC";
break;
default:
tmpstr2 = "Unknown error: " + String(result);
break;
}
Serial.println(tmpstr2);
return false;
}
При загрузке sketch на плату иногда возникает ошибка вида:
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x00
Лечится, либо снятием IO expansion shield перед «Upload» sketch, либо снятием крайнего правого джампера RS485, чтобы разорвать RX соединение с MAX485 чипом.