mBuino program that shows how to read VCC using the blink of a LED

Dependencies:   USBDevice mbed

mBuino PowerMeter

This program shows how to read the current voltage on the 3V3 (VCC) pin of mBuino using the blink of a LED.

Since mBuino uses the VCC voltage as reference for analog reads, all readings are relative. To get an absolute reading an external reference voltage is needed. An easy way to get an external reference is by using a zener-diode with proper characteristics.

Not having such a zener around made me look for alternatives. I found some on this page: http://www.talkingelectronics.com/projects/200TrCcts/200TrCcts.html#52

/media/uploads/maxint/reference_voltage_using_diode.jpg

Use a LED!

The most interesting method I found was to use the LEDs on mBuino! All needed to use this is an extra connection. I used a 100R resistor as connection between pin 14 and LED6. Pin 14 is the small dot right above the one of the version number. Alternatively you can also use an external LED or (zener)-diode. The picture below shows both the added resistor as well as an external LED/resistor circuit. /media/uploads/maxint/mbuino_powermeter.jpg

Serial USB

The picture above shows a USB cable connected to mBuino. When mBuino is powered via USB and nothing else is connected to VCC, power comes from the 3v3 regulator. The VCC reading will then be around its maximum. USB is used to display the readings on the USB serial console. Note that for this the USB serial driver and a terminal application such as Putty is required. When using the console the spacebar can be hit to switch between pin14+LED6 and pin15 with an external LED/resistor via pin4.

See the code comments for more information.

Revision:
1:0434198567a4
Parent:
0:5ed29b03d6ce
Child:
2:7a501b777146
--- a/main.cpp	Sat Aug 01 06:58:12 2015 +0000
+++ b/main.cpp	Sat Aug 01 07:51:44 2015 +0000
@@ -1,23 +1,33 @@
+/*
+** mBuino_PowerMeter
+** 
+** This program shows how to read the current voltage on the 3V3 (VCC) pin of mBuino using the blink of a LED.
+**
+** Since mBuino uses the VCC voltage as reference for analag reads, all readings are relative.
+** To get an absolute reading an external reference voltage is needed.
+** An easy way to get an external reference is by using a zener-diode with proper characteristics.
+** Not having such a zener around made me look for alternatives. I found some on this page:
+**   http://www.talkingelectronics.com/projects/200TrCcts/200TrCcts.html#52
+** The most interesting method I found was to use the LEDs on mBuino
+** See the code comments and this programs homepage for more information.
+
+**
+** 0.1.150801 First version made for mBuino on mbed.org by maxint on 1-aug-2015
+**
+** Feel free to use this code anyway you want, but please acknowledge my work by mentioning maxint as creator.
+**
+*/
+
+
 #include "mbed.h"
 #include "USBSerial.h"
 
-#define TIME_BETWEEN_SAMPLES_ms 300
-
 // The USB virtual serial port is used for debugging. Note: driver required, see http://developer.mbed.org/handbook/USBSerial
 USBSerial serialUSB(0x1f00, 0x2012, 0x0001, false); // Virtual serial port over USB, set connect_blocking to false to allow starting without PC
 #define USBSERIAL_DEBUG 1
 
 DigitalOut LED[] = {(LED1), (LED2), (LED3), (LED4), (LED5), (LED6), (LED7)};// declare 7 LEDs
 
-void ledFlash(uint8_t nLed, float ftDelay=0.005)
-{
-    if(nLed>6) nLed=6;
-    LED[nLed]=!LED[nLed];
-    wait(ftDelay);
-    LED[nLed]=!LED[nLed];
-}
-
-
 float readVCC(PinName nAnalogIn=P0_14, PinName nLed=LED6, int nBlinkDelayMsec=0, float ftVrefInit=1.91)
 {   // Unlike Arduino, mBuino v1.5 has no internal reference voltage for analog reads.
     // As all analog reads are relative to VCC, it would be nice to be able to tell the VCC
@@ -32,7 +42,7 @@
     // One way to get a reference voltage is by connecting a led via a resistor between VCC and GND.
     // The voltage over the led is (more or less) constant (about 1.7V, depending on the kind of LED).
     // This constant voltage can be measured by using a multimeter.
-    // Measured voltages are e.g. 1,77V  for a yellow led, 1,66 for a red led and 1,73 for a green led.
+    // Measured voltages are e.g. 1,77V  for a yellow led, 1,66 for a red led and 1,73 for a green led (and 1K resistor).
     // See http://www.talkingelectronics.com/projects/200TrCcts/200TrCcts.html#52 for more methods.
     //
     // As mBuino already has LEDs we can use them as a reference by connecting P0_14 to the left leg of LED7 or LED6.
@@ -57,7 +67,7 @@
 
     // Some silly trial and error compensations. Note: this compensation is not very precise!
     // TODO: improve the compensation to get more accurate readings. Now final readings may differ up to 0.10V from 
-    // actual values, depending on the reference voltage, length of the blink, VCC-level and probably temperature.
+    // actual values, depending on the reference voltage, length of the blink, resistor and LED used, VCC-level and probably temperature.
     if(!fLedStatus && nBlinkDelayMsec<=10)
         ftVref+=(0.05-nBlinkDelayMsec/200.0); //compensate for lower voltage due to short delays.
     ftVref-=(0.04+(ftVoltage-0.66)/4);   // compensation: Vref is slightly lower on low voltages.
@@ -69,18 +79,28 @@
     return(ftVoltage);
 }
 
-void SweepAllLeds(bool fLeftToRight=true, float flDelay=0.1)
+
+void ledFlash(uint8_t nLed, float ftDelay=0.005)
+{
+    if(nLed>6) nLed=6;
+    LED[nLed]=!LED[nLed];
+    wait(ftDelay);
+    LED[nLed]=!LED[nLed];
+}
+
+void SweepAllLeds(uint8_t nMaxLeds=7, bool fLeftToRight=true, float flDelay=0.1)
 {   // light all leds up from left to rigth or vise-versa and then switch them off from reverse direction
     // leds on, left to right
-    for(int n=0; n<7; n++)
+    if(nMaxLeds>7) nMaxLeds=7;
+    for(int n=0; n<nMaxLeds; n++)
     {
-        LED[fLeftToRight?n:6-n] = 1; // turn on
+        LED[fLeftToRight?n:nMaxLeds-1-n] = 1; // turn on
         wait(flDelay); // delay
     }
     // leds off, right to left
     for(int n=0; n<7; n++)
     {
-        LED[!fLeftToRight?n:6-n] = 0; // turn off
+        LED[!fLeftToRight?n:nMaxLeds-1-n] = 0; // turn off
         wait(flDelay); // delay
     }
 }
@@ -97,7 +117,7 @@
 
     // small initial delay to show all leds are working and to allow USB connection
     SweepAllLeds();
-    SweepAllLeds(false,0.02);
+    SweepAllLeds(7, false,0.02);
     SweepAllLeds();
 
     t.start();
@@ -111,7 +131,7 @@
     ledFlash(0);
     wait(0.5);
 
-    serialUSB.printf("\r\n === mBuino PowerMeter ====  \r\n");
+    serialUSB.printf("\r\n=== mBuino PowerMeter ====  \r\n");
     serialUSB.printf("Measuring LED pin %d [%1.2fV] using pin %d\r\n", pinLed, ftVled, pinAnalog);
     serialUSB.printf("Hit spacebar to change to LED pin 4 [1.85V] using pin 15.\r\n");
     while(true)
@@ -129,6 +149,7 @@
             if(ftVcc>=2.40) uLed=4;
             if(ftVcc>=2.60) uLed=5;
             if(ftVcc>=2.75) uLed=6;
+            SweepAllLeds(uLed+1);
             ledFlash(uLed);
             wait(1);
         }
@@ -143,7 +164,7 @@
             if(serialUSB._getc()==' ')
             {
                pinLed=(pinLed==P0_4?LED6:P0_4);
-               //ftVled=(ftVled!=1.85?1.85f:1.91f);
+               //ftVled=(ftVled!=1.85?1.85f:1.91f);   // hmm, weird bug; no conditional assignment on floats?
                if(ftVled!=1.91f) ftVled=1.91f; else ftVled=1.85f;
                pinAnalog=(pinAnalog==P0_15?P0_14:P0_15);
                serialUSB.printf("Switched to measuring LED pin %d [%1.2fV] using pin %d\r\n", pinLed, ftVled, pinAnalog);