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 }