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);
  }
}
 
				


