Use Arduino to Communicate With Tracer MT5 Charge Controller

14,097

21

21

Published

Introduction: Use Arduino to Communicate With Tracer MT5 Charge Controller

I bought an MPPT TRACER 3215RN Solar Charge Controller, made by EP Solar (I've also seen SainSonic mentioned as the manufacturer, but it's the same product). I wanted to use my computer to monitor the PV panel and battery instead of buying the manufacturer's MT-5 Remote Meter, (a) because I wanted to log the data on my computer, and (b) why spend $36 when you don't need to.

I hunted around on the Internet and found a straightforward way of doing this with an Arduino Uno. I hope it works for you.

Step 1: Prepare Ethernet Cable

Get an Ethernet cable. It makes your head spin when you start looking into connector standards (technically the Tracer uses 8P8C), but so long as it has 8 wires it should be ok.

Cut the connector off one end.

Plug the end with the connector still on it into the Tracer.

On the end you just cut, use a multimeter to determine which wires are which:

- 4 of them will be ground

- 2 of them will be approx +12V

- 2 of them will be approx +3.3V

Trim off three of the ground wires and the two 12V wires, so you're left with one ground wire and the two 3.3V wires.

I then soldered breadboard wires to the three used wires to make it easy to hook up to the Arduino.

Step 2: Install This Arduino Sketch

This Arduino sketch (and most of the info in this posting) is from https://github.com/xxv/tracer However they used a serial baud rate of 57600, I had to drop it to 9600 to work on my Arduino/computer combination.

I had some trouble copying and pasting the sketch below because of unsupported characters, so if you get any errors with the sketch get the original from the github site.

/*
* An interface to the Tracer solar regulator. * Communicating in a way similar to the MT-5 display */

#include

SoftwareSerial myserial(10, 11); // RX, TX

uint8_t start[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xEB, 0x90, 0xEB, 0x90, 0xEB, 0x90 }; uint8_t id = 0x16; uint8_t cmd[] = { 0xA0, 0x00, 0xB1, 0xA7, 0x7F };

uint8_t buff[128];

void setup() { Serial.begin(9600);

myserial.begin(9600); }

float to_float(uint8_t* buffer, int offset){ unsigned short full = buffer[offset+1] << 8 | buff[offset];

return full / 100.0; }

void loop() { Serial.println("Reading from Tracer");

myserial.write(start, sizeof(start)); myserial.write(id); myserial.write(cmd, sizeof(cmd));

int read = 0;

for (int i = 0; i < 255; i++){ if (myserial.available()) { buff[read] = myserial.read(); read++; } }

Serial.print("Read "); Serial.print(read); Serial.println(" bytes");

for (int i = 0; i < read; i++){ Serial.print(buff[i], HEX); Serial.print(" "); }

Serial.println();

float battery = to_float(buff, 9); float pv = to_float(buff, 11); //13-14 reserved float load_current = to_float(buff, 15); float over_discharge = to_float(buff, 17); float battery_max = to_float(buff, 19); // 21 load on/off // 22 overload yes/no // 23 load short yes/no // 24 reserved // 25 battery overload // 26 over discharge yes/no uint8_t full = buff[27]; uint8_t charging = buff[28]; int8_t battery_temp = buff[29] - 30; float charge_current = to_float(buff, 30);

Serial.print("Load is "); Serial.println(buff[21] ? "on" : "off");

Serial.print("Load current: "); Serial.println(load_current);

Serial.print("Battery level: "); Serial.print(battery); Serial.print("/"); Serial.println(battery_max);

Serial.print("Battery full: "); Serial.println(full ? "yes " : "no" );

Serial.print("Battery temperature: "); Serial.println(battery_temp);

Serial.print("PV voltage: "); Serial.println(pv);

Serial.print("Charging: "); Serial.println(charging ? "yes" : "no" );

Serial.print("Charge current: "); Serial.println(charge_current);

delay(1000); }

Step 3: Connect Wires to Arduino

Connect the ground wire to Arduino ground.

One of the 3.3V wires connects to Arduino pin 10, and the other 3.3V wire connects to Arduino pin 11. There's probably a way of telling which goes which from the colors (comments welcome!), but there's only 2 wires so just swap them if it doesn't work first time.

Watch the results in the serial window (terminal emulator) on your computer.

Good luck!

2 People Made This Project!

Recommendations

  • Clocks Contest

    Clocks Contest
  • Make it Move Contest

    Make it Move Contest
  • Oil Contest

    Oil Contest
user

We have a be nice policy.
Please be positive and constructive.

Tips

Questions

21 Comments

is it posibly to use arduino nano for this project? im realy new to arduino, but what i understand uno and nano have same atmega, so could i still use pin 10 and 11 for tx and rx?

Hi BF72,

I am trying to get the data on following mppt charger and i have no idea about communication with it via Arduino. I have asked the comm. protocol to the manufacturer however no answers at all. I am open to any suggestion.

http://www.cnbou.com/10a-mppt-solar-charge-controller/

It has windows based software which you can follow the info, but it only shows up the last status. We would like to save and upload to PV data to the thingspeak.

http://inverterfactory.com/file/2016-8%20MPPT%20solar%20chagre%20controller%20PC%20Program.zip

Thanks in advance.

I made it, but it doesn't work. :(

I use controller Tracer 2210 -> works fine
I use Arduino Mega, serial 2 (17=RX, 16=TX)
I use the exact same sketch from here above.

After I sent the initialisation strings, I do get a response from the controller that I can see on my osciloscope. I've put a "schmitt trigger" in front of the RX pin so that I get nice 5V pulses on pin 17.
On my serial, I see nothing but ZERO's (except the temperature which is -30)

Baud rates are both set to 9600
I tried 15 and 14 as RX and TX, but the same result.
When I try another baud rate , I don't get nothing back from the charger.
I tried without the schmitt trigger : same result (pulses are only 3V)

What did I do wrong ?

2 replies

Use this code for Arduino MEGA :

/*
An interface to the Tracer solar regulator.
Communicating in a way similar to the MT-5 display
for ARDUINO MEGA
*/
// DO NOT include <SoftwareSerial.h> !!
// connect RX from MT5 to pin 14 of Arduino MEGA
// connect TX from MT5 to pin 15 of Arduino MEGA
// Arduino MEGA has 3 Serials. Serial3 is standard 14/15 !!

uint8_t start[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0xEB, 0x90, 0xEB, 0x90, 0xEB, 0x90
};
uint8_t id = 0x16;
uint8_t cmd[] = { 0xA0, 0x00, 0xB1, 0xA7, 0x7F };
uint8_t buff[128];

void setup() {
Serial.begin(9600);
Serial3.begin(9600); // >>>>>>>>>>>>>>>>> Notice the 3 !
}

float to_float(uint8_t* buffer, int offset) {
unsigned short full = buffer[offset + 1] << 8 | buff[offset];
return full / 500.0;
}

void loop()
{
Serial.println("-------------------------------------");
Serial.println("Reading from Tracer");

Serial3.write(start, sizeof(start));
Serial3.write(id);
Serial3.write(cmd, sizeof(cmd));

int read = 0;

for (int i = 0; i < 255; i++) {
if (Serial3.available()) {
buff[read] = Serial3.read();
read++;
}
}

Serial.print("Read ");
Serial.print(read);
Serial.println(" bytes");

for (int i = 0; i < read; i++) {
Serial.print(buff[i], HEX);
Serial.print(" ");
}

Serial.println();

float battery = to_float(buff, 9);
float pv = to_float(buff, 11);
//13-14 reserved
float load_current = to_float(buff, 15);
float over_discharge = to_float(buff, 17);
float battery_max = to_float(buff, 19);
// 21 load on/off
// 22 overload yes/no
// 23 load short yes/no
// 24 reserved
// 25 battery overload
// 26 over discharge yes/no
uint8_t full = buff[27];
uint8_t charging = buff[28];
int8_t battery_temp = buff[29] - 30;
float charge_current = to_float(buff, 30);

Serial.print("Load is ");
Serial.println(buff[21] ? "on" : "off");

Serial.print("Load current: ");
Serial.println(load_current);

Serial.print("Battery level: ");
Serial.print(battery);
Serial.print("/");
Serial.println(battery_max);

Serial.print("Battery full: ");
Serial.println(full ? "yes " : "no" );

Serial.print("Battery temperature: ");
Serial.println(battery_temp);

Serial.print("PV voltage: ");
Serial.println(pv);

Serial.print("Charging: ");
Serial.println(charging ? "yes" : "no" );

Serial.print("Charge current: ");
Serial.println(charge_current);
Serial.println();

delay(2000);
}

"exact same sketch" but of course changed SoftwareSerial myserial to (17,16) ! :)

Use this code for Arduino MEGA :

/*
An interface to the Tracer solar regulator.
Communicating in a way similar to the MT-5 display
for ARDUINO MEGA
*/
// DO NOT include <SoftwareSerial.h> !!
// connect RX from MT5 to pin 14 of Arduino MEGA
// connect TX from MT5 to pin 15 of Arduino MEGA
// Arduino MEGA has 3 Serials. Serial3 is standard 14/15 !!

uint8_t start[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0xEB, 0x90, 0xEB, 0x90, 0xEB, 0x90
};
uint8_t id = 0x16;
uint8_t cmd[] = { 0xA0, 0x00, 0xB1, 0xA7, 0x7F };
uint8_t buff[128];

void setup() {
Serial.begin(9600);
Serial3.begin(9600); // >>>>>>>>>>>>>>>>> Notice the 3 !
}

float to_float(uint8_t* buffer, int offset) {
unsigned short full = buffer[offset + 1] << 8 | buff[offset];
return full / 500.0;
}

void loop()
{
Serial.println("-------------------------------------");
Serial.println("Reading from Tracer");

Serial3.write(start, sizeof(start));
Serial3.write(id);
Serial3.write(cmd, sizeof(cmd));

int read = 0;

for (int i = 0; i < 255; i++) {
if (Serial3.available()) {
buff[read] = Serial3.read();
read++;
}
}

Serial.print("Read ");
Serial.print(read);
Serial.println(" bytes");

for (int i = 0; i < read; i++) {
Serial.print(buff[i], HEX);
Serial.print(" ");
}

Serial.println();

float battery = to_float(buff, 9);
float pv = to_float(buff, 11);
//13-14 reserved
float load_current = to_float(buff, 15);
float over_discharge = to_float(buff, 17);
float battery_max = to_float(buff, 19);
// 21 load on/off
// 22 overload yes/no
// 23 load short yes/no
// 24 reserved
// 25 battery overload
// 26 over discharge yes/no
uint8_t full = buff[27];
uint8_t charging = buff[28];
int8_t battery_temp = buff[29] - 30;
float charge_current = to_float(buff, 30);

Serial.print("Load is ");
Serial.println(buff[21] ? "on" : "off");

Serial.print("Load current: ");
Serial.println(load_current);

Serial.print("Battery level: ");
Serial.print(battery);
Serial.print("/");
Serial.println(battery_max);

Serial.print("Battery full: ");
Serial.println(full ? "yes " : "no" );

Serial.print("Battery temperature: ");
Serial.println(battery_temp);

Serial.print("PV voltage: ");
Serial.println(pv);

Serial.print("Charging: ");
Serial.println(charging ? "yes" : "no" );

Serial.print("Charge current: ");
Serial.println(charge_current);
Serial.println();

delay(2000);
}

Could you do Instructions for tracer BN series? It uses an RS-485 interface.

Description of communication protocol is http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf

4 replies

That would be great!

Lubsz, have you managed to get it to work?

Working... epsolar BN series. I have 4215BN.

https://github.com/kasbert/epsolar-tracer

I'm trying to read the data from a Tracer 4210a, which I gather is a BN series, which uses modbus. So far no luck, including with the Windows program "Solar Station Monitor" from EPEVER. It works just fine with the MT50 remote monitoring box though.

I'm using the USB cable from here:

https://www.amazon.com/Battery-Temperature-Sensor-...

Has anyone figured out how to read data from these controllers?

How it work with Windows10 iot + raspberry pi !!?

I followed your steps and it worked. TY!

On my Ethernet cable, I used brown as ground and stripe-blue went to arduino pin 10 (RX), and solid green went to arduino pin 11 (TX).

Hi,

I aslo have the sme setup and tried to use your code to get the readings.

When I view the information in the serial window it only shows a lot of special characters over and over, did I miss a step or is there another setting I need to changeto get the right information?

I swapped the 2 wires on pin 10 and 11 aswell and no change..

Regards

1 reply
user

Sometimes getting weird characters is due to the wrong baud rate being set. You might want to check that everything is set to 9600, ie. ensure in the sketch it says Serial.begin(9600) and myserial.begin(9600).

Hope this helps.

user

I tried using one of the +12V wires from the Tracer to power the Arduino and Ethernet board, but it didn't work. The Ethernet board needs a lot of power (they get really hot, which is normal) and there wasn't sufficient power from the Tracer. I needed to plug the Arduino into a dedicated power supply.