EPSOLAR VS6048 Solar Charge Controller Monitoring System

Hi everyone,

Newbie trying to read from EPSOLAR charge controller using MODBUS as per following details:

Arduino: Mega

Library used: ModbusMaster

Display Device: Liquid Crystal Display

Circuit: Max485 module connected as follows:

  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
#include <LiquidCrystal.h>
#include <ModbusMaster.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 53, en = 51, d4 = 49, d5 = 47, d6 = 45, d7 = 43;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// 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

#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

// instantiate ModbusMaster object

static const uint16_t ku16MBResponseTimeout = 3000;

ModbusMaster node;
//static const uint16_t ku16MBResponseTimeout = 3000;
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(16, 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
  Serial1.begin(115200,SERIAL_8N1);

  // Modbus slave ID 1

  node.begin(1, Serial1);

  // Callbacks allow us to configure the RS485 transceiver correctly

  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

  node.clearResponseBuffer();
  node.clearTransmitBuffer();
}

int loopcount=0;

void loop() {
   
  // set the cursor to column 0, l. Line 1 is the second row, since counting begins with 0.
  
  
  
  uint8_t result=1;
   
 // Read 1 register starting at 0x3100)
  
result = node.readInputRegisters(0x3100,1);
 
if (result == node.ku8MBSuccess)
  {
    float pV = node.getResponseBuffer(PANEL_VOLTS)/100.0f;
    //float pI = node.getResponseBuffer(PANEL_AMPS)/100.0f;
    //float pP = (node.getResponseBuffer(PANEL_POWER_L) |
                    //(node.getResponseBuffer(PANEL_POWER_H) << 8))/100.0f;
                    
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("VPanel:");
   lcd.print(pV);
   
   //lcd.print("IPanel:");
   //lcd.print(node.getResponseBuffer(PANEL_AMPS)/100.0f);
   //lcd.print("PPanel:");
   //lcd.println((node.getResponseBuffer(PANEL_POWER_L) |
                    //(node.getResponseBuffer(PANEL_POWER_H) << 8))/100.0f);   
   
  } else {
    lcd.setCursor(0, 0);
    lcd.print("Miss read: ");
    lcd.print(result, HEX);
  }
    
delay(5000);

  }

I have tested the sketch and the hardware with software by (www.modbustools.com) and it works OK. When connected to the Charge Controller the response is consistently E2 ( slave timed out).

Please help.

TIA

azhaque

  1. MAX485_RO --> RX Pin of Arduino
  2. MAX485_DI --> TX Pin of Arduino
  // Modbus communication runs at 115200 baud
  Serial1.begin(115200,SERIAL_8N1);

You connect the wires to first serial interface (Serial) but use the second serial interface (Serial1) in the sketch?

I have tested the sketch and the hardware with software by (www.modbustools.com) and it works OK.

It would be interesting how you tested that. With the hardware mentioned here this isn't possible.

I'm missing the link to the manual of your charge controller.

Good Morning/Evening Pylon.

pylon:
You connect the wires to first serial interface (Serial) but use the second serial interface (Serial1) in the sketch?

The section from the code that you have referred to, are just a reminder (through these comments) on the connection to the MAX485, as it is easy to mix up the wiring in this area. The physical wires in the circuit ARE going to RX1 and TX1.

pylon:
It would be interesting how you tested that. With the hardware mentioned here this isn't possible.

I'm missing the link to the manual of your charge controller.


http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf

The foregoing link is to the document detailing the MODBUS protocol used by the VS6048BN Charge Controllers.


The Manual of the Charge Controller.


As I submitted before, for testing I had used evaluation versions of the software supplied by www.modbustools.com. The following is an excerpt from the Communication log generated by the software.

Tx:000002-01 04 31 00 00 02 7F 37 
Rx:000003-01 10 1A 2A A4 
Tx:000004-01 04 31 00 00 02 7F 37 
Rx:000005-01 10 1A 4A A0 
Tx:000006-01 04 31 00 00 02 7F 37 
Rx:000007-01 10 1A 4A A0 
Tx:000008-01 04 31 00 00 02 7F 37 
Rx:000009-01 10 1A 4A A0 
Tx:000010-01 04 31 00 00 02 7F 37 
Rx:000011-01 10 1A 53 A0 D6 1A 
Tx:000012-01 04 31 00 00 02 7F 37 
Rx:000013-01 10 1A 53 A0 63 53 
Tx:000014-01 04 31 00 00 02 7F 37 
Rx:000015-01 10 1A 4A 9F 0D

Although the above is an initial version that I had lying on my computer desktop, yet subsequently it was working flawlessly with the connections to Serial1 TX and Serial1 RX. If you feel it is important for the diagnosis, I can certainly post it here.

In the meanwhile I have reduced the length of the wire from the RJ45 connector on the charge controller to the Arduino circuit, to 1 meter. Its length was previously 3 meters. This was done to reduce transmission line issues. I also tried to reduce the speed of the COM port but the charge controller did not allow it, despite the fact that it finds mention in the manual. The intent here was also to reduce transmission line issues. Cable being used for the connection is a standard Network Cable with a RJ45 male at its business end. On the circuit side it terminates on a two pin BLOCK connector.

Circuit is implemented on a 0.1 inch veroboard. I am following Paulca as per the following link.

Regards and Good wishes.

Regards

Noiasca

Greetings and thanks for your input.

noiasca:
You are using a sketch from another forum, so I suggest, you register there and ask the guy who provided the sketch and pictures as the wiring of DE/RE is somehow "special" anyway.

The issue is that the thread on the other forum is closed by its admin.

Perusal of the thread would show that the Arduino based solution is abandoned early on and ESP8266 is brought into the picture.

noiasca:
.......I'm using a different library. As the function and the register look ok....

Which Library are you using. Is it ModbusRTU? I can certainly look at that, in case the problem remains unresolved.

Regards

As I submitted before, for testing I had used evaluation versions of the software supplied by www.modbustools.com.

This site provides several tools. Which one did you use?

The section from the code that you have referred to, are just a reminder (through these comments) on the connection to the MAX485, as it is easy to mix up the wiring in this area.

I was referring to the wiring you described in your post! You wrote you connect the adapter to RX/TX and not to RX1/TX1.

In the meanwhile I have reduced the length of the wire from the RJ45 connector on the charge controller to the Arduino circuit, to 1 meter. Its length was previously 3 meters. This was done to reduce transmission line issues. I also tried to reduce the speed of the COM port but the charge controller did not allow it, despite the fact that it finds mention in the manual. The intent here was also to reduce transmission line issues. Cable being used for the connection is a standard Network Cable with a RJ45 male at its business end. On the circuit side it terminates on a two pin BLOCK connector.

The cable length is not important here as RS-485 is find for several hundred meters. But the connection of the RJ-45 connector to the "block" connector (I guess that's a screw terminal) is of interest. Try to describe that connection or make and post pictures of it. You don't have to connect GND to the GND on the Arduino side (I recommend against doing that) but it's important to connect A and B correctly.

Circuit is implemented on a 0.1 inch veroboard. I am following Paulca as per the following link.
http://www.eevblog.com/forum/projects/nodemcu-esp8266-rs485-epever-solar-monitor-diy/msg1404831/#msg1404831

That's for an ESP8266 which is a 3V3 device. The Mega you're using is a 5V device. Did you respect that?

Provide a link to the RS-485 adapter you're using!

Greetings and thank you for the comeback Pylon.

Before we go ahead let me show you the setup so that my need can be appreciated.

There is another set of inverter/batteries for redundancy. Total installed solar is 12.5KW. This is all off-grid and runs the house.

To the main topic:

pylon:
This site provides several tools. Which one did you use?

MODBUS Poll and MODBUS Slave.

pylon:
I was referring to the wiring you described in your post! You wrote you connect the adapter to RX/TX and not to RX1/TX1.

OK. Here is a pic.

The pic below is the prototype.

The RS485 module is visible on the right. Wires can be seen to be linking to the Arduino Mega.

pylon:
The cable length is not important here as RS-485 is find for several hundred meters. But the connection of the RJ-45 connector to the "block" connector (I guess that's a screw terminal) is of interest. Try to describe that connection or make and post pictures of it. You don't have to connect GND to the GND on the Arduino side (I recommend against doing that) but it's important to connect A and B correctly.

You have guessed correctly. The block (aka screw terminal) can be seen in the pic above in detail. It is also visible in the pic of the prototype pasted just above.

The two wires going coming from the block connector and going underneath the RS485 module are the A and B of the RS485. I have A and B marked carefully on the veroboard so that I do not mess up. In any case, the system works with the emulator software flawlessly so the connections etc. are not an issue, I think.

I have another block connector for GND, but I am not using it. The system was working with the computer running the emulator software without using the GND wire. So I figured there was no need to connect the GND wire.

pylon:
That's for an ESP8266 which is a 3V3 device. The Mega you're using is a 5V device. Did you respect that?

Infact Yes. If you look at the pic of the prototype you can see the red block in the center. That is the level converter, with its picture.

My original plan was to implement it on ESP8266. The picture of the prototype shows the parallel rails where the ESP is to be installed. However initial attempts with the ESP were not successful due to my lack of capacity. So I changed tack and am now pursuing this course.

pylon:
Provide a link to the RS-485 adapter you're using!

I'm using the MAX485 based adapter purchased from:
https://hallroad.org/components/sensors-and-sensor-modules/max485-rs485-transceiver-module-in-pakistan/

This is the circuit.

These modules are of low quality and thus cheap. I therefore resoldered all the joints. I have two pieces and both work when the modbustools software is running.

To conclude.

  1. My prototype works with the modbustools software using the RS485 to USB adapter on the computer side, (linked below), using the ModbusMaster.h Library.

https://hallroad.org/components/development-boards-kits-and-diy/usb-to-rs485-ttl-serial-converter-in-pakistan-en/

  1. The o/p from the charge controller can be easily seen on the modbustools software using EPSOLAR supplied cable. This cable has a CH340 attachment at its USB end.

Logically therefore I conclude that:

a. No problem due to the CC
b. No problem due to the <ModbusMaster.h> library.

The only thing is the Cable.

What do you say.

Regards

azhaque

I have run the modbustools software and linked it up with the prototype. A short video is linked below that clearly shows the data exchange between the software running on the laptop and the prototype:

#include <LiquidCrystal.h>
#include <ModbusMaster.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 53, en = 51, d4 = 49, d5 = 47, d6 = 45, d7 = 43;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// 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

#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

// instantiate ModbusMaster object

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(16, 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
  Serial1.begin(115200);

  // Modbus slave ID 1

  node.begin(1, Serial1);

  // Callbacks allow us to configure the RS485 transceiver correctly

  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
}

int loopcount=0;

void loop() {
   
  // set the cursor to column 0, l. Line 1 is the second row, since counting begins with 0.
  lcd.setCursor(0, 0);
  
  uint8_t result;
  //uint16_t data[6];
  
 
 // Read 1 registers starting at 0x3100)
  
result = node.readInputRegisters(0x3100, 6);

 if (result == node.ku8MBSuccess)
  {
    float pV = node.getResponseBuffer(PANEL_VOLTS);
    float pI = node.getResponseBuffer(PANEL_AMPS);

    float pP = (node.getResponseBuffer(PANEL_POWER_L) |
                    (node.getResponseBuffer(PANEL_POWER_H) << 8))/100.0f;
   
  float bV = node.getResponseBuffer(BATT_VOLTS);
    //float bI = node.getResponseBuffer(BATT_AMPS);
    

  lcd.setCursor(0, 0);
  lcd.print("VSolar :");
  lcd.print(pV);
  
   lcd.setCursor(0, 1);
   lcd.print("ISolar :");
   lcd.print(pI);
 
  lcd.setCursor(0, 2);
  lcd.print("SolarP:");
  lcd.print(pP);
  
  lcd.setCursor(0, 3);
  lcd.print("BattV :");
  lcd.print(bV);
  
  //lcd.setCursor(0, 2);
  //lcd.print(bI);
} 
else {
  lcd.clear();
  lcd.setCursor(0, 0);
  
  lcd.print("Miss read: ");
  lcd.print(result, HEX);
  lcd.print(loopcount);
  }

loopcount++;
delay(3000);
lcd.clear();
  }

azhaque:
The only thing is the Cable.

azhaque

Changed the Cable.
Didn't work.

azhaque

  1. My prototype works with the modbustools software using the RS485 to USB adapter on the computer side, (linked below), using the ModbusMaster.h Library.

  2. The o/p from the charge controller can be easily seen on the modbustools software using EPSOLAR supplied cable. This cable has a CH340 attachment at its USB end.

What you didn't test is that the connections between your prototype and the charge controller works. Try to connect the charge controller to the prototype and the prototype to the PC as you did in the above tests but don't power the prototype. That setup has a superfluous terminal resistor but should work theoretically. Then use your PC software to request data from the charge controller.

pylon:
What you didn't test is that the connections between your prototype and the charge controller works. Try to connect the charge controller to the prototype and the prototype to the PC as you did in the above tests but don't power the prototype. That setup has a superfluous terminal resistor but should work theoretically. Then use your PC software to request data from the charge controller.

EUREKA. It works.

This morning I removed the 120 Ohm resistor to see whether it was causing loading. The change didn't effect the working.

Out of a whim I just reversed the A & B wires and it started to work.

The problem was that the modbus register data ( http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf ) has, on its last page the pinouts of the RJ45 connector on the charge controller. There A is shown as connected to pins 3, 4 and B to 5,6 respectively. THIS IS A MISSPRINT. It is its opposite i.e. 3,4-->B, 5,6-->A.

Will post video of the working prototype shortly.

Thanks everyone for their inputs.

Now to give the data to ESP8266 and put it on the Net.

Regards and Good wishes all round.

Hi all,

A quick update.

Attached herewith is the datasheet/writeup about the innards of the VS6048 CC, very graciously shared by EPEVER/EPSOLAR. This paper corrects the missprint about the pinouts of the RJ45 connector in the earlier document.

Should be useful for those who would like to continue on this line of work.

Video about the prototype in action.

Regards

azhaque

BSeriesControllerProtocolv2.4.zip (903 KB)

the new datasheet is nice, would have saved a lot of work two years ago ;-(

By the way, I'm using the simplemodbus 2.2 from Juan Bester:
https://drive.google.com/drive/folders/0B0B286tJkafVYnBhNGo4N3poQ2c

I like his approach when dealing with lot of registers - and the library is very well documented - see the PDF.