Introduction

Portable solar charging tracker

This is actually not any sort of product or public project (!) - it's something I designed to help me evaluate solar panels and how they act when charging batteries. Normally this requires a lot of multimeters and it's a bit of a pain to do if you have to constantly change out panels. So I decided I would build a specialized tool that would assist me. Here is what I wanted!

  • Portable! Its hard to test solar panels inside
  • Ability to log to an SD card for long-term data analysis (to be added later)
  • Keep track of the solar panel voltage
  • Keep track of the battery voltage
  • Keep track of how much current is going thru the panel to the charger

I figured if I had to build this, someone might find my notes useful. However, this documentation is primarly intended to demonstrate how to use the enclosure we carry in the adafruit shop.

This design is intended for ~6V panels, single Lithium Polymer cells and chargers. It can very easily be adapted to any kind of panel and charger, you'll just need to adjust the resistor dividers and such!

Please note, this project isn't a solar-powered datalogger. You do need to power it with batteries, it's only meant for analysis of panels!

Parts List

The Arduino, case and display:

The analog electronics!

Then of course, the stuff to log. You can substitute other types of batteries & chargers.

If you want to take it outside you'll need a portable power source, we like AA's but you can also use a 9V if you're not going to be out long.

Analog Stuff

There's a little bit of analog stuff going on. The two easiest parts to understand is the voltage dividers made of R1 & R2 and R3 & R4. R1 & R2 take the 6V solar panel voltage and divide it by two (just make R1 = R2) so that the input to the analog converter is under 3.3V. Likewise, R3 & R4 take the as-high-as 4.2V lipoly voltage and divide it by 3/5 to get it down to under 3.3V so we can track that voltage.

The more complex part is the op amp that is used to measure the current draw. We stick a 0.1 ohm resistor between the negative wire of the solar panel and ground, so that we can measure the current going though the panel by measuring across the resistor. 1 Amp of current gets turned into 100mV (our panel can't do much more than 300mA which would be 30mV). This is low enough that doesn't affect the solar panel's charging ability. However, 30mV is really low and that's the maximum we expect from the panel. We use a non-inverting amplifer that amplifies that voltage to a bigger and easier to manage voltage. In particular. This amp multiplies the voltage by 1 + R6/R7 = 48x! That turns our 30mV max signal into 1.5V. The reason we don't amplify more is that I want to be able to use bigger panels that can provide 500mA or more, so a little headroom will be handy.

In general, I used resistors I had lying around on my desk (except the 0.1 ohm, that value is important) so feel free to adjust the values.

If I were to build this project today, I'd use a proper high-side current sensor such as the INA219 which is precise, can measure high voltages, and is easy to use!
Sadly it was not on hand when I originally designed this project

Now to the soldering iron! This is actually the most annoying part. If you don't need datalogging - just the LCD feedback, you'll be happier if you solder this onto a protoshield as there's way more space. Click on the pictures for zoomed in shots. To solder, we bend over the wires and carefully solder together before clipping. It's sometimes a bit tough to follow so go slow and check your work at each step.

Note that we tie ARef to 3.3v for more stable analog readings - especially when using battery-powered portable loggers!

Casing

I'll start by prepping the case. For the bottom, snap in the pieces to cover the two holes.

Place the Arduino so it lines up with the mounting holes.
Attach! Use two screws, the third won't fit because the Arduino drill is too small.
Get the LCD out of the packaging. You'll need some sort of 10K potentiometer. We will use some header and premium socket jumpers but you can skip that part and just solder direct wires.
Solder the header in, then we clip the unused data pins to avoid confusion.
Connect the LED backlight lines to the LCD logic power lines.
Ground the RW pin (it's not used).
And get rid of that pin as well as pins #1 and #2 (they are close to the mounting post so we'll connect to pins #15 and #16 instead).
Connect the 10K pot to 5V, pin 3 and ground.
And clip pin 3.
Now we have the used 8 pins, from left to right: ground, power, D7 thru D4, RS and EN. Connect sockets.
And clip the other end.

LCD Connect and Test

Start with connecting up power, red goes to +5V and black goes to ground. Perform the tests in the LCD tutorial to verify the contrast pot works.

Connect the remaining wires as such:

  • EN → Digital #2
  • RS → Digital #3
  • D4 → Digital #4
  • D5 → Digital #5
  • D6 → Digital #6
  • D7 → Digital #7

Then try out the LCD by uploading the sketch. You should get the LCD working even if it's not displaying anything.

/* 
Portable solar panel efficiency tracker. For testing out solar panels!
See https://learn.adafruit.com/portable-solar-charging-tracker for more information
Code is public domain, MIT License by Limor "Ladyada" Fried 
*/

// include the library code:
#include <LiquidCrystal.h>
#include <Wire.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 3, 4, 5, 6, 7 );

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!

int lipoPin = 3;      // the battery 
float lipoMult = 1.666;  // how much to multiply to get the original voltage

int PVPin = 2;      // the cell
float PVMult = 2;  // how much to multiply to get the original voltage

int currentPin = 1;
float currentMult = 208; // how much to multiply to get the original current draw
    
void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);   
  
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  lcd.clear();
  // Print a message to the LCD.
  lcd.print("Solar logger");
  delay(2000);
  lcd.clear();
  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
  
  byte delta[8] = {
	B00000,
	B00100,
	B00100,
	B01010,
	B01010,
	B10001,
	B11111,
	B00000
};

  lcd.createChar(0, delta);
}



void loop(void) {
  int adcreading;
 
  adcreading = analogRead(lipoPin);  
  Serial.println(adcreading);
  
  float lipoV = adcreading;
  lipoV *= aref_voltage;
  lipoV /= 1024;
  lipoV *= lipoMult;

  lcd.clear();
  Serial.print("LiPo voltage = ");
  Serial.println(lipoV);     // the raw analog reading
  
  lcd.setCursor(0, 0);
  lcd.print("LiPo=");
  lcd.print(lipoV);
  lcd.print(' ');
  lcd.write((uint8_t)0);
  
  adcreading = analogRead(PVPin);  
  float PVV = adcreading;
  PVV *= aref_voltage;
  PVV /= 1024;
  PVV *= PVMult;
  
  lcd.print((int)((PVV-lipoV) * 1000), DEC);  // in mV
  lcd.print("mV");
  
  Serial.print("PV voltage = ");
  Serial.println(PVV);     // the raw analog reading

  lcd.setCursor(0, 1);
  lcd.print("PV=");
  lcd.print(PVV);
  
  adcreading = analogRead(currentPin);  
  float currentI = adcreading;
  currentI *= aref_voltage;
  currentI /= 1024;
  currentI *= currentMult;
  Serial.print("Current (mA) = ");
  Serial.println(currentI);     // the raw analog reading
  
  lcd.print(" I=");
  lcd.print((int)currentI);
  lcd.print("mA");
  delay(1000);
}

Mechanical

Now to connect the external panel and batteries and such. The terminal blocks are OK but not very elegant. Instead, I will use pluggable connectors. Audio connectors will work well here and I only need 2 pins (ground and signal) per connection so mono 3.5mm headphone plugs and jacks are an inexpensive an easy-to-get solution. Be sure to get panel-mount jacks!
Start with the JST cable that goes to the charger output (to measure the lipo). Unscrew the plug, slip thru the wire, Then solder each pin to crimpies. As a rule, you should always make 'sleeve' or 'ring' ground and 'tip' positive signal. Keeps things easy to track!
Crimp, making sure not to short the wires. This can be a bit challenging so use a multimeter to test!

Next, the miniB usb cable is stripped and the red and black wires pulled out. We also use some heatshrink to protect the end of the cable.

Crimp

Heat shrink!

Next, the jacks. Connect any stranded wire to the sleeve and tip connections as shown.

We like heat shrink!

Connect the jacks to the terminal blocks.
Now is a good time to test, before finishing it all up! Verify you're getting reasonable voltages from the panel and lipoly battery. If you can get near a window, see if you can get the battery charging.

Finishing

Of course, we want the panel mount jacks to be panel mounted. Grab the box end piece. It's made of ABS…
Which means they're very easy to drill or machine!
We have a label maker so we made nice little labels!
The other side gets the precut case that covers the Arduino power and programming slot.
Ready to go! Here I show how I can try different panels by connecing alligator chips. The lipo input is from the passthrough connection on the charger. As the panel charges the battery I can track the voltages and current.
This guide was first published on Apr 21, 2013. It was last updated on Apr 21, 2013.