Sunday, 2 April 2017

#arduinoD17 project: Arduino decodes the BSIDE ADM20 serial infrared protocol

##### THIS  POST  NEEDS  MORE WORK ####

Due to the time constraints, my video on decoding the protocol is not quite as polished as usual, but possibly more "authentic".

A look inside

Although it did not make it into my review video, I one of the first things I did was taking the meter apart. Apart from making sure that the basic safety features were in place, the thing that caught my eye was the USB Interface.
It is completely a self-contained module powered by the PC over the USB cable. The CH340 USB-UART bridge chip should be familiar to anyone using Arduino knockoffs.
The module, of course is completly insulated against the meter, which sends a stream of serial data through a single infrared LED.


Where to get the multimeter
The meter is available under several names:

Other materials

... and as I have been asked about the cute scope I used:
It is around 20€ and easy to build. There is a firmware update available from JYE Tech. I'll do a video about the process.

The protocol

As mentioned previously, the meter sends a continuous stream of data at a rate of 2400 baud. This can be captured easily.
The only part of the protocol I figured out so far are the actual digits. I still have too look into the units and the "minus". The protocol is not "human-friendly", but feels like it is derived from the meter's data stream to the LCD module.


Code

So here is the code for you to try:

 //Meater-Reater (Arduino version)  
 //Arduino infrared interface for BSIDE ADM20 Multimeter  
 //see www.AReResearch.net for details  
 //20170401 by Andy Reischle  
 #include <SoftwareSerial.h>  
 // Softserial only required during development to preserve  
 // serial debugging. When done, move to hardware UART  
 SoftwareSerial swSer(8,9);  
 uint8_t inByte = 0;  
 int initvalues[6] = {0xAA, 0x55, 0x52, 0x24, 0x01, 0x10};  
 int line[22];  
 int measures[4];  
 int counter = 0;  
 int dval;  
 String result = "";  
 bool initstart = false;  
 void setup() {  
  Serial.begin(9600);  
  swSer.begin(2400);  
  Serial.println("\nStart reading from Soft UART");  
        }  
 void loop() {  
  // Serial.println("Doing my thing");  
  Serial.println(measure());  
  delay(5000);  
 }  
 String measure() {  
  initstart = true;  
  result="";  
  counter=0;  
  swSer.flush();  
  while (initstart) {  
   if (swSer.available() > 0)  
   {  
   inByte = swSer.read();  
 // Serial.print(inByte, HEX);  
 //  Serial.print(" ");  
   if (counter >5 )  
    {  
     measures[counter-6] = inByte;  
     //Serial.print("result: ");  
     //Serial.println(inByte, HEX);  
     if (counter == 9)  
      {  
       if (measures[3] > 128) result = result + ".";  
       result = result + displval(measures[3]);  
       if (measures[2] > 128) result = result + ".";  
       result = result + displval(measures[2]);  
       if (measures[1] > 128) result = result + ".";  
       result = result + displval(measures[1]);  
       if (measures[0] > 128) result = result + ".";  
       result = result + displval(measures[0]);  
       // Serial.println (result);  
       return result;  
       initstart = false;  
      }  
     counter++;  
     if (counter > 9)  
      {  
       counter = 0;  
       result="";  
       initstart = false;  
      }  
    }  
   else if (inByte == initvalues[counter])  
    {  
     counter ++;  
    }  
                 }  
       }  
 }  
 //  
 // Convert display values  
 //  
 int displval(int dval)  
 {  
 if (dval > 128)  
  {  
   dval = dval -128;  
  }  
  if (dval == 95) return 0;  
  if (dval == 6) return 1;  
  if (dval == 107) return 2;  
  if (dval == 47) return 3;  
  if (dval == 54) return 4;  
  if (dval == 61) return 5;  
  if (dval == 125) return 6;  
  if (dval == 7) return 7;  
  if (dval == 127) return 8;  
  if (dval == 63) return 9;  
  if (dval == 0) return 0;  
 }  

No comments:

Post a Comment