I am trying to get a RAK5005+RAK5802 using Arduino code to read the above Modbus interface. I keep getting error messages connection timed out.
Here is the output -
Here is the code -
/* -----------------------------------------
* SDM230-Modbus Energy Meter to Arduino ModbusRTU Client
* -----------------------------------------
*
* https://gfinder.findernet.com/public/attachments/7E/EN/PRT_Modbus_7E_64_68_78_86EN.pdf
*/
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
#include <LoRaWan-RAK4630.h>
#define INPUT_REGISTERS 3
constexpr auto baudrate {9600};
// 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 };
constexpr auto preDelayBR { bitduration * 9.6f * 3.5f * 1e6 };
constexpr auto postDelayBR { bitduration * 9.6f * 3.5f * 1e6 };
// constexpr auto preDelayBR { bitduration * 10.0f * 3.5f * 1e6 };
unsigned long rate = 6000;
unsigned long lastMillis = 0;
float voltage;
float current;
float power;
float frequency;
float exportEnergy;
void setup()
{
Serial.begin(9600);
while (!Serial);
Serial.println("\nModbus RTU Client\n");
RS485.setDelays(preDelayBR, postDelayBR);
if (!ModbusRTUClient.begin(baudrate, SERIAL_8N1))
{
Serial.println("Failed to start Modbus RTU Client!");
while (1);
}
}
void loop()
{
if (millis() - lastMillis > rate)
{
lastMillis = millis();
voltage = readVoltage();
delay(100);
current = readCurrent();
delay(100);
power = readPower();
delay(100);
frequency = readFreq();
delay(100);
exportEnergy = readExportEnergy();
Serial.print("\nVoltage = " + String(voltage, 1) + " V Current = " + String(current, 1) + " A Power = " + String(power, 1) + " W Freq = ");
Serial.println(String(frequency, 1) + " Hz Export Energy = " + String(exportEnergy, 1) + " kWh\n");
delay(100);
}
}
float readVoltage()
{
float volt = 0.;
if (!"connection timed out".
Here ".requestFrom(01, INPUT_REGISTERS, 1, 2))
{
Serial.print("Failed to read the voltage. ");
Serial.println(ModbusRTUClient.lastError());
}
else
{
// Response handler
Serial.println(ModbusRTUClient.available());
uint16_t word1 = ModbusRTUClient.read();
uint16_t word2 = ModbusRTUClient.read();
uint32_t volt = word1 << 16 | word2;
}
return volt;
}
float readCurrent()
{
float ampere = 0.;
if (!ModbusRTUClient.requestFrom(0x01, INPUT_REGISTERS, 7, 2))
{
Serial.print("Failed to read the current. ");
Serial.println(ModbusRTUClient.lastError());
}
else
{
// Response handler
uint16_t word1 = ModbusRTUClient.read();
uint16_t word2 = ModbusRTUClient.read();
int32_t ampere = word1 << 16 | word2;
}
return ampere;
}
double readPower()
{
double watt = 0.;
if (!ModbusRTUClient.requestFrom(0x01, INPUT_REGISTERS, 13, 2))
{
Serial.print("Failed to read power. ");
Serial.println(ModbusRTUClient.lastError());
}
else
{
// Response handler
uint16_t word1 = ModbusRTUClient.read();
uint16_t word2 = ModbusRTUClient.read(); from buffer
int32_t watt = word1 << 16 | word2;
}
return watt;
}
float readFreq()
{
float freq = 0.;
if (!ModbusRTUClient.requestFrom(0x01, INPUT_REGISTERS, 71, 2))
{
Serial.print("Failed to read frequency. ");
Serial.println(ModbusRTUClient.lastError());
}
else
{
// Response handler
uint16_t word1 = ModbusRTUClient.read();
uint16_t word2 = ModbusRTUClient.read();
int32_t freq = word1 << 16 | word2;
}
return freq;
}
double readExportEnergy()
{
double kwh = 0.;
if (!ModbusRTUClient.requestFrom(0x01, INPUT_REGISTERS, 75, 2))
{
Serial.print("Failed to read energy. ");
Serial.println(ModbusRTUClient.lastError());
}
else
{
// Response handler
uint16_t word1 = ModbusRTUClient.read();
uint16_t word2 = ModbusRTUClient.read();
int32_t dwh = word1 << 16 | word2;
kwh = dwh/10000.0;
}
return kwh;
}
Any help would be gratefully appreciated.






