ESP8266 (NoceMCU), EPEver Tracer A and MAX485 module

My current code is split into 12 tabs in my Arduino IDE project, so isn’t really suitable for sharing here.

However, I do have some earlier code which worked, but not as well as the code I posted above because trying to read all the registers at once doesn’t work well.

I’d suggest that you just try reading one group of registers (such as the 8 registers starting at 0x3100) as a test.

But, first things first, are you powering your MAX485 module with 5V from your Wemos? (Powering it from the Tracer didn’t work for me)
Are the lights on on the MAX485 and does one of then flash when you try to take a reading?

Also, without an FTDI, debugging is very difficult! The Rx pin on the FTDI connects to pin D4 on the D1 Mini (GPIO2) and the GND connection should connect to the GND on the board.

Here’s my basic (early) code…

#include <ModbusMaster.h>      //https://github.com/4-20ma/ModbusMaster/
 #include <ESP8266WiFi.h>
 #include <SimpleTimer.h>      // Non-blocking timer
 #include <PubSubClient.h>     // https://github.com/knolleary/pubsubclient
 
 #define MAX485_DE       D2
 #define MAX485_RE       D1

 #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
 #define LOAD_VOLTS      0x0C
 #define LOAD_AMPS       0x0D
 #define LOAD_POWER_L    0x0E
 #define LOAD_POWER_H    0x0F

// Added by PK...
 #define CONTROL_TEMP   0x11
 #define BATT_TEMP      0x10 // Remote Battery Temp. If 0x1B not working then try 0x10
 #define BATT_SOC       0x1A // Battery State of Charge (Percentage)

// #define HB D4

// Initialise ModbusMaster object
ModbusMaster node;

// Initialise the timer object
SimpleTimer timer;


const char* ssid = "REDACTED";
const char* pass = "REDACTED";

IPAddress ip            (REDACTED, REACTED, REDACTED, REACTED);          //Static IP Address for the device
IPAddress gateway       (REDACTED, REACTED, REDACTED, REACTED);
IPAddress subnet        (REDACTED, REACTED, REDACTED, REACTED);

IPAddress MQTTserver    (REDACTED, REACTED, REDACTED, REACTED);       // IP Address for the MQTT Server...

WiFiClient My_WiFi_Client;

PubSubClient MQTTclient(My_WiFi_Client);


void setup()
{
  WifiConnect(); 

  MQTTclient.setServer(MQTTserver, REDACTED);
  MQTTconnect();

  
//  WiFi.begin(ssid, password);

  Serial1.begin (74880);
  Serial1.println("Serial1 Initialised");
  
  Serial.begin(115200); // DO NOT CHANGE!

  pinMode(MAX485_RE, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE, 0);
  digitalWrite(MAX485_DE, 0);

  // EPEver Device ID 1
  node.begin(1, Serial);

  // Callbacks 
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

timer.setInterval(2000, readMODBUS);

}


void readMODBUS()
{
  uint8_t result;

  // Read 20 registers starting at 0x3100)
  node.clearResponseBuffer();
  result = node.readInputRegisters(0x3100, 20); 

  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;

    float bV = node.getResponseBuffer(BATT_VOLTS)/100.0f;
    float bI = node.getResponseBuffer(BATT_AMPS)/100.0f;
    float bP = (node.getResponseBuffer(BATT_POWER_L) |
                    (node.getResponseBuffer(BATT_POWER_H) << 8))/100.0f;

    float lV = node.getResponseBuffer(LOAD_VOLTS)/100.0f;
    float lI = node.getResponseBuffer(LOAD_AMPS)/100.0f;
    float lP = (node.getResponseBuffer(LOAD_POWER_L) |
                    (node.getResponseBuffer(LOAD_POWER_H) << 8))/100.0f;

// Added by PK
    float bT = node.getResponseBuffer(BATT_TEMP)/100.0f;
    float bSOC = node.getResponseBuffer(BATT_SOC)/100.0f;
    
    float cT = node.getResponseBuffer(CONTROL_TEMP)/100.0f;   
                    
                    
    Serial1.print("VPanel: ");
    Serial1.println(pV);
    Serial1.print("IPanel: ");
    Serial1.println(pI);
    Serial1.print("PPanel: ");
    Serial1.println(pP);
    Serial1.println();

    Serial1.print("VBatt: ");
    Serial1.println(bV);
    Serial1.print("IBatt: ");
    Serial1.println(bI);
    Serial1.print("PBatt: ");
    Serial1.println(bP);                    
    Serial1.print("TBatt: ");
    Serial1.println(bT);
    Serial1.print("SOC  : ");
    Serial1.println(bSOC);         
    Serial1.println();
    
    Serial1.print("VLoad: ");
    Serial1.println(lV);
    Serial1.print("ILoad: ");
    Serial1.println(lI);
    Serial1.print("PLoad: ");
    Serial1.println(lP);   
    Serial1.println();
    Serial1.print("CTemp: ");    
    Serial1.println(cT);    
    
    Serial1.println();
    Serial1.println();

    MQTTclient.publish("REDACTED/REDACTED/Panel_Output_Voltage",String(pV).c_str(),true);   
    MQTTclient.publish("REDACTED/REDACTED/Panel_Output_Current",String(pI).c_str(),true);   
    MQTTclient.publish("REDACTED/REDACTED/Panel_Output_Wattage",String(pP).c_str(),true);
    MQTTclient.loop();    
    MQTTclient.publish("REDACTED/REDACTED/Battery_Voltage",String(bV).c_str(),true);   
    MQTTclient.publish("REDACTED/REDACTED/Battery_Charge_Current",String(bI).c_str(),true);   
    MQTTclient.publish("REDACTED/REDACTED/Battery_Charge_Wattage",String(bP).c_str(),true);
    MQTTclient.publish("REDACTED/REDACTED/Battery_Temperature",String(bT).c_str(),true);      
    MQTTclient.publish("Spain/Solar_Monitor/Battery_SOC",String(bSOC).c_str(),true);
    MQTTclient.loop();   
    MQTTclient.publish("REDACTED/REDACTED/Load_Voltage",String(lV).c_str(),true);   
    MQTTclient.publish("REDACTED/REDACTED/Load_Current",String(lI).c_str(),true);
    MQTTclient.publish("REDACTED/REDACTED/Load_Wattage",String(lP).c_str(),true);   
    MQTTclient.loop();   
    MQTTclient.publish("REDACTED/REDACTED/Controller_Temerature",String(cT).c_str(),true);           
    
  } else {
    Serial1.print("Bad Read, ret val:");
    Serial1.println(result, HEX);

    // Result codes:
    // 00 Success
    // 01 Illegal function Error
    // 02 Illegal Data Address Error
    // 03 Illegal Data Value Error
    // E0 Invalid Response Slave ID Error
    // E1 Invalid Response Function Error
    // E2 Response Timed-Out Error
    // E3 Invalid Response CRC Error
   }
}


void loop()
{
  timer.run();

  if (!MQTTclient.connected())
  {
    MQTTconnect();
  }
  MQTTclient.loop();

    if(WiFi.status() != WL_CONNECTED)
  {
    WifiConnect(); 
  }
}

void WifiConnect()
{
  WiFi.begin(ssid, pass);
  WiFi.config(ip, gateway, subnet);
  WiFi.mode(WIFI_STA);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial1.print(".");
  }
} // End of void WiFiConnect


void MQTTconnect()
{
  // Loop until we're connected
  while (!MQTTclient.connected())
  {
    int reason=MQTTclient.state();
    Serial1.print("MQTT Disconnection reason = ");
    Serial1.println(reason);  
    
    
    Serial1.print(F("Attempting MQTT connection..."));
    // Attempt to connect
    if (MQTTclient.connect("REDACTED", "REDACTED", "REDACTED"))
    {
      Serial1.println(F("MQTT Connected"));        
      // Once connected, publish an announcement...
      MQTTclient.publish("REDACTED/REDACTED/REDACTED","ALIVE");      
      MQTTclient.loop();
    }
      // ... and subscribe or re-subscribe

    else  // We get here if the MQTT Connect failed....
    {
      Serial1.print(F("failed, rc="));
      Serial1.print(MQTTclient.state());
      Serial1.println(F(" try again in 1 seconds"));
      // Wait 1 second before retrying
      delay(1000);
    }
  }  
} // End of function MQTTconnect


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

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

Pete.

1 Like