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 ?