Någon kanske får nytta av det.
Hur som, på jobbet behöver vi nån pryl att prova ModBus-kommunikation mot. Nåt enkelt som vi har koll på, och kan ändra ID och baudrate på.
Så jag kom på idén att bygga en pryl av en arduino helt enkelt.
Initialt är det ModBus över RS485 som är intressant. Men jag vet inte om man kan styra vilken av TX/RX-pinnarna ModBusen kommunicerar över, så enklast vore ju faktiskt att använda en så enkel Arduino som möjligt och fysiskt växla vilket gränssnitt som jag kommunicerar med.
Så en Arduino Pro Mini valdes, utan USB-port.
Till denna köptes sen en USB-TTL och en RS485-TTL. Dessa kan jag sen bygla in beroende på vilken jag vill nyttja.
Mitt USB-TTL har ingen reset vid programmering, så man får resetta manuellt vid nedladdning av kod, men det är inget problem.
RS485-gränssnittet ansluts precis som USB-gränssnittet, med undantaget av att det finns en enable som måste sättas hög.
Första testet var helt enkelt att skicka ett Hello World. Via USB (som emulerar en COM-port på datorn) var det inga problem att ta emot texten.
Men via RS485 var det värre, "text" tas emot, men inte alls läsbart. Förmodligen beror det på det USB-RS485 gränssnitt jag använder, det är inte helt säkert att det är transparent så att säga. Det testet kan dock vänta, nånting kommer ju, så det lär väl fungera.
ModBus-programmet då, det baseras på exempel från ArduinoModbus, och jag lägger upp 10 coils och 10 holding.
Sedan mappar jag den LED som finns på Arduinon till en coil, och resterande får några ingångar mappade, och nån helt utan mappning. Då kan man testa läsa/skriva och se att det händer nåt.
De 10 holding är mappade mot de 4 analoga ingångarna, några har fasta värden, nån replikerar aktuell baudrate. Samma här, man kan läsa och skriva och se att nåt händer.
Så test med ett annat RS485-gränssnitt mot prylen ska utföras. Sen kan man komplettera med RS422 eller RS232 kanske, men det är inte så vanligt att vi använder.
Programmet:
Kod: Markera allt
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
int iMBID = 1; //Default om ingen ingång sänkt
long lBPS = 9600; //Default om ingen ingång sänkt
int iAI1;
int iAI2;
int iAI3;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(2, INPUT_PULLUP); //ID 2
pinMode(3, INPUT_PULLUP); //ID 3
pinMode(4, INPUT_PULLUP); //1200bps
pinMode(5, INPUT_PULLUP); //19200bps
pinMode(6, INPUT_PULLUP); //115200bps
pinMode(7, INPUT_PULLUP); //input
pinMode(8, INPUT_PULLUP); //input
pinMode(9, INPUT_PULLUP); //input
pinMode(12, OUTPUT); //RS485 enable
digitalWrite(12, HIGH); //RS485 enable
if (!digitalRead(2)){ iMBID = 2; }
if (!digitalRead(3)){ iMBID = 3; }
if (!digitalRead(4)){ lBPS = 1200; }
if (!digitalRead(5)){ lBPS = 19200; }
if (!digitalRead(6)){ lBPS = 115200; }
Serial.begin(lBPS);
// start the Modbus RTU server
ModbusRTUServer.begin(iMBID, lBPS);
// configure coils and holdings
ModbusRTUServer.configureCoils(0x00, 10);
ModbusRTUServer.configureHoldingRegisters(0x00, 10);
}
void loop() {
// poll for Modbus RTU requests
ModbusRTUServer.poll();
// read the current value of the coil
int coilValue = ModbusRTUServer.coilRead(0x00);
ModbusRTUServer.coilWrite(0x01, 1); //digitalRead(2));
ModbusRTUServer.coilWrite(0x02, digitalRead(3));
ModbusRTUServer.coilWrite(0x03, digitalRead(4));
ModbusRTUServer.coilWrite(0x04, digitalRead(5));
ModbusRTUServer.coilWrite(0x05, digitalRead(6));
ModbusRTUServer.coilWrite(0x06, digitalRead(7));
ModbusRTUServer.coilWrite(0x07, digitalRead(8));
ModbusRTUServer.coilWrite(0x08, digitalRead(9));
ModbusRTUServer.holdingRegisterWrite(0x00, analogRead(A0));
ModbusRTUServer.holdingRegisterWrite(0x01, analogRead(A1));
ModbusRTUServer.holdingRegisterWrite(0x02, analogRead(A2));
ModbusRTUServer.holdingRegisterWrite(0x03, analogRead(A3));
ModbusRTUServer.holdingRegisterWrite(0x04, 11);
ModbusRTUServer.holdingRegisterWrite(0x05, 111);
ModbusRTUServer.holdingRegisterWrite(0x06, 1111);
ModbusRTUServer.holdingRegisterWrite(0x07, lBPS/10);
if (coilValue) {
// coil value set, turn LED on
digitalWrite(LED_BUILTIN, HIGH);
} else {
// coild value clear, turn LED off
digitalWrite(LED_BUILTIN, LOW);
}
}