## Measure voltage coming from solar panel with AVR.

47 posts / 0 new
Author
Message

So I know there are several ways to step voltage down to be readable by the AVR, but I am not familiar with them all. In my example the max voltage is 24 volts coming from the solar panels. The max current is 0.55Amps. When I get less sunlight the volts can dip to ~16 with ~ 0.33Amps.

I could use some high wattage resistors to measure the voltage, but doesn't my resistance change when the current changes? What is a better way to step down the 24 volts to be read by the ADC on my AVR?

This topic has a solution.

There are several Freaks who have built solar panel tracking systems, and they might also provide some valuable insight.

The point here is that R1 and R2 form a resistor divider to drop the 24 V signal down to < 5 V for input to the AVR.

In this case Vout = Vin (R2/(R1+R2)).

If R1 is 56K and R2 is 10K then 24 V in gives 3.6 Vout, to the ADC.

So, rework the divider to use a bit more of the full scale, 0-5 V, if you so desire.

Diode D eats up some of your output voltage, about 0.6 V.

You might or might not want it, and much actually depends upon what the solar cell is charging / powering.

The point, however, is that you don't want to get the output from the panel backwards, and feed a negative voltage into the ADC.

You could also put voltage clamps on the ADC input, but that is a fine point, and the circuit below will get you started.

The cap, C, is to help filter out noise on the input signal to the ADC.

You mentioned high wattage resistors.

Note that you DON'T want to put a high wattage resistor in series with the solar panel output, or it burns up all of the solar panel's energy, (as heat).

R1 and R2 don't have to be high wattage.

Assume 24 V at the top of R1, and calculate the current flowing to ground, (through the resistors).

Then you can calculate what wattage they will dissipate.

Then pick a suitably larger wattage resistor, say by a factor of at least 2, or perhaps even 4.

JC

Edit: Typo.

Last Edited: Fri. Apr 3, 2015 - 08:31 PM

Yes this is practically the circuit I am familiar with minus the diode and the capacitor. I was thinking though that if I had to measure more current, say 1AMP wouldn't it make the resistors too hot?

but doesn't my resistance change when the current changes?

No.  Your resistors are fixed in value.   Whats changing is the solar cells' capacity at varying levels of sunlight.

Keep in mind that .55 amps is the maximum it can source at full sunlight.  It does NOT mean that it is putting a half amp of current into your load.  your load can draw .1a@24vdc and if there is nothing else connected then the cell is outputting .1a of current at 24vdc, with the ability to deliver another .4a if needed.

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Something like a acs712 can be used to measure the current. If you trawl some of the arduino sites, there's plenty of examples of solar chargers etc.

Thank you I've already ordered one :)

So I have r1 = 38k(Two 14,xxx and one 10k in series) and r2 = 10k

By my calculations 5v will be the maximum output if the maximum input is 24v

However when I connect the solar panel to the common ground and the positive lead in front of my resistors... my measurement between the resistors is 5.7V at 14v coming from the panel. I've checked and double checked the value of the resistors. I'm not sure what I'm doing wrong.

Here is a basic diagram of my voltage divider -

VIN -> 14kOhm -> 14kOhm -> 10KOhm -> VOUT -> 10KOhm -> Ground

Last Edited: Sat. Apr 4, 2015 - 12:29 AM

ok, where are you taking the measurement from?

Lets round off the 38k to 40k to make the math easy.

Your divider with a 40k and a 10 k is 4:1  meaning that with 24vdc in from 10k to ground you will see 6vdc as 24/4=6

At 14vdc the reading would be ~3.5vdc

So it comes down to where you are putting your meter leads

Jim

EDIT:  14K resistor????

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Sat. Apr 4, 2015 - 01:20 AM

I put the meter positive lead at VOUT in between the two 10kOhm resistors and gnd to GND.

The same wire that goes to my ADC.

Last Edited: Sat. Apr 4, 2015 - 01:19 AM

Draw a schematic and post it.  Even if it is a picture of a piece of paper with your drawing on it....NEATLY

JIm

EDIT:

In case you missed my previous edit, I am having a little trouble accepting you have 14k resistors.  Double check that.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

"The critical shortage here is not stuff, but time." - Johan Ekdahl

"Step N is required before you can do step N+1!" - ka7ehk

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Sat. Apr 4, 2015 - 01:36 AM

A 12V nominal solar cell has an open circuit voltage of about 21V. Therefore a nominal 24V solar cell is going to have an open circuit voltage of around 42V. Therefore you'd want a division of 5:1.

(Gee, I guess the schematic with 56K and 10K was a good choice!)

JC

New guys get volts and amps and watts all mixed in a pile. Volts is like water pressure in the hose, amps is like gallons per minute, and watts is volts times amps. Pump power is psi times flow. Car engine power is torque times rpm. No volts, no power. No amps no power. Max power is about a little less than max volts and a little less than short circuit amps when dealing with solar panels *Ross*.

Imagecraft compiler user

Last Edited: Sat. Apr 4, 2015 - 02:18 AM

Here is my circuit. I hope you can understand it.

Where does the negative of the battery and solar panel go? Gnd is where they should be connected. We also need some capacitors in critical places - otherwise things won't work as expected. You regulator probably needs some, AREF needs one, the AVR needs one for power and for avcc and another as outlined by the doc for your adc input. 100nF is a good value.

Doesnt a voltage divider with a 40k and a 10k have a gain of 1/5th? Anyway, You want to attenuate the open circuit voltage down to within the 0-5V range read by the a/d. Lets say 40V to 4V. So you need a 10 to 1 divider. Something like 90K and 10K? These resistors wont get hot because the resistance is large, so they dont have much current going thru them. If you used 900ohms and 100ohms, they'd get Real Hot. So you convert the a/d reading to volts at the pin by multiplying the a/d value by 5/1024, THEN you multiply that voltage by 10 to get the panel voltage. Clever?

Imagecraft compiler user

Last Edited: Sat. Apr 4, 2015 - 12:00 PM

Bob, clever is having the ratio so that the adc result only needs a shift or so

Naaah. Divider should be chosen to maximize span on the a/d input. Max volts from panel should use most of the 5V but not clip.

Imagecraft compiler user

Max volts from panel should use most of the 5V but not clip.

However 'bright' is 24v and 'low light' is 16v so if you set 32v as full scale (1024 = 32v, 512 = 16v etc.) then it is a simple shift to get the voltage and operational range is 1/4 of full scale so 8 bit resolution.  Resistor divider 27k-tap-4k7-300R.

If you want better resolution for the operational range you need to offset the voltage.

David

Guys thank you for all of your replies.

@Kartman I do not have any capacitors yet, but they shouldn't have an affect on my voltage divider. I'm not very good at making schematics so I forgot to put those grounds you mentioned on the schematic.

I used 24V as the max voltage measured. I used this formula to determine what my resistors should be -

Vout = Vin (R2/(R1+R2)).

So

X = 24(10 / ( 50 ) )

X = 4.8

I should have a max voltage of 4.8 with 24 volt max right? I tried r2 and r1 in reverse orientation as @bobgardner suggested and I got close to the ouput of the panels... so I know that is not the issue.

Last Edited: Sat. Apr 4, 2015 - 04:12 PM

You won't get 40k resistors though.  You could use 2x 20k and a 10k or even use a multiturn pot it just depends what you want to measure and how accurately.  Could the panels ever go over 24v?  what do you want to measure down to?  what resolution?

David

I can use resistors in a series right? Two 15k and a 10k resistor to get my 40k.

I just want to get this issue figured out with my current setup and I can modify it for different voltages and R values using this experience later.

That'll do.

David

Yes but the issue I'm having... I just measured outside and the panel is giving me 16.something volts. My voltage divider output is giving 6.something volts.

Using two (Brown Green Black Red Brown) resistors and two ( Brown Black Black Red Brown )

I measured these resistors with my multimeter also and they are a little below spec. at 14.xxx and 9.xxx

Last Edited: Sat. Apr 4, 2015 - 04:30 PM

You should have:

Panel V+ -15k--15k--10k--------Tap-----10k- Gnd

sounds like you have

Panel V+ -15k--15k--------Tap-----10k--10k- Gnd

Tap being the measuring point - connect to AVR ADC.

David

Here is a picture. The orange wire is my VIN, the black wire between the resistors is my TAP. The black wire to the left of my tap is the ground.

This reply has been marked as the solution.

it looks like the first resistor has both ends connected to the same strip - shorting it out.

<Edit>meaning Vin -15k--10k---TAP--10k- Gnd

Also where is the connection across the 'gap'

David

Last Edited: Sat. Apr 4, 2015 - 06:54 PM

I was thinking placing the resistor in this way just made it part of that series circuit, but I should actually be moving over one row each time... makes sense. I'll fix my circuit and update you.

Thanks for your help! This was the entire issue :(

Last Edited: Tue. Apr 7, 2015 - 04:40 AM

Hello. Sorry for rising this thread up, but I have a similar problem.

I try to measure voltage from Solar Panel, P=0.7W, V=5.5V.

As I use not very stable power source (pack of 4 NiMH accumulators), I decided to use internal voltage (1.1V).

Used mc AtMega328P.

I set a voltage divider for panel Vout with such scheme: Vpanel+ -> R10k -> Point -> R1k -> CommonGND.

Vpanel- is also connected to common GND.

Code looks like this:

```static float ADC0Read()
{
uint8_t i=0;
_delay_us(200); //delay for starting band_gap
_delay_us(100);
while(i<=16){
_delay_us(50);
i++;
}
}```

And I have next problem: when I measure voltage by miltimeter directly between ADC0 and GND - I got 0.25V, voltage on solar panel is 2.52, so I expect 0.25V on ADC output. But ADC returnes me value ​0.0406.

Photo of connections is attached.

Orange wire: from solar panel V+, green wire: from solar panel V-.

## Attachment(s):

Maksym

I would write your function like this:

```static float ADC0Read()
{
uint8_t i = 0;
_delay_us(200); //delay for starting band_gap
_delay_us(100);
while (i <= 16) {                           //why do 17 loops ??
_delay_us(50);                          //pointless delay
i++;                                    //pointless loop
}
}```

But it would be simpler to use the 10-bit ADCW in the first place.   And use the ADC properly:

```static float ADC0Read()
{
}```

If you are actually dividing the Solar Panel by 10,  then the SCALING_FACTOR would be 10 * ((BAND_GAP/1024))

Your maths is equivalent but a little unintuitive.   It seems unusual to divide by the reciprocal of a Scaling Factor.

Quite honestly,  if your Solar Panel outputs 2.52V you might just as well use a 5V reference with no potential divider resistors.

David.

Last Edited: Thu. Sep 15, 2016 - 09:26 AM

Hello.

Let me try to explain, why I added loops: without them I have a big difference between measured values (more then 20%), with loops: about 1-4%.

V=2.52 is current voltage with current light, but max can be up to 5.5V, and I don't have stable source with 5V, that's why i'm using internal source and divider.

Unfortunately, yours code didn't helped me - I still get invalid values (from 0.383 to 0.560), but multimeter shows me 0.28V after divider (2.84V on solar panel outputs).

Maksym

Did you not see that your test was wrong. i.e. you should wait for ADSC to clear
.
My code was untested but it still looks ok to me.
Using AVCC for the reference is reasonable. You can always measure it every now and then. The most important step is to have sufficient 100nF capacitors for stable operation.
.
David.

I thought that I should put my money where my mouth is.

So I connected a pot to an Arduino Uno with its slider on A0.

```static float ADC0Read()
{
ADMUX = (3 << REFS0) | (0 << MUX0);   //band_gap, 10-bit, ADC0
}

void setup()
{
Serial.begin(9600);
}

void loop()
{
Serial.println("V");
delay(1000);
}
```

And it worked just fine.   I could also test it with VREF as AVCC but obviously with reduced resolution.   250mV does not go very far against 5V

Incidentally,  this just shows how easy it is to test ANY idea with a Uno.    The hardest work was connecting the 3 terminals of a pot.

David.

Last Edited: Thu. Sep 15, 2016 - 11:58 AM

Well, I just copy-paste yours code, added one line to get ADCW and try to run it :-)

That's what I got as the results (in V after divider/ADC value)

1.058/1023

1.058/1023

1.058/1023

0.316/306

0.311/301

0.974/941

1.058/1023

1.058/1023

0.309/299

1.058/1023

0.312/302

Measured each 1.5 seconds. Voltage from solar was +\- stable in next range: 2.1-2.3V. Capacitors on Aref, Avc and Vcc are present (100nF each). Unfortunately, I don't have UNO, only MC :-)

Maksym

To be honest, I have no idea what is wrong. I measured power supply voltage for MC, and I got correct results (using such way: ADMUX=(1<<REFS0)|(1<<REFS1)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1) and corrected formula for measured voltage, +\- 0.08V).

Maksym

I do not follow what you have done.   I provided a full Uno sketch.

You could run it on a bare MCU because it is a simple C function.

Why would you want to: added one line to get ADCW and try to run it ?

Regarding lack of Uno.   A Chinese Uno clone costs less than a pint of beer.   A Chinese Nano clone costs even less.

Whatever part of the world you come from,   either cost only a few minutes of employment.

Regarding "my style" of grouping SFR bits.   It is no different to yours.   I find it easier to read.   Often requires no comments at all.

David.

"You could run it on a bare MCU because it is a simple C function." -> actually, that's what I did :-). I'm using Atmel Studio. But got strange results in normal running mode or in debugWire mode.

"Why would you want to: added one line to get ADCW and try to run it ?​" - just to be sure, that this is not a formula mistake and check, what exactly was read from ADC.

I agree that Uno\Nano\etc... is a good thing. But anyway, I got that MCU as present from store and plan to use it for my experiments. :-)

Anyway, thanks for help :-). I will continue to think about solution and will try to find, what's wrong.

But, theoretically - can it be the potential problem, if solar panel is not connected to any load - only 2 resistors (10k + 1k) in voltage divider and that's all.

Maksym

Last Edited: Thu. Sep 15, 2016 - 03:33 PM

I have no idea how Solar Panels behave.   What does the data sheet say?

Surely you would have a dummy load of some description.

If your potential divider is 10k + 1k,  it is dividing by eleven not ten.

The GCC compiler will understand ADC as well as ADCW for the 10-bit result.   ADC does not seem a very intuitive name and is not understood by other compilers.

Having said that,   most people understand the concept of TCNT1H, TCNT1L, TCNT1 to refer to 8-bit or 16-bit quantities.

David.

Majestry23 wrote:
without them I have a big difference between measured values (more then 20%), with loops: about 1-4%.

We don't see the entire schematic, nor a full simple test program.

1)  AVR ADC works well with input impedances <10k.  Perhaps your signal doesn't have enough drive; add a small cap next to the input pin for the ADC to sip from.

2)  WORK IN ADC COUNTS UNTIL YOU GET EXPECTED, REPEATABLE, RESULTS.  >>Then<< begin to work in units.

2a)  Re units:  Get rid of the floats.  Do V calculations, if you must, in e.g. millivolts or similar scaled integer units.

2b)  Speaking of floats, do your conversion equation on paper, using integers (which is the way you wrote it).  What do you find?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Folks,

Is it possible that the solar panel is getting an unstable amount of sunshine? They do have a fast response time.

edit:

And an extra thought... replace your solar panel with an adjustable power supply during your code development until you are satisfied that all is working accurately... then attach your solar panel.

Ross McKenzie ValuSoft Melbourne Australia

Last Edited: Thu. Sep 15, 2016 - 11:03 PM

Keep in mind that if you do not or hardly load your solar panel, the voltage not be stable at all.

The problem is that with a very small amount of light the cells will very quickly get to their maximum voltage. That is what you probably see.

The more load you add, the more you can see the variations in light intensity hense the current that the cells generate.

looking at your results it almost seems to me that you have choosen the internal 1.1V bandgap reference as ADC reference. and ADC of 1023 with only a Vin to the processor of 1.1V does suggest this.

fast scrolling through the tread, you also wirte it in a comment.

Note that you should either use the 5V supply as reference, or change the resistive dividers to be 24V -> 1.1V instead of 24V -> 5V.

Ok.

I made a few changes but still got a problem.

MCU power: 5V stable, connected to Vcc, Vavcc, Vref. All are decoupled by 0.1nF capacitors.

Scheme of solar panel connection is in attachements

Code:

```#define UART_BAUD_RATE 9600
#define BAND_GAP_V 1.06

int main(void)
{
sei();
uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
while (1)
{
_delay_ms(2500);
}

{
ADMUX = (0 << MUX3)|(0 << MUX2)|(0 << MUX1)|(0 << MUX0)|(1<<REFS1)|(1 << REFS0);
_delay_us(250);
_delay_ms(1);
}```

Results from ADC and after calculations are next

Measured V: 0.000
Measured V: 0.000

Measured V: 0.000
Measured V: 0.000
Measured V: 0.000
Measured V: 0.980
Measured V: 10.91
Measured V: 11.66
Measured V: 11.66
Measured V: 11.66
Measured V: 10.88
Measured V: 0.000
Measured V: 0.000
Measured V: 0.000
Measured V: 0.000
Measured V: 3.852
Measured V: 11.66

Light level was the same all the time - from lamp.

Also, attached photo with measurement voltage using multimeter. Where 10mV - between ADC0 and GND, where 104 - between ADC0 and V+ from solar panel. Also, LED doesn't light at all when divider is connected.

## Attachment(s):

Maksym

Your schematic, photos, code do not make much sense at all.

1. Test your code with a regular variable pot or voltage source.   i.e. verify that you can read 0mV - 1060mV

2. Test your Solar Panel with a real load and regular DMM.  i.e. verify that it is producing voltage.

3.  Draw an accurate schematic.

5.  Post the code.   i.e. with full declarations for the variables

6.  Post the results.

David.

Step 1 - founded potential problem

I put stable 3.3V to ADC0 via 11 times divider (100 Ohms -> 10Ohms) - and receive correct results. (0.328V). The same for 4.25V - I got 0.424 after measures.

But.... I got this results when Aref is not connected, if it's connected to Vcc\Avcc (even decoupled) - then I got wrong results (0.05V).

But, where is said, that Aref should be off when using internal 1.1v?????? I founded nothing about this.

Maksym

Last Edited: Fri. Sep 16, 2016 - 12:27 PM

Majestry23 wrote:

But, where is said, that Aref should be off when using internal 1.1v?????? I founded nothing about this.

You mean, other than in the datasheet...

Quote:

...
If the user has a fixed voltage source connected to the AREF pin, the user may not use the other
reference voltage options in the application, as they will be shorted to the external voltage. If no external
voltage is applied to the AREF pin, the user may switch between AVCC and 1.1V as reference selection.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."