brymen_bm869s_ir_cable

Brymen 869s Serial PC-Comm DIY Cable.
git clone htps://git.e1e0.net/brymen_bm869s_ir_cable.git
Log | Files | Refs | README

main.c (7650B)


      1 /*
      2  * all the relevant parts of this code have been shamelessly taken and adapted
      3  * from here:
      4  *
      5  * https://www.eevblog.com/forum/testgear/brymen-ir-connection-protocol-anyone-sniffed-it-yet/msg874805/#msg874805
      6  *
      7  * All credit goes to eevblog forum user 'jesuscf'. I just adapted to AVR C for
      8  * the ATTiny85
      9  */
     10 
     11 #include <avr/io.h>
     12 #include <util/delay.h>
     13 
     14 #include <bm869s.h>
     15 #include <avr305.h>
     16 
     17 #define HIGH 1
     18 #define LOW 0
     19 #define IRTX PB3
     20 #define IRRX PB2
     21 
     22 /* Storage for the information received from the multimeter */
     23 #define BM_PBYTES 20 /* 16 bytes with data and 4 bytes with other information */
     24 unsigned char bm[BM_PBYTES];
     25 
     26 void digitalWrite(int pin, int state)
     27 {
     28     if (state == HIGH) {
     29         PORTB |= (1 << pin);
     30     } else {
     31         PORTB &= ~(1 << pin);
     32     }
     33 }
     34 
     35 unsigned char digitalRead(int pin)
     36 {
     37     return (PINB & (1 << pin));
     38 }
     39 
     40 /* Reads a byte from the multimeter */
     41 unsigned char getByte(void)
     42 {
     43     unsigned char result, mask;
     44 
     45     /* bit by bit check (using shift mask)
     46      * clock --> check --> "unclock" */
     47     for (mask = 1, result = 0; mask != 0; mask <<= 1) {
     48         digitalWrite(IRTX, HIGH);
     49         _delay_us(250);
     50 
     51         /* checking on low instead of high, so maybe we can reuse
     52          * some work done on eevblog forum */
     53         if (digitalRead(IRRX) == LOW) result |= mask;
     54 
     55         digitalWrite(IRTX, LOW);
     56         _delay_us(250);
     57     }
     58     return result;
     59 }
     60 
     61 /* Reads 20 bytes from the multimeter */
     62 int readBM689s(void)
     63 {
     64     unsigned int timeout;
     65     unsigned char j;
     66 
     67     /* wait in case dmm is transmitting already */
     68     while (digitalRead(IRRX) == HIGH);
     69 
     70     /* init communication 10ms pulse */
     71     digitalWrite(IRTX, HIGH);
     72     _delay_ms(10);
     73     digitalWrite(IRTX, LOW);
     74 
     75     /* wait for dmm response */
     76     timeout = 0;
     77     while (digitalRead(IRRX) == LOW) {
     78         _delay_ms(1);
     79         timeout++;
     80         if (timeout > 1000) break;
     81     }
     82     /* if we did not reach timeout, get 20 bytes. */
     83     if (timeout <= 1000) {
     84         for (j = 0; j < BM_PBYTES; j++) bm[j] = getByte();
     85         return 1;
     86     }
     87     return 0;
     88 }
     89 
     90 /* Converts the digits information received into ASCII characters */
     91 char Decode_7seg(unsigned char val)
     92 {
     93     switch (val & 0xfe) {
     94         case LETTER_C: return'C'; break;
     95         case LETTER_d: return'd'; break;
     96         case LETTER_F: return'F'; break;
     97         case LETTER_i: return'i'; break;
     98         case LETTER_L: return'L'; break;
     99         case LETTER_o: return'o'; break;
    100         case BLANK:    return' '; break;
    101         case DASH:     return'-'; break;
    102         case NUMBER_0: return'0'; break;
    103         case NUMBER_1: return'1'; break;
    104         case NUMBER_2: return'2'; break;
    105         case NUMBER_3: return'3'; break;
    106         case NUMBER_4: return'4'; break;
    107         case NUMBER_5: return'5'; break;
    108         case NUMBER_6: return'6'; break;
    109         case NUMBER_7: return'7'; break;
    110         case NUMBER_8: return'8'; break;
    111         case NUMBER_9: return'9'; break;
    112         default:
    113             return'?';
    114             break;
    115     }
    116 }
    117 
    118 /* Sends via serial port whatever was read and decoded from the multimeter for
    119  * the main display */
    120 void Send_Disp1(void)
    121 {
    122     char c;
    123 
    124     /* + or - sign */
    125     if (((bm[14] & Hz_1) == 0) && ((bm[14] & DUTY) == 0)
    126             && ((bm[14] & OHM) == 0) && ((bm[13] & FARAD) == 0)) {
    127         printc(bm[1]&negative_1 ? '-' : '+');
    128     }
    129 
    130     /* main digits */
    131     printc(Decode_7seg(bm[2]));
    132     if (bm[3] & seg_p) printc('.');
    133     printc(Decode_7seg(bm[3]));
    134     if (bm[4] & seg_p) printc('.');
    135     printc(Decode_7seg(bm[4]));
    136     if (bm[5] & seg_p) printc('.');
    137     printc(Decode_7seg(bm[5]));
    138     if (bm[6] & seg_p) printc('.');
    139     printc(Decode_7seg(bm[6]));
    140     c = Decode_7seg(bm[7]);
    141     if (c != ' ') printc(c);
    142 
    143     /* Display the units of voltage or current */
    144     if ((bm[7] & V_1) || (bm[13] & A_1)) {
    145         if ((bm[14] & m_1) || (bm[14] & u_1)) {
    146             printc('E');
    147             printc('-');
    148             printc((bm[14] & m_1) ? '3' : '6');
    149         }
    150         printc(' ');
    151         if (bm[7] & V_1)
    152             printc('V');
    153         else
    154             printc('A');
    155         if (bm[0] & DC) {
    156             if (bm[1] & AC_1) {
    157                 printc('R');
    158                 printc('M');
    159                 printc('S');
    160             } else {
    161                 printc('D');
    162                 printc('C');
    163             }
    164         } else if (bm[1] & AC_1) {
    165             printc('A');
    166             printc('C');
    167         }
    168     }
    169 
    170     /* Frequency */
    171     if (bm[14] & Hz_1) {
    172         if ((bm[14] & k_1) || (bm[14] & M_1)) {
    173             printc('E');
    174             printc('+');
    175             if (bm[14] & k_1)
    176                 printc('3');
    177             else
    178                 printc('6');
    179         }
    180         printc(' ');
    181         printc('H');
    182         printc('z');
    183     }
    184 
    185     /* Duty cycle */
    186     if (bm[14] & DUTY) {
    187         printc(' ');
    188         printc('D');
    189         printc('%');
    190     }
    191 
    192     /* dB */
    193     if (bm[14] & dB) {
    194         printc(' ');
    195         printc('d');
    196         printc('B');
    197         if (bm[14] & m_1) printc('m');
    198     }
    199 
    200     /* Resistance */
    201     if (bm[14] & OHM) {
    202         if ((bm[14] & k_1) || (bm[14] & M_1)) {
    203             printc('E');
    204             printc('+');
    205             if (bm[14] & k_1)
    206                 printc('3');
    207             else
    208                 printc('6');
    209         }
    210         printc(' ');
    211         printc('O');
    212         printc('H');
    213         printc('M');
    214     }
    215 
    216     /* Capacitance */
    217     if (bm[13] & FARAD) {
    218         if ((bm[13] & n) || (bm[14] & u_1) || (bm[14] & m_1)) {
    219             printc('E');
    220             printc('-');
    221             if (bm[13] & n)        printc('9');
    222             else if (bm[14] & u_1) printc('6');
    223             else if (bm[14] & m_1) printc('3');
    224         }
    225         printc(' ');
    226         printc('F');
    227     }
    228 }
    229 
    230 /* Sends via serial port whatever was read and decoded from the multimeter for
    231  * the second display */
    232 void Send_Disp2(void)
    233 {
    234     char c;
    235 
    236     c = Decode_7seg(bm[9]);
    237 
    238     if (c != ' ') {
    239         printc(bm[8]&negative_2 ? '-' : '+');
    240         printc(Decode_7seg(bm[9]));
    241         if (bm[10] & seg_p) printc('.');
    242         printc(Decode_7seg(bm[10]));
    243         if (bm[11] & seg_p) printc('.');
    244         printc(Decode_7seg(bm[11]));
    245         if (bm[12] & seg_p) printc('.');
    246         printc(Decode_7seg(bm[12]));
    247 
    248         /* Display the units of voltage or current */
    249         if ((bm[13] & V_2) || (bm[8] & A_2)) {
    250             if ((bm[8] & m_2) || (bm[8] & u_2)) {
    251                 printc('E');
    252                 printc('-');
    253                 printc((bm[8] & m_2) ? '3' : '6');
    254             }
    255             printc(' ');
    256             if (bm[13] & V_2)
    257                 printc('V');
    258             else
    259                 printc('A');
    260             if (bm[8] & AC_2) {
    261                 printc('A');
    262                 printc('C');
    263             } else {
    264                 printc('D');
    265                 printc('C');
    266             }
    267         }
    268 
    269         /* Frequency */
    270         if (bm[13] & Hz_2) {
    271             if ((bm[13] & k_2) || (bm[13] & M_2)) {
    272                 printc('E');
    273                 printc('+');
    274                 if (bm[13] & k_2)
    275                     printc('3');
    276                 else
    277                     printc('6');
    278             }
    279             printc(' ');
    280             printc('H');
    281             printc('z');
    282         }
    283     }
    284 }
    285 
    286 int main(void)
    287 {
    288     /* Pin initialization */
    289     DDRB |= (1 << IRTX);         /* port output */
    290     DDRB &= ~(1 << IRRX);        /* port input */
    291     PORTB &= ~(1 << IRTX);       /* set output ports to low */
    292 
    293     while (1) {
    294         readBM689s();
    295         Send_Disp1();
    296         printc(' ');
    297         Send_Disp2();
    298         printc('\r');
    299         printc('\n');
    300         _delay_ms(200);
    301     }
    302 
    303     return 0;
    304 }