byte anode_portC [] = { 0x0C, 0x03, 0x30 } ; byte cathodes [] = { 0x11, 0x7D, 0x23, 0x29, 0x4D, 0x89, 0x81, 0x3D, 0x01, 0x09, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xFF, 0x88, 0xEB, 0x4C, 0x49, 0x2B, 0x19, 0x18, 0xCB, 0x08, 0x09, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0x11, 0x7D, 0x23, 0x29, 0x4D, 0x89, 0x81, 0x3D, 0x01, 0x09, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xFF, } ; byte disp [3] ; byte dp = 0 ; void display () { for (int i = 0 ; i < 30 ; i++) { for (byte d = 0 ; d < 3 ; d++) { int caths = (cathodes [(d << 4) + (disp [d] & 0xF)]) & 0xFF ; caths ^= 0xFF ; if (dp == d) caths |= (d == 1 ? 8 : 1) ; PORTC = anode_portC [d] ; DDRD |= (caths << 5) & 0xE0 ; DDRB |= (caths >> 3) & 0x1F ; delay (1) ; DDRD &= 0x1F ; DDRB &= 0xE0 ; } } PORTC = 0x00 ; } #define TOUCH_PIN 2 unsigned long last_ts ; void setup () { pinMode (TOUCH_PIN, INPUT_PULLUP) ; PORTC = 0x00 ; DDRC |= 0x3F ; PORTB &= 0xE0 ; DDRB &= 0xE0 ; PORTD &= 0x1F ; DDRD &= 0x1F ; last_ts = micros () ; } unsigned long micro_coulombs = 0L ; unsigned int kilo_coulombs = 0 ; const float conversion_factor = 1000.0 * 5.0 / 1024 / 100 / 0.05 ; void loop () { int value = analogRead (7) ; unsigned long this_ts = micros () ; float milliamps = conversion_factor * value ; micro_coulombs += ((int) milliamps) * (this_ts-last_ts) / 1000 ; if (micro_coulombs >= 1000000000UL) { micro_coulombs -= 1000000000UL ; kilo_coulombs ++ ; } last_ts = this_ts ; // float watts = milliamps * 5000 ; unsigned int dispval ; int phase = (millis () & 0xF80) >> 7 ; if (phase == 0 || phase == 5) { disp [0] = disp[1] = disp[2] = 0xF ; dp = 4 ; } else { if (phase < 5) dispval = (int) (micro_coulombs / 3.6e6 + kilo_coulombs * 1000 / 3.6) ; else dispval = (int) milliamps ; dp = 2 ; // dispval is an int 1000 times the true float value, // need to round: dispval += 5 ; // round for (char i = 0 ; i < 3 ; i++) { dispval /= 10 ; // pre-divide since interested in N.NN not .NNN disp [i] = (char) (dispval % 10) ; } } display () ; }