Skip to content

Instantly share code, notes, and snippets.

@qknight
Created October 16, 2025 09:42
Show Gist options
  • Select an option

  • Save qknight/0dde3150b02b239dc61df500cc828179 to your computer and use it in GitHub Desktop.

Select an option

Save qknight/0dde3150b02b239dc61df500cc828179 to your computer and use it in GitHub Desktop.
This is a minimal "hello world" program used between these two devices:
* Arduino Opta RS485
* ODE-3-120023-1f12 INVERTEK DRIVES-Vektor-Umrichter
Took me 2 days to figure out that I had to plug the OPTA this way:
* A(-) to pin 8
* GND to pin 3
* B(+) TO pin 7
# the source code
#include <ArduinoModbus.h>
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
constexpr auto baudrate { 115200 };
// Calculate preDelay and postDelay in microseconds as per Modbus RTU Specification
// MODBUS over serial line specification and implementation guide V1.02
// Paragraph 2.5.1.1 MODBUS Message RTU Framing
// https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
constexpr auto bitduration { 1.f / baudrate }; // Time for one bit (~8.68 μs at 115200 bps)
constexpr auto preDelayBR { bitduration * 10.0f * 3.5f * 1e6 }; // 10 bits per character
constexpr auto postDelayBR { bitduration * 10.0f * 3.5f * 1e6 }; // 10 bits per character
const uint16_t STATUS_REG = 0;
const uint8_t SLAVE_ID = 1;
int counter = 0;
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("Modbus RTU Client");
RS485.setDelays(preDelayBR, postDelayBR);
// Start the Modbus RTU client
if (!ModbusRTUClient.begin(baudrate, SERIAL_8N1)) {
Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
void loop() {
readInputRegisterValues();
startMotor(); // Call the new function to start the motor
counter++;
Serial.print(F("counter: "));
Serial.println(counter);
delay(1000);
}
void readInputRegisterValues() {
Serial.print("Reading input register values ... ");
if (!ModbusRTUClient.requestFrom(SLAVE_ID, HOLDING_REGISTERS, STATUS_REG, 1)) {
Serial.print("failed! ");
Serial.println(ModbusRTUClient.lastError());
} else {
Serial.println("success");
while (ModbusRTUClient.available()) {
Serial.print(ModbusRTUClient.read());
Serial.print(' ');
}
Serial.println();
}
}
void startMotor() {
Serial.print("Writing to register to start motor ... ");
// Use function code 06 (Write Single Register) to write value 1 to register 1
if (!ModbusRTUClient.holdingRegisterWrite(SLAVE_ID, STATUS_REG, 1)) {
Serial.print("failed! ");
Serial.println(ModbusRTUClient.lastError());
} else {
Serial.println("success");
}
}
# the output in the arduino IDE serial port with cable plugged
Writing to register to start motor ... success
counter: 465
Modbus RTU Client
Reading input register values ... success
1
Writing to register to start motor ... success
counter: 1
Reading input register values ... success
1
Writing to register to start motor ... success
counter: 2
Reading input register values ... success
1
Writing to register to start motor ... success
counter: 3
Reading input register values ... success
1
Writing to register to start motor ... success
counter: 4
Reading input register values ... success
1
# the output in the arduino IDE serial port with cable unplugged
Reading input register values ... Modbus RTU Client
Reading input register values ... failed! Connection timed out
Writing to register to start motor ... failed! Connection timed out
counter: 1
Reading input register values ... failed! Connection timed out
Writing to register to start motor ... failed! Connection timed out
counter: 2
Reading input register values ... failed! Connection timed out
Writing to register to start motor ... failed! Connection timed out
counter: 3
Reading input register values ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment