USB current monitor markt

usb-current-monitor / USB_current.ino

2.2 KB · raw

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 () ;
}