Modbus over Wifi

I've got an 80W solar panel with an LS1024B charger controller set up in my back garden for running all my lights in the garden with a dusk until dawn timer, Which is all working great.

I've got some code set up that can read the incoming data and can display that on an LCD which is working good which was connected direct to the charge controller. I've also got the Epever monitor software installed. But the trouble is the charge controller is set up at the bottom of the garden and not really near the house.

So after some research I found a gentlemen called Colin Hickey who made a DIY RS485 Wi-Fi serial bridge using ESP-Link, So I've got all this set up and using some software called Hw virtual serial port I can read the incoming data on the solar monitor software which is great but I don't want to leave my computer on all the time or just to boot it up just to check in on things.

So the question is would it be possible to connect to the ESP-link and use an Uno to get the incoming data so that I can display it on an LCD ?

This is the code to read direct from the charge controller

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#include <ModbusMaster.h>
// Using MAX485 based Module, following configuration should be used:
// 1. MAX485_DE --> Pin 3 of Arduino
// 2. MAX485_RE_NEG --> Pin 2 of Arduino
// 3. MAX485_RO --> RX Pin of Arduino
// 4. MAX485_DI --> TX Pin of Arduino
#define MAX485_DE      3
#define MAX485_RE_NEG  2
// ModBus Register Locations
//
#define LIVE_DATA       0x3100     // start of live-data 
#define LIVE_DATA_CNT   6         // 16 regs

// just for reference, not used in code
#define PANEL_VOLTS     0x00
#define PANEL_AMPS      0x01
#define PANEL_POWER_L   0x02
#define PANEL_POWER_H   0x03

#define BATT_VOLTS      0x04
#define BATT_AMPS       0x05
#define BATT_POWER_L    0x06
#define BATT_POWER_H    0x07

// dummy * 4

#define LOAD_VOLTS      0x0C
#define LOAD_AMPS       0x0D
#define LOAD_POWER_L    0x0E
#define LOAD_POWER_H    0x0F



#define RTC_CLOCK           0x9013  // D7-0 Sec, D15-8 Min  :   D7-0 Hour, D15-8 Day  :  D7-0 Month, D15-8 Year
#define RTC_CLOCK_CNT       3       // 3 regs

#define BATTERY_SOC         0x311A  // State of Charge in percent, 1 reg

#define BATTERY_CURRENT_L   0x331B  // Battery current L
#define BATTERY_CURRENT_H   0x331C  // Battery current H



#define STATISTICS      0x3300 // start of statistical data
#define STATISTICS_CNT  22     // 22 regs

// just for reference, not used in code
#define PV_MAX     0x00 // Maximum input volt (PV) today  
#define PV_MIN     0x01 // Minimum input volt (PV) today
#define BATT_MAX   0x02 // Maximum battery volt today
#define BATT_MIN   0x03 // Minimum battery volt today

#define CONS_ENERGY_DAY_L   0x04 // Consumed energy today L
#define CONS_ENGERY_DAY_H   0x05 // Consumed energy today H
#define CONS_ENGERY_MON_L   0x06 // Consumed energy this month L 
#define CONS_ENGERY_MON_H   0x07 // Consumed energy this month H
#define CONS_ENGERY_YEAR_L  0x08 // Consumed energy this year L
#define CONS_ENGERY_YEAR_H  0x09 // Consumed energy this year H
#define CONS_ENGERY_TOT_L   0x0A // Total consumed energy L
#define CONS_ENGERY_TOT_H   0x0B // Total consumed energy  H

#define GEN_ENERGY_DAY_L   0x0C // Generated energy today L
#define GEN_ENERGY_DAY_H   0x0D // Generated energy today H
#define GEN_ENERGY_MON_L   0x0E // Generated energy this month L
#define GEN_ENERGY_MON_H   0x0F // Generated energy this month H
#define GEN_ENERGY_YEAR_L  0x10 // Generated energy this year L
#define GEN_ENERGY_YEAR_H  0x11 // Generated energy this year H
#define GEN_ENERGY_TOT_L   0x12 // Total generated energy L
#define GEN_ENERGY_TOT_H   0x13 // Total Generated energy  H

#define CO2_REDUCTION_L    0x14 // Carbon dioxide reduction L  
#define CO2_REDUCTION_H    0x15 // Carbon dioxide reduction H 


#define LOAD_STATE         0x02 // r/w load switch state

#define STATUS_FLAGS    0x3200
#define STATUS_BATTERY    0x00  // Battery status register
#define STATUS_CHARGER    0x01  // Charging equipment status register
uint8_t batterySOC = 0;
uint8_t batterycharge;
ModbusMaster node;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

void setup() {

  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
  // Modbus communication runs at 115200 baud
  Serial.begin(115200);
  // Modbus slave ID 1
  node.begin(1, Serial);
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

int loopcount = 0;

void loop() {
  uint8_t i, result;
  char charger_charging_status[][12] = {
    "Off",
    "Float",
    "Boost",
    "Equlization"
  };
  //################################
  //# READ BATTERY AND SOLAR PANEL #
  //################################
  result = node.readInputRegisters(0x3100, 6);

  if (result == node.ku8MBSuccess)
  {
    uint16_t pV = node.getResponseBuffer(PANEL_VOLTS);
    uint16_t pI = node.getResponseBuffer(PANEL_AMPS);
    uint16_t pP = (node.getResponseBuffer(PANEL_POWER_L) |
                (node.getResponseBuffer(PANEL_POWER_H) << 8)) / 100.0f;
    uint16_t bV = node.getResponseBuffer(BATT_VOLTS);
    uint16_t bI = node.getResponseBuffer(BATT_AMPS);
    //Display the data
    lcd.setCursor(0, 0);
    lcd.print("BattV :");
    lcd.print(bV / 100.0f);
    lcd.print("  ");
    lcd.setCursor(0, 1);
    lcd.print("BattA :");
    lcd.print(bI / 100.0f);
    lcd.print("  ");

  }
  else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Miss read: ");
    lcd.print(result, HEX);
    lcd.print(loopcount);
  }




  delay(200);
  //############################
  //# BATTERY STATE OFF CHARGE #
  //############################
  node.clearResponseBuffer();
  result = node.readInputRegisters(BATTERY_SOC, 1);
  if (result == node.ku8MBSuccess)  {

    batterySOC = node.getResponseBuffer(0);
    lcd.setCursor(0, 2);
    lcd.print("SOC :");
    lcd.print(batterySOC);
    lcd.print("%                 ");
  } else  {
    lcd.setCursor(0, 2);
    lcd.print("MISSING DATA");

  }
  delay(50);
  //#################
  //# CHARGING MODE #
  //#################
  uint8_t charger_mode  = 0;
  node.clearResponseBuffer();
  result = node.readInputRegisters(  0x3200, 2 );
  if (result == node.ku8MBSuccess)  {
    lcd.setCursor(0, 3);
    uint8_t Charging_Mode = node.getResponseBuffer(1);
    charger_mode = ( Charging_Mode & 0b0000000000001100 ) >> 2 ;
    lcd.print(charger_charging_status[ charger_mode] );
    lcd.print("      ");
  } else  {
    lcd.print("MISS READ");
    lcd.print(result, HEX);
  }

  loopcount++;
}

I'm not sure if this is the correct way so really after some input how to get data from the ESP-link using an ESP2866 ?

This second part as it was to big to post in one so rather than get people to download the code this is the Modbus TCP/ip code if this is the correct approach

Now I've tried to set up an Modbus TCP/Ip but cannot get it to read the data

/* esp32Modbus

Copyright 2018 Bert Melis




/*

The modbus server (= SMA Sunny Boy) is defined as
ModbusTCP sunnyboy(3, {192, 168, 123, 123}, 502);
where:
- 3 = device ID
- {192, 168, 123, 13} = device IP address
- 502 = port number

All defined registers are holding registers, 2 word size (4 bytes)

*/


#include <Arduino.h>
#include <WiFi.h>
#include <esp32ModbusTCP.h>

const char* ssid = "xxxxxx";
const char* pass = "xxxxxxxL";
bool WiFiConnected = false;

esp32ModbusTCP sunnyboy(1, {192, 168, 0, 30}, 502);
enum smaType {
  ENUM,   // enumeration
  UFIX0,  // unsigned, no decimals
  SFIX0,  // signed, no decimals
};
struct smaData {
  const char* name;
  uint16_t address;
  uint16_t length;
  smaType type;
  uint16_t packetId;
};
smaData smaRegisters[] = {
  "status", 30201, 2, ENUM, 0,
  "connectionstatus", 30217, 2, ENUM, 0,
  "totalpower", 30529, 2, UFIX0, 0,
  "currentpower", 30775, 2, SFIX0, 0,
  "currentdc1power", 30773, 2, SFIX0, 0,
  "currentdc2power", 30961, 2, SFIX0, 0
};
uint8_t numberSmaRegisters = sizeof(smaRegisters) / sizeof(smaRegisters[0]);
uint8_t currentSmaRegister = 0;


void setup() {
    Serial.begin(115200);
    WiFi.disconnect(true);  // delete old config

    sunnyboy.onData([](uint16_t packet, uint8_t slave, esp32Modbus::FunctionCode fc , uint8_t* data , uint16_t len) {
      for (uint8_t i = 0; i < numberSmaRegisters; ++i) {
        if (smaRegisters[i].packetId == packet) {
          smaRegisters[i].packetId = 0;
          switch (smaRegisters[i].type) {
          case ENUM:
          case UFIX0:
            {
            uint32_t value = 0;
            value = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
            Serial.printf("%s: %u\n", smaRegisters[i].name, value);
            break;
            }
          case SFIX0:
            {
            int32_t value = 0;
            value = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
            Serial.printf("%s: %i\n", smaRegisters[i].name, value);
            break;
            }
          }
          return;
        }
      }
    });
    sunnyboy.onError([](uint16_t packet, esp32Modbus::Error e) {
      Serial.printf("Error packet %u: %02x\n", packet, e);
    });

    delay(1000);

    WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info) {
      Serial.print("WiFi connected. IP: ");
      Serial.println(IPAddress(info.got_ip.ip_info.ip.addr));
      WiFiConnected = true;
    }, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
    WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){
        Serial.print("WiFi lost connection. Reason: ");
        Serial.println(info.disconnected.reason);
        WiFi.disconnect();
        WiFiConnected = false;
    }, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);

    WiFi.begin(ssid, pass);

    Serial.println();
    Serial.println("Connecting to WiFi... ");
}

void loop() {
  static uint32_t lastMillis = 0;
  if ((millis() - lastMillis > 30000 && WiFiConnected)) {
    lastMillis = millis();
    Serial.print("reading registers\n");
    for (uint8_t i = 0; i < numberSmaRegisters; ++i) {
      uint16_t packetId = sunnyboy.readHoldingRegisters(smaRegisters[i].address, smaRegisters[i].length);
      if (packetId > 0) {
        smaRegisters[i].packetId = packetId;
      } else {
        Serial.print("reading error\n");
      }
    }
  }
}