Arduino for interrogation of counters "Mercury-230"

    When servicing metering devices Mercury-230 ART, installed at remote
    transformer substations, it often becomes necessary to quickly check the performance of meters.

    As a rule, in places where the meters work as part of the automated metering and control system and are connected in groups of twisted
    pair RS 485 and connected to the gateway Mercury 228, the connection disappears when the connection is
    established from the server side.

    To find out why the data from the counter does not arrive on the server, you must
    always carry a laptop and a Mercury 221 converter with you, and if you check the
    meter is connected correctly in the cell, you must still use the VAF device.
    Given that substations in outdoor switchgear or indoor switchgear do not always have the ability to provide a place to work with computer equipment, I have developed a small device based on the Arduino modules from amperka.ru.

    The meters are polled from the application installed on the smartphone, while the connection is via Bluetooth.

    Converter board.


    The converter board is a set of modules:

    - Iskra Mini - a full-fledged Arduino platform with an ATmega328 microcontroller installed.
    - Expansion card - Bluetooth module HC-05.
    - Expansion card - RS-485 transceiver.
    - 9V rechargeable battery of the “Krona” type (I will make a reservation right away, it’s better to use the battery to recharge the phones)
    - The power button.
    - USB connector for 5V power supply.
    - RJ11 connector for connecting the RS485 line.

    All elements are located on a separate motherboard placed in a plastic case. When the converter is turned on, the HC-05 Bluetooth module enters the operating mode
    “Transparent UART” and expects to connect from the smartphone.

    image

    Connection diagram.


    When the switch SW1 is turned on, the supply voltage of 9-12 Volts is supplied to the electronic
    regulator LM7805 (it is advisable to replace it with another model).

    From the regulator output, a lowered voltage of 5 Volts is applied to the Iskra Mini pin “+ 5V”, the Bluetooth module pin “V” and the RS485 pin “V”. The negative battery wire is connected to the GND pins of all modules. When applying a supply voltage of 5 volts through the microUSB connector, all modules are powered similarly, bypassing the LM7805 regulator.

    J1 and J2 are jumpers and must be closed during operation.
    J3 - a six-pin connector designed to “flash” the Iskra Mini module using a
    USB-Serial adapter.

    When downloading software to the Iskra Mini module, jumpers J1 and J2 must be open. Capacitor C1 is designed to reset the microcontroller at the time of downloading the software.

    The “RX” terminal Iskra Mini is connected to the “TX” terminal of the Bluetooth module, thus the
    microcontroller receives data from Bluetooth.
    “ТX” terminal Iskra Mini is connected to the “RX” terminal of the Bluetooth module, thus the
    microcontroller transmits commands to Bluetooth.
    Conclusion «8» Iskra Mini is connected to the output of «DI» module RS485, MCU generates
    transmission commands in a line.
    Pin “11” Iskra Mini connects to the pin “RO” of the RS485 module, the microcontroller
    reads the responses from the line.
    Pin “5” Iskra Mini is connected to the pin “In / Out” of the RS485 module, the microcontroller
    switches the operating modes of the RS485 transceiver.
    RJ11 - connector for connecting the RS485 line.

    image

    Converter software.


    After power is supplied to the device, the microcontroller enters the cyclic
    standby mode of receiving a command.

    The list of commands:

    ping_ -- после получения этой команды МК в ответ отсылает «ping_».
    Используется для тестирования канала связи между смартфоном и преобразователем.
    

    scan_ -- команда сканирования сети на наличие приборов учета от адреса 0 до адреса 254
    

    init_XXX – где ХХХ это сетевой адрес опрашиваемого прибора учета. Надо учитывать, что к сетевым адресам меньше 10 должны добавляться два нуля, 
    а адресам меньше 100 – один ноль. 
    После получения этой команды МК в ответ отсылает «init_XXX». 
    Используется для однократного опроса прибора учета.
     Пример.
     Прибор учета № 13 02 97 02
     Команда: init_002
     Ответ: init_002
     Прибор учета № 16 24 07 32
     Команда: init_032
     Ответ: init_032
     Прибор учета № 17 14 51 52
     Команда: init_152
     Ответ: init_152
    

    loop_XXX – После получения этой команды МК в ответ отсылает «loop_XXX». 
    Используется для непрерывного опроса прибора учета.
    

    stop_ – После получения этой команды МК в ответ отсылает «stop_000». Используется для
    остановки режима непрерывного опроса прибора учета.
    

    Variants of the answers of the microcontroller after executing the commands:

    Connect_OK - a device with the specified network address was found on the network.
    Connect_FAIL - devices with this network address are not responding.
    Access_OK - the access password is transmitted, the response is received.
    Access_FAIL - access is closed, password is not accepted.

    The microcontroller software operation algorithm.


    After receiving the init or loop command, the
    Net Address, 0x00, 0x00, CRC 1, CRC 2 byte sequence is sent .

    If the device is located on the network, there will be a similar response, after which the network addresses are sent and received.

    CRC checks in the response array are currently not performed.
    If the comparison is positive, the Connect_OK string is sent to the Bluetooth module, otherwise Connect_FAIL.

    Next, an access request is sent with the transmission of the password Net Address, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, CRC 1, CRC.

    Upon receipt of a response similar to the device discovery request, the Access_OK string is sent to the Bluetooth module, otherwise Access_FAIL.

    After establishing a connection, the transmission of requests for receiving data according to the
    protocol begins .

    Net Address, 0x00, 0x08, 0x00, CRC 1, CRC -- серийный номер
    Net Address, 0x00, 0x08, 0x16, 0x40, CRC 1, CRC -- частота
    Net Address, 0x00, 0x08, 0x16, 0x21, CRC 1, CRC -- ток
    Net Address, 0x00, 0x08, 0x16, 0x11, CRC 1, CRC -- напряжение
    Net Address, 0x00, 0x08, 0x16, 0x00, CRC 1, CRC-- мощность
    Net Address, 0x00, 0x08, 0x16, 0x51, CRC 1, CRC -- углы
    Net Address, 0x00, 0x05, 0x00, 0x00, CRC 1, CRC -- суммарная энергия прямая + обратная + активная + реактивная.
    

    Referring to the manufacturer’s recommendations, special attention should be paid to the timeout between the request and the response, since the converter is always a Master device, and the polled devices are a Slave.

    Experience shows that the timeout value and the number of correct answers depend on the quality and length of the RS485 line, so you may have to make adjustments to these parameters.

    m230.ino
    #include 
    //-------- порты для rs 485
    #define SSerialRx        11  // Serial Receive pin RO
    #define SSerialTx        8   // Serial Transmit pin DI
    //-------- инициализация 
    SoftwareSerial RS485Serial(SSerialRx, SSerialTx); // Rx, Tx
    //// линия управления передачи приема
    #define SerialControl 5   // RS485 Direction control
    /////// флаг приема передачи
    #define RS485Transmit    HIGH
    #define RS485Receive     LOW
    /////// команды
    byte testConnect[] = { 0x00, 0x00 };
    byte Access[]      = { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
    byte Sn[]          = { 0x00, 0x08, 0x00 }; // серийный номер
    byte Freq[]        = { 0x00, 0x08, 0x16, 0x40 }; // частота
    byte Current[]     = { 0x00, 0x08, 0x16, 0x21 };//  ток
    byte Suply[]       = { 0x00, 0x08, 0x16, 0x11 }; // напряжение
    byte Power[]       = { 0x00, 0x08, 0x16, 0x00 };// мощность p
    byte PowerQ[]       = { 0x00, 0x08, 0x16, 0x08 };// мощность Q
    byte PowerS[]       = { 0x00, 0x08, 0x16, 0x04 };// мощность S
    byte CosF[]       = { 0x00, 0x08, 0x16, 0x30 };// cosf
    byte Angle[]       = { 0x00, 0x08, 0x16, 0x51 }; // углы
    byte energyT0[]  =   { 0x00, 0x05, 0x00, 0x00 };///  суммарная энергия прямая + обратная + активная + реактивная
    byte energyT1[]  =   { 0x00, 0x05, 0x00, 0x01 };///  суммарная энергия прямая + обратная + активная + реактивная
    byte energyT2[]  =   { 0x00, 0x05, 0x00, 0x02 };///  суммарная энергия прямая + обратная + активная + реактивная
    byte energyT3[]  =   { 0x00, 0x05, 0x00, 0x03 };///  суммарная энергия прямая + обратная + активная + реактивная
    byte energyT4[]  =   { 0x00, 0x05, 0x00, 0x04 };///  суммарная энергия прямая + обратная + активная + реактивная
    byte response[19];
    int byteReceived;
    int byteSend;
    int netAdr;
    int SCAN_YES_NO=0;
    int TST_YES_NO=0;  
    int ACCESS_YES_NO=0;
    int ALLOW=0; 
    void setup() {
    RS485Serial.begin(9600);
    Serial.begin(9600);
    // 5 пин в режим выхода
    pinMode(SerialControl, OUTPUT);
    // ставим на прием
    digitalWrite(SerialControl, RS485Receive);
    delay(300);
    Serial.println("Start_v2.3\r\n");
    }
    void loop() {
    TST_YES_NO=0;  
    ACCESS_YES_NO=0;
    ALLOW=0;  
                   while (Serial.available()) 
                  {    char incomingBytes[15]; 
                       if(Serial.available()>0)       
                        {      
                            Serial.readBytes(incomingBytes,10);
                        }                   
                               String getS = String(incomingBytes);
                                   if(getS.substring(0,5) == "init_") 
                                { ALLOW=1;  
                                       Serial.print(getS.substring(0,5)+getS.substring(5,8)+"\r\n");
                                  netAdr=getS.substring(5,8).toInt();
                                }
                                   if(getS.substring(0,5) == "loop_") 
                                { ALLOW=1;
                                  SCAN_YES_NO=1;  
                                  Serial.print(getS.substring(0,5)+getS.substring(5,8)+"\r\n");
                                  netAdr=getS.substring(5,8).toInt();
                                }
                                  if(getS.substring(0,5) == "scan_") 
                                { ALLOW=0;
                                  SCAN_YES_NO=0;  
                                  Serial.print(getS.substring(0,5)+"\r\n");
                                         netAdr=1;
                                         while(netAdr < 256)
                                         {
                                            testConnect[0] = netAdr;
                                            response[0] = 0;
                                            send(testConnect, sizeof(testConnect), response);
                                                   if(response[0] == netAdr)
                                                 { 
                                                       Serial.print("scan;ok;"+String(netAdr)+";0\r\n");   
                                                 }
                                                       else
                                                 {     
                                                       Serial.print("scan;no;"+String(netAdr)+";0\r\n");   
                                                 }
                                         netAdr++;
                                         delay(5);
                                         }
                                         netAdr=0;
                                }
                                      if(getS.substring(0,5) == "stop_") 
                                { ALLOW=0;
                                  SCAN_YES_NO=0;  
                                  Serial.print(getS.substring(0,5)+"000\r\n");
                                  //netAdr=getS.substring(5,8).toInt();
                                }
                                      if(getS.substring(0,5) == "ping_") 
                                {   
                                  Serial.print(getS.substring(0,5)+"\r\n");
                                }
                    }
     if(ALLOW==1 or SCAN_YES_NO==1)
    {
     //========================================================================
      testConnect[0] = netAdr;
      response[0] = 0;
      send(testConnect, sizeof(testConnect), response);
           if(response[0] == netAdr)
          {      TST_YES_NO=1;
                 Serial.print("Connect_OK\r\n");   
          }
           else
          {      TST_YES_NO=0;
                 Serial.print("Connect_FAIL\r\n");   
          }
      //========================================================================
         if(TST_YES_NO==1)
         {
              delay(100);
              Access[0] = netAdr;
              response[0] = 0;
              send(Access, sizeof(Access), response);
                  if(response[0] == netAdr)
                 {      ACCESS_YES_NO=1;
                        Serial.print("Access_OK\r\n");   
                 }
                  else
                 {      ACCESS_YES_NO=0;
                        Serial.print("Access_FAIL\r\n");   
                 }
         }
            if(ACCESS_YES_NO==1)
         {
             String serNum = getSerialNumber(netAdr);
             Serial.print("s:"+ serNum +"\r\n");   
             String ARPower = getEnergyT0(netAdr);
             Serial.print("p:"+ ARPower+"\r\n");   
             String valFreq = getFreq(netAdr);
             Serial.print("f:"+ valFreq+"\r\n");   
             String U = getSuply(netAdr);
             Serial.print("u:"+ U+"\r\n");   
             String A = getCurrent(netAdr);
             Serial.print("a:"+ A+"\r\n");   
             String Angle = getAngle(netAdr);
             Serial.print("g:"+ Angle+"\r\n");   
             String PowerNow = getPowerNow(netAdr);
             Serial.print("e:"+ PowerNow+"\r\n");  
             String Tarif1 = getEnergyT1(netAdr);
             Serial.print("t1:"+ Tarif1+"\r\n");  
             String Tarif2 = getEnergyT2(netAdr);
             Serial.print("t2:"+ Tarif2+"\r\n");  
             String Tarif3 = getEnergyT3(netAdr);
             Serial.print("t3:"+ Tarif3+"\r\n");  
             String Tarif4 = getEnergyT4(netAdr);
             Serial.print("t4:"+ Tarif4+"\r\n");  
             String PQ = getPowerQ(netAdr);
             Serial.print("q:"+ PQ+"\r\n");  
             String PS = getPowerS(netAdr);
             Serial.print("c:"+ PS+"\r\n");  
             String CSF = getCosF(netAdr);
             Serial.print("k:"+ CSF+"\r\n");  
         }
      delay(1000);
    }
    }
    String getSerialNumber(int netAdr)
    {
      String s1,s2,s3,s4;
      response[0]=0;
      Sn[0] = netAdr;
      send(Sn, sizeof(Sn),response);
      if((int)response[1] < 10) { s1="0" + String((int)response[1]); } else {s1=String((int)response[1]);}
      if((int)response[2] < 10) { s2="0" + String((int)response[2]); } else {s2=String((int)response[2]);}
      if((int)response[3] < 10) { s3="0" + String((int)response[3]); } else {s3=String((int)response[3]);}
      if((int)response[4] < 10) { s4="0" + String((int)response[4]); } else {s4=String((int)response[4]);}
      String n = s1+s2+s3+s4;
      return String(response[0])+";"+n;
    }
    String getPowerNow(int netAdr)
    {
      response[0]=0;
      Power[0] = netAdr;
      send(Power, sizeof(Power),response);
      long r = 0;
      int dir_U0=0;
      int dir_U1=0;
      int dir_U2=0;
      int dir_U3=0;
      if((long)response[1]<<16 == 0x40) dir_U0=1;
      if((long)response[1]<<16 == 0x80) dir_U0=-1;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U0= String(r * dir_U0);
      r = 0;
      if((long)response[4]<<16 == 0x40) dir_U1=1;
      if((long)response[4]<<16 == 0x80) dir_U1=-1;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U1= String(r * dir_U1);
      r=0;
      if((long)response[7]<<16 == 0x40) dir_U2=1;
      if((long)response[7]<<16 == 0x80) dir_U2=-1;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U2= String(r * dir_U2);
      r = 0;
      if((long)response[10]<<16 == 0x40) dir_U3=1;
      if((long)response[10]<<16 == 0x80) dir_U3=-1;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String U3= String(r * dir_U3);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U0+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getPowerQ(int netAdr)
    {
      response[0]=0;
      PowerQ[0] = netAdr;
      send(PowerQ, sizeof(PowerQ),response);
      long r = 0;
      int dir_U0=0;
      int dir_U1=0;
      int dir_U2=0;
      int dir_U3=0;
      if((long)response[1]<<16 == 0x40) dir_U0=1;
      if((long)response[1]<<16 == 0x80) dir_U0=-1;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U0= String(r * dir_U0);
      r = 0;
      if((long)response[4]<<16 == 0x40) dir_U1=1;
      if((long)response[4]<<16 == 0x80) dir_U1=-1;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U1= String(r * dir_U1);
      r=0;
      if((long)response[7]<<16 == 0x40) dir_U2=1;
      if((long)response[7]<<16 == 0x80) dir_U2=-1;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U2= String(r * dir_U2);
      r = 0;
      if((long)response[10]<<16 == 0x40) dir_U3=1;
      if((long)response[10]<<16 == 0x80) dir_U3=-1;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String U3= String(r * dir_U3);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U0+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getPowerS(int netAdr)
    {
      response[0]=0;
      PowerS[0] = netAdr;
      send(PowerS, sizeof(PowerS),response);
      long r = 0;
      int dir_U0=0;
      int dir_U1=0;
      int dir_U2=0;
      int dir_U3=0;
      if((long)response[1]<<16 == 0x40) dir_U0=1;
      if((long)response[1]<<16 == 0x80) dir_U0=-1;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U0= String(r * dir_U0);
      r = 0;
      if((long)response[4]<<16 == 0x40) dir_U1=1;
      if((long)response[4]<<16 == 0x80) dir_U1=-1;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U1= String(r * dir_U1);
      r=0;
      if((long)response[7]<<16 == 0x40) dir_U2=1;
      if((long)response[7]<<16 == 0x80) dir_U2=-1;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U2= String(r * dir_U2);
      r = 0;
      if((long)response[10]<<16 == 0x40) dir_U3=1;
      if((long)response[10]<<16 == 0x80) dir_U3=-1;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String U3= String(r * dir_U3);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U0+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getCosF(int netAdr)
    {
      response[0]=0;
      CosF[0] = netAdr;
      send(CosF, sizeof(CosF),response);
      long r = 0;
      int dir_U0=0;
      int dir_U1=0;
      int dir_U2=0;
      int dir_U3=0;
      if((long)response[1]<<16 == 0x40) dir_U0=1;
      if((long)response[1]<<16 == 0x80) dir_U0=-1;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U0= String(r * dir_U0);
      r = 0;
      if((long)response[4]<<16 == 0x40) dir_U1=1;
      if((long)response[4]<<16 == 0x80) dir_U1=-1;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U1= String(r * dir_U1);
      r=0;
      if((long)response[7]<<16 == 0x40) dir_U2=1;
      if((long)response[7]<<16 == 0x80) dir_U2=-1;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U2= String(r * dir_U2);
      r = 0;
      if((long)response[10]<<16 == 0x40) dir_U3=1;
      if((long)response[10]<<16 == 0x80) dir_U3=-1;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String U3= String(r * dir_U3);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U0+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getAngle(int netAdr)
    {
      response[0]=0;
      Angle[0] = netAdr;
      send(Angle, sizeof(Angle),response);
      long r = 0;
      r |= (long)response[1]<<16;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U1= String(r);
      r = 0;
      r |= (long)response[4]<<16;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U2= String(r);
      r=0;
      r |= (long)response[7]<<16;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U3= String(r);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getCurrent(int netAdr)
    {
      response[0]=0;
      Current[0] = netAdr;
      send(Current, sizeof(Current),response);
      long r = 0;
      r |= (long)response[1]<<16;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U1= String(r);
      r = 0;
      r |= (long)response[4]<<16;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U2= String(r);
      r=0;
      r |= (long)response[7]<<16;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U3= String(r);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getSuply(int netAdr)
    {
      response[0]=0;
      Suply[0] = netAdr;
      send(Suply, sizeof(Suply),response);
      long r = 0;
      r |= (long)response[1]<<16;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String U1= String(r);
      r = 0;
      r |= (long)response[4]<<16;
      r |= (long)response[6]<<8;
      r |= (long)response[5];
      String U2= String(r);
      r=0;
      r |= (long)response[7]<<16;
      r |= (long)response[9]<<8;
      r |= (long)response[8];
      String U3= String(r);
      if(response[0] == netAdr)   return String(String(response[0])+";"+U1+";"+U2+";"+U3);
      else   return String("Error");
    }
    String getFreq(int netAdr)
    {
      response[0]=0;
      Freq[0] = netAdr;
      send(Freq, sizeof(Freq),response);
      long r = 0;
      r |= (long)response[1]<<16;
      r |= (long)response[3]<<8;
      r |= (long)response[2];
      String fr= String(r);
      //return fr;
      if(response[0] == netAdr)   return String(response[0])+";"+fr;
      else   return String("Error");
    }
    String getEnergyT0(int netAdr)
    {
      response[0]=0;
      energyT0[0] = netAdr;
      send(energyT0, sizeof(energyT0),response);
      if(response[0] == netAdr) 
      {
      long r = 0;
      r |= (long)response[2]<<24;
      r |= (long)response[1]<<16;
      r |= (long)response[4]<<8;
      r |= (long)response[3];
      String A_plus= String(r);
      r=0;
      r |= (long)response[6]<<24;
      r |= (long)response[5]<<16;
      r |= (long)response[8]<<8;
      r |= (long)response[7];
      String A_minus= String(r);
      r = 0;
      r |= (long)response[10]<<24;
      r |= (long)response[9]<<16;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String R_plus= String(r);
      r = 0;
      r |= (long)response[14]<<24;
      r |= (long)response[13]<<16;
      r |= (long)response[16]<<8;
      r |= (long)response[15];
      String R_minus= String(r);
      return String(String(response[0])+";"+A_plus+";"+A_minus+";"+R_plus+";"+R_minus);
      }
      else   return String("Error");
    }
    String getEnergyT1(int netAdr)
    {
      response[0]=0;
      energyT1[0] = netAdr;
      send(energyT1, sizeof(energyT1),response);
      if(response[0] == netAdr) 
      {
      long r = 0;
      r |= (long)response[2]<<24;
      r |= (long)response[1]<<16;
      r |= (long)response[4]<<8;
      r |= (long)response[3];
      String A_plus= String(r);
      r=0;
      r |= (long)response[6]<<24;
      r |= (long)response[5]<<16;
      r |= (long)response[8]<<8;
      r |= (long)response[7];
      String A_minus= String(r);
      r = 0;
      r |= (long)response[10]<<24;
      r |= (long)response[9]<<16;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String R_plus= String(r);
      r = 0;
      r |= (long)response[14]<<24;
      r |= (long)response[13]<<16;
      r |= (long)response[16]<<8;
      r |= (long)response[15];
      String R_minus= String(r);
      return String(String(response[0])+";"+A_plus+";"+A_minus+";"+R_plus+";"+R_minus);
      }
      else   return String("Error");
    }
    String getEnergyT2(int netAdr)
    {
      response[0]=0;
      energyT2[0] = netAdr;
      send(energyT2, sizeof(energyT2),response);
      if(response[0] == netAdr) 
      {
      long r = 0;
      r |= (long)response[2]<<24;
      r |= (long)response[1]<<16;
      r |= (long)response[4]<<8;
      r |= (long)response[3];
      String A_plus= String(r);
      r=0;
      r |= (long)response[6]<<24;
      r |= (long)response[5]<<16;
      r |= (long)response[8]<<8;
      r |= (long)response[7];
      String A_minus= String(r);
      r = 0;
      r |= (long)response[10]<<24;
      r |= (long)response[9]<<16;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String R_plus= String(r);
      r = 0;
      r |= (long)response[14]<<24;
      r |= (long)response[13]<<16;
      r |= (long)response[16]<<8;
      r |= (long)response[15];
      String R_minus= String(r);
      return String(String(response[0])+";"+A_plus+";"+A_minus+";"+R_plus+";"+R_minus);
      }
      else   return String("Error");
    }
    String getEnergyT3(int netAdr)
    {
      response[0]=0;
      energyT3[0] = netAdr;
      send(energyT3, sizeof(energyT3),response);
      if(response[0] == netAdr) 
      {
      long r = 0;
      r |= (long)response[2]<<24;
      r |= (long)response[1]<<16;
      r |= (long)response[4]<<8;
      r |= (long)response[3];
      String A_plus= String(r);
      r=0;
      r |= (long)response[6]<<24;
      r |= (long)response[5]<<16;
      r |= (long)response[8]<<8;
      r |= (long)response[7];
      String A_minus= String(r);
      r = 0;
      r |= (long)response[10]<<24;
      r |= (long)response[9]<<16;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String R_plus= String(r);
      r = 0;
      r |= (long)response[14]<<24;
      r |= (long)response[13]<<16;
      r |= (long)response[16]<<8;
      r |= (long)response[15];
      String R_minus= String(r);
      return String(String(response[0])+";"+A_plus+";"+A_minus+";"+R_plus+";"+R_minus);
      }
      else   return String("Error");
    }
    String getEnergyT4(int netAdr)
    {
      response[0]=0;
      energyT4[0] = netAdr;
      send(energyT4, sizeof(energyT4),response);
      if(response[0] == netAdr) 
      {
      long r = 0;
      r |= (long)response[2]<<24;
      r |= (long)response[1]<<16;
      r |= (long)response[4]<<8;
      r |= (long)response[3];
      String A_plus= String(r);
      r=0;
      r |= (long)response[6]<<24;
      r |= (long)response[5]<<16;
      r |= (long)response[8]<<8;
      r |= (long)response[7];
      String A_minus= String(r);
      r = 0;
      r |= (long)response[10]<<24;
      r |= (long)response[9]<<16;
      r |= (long)response[12]<<8;
      r |= (long)response[11];
      String R_plus= String(r);
      r = 0;
      r |= (long)response[14]<<24;
      r |= (long)response[13]<<16;
      r |= (long)response[16]<<8;
      r |= (long)response[15];
      String R_minus= String(r);
      return String(String(response[0])+";"+A_plus+";"+A_minus+";"+R_plus+";"+R_minus);
      }
      else   return String("Error");
    }
    //////////////////////////////////////////////////////////////////////////////////
    void send(byte *cmd, int s, byte *response) {
     // Serial.print("sending...");
      unsigned int crc = crc16MODBUS(cmd, s);
      unsigned int crc1 = crc & 0xFF;
      unsigned int crc2 = (crc>>8) & 0xFF;
      delay(10);
      digitalWrite(SerialControl, RS485Transmit);  // Init Transceiver   
           for(int i=0; i> 8) ^ crcTable[(crc ^ s[i]) & 0xFF]);
        }
        return crc;
    }
    


    Smartphone software.


    After installing the Android application, in the smartphone in the application menu you need to find a
    shortcut with the name "M-230" and run the program.

    In the application click on the drop-down menu next to "Command"
    and then displays a list of commands.

    image
    Search for devices - a search will be made for available Bluetooth devices and offered to
    connect.

    Check communication - command to check communication with the converter.

    Interrogate - a single interrogation of the counter at the specified network address.

    Monitor - continuous cyclic polling of one device at a specified network address (online mode).

    Stop - stops the cyclic polling.

    Journal- the ability to observe the receipt of data in the exchange log located at the bottom of the program is turned on or off.

    image

    Here is the project file for Android Studio

    Also popular now: