Modbus RTU using esp32 for ADL400 energy meter

Thread Starter

Ahmet Pehlivan

Joined Oct 16, 2022
28
Hi everyone, i have find an example register using with ADL400 it works perfectly but my problem is
#define degerVoltagePhaseA 2304
#define degerVoltagePhaseC 2308
#define degerToplamGuc 2322
#define degerToplamEnerji 2332

when i look for adl400 registers in adl400 manual i can't find any value to match with this registers' value so if i want to add something i can't find which registers should i use, so what is the connection beetwen them.

1736891274502.png


esp32 with modbusrtu:
#include <ModbusMaster.h>


#define pinOkumaCP  27
#define pinOkumaPP  32
#define pinTxEkran  25
#define pinRxEkran  26
#define pinTxEnerjiMetre  14
#define pinRxEnerjiMetre  12
#define RSE_PIN 13       // RS485 RSE Pin ---> Arduino Pin 2



#define SLAVE_ID 1             // ADL400E'nin Slave ID'si (Genellikle 1'dir, ancak cihazınıza göre değişebilir)
#define REGISTER_ADDR_VOLTAGE 2304  // Gerilim adresi (Bu, ADL400E'nin voltaj register adresidir. Kılavuzdan kontrol edin.)
#define REGISTER_ADDR_CURRENT 2310  // Akım adresi (Yine, cihazın dökümantasyonundan öğrenin)
#define NUM_REGISTERS 2        // 32-bit float için 2 register
#define degerVoltagePhaseA 2304
#define degerVoltagePhaseC 2308
#define degerToplamGuc     2322
#define degerToplamEnerji   2332

#define degerStateA_Max 4100
#define degerStateA_Min 3600c

#define degerStateB_Max 3400
#define degerStateB_Min 3200

#define degerStateC_Max 3000
#define degerStateC_Min 2700

#define degerStateD_Max 2500
#define degerStateD_Min 2300

#define degerStateF_Max 2250
#define degerStateF_Min 1800

#define deger63A_Max  300
#define deger63A_Min  0

#define deger32A_Max  1000
#define deger32A_Min  400

#define deger20A_Max  1900
#define deger20A_Min  1300


#define deger13A_Max  2600
#define deger13A_Min  2000

#define degerNCA_Max  4095
#define degerNCA_Min  3500
//#define Serial Ekran


HardwareSerial Ekran(1);
HardwareSerial enerjiMetre(2);
ModbusMaster node;


void setup() {

Serial.begin(115200);
Ekran.begin(9600, SERIAL_8N1, pinRxEkran, pinTxEkran);
enerjiMetre.begin(9600,SERIAL_8N1,pinRxEnerjiMetre,pinTxEnerjiMetre); // Enerjimetrenizin baud hızına göre ayarlayın

pinMode(RSE_PIN, OUTPUT);
pinMode(pinOkumaCP, INPUT);
pinMode(pinOkumaPP, INPUT); 

Serial.println("ADL400E Veri Okuma Basladi.");

 
node.begin(SLAVE_ID, enerjiMetre);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);


}

void loop() {

int intOkumaCP = analogRead(pinOkumaCP);
int intOkumaPP = analogRead(pinOkumaPP);
float voltagePhaseA = readRegister(degerVoltagePhaseA);
delay(10);
float voltagePhaseC = readRegister(degerVoltagePhaseC);
delay(10);
float currentPhaseA = readRegister(REGISTER_ADDR_CURRENT);
delay(10);
float powerTotal=     readRegister(degerToplamGuc);
delay(10);
float energyTotal=    readRegister(degerToplamEnerji);
const char* voltagePhase;

Serial.printf("voltagePhaseA %.2f VoltagePhaseC %.2f CurrentPhaseA %.2f powerTotal %.2f energyTotal %.2f \n"
,voltagePhaseA ,voltagePhaseC ,currentPhaseA ,powerTotal ,energyTotal );

// powerTotal ve energyTotal'ı const char*'a dönüştür
String powerTotalStr = String(powerTotal, 2); // 2 ondalık basamak
const char* powerTotalCStr = powerTotalStr.c_str(); // const char*'a dönüştür

String energyTotalStr = String(energyTotal, 2); // 2 ondalık basamak
const char* energyTotalCStr = energyTotalStr.c_str(); // const char*'a dönüştür

if(voltagePhaseC > 100 && voltagePhaseC != NAN) //tek faz
{
  voltagePhase="3 faz 380V";
}
else if(voltagePhaseC < 100) //Üç faz
{
  voltagePhase="1 faz 220V";
}



for(int i=0;i<500;i++)
{
   int intOkumaFiltreCP = analogRead(pinOkumaCP);
 
  if(intOkumaCP <= intOkumaFiltreCP)
  {
    intOkumaCP = intOkumaFiltreCP;
  }
  delayMicroseconds(10);
}

Serial.print(intOkumaCP); Serial.println("CP okuma");
delay(5);
Serial.print(intOkumaPP); Serial.println("PP okuma");
delay(5);

if( degerStateA_Max >= intOkumaCP &&  degerStateA_Min <= intOkumaCP)
{
  funcCPDurumuYolla("Lutfen Soketi Yerlestiriniz");
  node.writeSingleRegister(512, 1); // Konnektör çıkarılınca enerji değerlerini temizler
}else if(degerStateB_Max >= intOkumaCP &&  degerStateB_Min<= intOkumaCP)
{
  funcCPDurumuYolla("Soket Basarili Bir Sekilde Takildi");
}else if(degerStateC_Max >= intOkumaCP &&  degerStateC_Min <= intOkumaCP)// Enerji metreden okunan değere göre de koşul değişecek
{
  if(currentPhaseA > 0.8) //0.8 Amper
  {
    funcCPDurumuYolla("Sarj İslemi Basladi"); 
  }
  else
  {
    funcCPDurumuYolla("Lutfen Karti Okutunuz");
  }
 
}else if(degerStateD_Max >= intOkumaCP &&  degerStateD_Min <= intOkumaCP)
{
  funcCPDurumuYolla("Aracin Havalandirilmasi Gerekiyor");
}
else if(degerStateF_Max >= intOkumaCP &&  degerStateF_Min<= intOkumaCP)
{
  funcCPDurumuYolla("Hata");
}else
{
   funcCPDurumuYolla("Bilinmeyen Durum");
}

delay(250);

if( deger63A_Max >= intOkumaPP && deger63A_Min <= intOkumaPP )
{
  funcPPDurumuYolla("63 Amper");
}else if(deger32A_Max >= intOkumaPP && deger32A_Min <= intOkumaPP)
{
  funcPPDurumuYolla("32 Amper");
}else if(deger20A_Max >= intOkumaPP && deger20A_Min <= intOkumaPP)
{
  funcPPDurumuYolla("20 Amper");
}else if(deger13A_Max >= intOkumaPP && deger13A_Min <= intOkumaPP)
{
  funcPPDurumuYolla("13 Amper");
}else if(degerNCA_Max >= intOkumaPP && degerNCA_Min <= intOkumaPP)
{
  funcPPDurumuYolla("Soket Takılı Değil");
}

delay(250);


//enerjiDegerleriniYolla(voltagePhase, powerTotalCStr, energyTotalCStr);

voltDegeriniYolla(voltagePhase);

delay(250);

if(!isnan(powerTotal))
{
  GucDegeriniYolla( powerTotalCStr);
}

delay(250);

if(!isnan(energyTotal))
{
  EnerjiDegeriniYolla(energyTotalCStr);
}

delay(250);

}





void funcCPDurumuYolla(const char* Cp)
{
 // Serial.print(Cp); Serial.println("cp durumu");
  Ekran.printf("tSarjDurumu.txt=\"%s\"",Cp);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
  delay(10);
}

void funcPPDurumuYolla(const char* Pp)
{
 // Serial.print(Pp); Serial.println("pp durumu");
  Ekran.printf("tAmper.txt=\"%s\"",Pp);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
}


void enerjiDegerleriniYolla(const char* volt, const char* Guc, const char* Enerji)
{
 // Serial.print(volt); Serial.println("gerilim durumu");
 // Serial.print(Guc); Serial.println("guc durumu");
  //Serial.print(Enerji); Serial.println("enerji durumu");

  Ekran.printf("t1.txt=\"%s\"",volt);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
  //delay(250);
  Ekran.printf("t3.txt=\"%s\"",Guc);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
 // delay(250);
  Ekran.printf("t4.txt=\"%s\"",Enerji);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
 // delay(250);

}

void voltDegeriniYolla(const char* volt)
{
  Ekran.printf("t1.txt=\"%s\"",volt);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
}

void GucDegeriniYolla(const char* Guc)
{
  Ekran.printf("t3.txt=\"%s kW\"",Guc);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
}


void EnerjiDegeriniYolla(const char* Enerji)
{
  Ekran.printf("t4.txt=\"%s kWH\"",Enerji);
  Ekran.write(0xff);
  Ekran.write(0xff);
  Ekran.write(0xff);
}


void preTransmission() {
  digitalWrite(RSE_PIN, HIGH); // Veri gönderimi öncesi transmitter moduna geç
}

void postTransmission() {
  digitalWrite(RSE_PIN, LOW); // Gönderim sonrası receiver moduna dön
}

float readRegister(uint16_t address) {
  uint8_t result = node.readHoldingRegisters(address, NUM_REGISTERS);

  if (result == node.ku8MBSuccess) {
    uint16_t highWord = node.getResponseBuffer(0);
    uint16_t lowWord = node.getResponseBuffer(1);

    // Byte sıralamasını düzelt (big-endian'dan little-endian'a)
    uint8_t bytes[4];
    bytes[0] = highWord >> 8;    // highWord üst byte
    bytes[1] = highWord & 0xFF;  // highWord alt byte
    bytes[2] = lowWord >> 8;     // lowWord üst byte
    bytes[3] = lowWord & 0xFF;   // lowWord alt byte

    // Big-endian'dan little-endian'a çevir
    uint8_t temp = bytes[0];
    bytes[0] = bytes[3];
    bytes[3] = temp;

    temp = bytes[1];
    bytes[1] = bytes[2];
    bytes[2] = temp;

    // Byte dizisini float'a dönüştür
    float value;
    memcpy(&value, bytes, sizeof(value));
    return value;
  } else {
    Serial.print("Modbus Hata Kodu: ");
    Serial.println(result);
    return NAN; // Hata durumunda NaN döndür
 }
}
 

MisterBill2

Joined Jan 23, 2018
27,164
The problem appears to be that no participants here have worked with that device and so do not have any idea as to how to solve the problem. Also, many of us are not at all programmers.
 
Top