reaper7 / SDM_Energy_Meter

reading SDM72 SDM120 SDM220 SDM230 SDM630 modbus energy meters from arduino (esp8266, esp32, avr)
240 stars 97 forks source link

No Reads from SDM630 #51

Closed Darnshelm closed 3 years ago

Darnshelm commented 3 years ago

Hi I totaly new to esp and modbus. I have try to fallow your instructions but i miss something I don't get any read value from 3 SDM630. I have use our sdm_live_page_esp8266_hwserial. I get the esp8266 to boot and i can access the webpage. I have same converter I have connected the converter to pin 3/1 on esp8266. convertar are connected A-A B-B and gnd 2- I have read many close issues to see if i can understand and find then problem but i have not. I try shift cabel inpus from sdm630 try change stopbit. hope it easy to solve

THX //David

630 Skärmklipp 138542823_1323664697989775_7960845659456181199_n 138586029_709537063268388_1975681733962925932_n 138093817_778594202867662_2200888109469842890_n 138529496_1083375468757187_4271408272268066350_n 138586029_709537063268388_1975681733962925932_n (1) 138093817_778594202867662_2200888109469842890_n (1) 138529496_1083375468757187_4271408272268066350_n (1) 138789633_971349953272021_4133318679013414134_n 138603574_4343588289000971_6331076422622568493_n 138689371_739431556699100_2901765211655343084_n

reaper7 commented 3 years ago

@Darnshelm - show what looks your SDM_Config_User.h and complete sketch file.

Do you have connected one or three meters ? If three then leave only one, until you solve the communication problem.

What about device addresses? I can see on the meter that you have set address 3, did you include it in the code??

What about the LEDs on the converter? none / one / two blinks ?

P.S. If you are using hardware serial on pins 1/3 then first disconnect converter from esp and connect esp to computer with some terminal, check if esp send 8 bytes per request like on this screenshot: term

If send then disconnect from computer, try to power it from a source other than the computer(powerbank?) to eliminate the influence of the computer's com port

If your sdm has set address 003 then first byte from esp request also must be a 03. You provide the address of the meter in the request (by default, if you do not provide it, it is assumed to be 01) https://github.com/reaper7/SDM_Energy_Meter/blob/master/examples/sdm_live_page_esp8266_hwserial/sdm_live_page_esp8266_hwserial.ino#L150

read from default 01 slave:

tmpval = sdm.readVal(sdmarr[i].regarr);

read from slave with address 003:

tmpval = sdm.readVal(sdmarr[i].regarr, 3);

If you have more meters connected together, each must have a different address!

Darnshelm commented 3 years ago

HI I have connected 3 Meters Yes I have set the adress on all 3 meters. Main meter to 1 garage to 2 House to 3 no I didn't include the adress in the code. it only blinks on TXD Yes it sends 8 bits 01 04 00 00 00 02 71 CB

SDM_Config_User.txt

reaper7 commented 3 years ago

uncomment line 17 in SDM_Config_User.txt from: //#define USE_HARDWARESERIAL to:

define USE_HARDWARESERIAL

Unmodified sketch trying to read from meter with addr 001, so on this meter (with address 001) set the correct transmission parameters (baudrate, parity, stop bits) like in a sketch, disconnect the other two meters (002, 003) and try again

if esp correctly sends 8 bytes as you have verified on the computer, and TX led blinks on converter and still the converter RX LED does not blins then the meters are not responding for some reason... I don't know what could be the reason for this...

Darnshelm commented 3 years ago

Hi thx for you help now it works with one meter. but i just see only one phase V and AMPs what lines should i uncomment to see more

and how should the lines for the another 2 meters lock like?

reaper7 commented 3 years ago

You must expand code not uncoment something :D both ino and index_page.h as well

Darnshelm commented 3 years ago

Okay it there a example where i can copy and paste from?

reaper7 commented 3 years ago

please... :D

I see that you can analyze and solve problems on your own, you can do it yourself...

reaper7 commented 3 years ago

quickly & dirty the site doesn't look stunning :D Good luck with tuning!

sdm630_multi_live_page_esp8266_hwserial.ino

//sdm live page example by reaper7

#define READSDMEVERY  2000                                                      //read sdm every 2000ms
#define NBREG   39                                                              //number of sdm registers to read
//#define USE_STATIC_IP

/*  WEMOS D1 Mini
                     ______________________________
                    |   L T L T L T L T L T L T    |
                    |                              |
                 RST|                             1|TX HSer
                  A0|                             3|RX HSer
                  D0|16                           5|D1
                  D5|14                           4|D2
                  D6|12                    10kPUP_0|D3
RX SSer/HSer swap D7|13                LED_10kPUP_2|D4
TX SSer/HSer swap D8|15                            |GND
                 3V3|__                            |5V
                       |                           |
                       |___________________________|
*/

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>

#include <ESPAsyncTCP.h>                                                        //https://github.com/me-no-dev/ESPAsyncTCP
#include <ESPAsyncWebServer.h>                                                  //https://github.com/me-no-dev/ESPAsyncWebServer

#include <SDM.h>                                                                //https://github.com/reaper7/SDM_Energy_Meter

#include "index_page.h"

#if !defined ( USE_HARDWARESERIAL )
  #error "This example works with Hardware Serial on esp8266, please uncomment #define USE_HARDWARESERIAL in SDM_Config_User.h"
#endif
//------------------------------------------------------------------------------
AsyncWebServer server(80);

SDM sdm(Serial, 9600, NOT_A_PIN, SERIAL_8N1, false);                            //HARDWARE SERIAL

//------------------------------------------------------------------------------
String devicename = "PWRMETER";

#if defined ( USE_STATIC_IP )
IPAddress ip(192, 168, 0, 130);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
#endif

const char* wifi_ssid = "YOUR_WIFI_SSID";
const char* wifi_password = "YOUR_WIFI_PASS";

String lastresetreason = "";

unsigned long readtime;
//------------------------------------------------------------------------------
typedef volatile struct {
  const uint8_t meter;
  volatile float regvalarr;
  const uint16_t regarr;
} sdm_struct;

volatile sdm_struct sdmarr[NBREG] = {
  {1, 0.00, SDM_PHASE_1_VOLTAGE},                                               //V
  {1, 0.00, SDM_PHASE_2_VOLTAGE},                                               //V
  {1, 0.00, SDM_PHASE_3_VOLTAGE},                                               //V
  {1, 0.00, SDM_PHASE_1_CURRENT},                                               //A
  {1, 0.00, SDM_PHASE_2_CURRENT},                                               //A
  {1, 0.00, SDM_PHASE_3_CURRENT},                                               //A
  {1, 0.00, SDM_PHASE_1_POWER},                                                 //W
  {1, 0.00, SDM_PHASE_2_POWER},                                                 //W
  {1, 0.00, SDM_PHASE_3_POWER},                                                 //W
  {1, 0.00, SDM_PHASE_1_POWER_FACTOR},                                          //PF
  {1, 0.00, SDM_PHASE_2_POWER_FACTOR},                                          //PF
  {1, 0.00, SDM_PHASE_3_POWER_FACTOR},                                          //PF
  {1, 0.00, SDM_FREQUENCY},                                                     //Hz
  {2, 0.00, SDM_PHASE_1_VOLTAGE},                                               //V
  {2, 0.00, SDM_PHASE_2_VOLTAGE},                                               //V
  {2, 0.00, SDM_PHASE_3_VOLTAGE},                                               //V
  {2, 0.00, SDM_PHASE_1_CURRENT},                                               //A
  {2, 0.00, SDM_PHASE_2_CURRENT},                                               //A
  {2, 0.00, SDM_PHASE_3_CURRENT},                                               //A
  {2, 0.00, SDM_PHASE_1_POWER},                                                 //W
  {2, 0.00, SDM_PHASE_2_POWER},                                                 //W
  {2, 0.00, SDM_PHASE_3_POWER},                                                 //W
  {2, 0.00, SDM_PHASE_1_POWER_FACTOR},                                          //PF
  {2, 0.00, SDM_PHASE_2_POWER_FACTOR},                                          //PF
  {2, 0.00, SDM_PHASE_3_POWER_FACTOR},                                          //PF
  {2, 0.00, SDM_FREQUENCY},                                                     //Hz
  {3, 0.00, SDM_PHASE_1_VOLTAGE},                                               //V
  {3, 0.00, SDM_PHASE_2_VOLTAGE},                                               //V
  {3, 0.00, SDM_PHASE_3_VOLTAGE},                                               //V
  {3, 0.00, SDM_PHASE_1_CURRENT},                                               //A
  {3, 0.00, SDM_PHASE_2_CURRENT},                                               //A
  {3, 0.00, SDM_PHASE_3_CURRENT},                                               //A
  {3, 0.00, SDM_PHASE_1_POWER},                                                 //W
  {3, 0.00, SDM_PHASE_2_POWER},                                                 //W
  {3, 0.00, SDM_PHASE_3_POWER},                                                 //W
  {3, 0.00, SDM_PHASE_1_POWER_FACTOR},                                          //PF
  {3, 0.00, SDM_PHASE_2_POWER_FACTOR},                                          //PF
  {3, 0.00, SDM_PHASE_3_POWER_FACTOR},                                          //PF
  {3, 0.00, SDM_FREQUENCY}                                                      //Hz
};
//------------------------------------------------------------------------------
void xmlrequest(AsyncWebServerRequest *request) {
  String XML = F("<?xml version='1.0'?><xml>");
  for (int i = 0; i < NBREG; i++) { 
    XML += "<response" + (String)i + ">";
    XML += String(sdmarr[i].regvalarr,2);
    XML += "</response" + (String)i + ">";
  }
  XML += F("<freeh>");
  XML += String(ESP.getFreeHeap());
  XML += F("</freeh>");
  XML += F("<rst>");
  XML += lastresetreason;
  XML += F("</rst>");
  XML += F("</xml>");
  request->send(200, "text/xml", XML);
}
//------------------------------------------------------------------------------
void indexrequest(AsyncWebServerRequest *request) {
  request->send_P(200, "text/html", index_page); 
}
//------------------------------------------------------------------------------
void ledOn() {
  digitalWrite(LED_BUILTIN, LOW);
}
//------------------------------------------------------------------------------
void ledOff() {
  digitalWrite(LED_BUILTIN, HIGH);
}
//------------------------------------------------------------------------------
void ledSwap() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
//------------------------------------------------------------------------------
void otaInit() {
  ArduinoOTA.setHostname(devicename.c_str());

  ArduinoOTA.onStart([]() {
    ledOn();
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    ledSwap();
  });
  ArduinoOTA.onEnd([]() {
    ledOff();
  });
  ArduinoOTA.onError([](ota_error_t error) {
    ledOff();
  });
  ArduinoOTA.begin();
}
//------------------------------------------------------------------------------
void serverInit() {
  server.on("/", HTTP_GET, indexrequest);
  server.on("/xml", HTTP_PUT, xmlrequest);
  server.onNotFound([](AsyncWebServerRequest *request){
    request->send(404);
  });
  server.begin();
}
//------------------------------------------------------------------------------
static void wifiInit() {
  WiFi.persistent(false);                                                       // Do not write new connections to FLASH
  WiFi.mode(WIFI_STA);
#if defined ( USE_STATIC_IP )
  WiFi.config(ip, gateway, subnet);                                             // Set fixed IP Address
#endif
  WiFi.begin(wifi_ssid, wifi_password);

  while( WiFi.status() != WL_CONNECTED ) {                                      //  Wait for WiFi connection
    ledSwap();
    delay(100);
  }
}
//------------------------------------------------------------------------------
void sdmRead() {
  float tmpval = NAN;
  for (uint8_t i = 0; i < NBREG; i++) {
    tmpval = sdm.readVal(sdmarr[i].regarr,sdmarr[i].meter);
    if (isnan(tmpval))
      sdmarr[i].regvalarr = 0.00;
    else
      sdmarr[i].regvalarr = tmpval;

    yield();
  }
}
//------------------------------------------------------------------------------
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  ledOn();

  lastresetreason = ESP.getResetReason();

  wifiInit();
  otaInit();
  serverInit();
  sdm.begin();

  readtime = millis();

  ledOff();
}
//------------------------------------------------------------------------------
void loop() {
  ArduinoOTA.handle();

  if (millis() - readtime >= READSDMEVERY) {
    sdmRead();
    readtime = millis();
  }

  yield();
}

index_page.h:

const char index_page[] PROGMEM = R"=====(
<!DOCTYPE HTML>
<HTML>
  <HEAD>
    <META name='viewport' content='width=device-width, initial-scale=1'>
    <TITLE>SDM live POWER table</TITLE>
    <SCRIPT>
    var xmlHttp=createXmlHttpObject();
    function createXmlHttpObject(){
     if(window.XMLHttpRequest){
        xmlHttp=new XMLHttpRequest();
     }else{
        xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');
     }
     return xmlHttp;
    }
    function process(){
      if(xmlHttp.readyState==0 || xmlHttp.readyState==4){
        xmlHttp.open('PUT','xml',true);
        xmlHttp.onreadystatechange=handleServerResponse;
        xmlHttp.send(null);
      }
      setTimeout('process()',2000);
    }
    function handleServerResponse(){
     if(xmlHttp.readyState==4 && xmlHttp.status==200){
       xmlResponse=xmlHttp.responseXML;
       for(i=0;i<39;i++){
        xmldoc=xmlResponse.getElementsByTagName('response'+i)[0].firstChild.nodeValue;
        document.getElementById('resp'+i).innerHTML=xmldoc;
       }
       xmldoc=xmlResponse.getElementsByTagName('freeh')[0].firstChild.nodeValue;
       document.getElementById('freeheap').innerHTML=xmldoc;
       xmldoc=xmlResponse.getElementsByTagName('rst')[0].firstChild.nodeValue;
       document.getElementById('rstreason').innerHTML=xmldoc;
     }
    }
    </SCRIPT>
    <STYLE>
      h1 {
        font-size: 120%;
        color: blue;
        margin: 0 0 10px 0;
      }
       table{
        border-collapse: collapse;
      }     
      table, th, td {
        text-align: center;
        border: 1px solid blue;
      }
      tr:nth-child(even) {background-color: #f2f2f2}
    </STYLE>
  </HEAD>
  <BODY onload='process()'>
    <CENTER>
      <H1>SDM live POWER table</H1>
      <TABLE BORDER=1>
        <TR><TH title="VOLTAGE">VOLTAGE PH1 M1</TH><TD><A id='resp0'></A></TD><TD>V</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH2 M1</TH><TD><A id='resp1'></A></TD><TD>V</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH3 M1</TH><TD><A id='resp2'></A></TD><TD>V</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH1 M1</TH><TD><A id='resp3'></A></TD><TD>A</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH2 M1</TH><TD><A id='resp4'></A></TD><TD>A</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH3 M1</TH><TD><A id='resp5'></A></TD><TD>A</TD></TR>
        <TR><TH title="POWER">POWER PH1 M1</TH><TD><A id='resp6'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER">POWER PH2 M1</TH><TD><A id='resp7'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER">POWER PH3 M1</TH><TD><A id='resp8'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH1 M1</TH><TD><A id='resp9'></A></TD><TD>PF</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH2 M1</TH><TD><A id='resp10'></A></TD><TD>PF</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH3 M1</TH><TD><A id='resp11'></A></TD><TD>PF</TD></TR>
        <TR><TH title="FREQUENCY">FREQUENCY M1</TH><TD><A id='resp12'></A></TD><TD>Hz</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH1 M2</TH><TD><A id='resp13'></A></TD><TD>V</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH2 M2</TH><TD><A id='resp14'></A></TD><TD>V</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH3 M2</TH><TD><A id='resp15'></A></TD><TD>V</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH1 M2</TH><TD><A id='resp16'></A></TD><TD>A</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH2 M2</TH><TD><A id='resp17'></A></TD><TD>A</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH3 M2</TH><TD><A id='resp18'></A></TD><TD>A</TD></TR>
        <TR><TH title="POWER">POWER PH1 M2</TH><TD><A id='resp19'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER">POWER PH2 M2</TH><TD><A id='resp20'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER">POWER PH3 M2</TH><TD><A id='resp21'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH1 M2</TH><TD><A id='resp22'></A></TD><TD>PF</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH2 M2</TH><TD><A id='resp23'></A></TD><TD>PF</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH3 M2</TH><TD><A id='resp24'></A></TD><TD>PF</TD></TR>
        <TR><TH title="FREQUENCY">FREQUENCY M2</TH><TD><A id='resp25'></A></TD><TD>Hz</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH1 M3</TH><TD><A id='resp26'></A></TD><TD>V</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH2 M3</TH><TD><A id='resp27'></A></TD><TD>V</TD></TR>
        <TR><TH title="VOLTAGE">VOLTAGE PH3 M3</TH><TD><A id='resp28'></A></TD><TD>V</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH1 M3</TH><TD><A id='resp29'></A></TD><TD>A</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH2 M3</TH><TD><A id='resp30'></A></TD><TD>A</TD></TR>
        <TR><TH title="CURRENT">CURRENT PH3 M3</TH><TD><A id='resp31'></A></TD><TD>A</TD></TR>
        <TR><TH title="POWER">POWER PH1 M3</TH><TD><A id='resp32'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER">POWER PH2 M3</TH><TD><A id='resp33'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER">POWER PH3 M3</TH><TD><A id='resp34'></A></TD><TD>W</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH1 M3</TH><TD><A id='resp35'></A></TD><TD>PF</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH2 M3</TH><TD><A id='resp36'></A></TD><TD>PF</TD></TR>
        <TR><TH title="POWER FACTOR">POWER FACTOR PH3 M3</TH><TD><A id='resp37'></A></TD><TD>PF</TD></TR>
        <TR><TH title="FREQUENCY">FREQUENCY M3</TH><TD><A id='resp38'></A></TD><TD>Hz</TD></TR>
        <TR><TH title="FREE HEAP">FREE HEAP</TH><TD><A id='freeheap'></A></TD><TD>bytes</TD></TR>
        <TR><TH title="LAST RESET REASON">LAST RESET REASON</TH><TD colspan="2"><A id='rstreason'></A></TD></TR>
      </TABLE>
    </CENTER>
  </BODY>
</HTML>
)=====";
Darnshelm commented 3 years ago

thanks you very much for all help and for the codes and the motivation. had started and found what lines and what code I needed. it does not have to look good, just download data from there to the home assistant.

reaper7 commented 3 years ago

You need to work on the appearance of the html page in the index_page.h file (with a line starting with TABLE BORDER=1) ... you know ... tables, rows, columns you can group, for example, all voltages from one meter in one line https://www.w3schools.com/html/html_tables.asp

for HA I use esphome with custom component based on code from this lib: https://github.com/reaper7/esphome_sdm_custom of course it also needs to be adapted to your configuration

reaper7 commented 3 years ago

little better page:

3mpage

index_page.h:

const char index_page[] PROGMEM = R"=====(
<!DOCTYPE HTML>
<HTML>
  <HEAD>
    <META name='viewport' content='width=device-width, initial-scale=1'>
    <TITLE>SDM live POWER table</TITLE>
    <SCRIPT>
    var xmlHttp=createXmlHttpObject();
    function createXmlHttpObject(){
     if(window.XMLHttpRequest){
        xmlHttp=new XMLHttpRequest();
     }else{
        xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');
     }
     return xmlHttp;
    }
    function process(){
      if(xmlHttp.readyState==0 || xmlHttp.readyState==4){
        xmlHttp.open('PUT','xml',true);
        xmlHttp.onreadystatechange=handleServerResponse;
        xmlHttp.send(null);
      }
      setTimeout('process()',2000);
    }
    function handleServerResponse(){
     if(xmlHttp.readyState==4 && xmlHttp.status==200){
       xmlResponse=xmlHttp.responseXML;
       for(i=0;i<39;i++){
        xmldoc=xmlResponse.getElementsByTagName('response'+i)[0].firstChild.nodeValue;
        document.getElementById('resp'+i).innerHTML=xmldoc;
       }
       xmldoc=xmlResponse.getElementsByTagName('freeh')[0].firstChild.nodeValue;
       document.getElementById('freeheap').innerHTML=xmldoc;
       xmldoc=xmlResponse.getElementsByTagName('rst')[0].firstChild.nodeValue;
       document.getElementById('rstreason').innerHTML=xmldoc;
     }
    }
    </SCRIPT>
    <STYLE>
      h1 {
        font-size: 120%;
        color: blue;
        margin: 0 0 10px 0;
      }
       table{
        border-collapse: collapse;
      }     
      table, th, td {
        text-align: center;
        border: 1px solid blue;
      }
      tr:nth-child(even) {background-color: #f2f2f2}
    </STYLE>
  </HEAD>
  <BODY onload='process()'>
    <CENTER>
      <H1>SDM live POWER table</H1>
      <TABLE BORDER=1>
        <TR><TH rowspan="5", title="METER 1">METER 1</TH><TD>VOLTAGE</TD><TD><A id='resp0'></A></TD><TD><A id='resp1'></A></TD><TD><A id='resp2'></A></TD><TD>V</TD></TR>
        <TR><TD>CURRENT</TD><TD><A id='resp3'></A></TD><TD><A id='resp4'></A></TD><TD><A id='resp5'></A></TD><TD>A</TD></TR>
        <TR><TD>POWER</TD><TD><A id='resp6'></A></TD><TD><A id='resp7'></A></TD><TD><A id='resp8'></A></TD><TD>W</TD></TR>
        <TR><TD>POWER FACT.</TD><TD><A id='resp9'></A></TD><TD><A id='resp10'></A></TD><TD><A id='resp11'></A></TD><TD>PF</TD></TR>
        <TR><TD>FREQUENCY</TD><TD colspan="3"><A id='resp12'></A></TD><TD>Hz</TD></TR>
      </TABLE>
      <BR/>
      <TABLE BORDER=1>
        <TR><TH rowspan="5", title="METER 2">METER 2</TH><TD>VOLTAGE</TD><TD><A id='resp13'></A></TD><TD><A id='resp14'></A></TD><TD><A id='resp15'></A></TD><TD>V</TD></TR>
        <TR><TD>CURRENT</TD><TD><A id='resp16'></A></TD><TD><A id='resp17'></A></TD><TD><A id='resp18'></A></TD><TD>A</TD></TR>
        <TR><TD>POWER</TD><TD><A id='resp19'></A></TD><TD><A id='resp20'></A></TD><TD><A id='resp21'></A></TD><TD>W</TD></TR>
        <TR><TD>POWER FACT.</TD><TD><A id='resp22'></A></TD><TD><A id='resp23'></A></TD><TD><A id='resp24'></A></TD><TD>PF</TD></TR>
        <TR><TD>FREQUENCY</TD><TD colspan="3"><A id='resp25'></A></TD><TD>Hz</TD></TR>
      </TABLE>
      <BR/>
      <TABLE BORDER=1>
        <TR><TH rowspan="5", title="METER 3">METER 3</TH><TD>VOLTAGE</TD><TD><A id='resp26'></A></TD><TD><A id='resp27'></A></TD><TD><A id='resp28'></A></TD><TD>V</TD></TR>
        <TR><TD>CURRENT</TD><TD><A id='resp29'></A></TD><TD><A id='resp30'></A></TD><TD><A id='resp31'></A></TD><TD>A</TD></TR>
        <TR><TD>POWER</TD><TD><A id='resp32'></A></TD><TD><A id='resp33'></A></TD><TD><A id='resp34'></A></TD><TD>W</TD></TR>
        <TR><TD>POWER FACT.</TD><TD><A id='resp35'></A></TD><TD><A id='resp36'></A></TD><TD><A id='resp37'></A></TD><TD>PF</TD></TR>
        <TR><TD>FREQUENCY</TD><TD colspan="3"><A id='resp38'></A></TD><TD>Hz</TD></TR>
      </TABLE>
      <BR/>
      <TABLE BORDER=1>
        <TR><TH rowspan="2", title="ESP">ESP</TH><TD>FREE HEAP</TD><TD><A id='freeheap'></A></TD><TD>bytes</TD></TR>
        <TR><TD>LAST RST REASON</TD><TD colspan="2"><A id='rstreason'></A></TD></TR>
      </TABLE>
    </CENTER>
  </BODY>
</HTML>
)=====";
Darnshelm commented 3 years ago

Hi Thx yes the site locks much better. I try to find where to tell esp8266 it 3 power meters to read of. I copy and past your code and i get the nice tabel on webpage. also use the code lines on sdm_live_page you send. but I only get it to read from one meter only

reaper7 commented 3 years ago

if You connect esp to PC (as we did before), you should have such inquiries on terminal:

01 04 00 00 00 02 71 cb  ......qË
01 04 00 02 00 02 d0 0b  ......Đ.
01 04 00 04 00 02 30 0a  ......0.
01 04 00 06 00 02 91 ca  ......‘Ę
01 04 00 08 00 02 f0 09  ......đ.
01 04 00 0a 00 02 51 c9  ......QÉ
01 04 00 0c 00 02 b1 c8  ......±Č
01 04 00 0e 00 02 10 08  ........
01 04 00 10 00 02 70 0e  ......p.
01 04 00 1e 00 02 11 cd  .......Í
01 04 00 20 00 02 70 01  ... ..p.
01 04 00 22 00 02 d1 c1  ..."..ŃÁ
01 04 00 46 00 02 90 1e  ...F...
02 04 00 00 00 02 71 f8  ......qř
02 04 00 02 00 02 d0 38  ......Đ8
02 04 00 04 00 02 30 39  ......09
02 04 00 06 00 02 91 f9  ......‘ů
02 04 00 08 00 02 f0 3a  ......đ:
02 04 00 0a 00 02 51 fa  ......Qú
02 04 00 0c 00 02 b1 fb  ......±ű
02 04 00 0e 00 02 10 3b  .......;
02 04 00 10 00 02 70 3d  ......p=
02 04 00 1e 00 02 11 fe  .......ţ
02 04 00 20 00 02 70 32  ... ..p2
02 04 00 22 00 02 d1 f2  ..."..Ńň
02 04 00 46 00 02 90 2d  ...F..-
03 04 00 00 00 02 70 29  ......p)
03 04 00 02 00 02 d1 e9  ......Ńé
03 04 00 04 00 02 31 e8  ......1č
03 04 00 06 00 02 90 28  ......(
03 04 00 08 00 02 f1 eb  ......ńë
03 04 00 0a 00 02 50 2b  ......P+
03 04 00 0c 00 02 b0 2a  ......°*
03 04 00 0e 00 02 11 ea  .......ę
03 04 00 10 00 02 71 ec  ......qě
03 04 00 1e 00 02 10 2f  ......./
03 04 00 20 00 02 71 e3  ... ..qă
03 04 00 22 00 02 d0 23  ..."..Đ#
03 04 00 46 00 02 91 fc  ...F..‘ü

first bytes of each query (next lines) contain addresses of meters to which inquiries are addressed. As you can see, at the beginning, the meter with the address 01 is read (all the data that interests us), then the meter with the address 02 is queried for the same values, and finally the meter with the address 03

The procedure that queries the meters is:

void sdmRead() {
  float tmpval = NAN;
  for (uint8_t i = 0; i < NBREG; i++) {
    tmpval = sdm.readVal(sdmarr[i].regarr,sdmarr[i].meter);
    if (isnan(tmpval))
      sdmarr[i].regvalarr = 0.00;
    else
      sdmarr[i].regvalarr = tmpval;

    yield();
  }
}

the query is described in the documentation: https://github.com/reaper7/SDM_Energy_Meter#reading where the last (second) parameter specifies the address of the meter being queried.

What parameters and from which meter we will take is specified by this "list":

volatile sdm_struct sdmarr[NBREG] = {
  {1, 0.00, SDM_PHASE_1_VOLTAGE},                                               //V
  {1, 0.00, SDM_PHASE_2_VOLTAGE},                                               //V
  {1, 0.00, SDM_PHASE_3_VOLTAGE},                                               //V
  {1, 0.00, SDM_PHASE_1_CURRENT},                                               //A
  {1, 0.00, SDM_PHASE_2_CURRENT},                                               //A
  {1, 0.00, SDM_PHASE_3_CURRENT},                                               //A
  {1, 0.00, SDM_PHASE_1_POWER},                                                 //W
  {1, 0.00, SDM_PHASE_2_POWER},                                                 //W
  {1, 0.00, SDM_PHASE_3_POWER},                                                 //W
  {1, 0.00, SDM_PHASE_1_POWER_FACTOR},                                          //PF
  {1, 0.00, SDM_PHASE_2_POWER_FACTOR},                                          //PF
  {1, 0.00, SDM_PHASE_3_POWER_FACTOR},                                          //PF
  {1, 0.00, SDM_FREQUENCY},                                                     //Hz
  {2, 0.00, SDM_PHASE_1_VOLTAGE},                                               //V
  {2, 0.00, SDM_PHASE_2_VOLTAGE},                                               //V
  {2, 0.00, SDM_PHASE_3_VOLTAGE},                                               //V
  {2, 0.00, SDM_PHASE_1_CURRENT},                                               //A
  {2, 0.00, SDM_PHASE_2_CURRENT},                                               //A
  {2, 0.00, SDM_PHASE_3_CURRENT},                                               //A
  {2, 0.00, SDM_PHASE_1_POWER},                                                 //W
  {2, 0.00, SDM_PHASE_2_POWER},                                                 //W
  {2, 0.00, SDM_PHASE_3_POWER},                                                 //W
  {2, 0.00, SDM_PHASE_1_POWER_FACTOR},                                          //PF
  {2, 0.00, SDM_PHASE_2_POWER_FACTOR},                                          //PF
  {2, 0.00, SDM_PHASE_3_POWER_FACTOR},                                          //PF
  {2, 0.00, SDM_FREQUENCY},                                                     //Hz
  {3, 0.00, SDM_PHASE_1_VOLTAGE},                                               //V
  {3, 0.00, SDM_PHASE_2_VOLTAGE},                                               //V
  {3, 0.00, SDM_PHASE_3_VOLTAGE},                                               //V
  {3, 0.00, SDM_PHASE_1_CURRENT},                                               //A
  {3, 0.00, SDM_PHASE_2_CURRENT},                                               //A
  {3, 0.00, SDM_PHASE_3_CURRENT},                                               //A
  {3, 0.00, SDM_PHASE_1_POWER},                                                 //W
  {3, 0.00, SDM_PHASE_2_POWER},                                                 //W
  {3, 0.00, SDM_PHASE_3_POWER},                                                 //W
  {3, 0.00, SDM_PHASE_1_POWER_FACTOR},                                          //PF
  {3, 0.00, SDM_PHASE_2_POWER_FACTOR},                                          //PF
  {3, 0.00, SDM_PHASE_3_POWER_FACTOR},                                          //PF
  {3, 0.00, SDM_FREQUENCY}                                                      //Hz
};

where the meter address comes first on each line.

so if in the reading loop value of i is, for example = 0 then this fuction:

tmpval = sdm.readVal(sdmarr[i].regarr,sdmarr[i].meter);

looks like this:

tmpval = sdm.readVal(SDM_PHASE_1_VOLTAGE, 1);

So you have to make sure that the meters have addresses of 001, 002 and 003 respectively.

reaper7 commented 3 years ago

lack of activity. closed