Ich hab mir vor kurzem dieses nette Teil gegönnt: Adafruit USB Power Gauge Mini-Kit
Das Teil mist den Strom/Volt/Watt die das angeschlossene Gerät schluckt/benötigt/zieht.
Auf dem PCB ist ein kleiner ATtiny85 verbraut, den man über die ausgeführten ICSP Pins flashen kann. Der Quellcode wurde >> hier << veröffentlicht (besteht aus 3 Dateien die alle benötigt werden)
"adafruit_usbpowergauge.ino"
/****************************************
Adafruit USB Power Gauge firmware
http://www.adafruit.com/products/1549
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution
****************************************/
// Select Trinket 16MHz, 'burn bootloader' to set fuses
// then upload via an *external usbtiny* (not the bootloader!)
#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial ss(-1, 1);
uint16_t calibration;
void allInputs(void);
void LED(uint8_t i, boolean f);
int readVCC(void);
int readCurrent(void);
volatile uint8_t x = 0;
volatile uint8_t Lidx = 0, litLEDs = 0;
volatile uint8_t Ldim[6] = {0,0,0,0,0,0};
volatile uint8_t pwm=0;
#define MAXPWM 32
uint8_t gamma[] = {0x0, 0x01, 0x03, 0x06, 0x0A, 0x10, 0x17, 0x20};
SIGNAL(TIMER1_COMPA_vect) {
// turn all LEDs off
allInputs();
// find the next LED and turn one LED on
while (Lidx < 6) {
if (litLEDs & _BV(Lidx)) {
// this LED is on!
if (Ldim[Lidx] >= pwm) {
LED(Lidx, true);
}
Lidx++;
break;
}
Lidx++;
}
if (Lidx >= 6) {
Lidx = 0;
pwm++;
if (pwm > MAXPWM)
pwm = 0;
}
}
// the setup routine runs once when you press reset:
void setup() {
allInputs();
ss.begin(9600);
TCCR1 = _BV(CS10);
OCR1A = 0xAF;
TIMSK |= _BV(OCIE1A);
// for just a tiny bit, turn all the LEDs on
litLEDs = 0xFF;
for (uint8_t i=0; i<6; i++) Ldim[i] = MAXPWM;
delay(20);
litLEDs = 0;
for (uint8_t i=0; i<6; i++) {
litLEDs |= _BV(i);
for (uint8_t p=0; p<MAXPWM; p++) {
Ldim[i]=p;
delay(2);
}
}
litLEDs = 0;
ss.println(F("Adafruit USB Power Meter"));
ss.println(__DATE__);
// read calibration
calibration = EEPROM.read(0);
calibration <<= 8;
calibration |= EEPROM.read(1);
if ((calibration == 0xFFFF) || (calibration < 800) || (calibration > 1300)) {
calibration = 0xFFFF;
ss.println(F("Not calibrated"));
} else {
ss.print(F("Calibration: "));
ss.println(calibration);
}
}
uint32_t vcc, icc, watt;
void printStringDelay(char *str) {
while (str[0]) {
while (Lidx != 0) {}
ss.write(str[0]);
str++;
}
}
uint8_t printCounter = 0;
void printDotDecimal(uint16_t x, uint8_t d) {
ss.print(x/1000);
if (d > 0) {
ss.print('.');
x %= 1000;
ss.print(x / 100);
}
if (d > 1) {
x %= 100;
ss.print(x / 10);
}
}
// the loop routine runs over and over again forever:
void loop() {
vcc = readVCC();
icc = readCurrent();
watt = vcc * icc;
watt /= 1000;
if (printCounter == 0) {
while (Lidx != 0) {}
// TIMSK &= ~_BV(OCIE1A);
printStringDelay("\n\rV: "); //ss.println(vcc);
vcc += 50; // this is essentially a way to 'round up'
printDotDecimal(vcc, 1);
delay(50);
printStringDelay(" I: ");
if (icc < 100) ss.print(' ');
if (icc < 10) ss.print(' ');
ss.print(icc);
printStringDelay(" mA ");
delay(50);
printStringDelay("Watts: ");
watt += 50; // this is essentially a way to 'round up'
printDotDecimal(watt, 1);
delay(50);
// TIMSK |= _BV(OCIE1A);
}
printCounter++;
printCounter %= 10;
// for OK voltages, turn on the green 'OK' LED
if (vcc >= 4500) {
litLEDs |= 0x1;
Ldim[0] = MAXPWM;
} else {
litLEDs &= ~0x1;
Ldim[0] = 0;
}
for (uint16_t w=1; w<6; w++) {
if (watt > (w*1000)) {
// on all the way
litLEDs |= _BV(w);
Ldim[w] = MAXPWM;
} else if (watt > (w-1)*1000) {
// on partially
litLEDs |= _BV(w);
Ldim[w] = gamma[(watt % 1000) / 125];
} else {
litLEDs &= ~_BV(w);
Ldim[w] = 0;
}
}
delay(100);
}
Alles anzeigen
"analog.cpp"
/****************************************
Adafruit USB Power Gauge firmware
http://www.adafruit.com/products/1549
Analog current/voltage reading support
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution
****************************************/
#include <Arduino.h>
#include <SoftwareSerial.h>
extern SoftwareSerial ss;
extern uint16_t calibration;
int readVCC(void) {
ADMUX = 0x0C; // read VBG
ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2);
delay(10);
ADCSRA |= _BV(ADSC);
while (ADCSRA & _BV(ADSC));
delay(10);
uint8_t low = ADCL;
uint8_t high = ADCH;
// do a second conversion
ADCSRA |= _BV(ADSC);
while (ADCSRA & _BV(ADSC));
low = ADCL;
high = ADCH;
int32_t reply = high;
reply <<= 8;
reply |= low;
//ss.println(reply);
uint32_t temp;
if (calibration != 0xFFFF) {
temp = calibration; // the 'true' mV reading
} else {
temp = 1100; // its about 1100mV
}
temp *= 1024;
temp /= reply;
reply = temp;
return reply;
}
int readCurrent(void) {
ADMUX = 3 | _BV(REFS1); // read PB3 (output from sensor)
ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2);
delay(10);
ADCSRA |= _BV(ADSC);
while (ADCSRA & _BV(ADSC));
delay(10);
// do a second conversion
ADCSRA |= _BV(ADSC);
while (ADCSRA & _BV(ADSC));
int32_t reply = ADC;
if (calibration != 0xFFFF) {
reply *= calibration; // the 'true' mV reading
} else {
reply *= 1100; // its about 1100mV
}
reply /= 1024;
return reply;
}
Alles anzeigen
"charlie.cpp"
/****************************************
Adafruit USB Power Gauge firmware
http://www.adafruit.com/products/1549
Charlie plex code for the LEDs!
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution
****************************************/
#include <Arduino.h>
void allInputs() {
PORTB &= ~_BV(0) & ~_BV(2) & ~_BV(4);
/*
digitalWrite(0, LOW);
digitalWrite(2, LOW);
digitalWrite(4, LOW);
*/
DDRB &= ~_BV(0) & ~_BV(2) & ~_BV(4);
/*
pinMode(0, INPUT);
pinMode(2, INPUT);
pinMode(4, INPUT);
*/
}
void LED(uint8_t i, boolean f) {
if (!f) {
allInputs();
return;
}
if (i == 0) {
DDRB |= _BV(2) | _BV(4);
//pinMode(2, OUTPUT);
//pinMode(4, OUTPUT);
DDRB &= ~_BV(0);
//pinMode(0, INPUT);
PORTB |= _BV(4);
PORTB &= ~_BV(2);
//digitalWrite(4, HIGH);
//digitalWrite(2, LOW);
}
if (i == 1) {
DDRB |= _BV(2) | _BV(4);
DDRB &= ~_BV(0);
PORTB |= _BV(2);
PORTB &= ~_BV(4);
}
if (i == 2) {
DDRB |= _BV(0) | _BV(4);
DDRB &= ~_BV(2);
PORTB |= _BV(0);
PORTB &= ~_BV(4);
}
if (i == 3) {
DDRB |= _BV(0) | _BV(4);
DDRB &= ~_BV(2);
PORTB |= _BV(4);
PORTB &= ~_BV(0);
}
if (i == 4) {
DDRB |= _BV(0) | _BV(2);
DDRB &= ~_BV(4);
PORTB |= _BV(0);
PORTB &= ~_BV(2);
}
if (i == 5) {
DDRB |= _BV(0) | _BV(2);
DDRB &= ~_BV(4);
PORTB |= _BV(2);
PORTB &= ~_BV(0);
}
}
Alles anzeigen
Nun aber zu meinem Anliegen:
Ich hab das USB-mini-Gauge Teil auf der einen Seite in eine USB-PowerBank gesteckt, und auf der anderen Seite in den microUSB meines RaspberryPI-B.
Im Raspberry steckt ein Edimax WLAN Stick der auch aktiv ist, eine RaspiCam, und ein Arduino Mega2560.
Nun hab ich den TX und GND des USB-mini-Gauge Teils in einen 2. RaspberryPI (also einen anderen!) gesteckt um die Ausgabe anzuzeigen:
V: 5.2 I: 521 mA Watts: 2.7
V: 5.2 I: 543 mA Watts: 2.8
V: 5.2 I: 513 mA Watts: 2.7
V: 5.2 I: 515 mA Watts: 2.7
V: 5.2 I: 493 mA Watts: 2.6
V: 5.2 I: 535 mA Watts: 2.8
V: 5.2 I: 652 mA Watts: 3.4
V: 5.2 I: 475 mA Watts: 2.5
V: 5.2 I: 624 mA Watts: 3.2
V: 5.2 I: 537 mA Watts: 2.8
V: 5.2 I: 616 mA Watts: 3.2
V: 5.2 I: 594 mA Watts: 3.1
V: 5.2 I: 523 mA Watts: 2.7
V: 5.2 I: 521 mA Watts: 2.7
V: 5.2 I: 515 mA Watts: 2.7
V: 5.2 I: 485 mA Watts: 2.5
V: 5.2 I: 537 mA Watts: 2.8
V: 5.2 I: 557 mA Watts: 2.9
V: 5.2 I: 551 mA Watts: 2.9
V: 5.2 I: 564 mA Watts: 2.9
V: 5.2 I: 497 mA Watts: 2.6
V: 5.2 I: 491 mA Watts: 2.6
V: 5.2 I: 630 mA Watts: 3.3
V: 5.2 I: 483 mA Watts: 2.5
V: 5.2 I: 584 mA Watts: 3.0
V: 5.2 I: 521 mA Watts: 2.7
V: 5.2 I: 473 mA Watts: 2.5
V: 5.2 I: 521 mA Watts: 2.7
V: 5.2 I: 535 mA Watts: 2.8
V: 5.2 I: 483 mA Watts: 2.5
V: 5.2 I: 541 mA Watts: 2.8
V: 5.2 I: 533 mA Watts: 2.8
V: 5.2 I: 481 mA Watts: 2.5
V: 5.2 I: 650 mA Watts: 3.4
V: 5.2 I: 543 mA Watts: 2.8
V: 5.2 I: 487 mA Watts: 2.5
V: 5.2 I: 618 mA Watts: 3.2
V: 5.2 I: 545 mA Watts: 2.8
V: 5.2 I: 477 mA Watts: 2.5
V: 5.2 I: 521 mA Watts: 2.7
V: 5.2 I: 493 mA Watts: 2.6
V: 5.2 I: 570 mA Watts: 3.0
Alles anzeigen
Und jetzt meine Frage:
Müsste der PI bzw mein Konstrukt nicht viel mehr benötigen/schlucken?
Misst das Teil mist?
Kann man den Code irgendwie optimieren sodass das nicht mehr so arg schwankt?