📜 ⬆️ ⬇️

Arduino to poll the counters "Mercury-230"

When servicing metering devices Mercury-230 ART installed on remote
transformer substations, it is often necessary to promptly check the performance of the meters.

As a rule, in places where meters work as part of AMR and are connected in groups by twisted
RS 485 pair and Mercury 228 are connected to the gateway, the connection is lost at the moment
establish a connection from the server.

To find out why the data from the meter does not arrive at the server, you need to
always carry a laptop and a Mercury 221 converter, and in the case of checking
the correct connection of the meter in the cell still needs to use the VAF device.
Considering that at substations in an open switchgear or indoor switchgear it is not always possible to provide a place to work with computer equipment, I have developed a small device based on Arduino modules from amperka.ru.

Interrogation of counters is made from the application installed on the smartphone, while communication is carried out via Bluetooth.
')

Converter board.


The converter board is a set of modules:

- Iskra Mini is a full-fledged Arduino platform with an ATmega328 microcontroller installed.
- Expansion card - Bluetooth module HC-05.
- Expansion card - RS-485 transceiver.
- Battery battery 9V type "Krona" (just make a reservation the bad option, it is better to use the battery to charge the phones)
- Power button.
- USB connector for power supply 5V.
- 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 Bluetooth module HC-05 switches to the operation mode
"Transparent UART" and is awaiting connection from the smartphone.

image

Connection diagram.


When the switch SW1 is turned on, the supply voltage of 9-12 volts is applied to the electronic
LM7805 regulator (preferably replaced with a different model).

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

J1 and J2 are jumpers and must be closed in run mode.
J3 is a six-pin connector designed for flashing the Iskra Mini using
USB-Serial adapter.

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

The “RX” pin of the Iskra Mini connects to the “TX” pin of the Bluetooth module, thus
The microcontroller receives data from Bluetooth.
The “TX” Iskra Mini pin is connected to the “RX” pin on the Bluetooth module, thus
microcontroller transmits commands to Bluetooth.
Conclusion "8" Iskra Mini is connected to the output "DI" of the RS485 module, the microcontroller produces
transfer of commands to the line.
Conclusion "11" Iskra Mini is connected to the output "RO" of the RS485 module, the microcontroller produces
reading responses from the line.
Conclusion "5" Iskra Mini is connected to the output "In / Out" of the RS485 module, microcontroller
switches the operating modes of the RS485 transceiver.
RJ11 - connector for connecting the RS485 line.

image

Software converter.


After powering the device, the microcontroller goes into cyclic mode.
waiting to receive a command.

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 answers of the microcontroller after the execution of commands:

Connect_OK — The device with the specified network address is detected on the network.
Connect_FAIL - devices with this network address are not responding.
Access_OK - the access password has been transmitted, the response has been received.
Access_FAIL - access is closed, the password is not accepted.

The algorithm of the microcontroller software.


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

If the device is found in the network, there will be a similar answer, after which the network addresses are compared - 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 password transfer Net Address, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, CRC 1, CRC.

When a response is received that is similar to the device discovery request, the Access_OK string is sent to the Bluetooth module, otherwise Access_FAIL.

After establishing the connection, the transmission of requests for data acquisition begins
protocol.

 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 the Master device, and the respondents are the slave devices.

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 <SoftwareSerial.h> //--------   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<s; i++) { RS485Serial.write(cmd[i]); } RS485Serial.write(crc1); RS485Serial.write(crc2); byte i = 0; digitalWrite(SerialControl, RS485Receive); // Init Transceiver delay(200); if (RS485Serial.available()) { while (RS485Serial.available()) { byteReceived= RS485Serial.read(); // Read received byte delay(10); response[i++] = byteReceived; } } delay(20); } unsigned int crc16MODBUS(byte *s, int count) { unsigned int crcTable[] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; unsigned int crc = 0xFFFF; for(int i = 0; i < count; i++) { crc = ((crc >> 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 label called "M-230" and run the program.

In the application that opens, click on the drop-down menu next to the "Commands"
after which a list of commands will appear.

image
Search devices - a search will be made for available Bluetooth devices and prompted
connect

Check connection - command to check communication with the converter.

Poll - a one-time poll of the counter at the specified network address.

Monitor - a constant cyclical polling of one device at the specified network address (online mode).

Stop - stop cyclic polling.

Log - turns on or off the ability to observe the flow of data in the exchange log located at the bottom of the program.

image

Here is the project file for Android Studio

Source: https://habr.com/ru/post/339868/


All Articles