I've used part of your code and I get random readings, but most of them are error -11. When data is collected, value is correct (I can verify the value with a python script).
16:47:38.116 -> Error Counter: -11
16:47:52.607 -> Error Count: -11
16:47:58.206 -> MB_reconnect
16:48:03.226 -> MB_reconnect
16:48:42.467 -> Error Counter: 1
16:48:42.824 -> Data840
16:48:43.088 -> Data840
16:48:43.135 -> Data840
16:48:45.142 -> Error Counter: -11
16:48:53.846 -> Data838
16:48:54.175 -> Data838
16:48:54.815 -> Data837
16:48:56.806 -> Error Counter: -11
16:49:11.669 -> Error Count: -11
Could you please help on these errors. ModBus protocol is not my forte. This is the code below I've used.
#include <SPI.h>
#include <WiFiNINA.h> // for MKR WiFi 1010
#include <Arduino_MKRIoTCarrier.h>
char ssid[] = "MY_SSID";
char pass[] = "MY_PASSWD";
int status = WL_IDLE_STATUS;
IPAddress server(192, 168, 1, 37);
int port = 6607;
char buff[50];
// Fronius Symo Hybrid SunSpec Modbus
const byte METER_UID = 240;
const int MODBUS_CONNECT_ERROR = -10;
const int MODBUS_NO_RESPONSE = -11;
const byte FNC_READ_REGS = 0x03;
const byte FNC_WRITE_SINGLE = 0x06;
const byte FNC_ERR_FLAG = 0x80;
enum {
MODBUS_DELAY,
BATTERY_DATA,
INVERTER_DATA,
METER_DATA
};
WiFiClient modbus;
uint8_t requestId = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
// you're connected now, so print out the status:
printWifiStatus();
}
const unsigned long GET_TIME_ATTEMPTS_TIMEOUT = 5000;
unsigned long startMillis = millis();
while (millis() - startMillis < GET_TIME_ATTEMPTS_TIMEOUT) {
if (requestActivePower())
return;
delay(500);
}
}
void loop() {
requestSymoRTC();
}
void modbusClearData() {
modbus.stop();
}
bool requestActivePower() {
short regs[2];
int res = modbusRequest(0, 32080, 2, regs);
if (modbusError(res))
return false;
Serial.print("Data");
Serial.println((unsigned short) regs[0] * 65536L + (unsigned short) regs[1]);
}
boolean modbusError(int err) {
const byte ERROR_COUNT_ALARM = 8;
static byte modbusErrorCounter = 0;
static int modbusErrorCode = 0;
if (modbusErrorCode != err) {
modbusErrorCounter = 0;
modbusErrorCode = err;
}
if (err == 0)
return false;
modbusErrorCounter++;
switch (modbusErrorCounter) {
case 1:
Serial.print("Error Counter: ");
Serial.println(err);
break;
case ERROR_COUNT_ALARM:
Serial.print("Error Count: ");
Serial.println(err);
modbus.stop();
break;
}
return true;
}
/*
* return
* - 0 is success
* - negative is comm error
* - positive value is modbus protocol exception code
* - error 4 is SLAVE_DEVICE_FAILURE. Check if 'Inverter control via Modbus' is enabled.
*/
int modbusRequest(byte uid, unsigned int addr, byte len, short *regs) {
const byte CODE_IX = 7;
const byte ERR_CODE_IX = 8;
const byte LENGTH_IX = 8;
const byte DATA_IX = 9;
int err = modbusConnection();
if (err != 0)
return err;
byte request[] = {requestId++, 1, 0, 0, 0, 6, uid, FNC_READ_REGS, (byte) (addr / 256), (byte) (addr % 256), 0, len};
modbus.write(request, sizeof(request));
modbus.flush();
int respDataLen = len * 2;
byte response[max((int) DATA_IX, respDataLen)];
while (true) {
int readLen = modbus.readBytes(response, DATA_IX);
if (readLen < DATA_IX) {
return MODBUS_NO_RESPONSE;
}
switch (response[CODE_IX]) {
case FNC_READ_REGS:
break;
case (FNC_ERR_FLAG | FNC_READ_REGS):
return response[ERR_CODE_IX]; // 0x01, 0x02, 0x03 or 0x11
default:
return -3;
}
if ((uint8_t)(requestId - 1) != response[0]) {
//sprintf(buff,F(" %d!=%d"), requestId - 1, (int) response[0])
//Serial.println(buff);
int l = response[LENGTH_IX];
while (l > 0 && modbus.read() != -1) {
l--;
}
continue; // while
}
readLen = modbus.readBytes(response, respDataLen);
if (readLen < respDataLen)
return -4;
break;
}
for (int i = 0, j = 0; i < len; i++, j += 2) {
regs[i] = response[j] * 256 + response[j + 1];
}
return 0;
}
int modbusConnection() {
while (modbus.read() != -1); // clean the buffer
if (!modbus.connected()) {
modbus.stop();
if (!modbus.connect(server, port))
return MODBUS_CONNECT_ERROR;
modbus.setTimeout(2000);
Serial.println(F(" MB_reconnect"));
}
return 0;
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}