USB current monitor markt
usb-current-monitor / USB_current.ino
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 () ;
}