A Monitored Power Supply for Clixx

This post describes a very simple 3.3V regulated power supply for Clixx based projects - what makes it interesting is on-board support for monitoring both voltage and current as well as providing a regulated power source. The board is designed to be connected to a standard Clixx TwinTab analog slot - instead of drawing power from the power pins it supplies a regulated 3.3V current at up to 250mA. The power source to the board is an external 4.5 to 6 volt supply (from a USB cable or battery pack for example).

Note: Do not use this board with power already provided to the power pins on the slot (such as the Raspberry Pi Dock), you will damage your host controller.

As well as providing a regulated supply the board also provides some power monitoring information on the analog pins. The output pin of the slot provides a measure of the main source voltage while the extra pin provides a measure of the current being drawn by the project. This is useful for monitoring battery levels and measuring the total current being drawn by your project.

How it Works


The circuit is very simple (see the schematic to the left) and can easily be put together on stripboard. This section goes through the main components and describes how to interpret the voltages returned by the sensors.

Voltage Regulator

Voltage regulation is based around an MCP1700 low drop out regulator which provides a 3.3V output voltage with up to 250mA of load from an input voltage of up to 6V. The only extra components required are two 1uF capacitors.

Voltage Monitoring

Voltage monitoring is provided through a simple resistor divider network which halves the input voltage and presents the result on the output pin of the TwinTab. To determine the actual input voltage you need to scale the reading according to your ADC (for example a reading of 512 on a 10 bit ADC with a reference voltage of 3.3V would be half the full range - 1.15V) and then double it to reverse the effects of the resistor divider. The general formula is:

 Vreal = (2 * Vref * reading) / ADC_MAX

To calculate the input voltage (in mV) for a 10 bit ADC with a 3.3V reference this would be:

 Vreal = (6600 * reading) / 1023

Current Sensing

The current sensing is done using an Adafruit module based around the INA169 DC Current Sensor chip. The boards comes with a 10K resistor which scales the output to 1V per 1A, I've swapped this to a 30K resistor so the output is scaled to 3V per 1A. Like the voltage level this value can be read by an ADC on the host microcontroller to determine the current be pulled by the circuit.

To determine the actual current from the ADC reading you need to use a similar process to the one described for the voltage. In this case you also have to take into account the additional scaling used to map current to voltage. The general formula is:

 Areal = ((Vref / 3) * reading) / ADC_MAX

To calculate the current (in mA) for a 10 bit ADC with a 3.3V reference this becomes:

 Areal = (1100 * reading) / 1023

Using the Board


Once the board was wired up (the stripboard layout is shown in the image to the right - you can find the Fritzing file in the GitHub repository) I connected it to a 6V source (4 x AA batteries) and got the following readings:

Test Point |Value ---------------|----- Input Voltage |6.26V Battery Level |3.09V Current Level |0.04V Regulated Power|3.28V

The battery level is about what is expected (allowing for variances in the values of the resistors used in the voltage divider) and the current level translates to 13 mA which is about the current being drawn by the power indicator LED.

I hooked the board up to a Babyduino wired to a general Clixx dock and used it to power the system. I used ``` /--------------------------------------------------------------------------- * Sample Driver for Power Board monitoring ---------------------------------------------------------------------------- * 16-Nov-2013 ShaneG * * This is a simple sketch using the monitoring inputs on the power board to * determine the battery voltage and current draw. ---------------------------------------------------------------------------/

define SLOT0_OUTPUT 0

define SLOT0_EXTRA 1

define LED_PIN 13


define LOOP_WAIT_TIME 200


/** Set up the hardware */ void setup() { // Set up serial Serial.begin(9600); // Set up the pins pinMode(LED_PIN, OUTPUT); }

/** Read the battery voltage * * @return the voltage in millivolts. */ int readVoltage() { delay(ANALOG_SETTLE_TIME); // Wait for input to settle long value = analogRead(SLOT0_OUTPUT); // Real value is double what is on the pin value = (6600L * value) / 1023L; return (int)value; }

/** Read the current being drawn * * @return the current in milliamps. */ int readCurrent() { delay(ANALOG_SETTLE_TIME); // Wait for input to settle long value = analogRead(SLOT0_EXTRA); // Current sensor is set to 3V/A so top values is 1.1A value = (1100L * value) / 1023L; return (int)value; }

/** Main loop */ void loop() { static int count = 0; static bool led = false; // Get the current readings and display them Serial.print(readVoltage()); Serial.print("mV, "); Serial.print(readCurrent()); Serial.println("mA"); // Change LED state if((count%LOOPS_PER_BLINK)==0) { count = 0; led = !led; digitalWrite(LED_PIN, led?HIGH:LOW); } // Increment count count++; // Wait out the rest of the loop delay(LOOP_WAIT_TIME - (2 * ANALOG_SETTLE_TIME)); } ```

to sample the two analog inputs, do the conversion for voltage and current and write the results to the serial port. I also toggle the status LED periodically so I can see some difference in current over time as a way to verify the results.

Once again I powered everything from a 6V battery source (4 x AA cells) and let it run. It reported a battery voltage of 6116mV (which matches the reading on my multimeter) and a current of 20mA while the LED was off and 25mA while the LED was on. Once again these values match what my multimeter was showing.

Next Steps

You probably don't need this circuit in your final project (although if you are doing anything that's powered by batteries it would probably be a good idea to detect when the battery is nearly flat) but it does provide a good way to test for voltage drops or current spikes directly from your microcontroller code while you are prototyping.

The data collected can help you determine how long batteries would last under various conditions and let you measure the maximum real (as opposed to estimated or calculated) current requirements. I built the board for exactly that reason, the Race Timing project I'm working on will use some RF transceivers that can pull up to 300mA while transmitting, I want to be able to measure this in-circuit and see what I can do to maximise battery life.