So I have an arduino due and if I measure the voltage of one or two batteries of 1,5V each, the sensor measures very good.
But If I try to measure the voltage of a solar panel using a voltage divider of 10k/310k ohm the adc measure very bad. The values overall are lower that what they should be and the samples rise and fall to much from the average value.
I read that the UNO output impedance for the adc must be 10kohm or lower and now I wonder if its the same for the DUE or if its different. I could not find an answer for this.
If that is not the issue, ¿what can cause this problem?
So you're trying to measure a 100volt solar panel, judging by your resistor choice.
If you would measure e.g. a 6volt solar panel with those resistors, you would have an A/D value of ~58.
A ~0.1 volt granularity.
The output voltage of a solar panel could ofcourse vary a lot with light.
I assume you have put some sort of capacitor or battery across it to smoothen out fast light variations.
I think we need to see you code.
And details of your setup.
Leo..
Wawa:
So you're trying to measure a 100volt solar panel, judging by your resistor choice.
If you would measure e.g. a 6volt solar panel with those resistors, you would have an A/D value of ~58.
A ~0.1 volt granularity.
The output voltage of a solar panel could ofcourse vary a lot with light.
I assume you have put some sort of capacitor or battery across it to smoothen out fast light variations.
I think we need to see you code.
And details of your setup.
Leo..
Yes, the maximum voltage of the panels we want to measure is 100V, but when I did this tests the voltage was only 17V.
When I did this test I didnt use capacitor of any kind, just measuring the open circuit voltage of the panel straight to the resistors and from there to the arduino due or ADC pins.
Some paint art here:
The code is really simple. It's just analogreadvoltage example changed to show 3 values:
/*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
analogReadResolution(12);
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
int sensorValue2 = analogRead(A1);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * 3.3 / 4095.0;
float voltage2 = sensorValue2 * 3.3 / 4095.0;
float voltage3 = sensorValue2 * 3.3 / 4095.0*31;
// print out the value you read:
Serial.print(voltage,3);
Serial.print(";");
Serial.print(voltage2,3);
Serial.print(";");
Serial.println(voltage3,3);
delay(1000);
}
weedpharma:
If as Wawa has suggested, you are measuring 100v, please bear in mind that this can be a lethal voltage.
DC has the ability to clamp muscles and prevent the release of the grip.
Please be careful in your layout and handling.
Weedpharma
100V is the maximum, when I do testing I use 17V which if fine.
MarkT:
Also have tou measured the voltage on the analog pin simultaneously with a multimeter?
Yes, I was measuring with a multimeter on the solar panel endings and also in the analog pins to ground of the arduino. Both were really constant when I was doing the testing.
Someone suggested me to use a small capacitor between analog and gnd while measuring but I cant test until monday.
"10k/310k"
I am not sure what the input impedance on that arduino is (I would guess about 45K), but I am pretty sure it is not 310k. I suggest lowering the resisters in your voltage divider, and putting a small cap between the analog pin and ground.
Are the wires going to the solar panel short or long (2 ft, or 20 ft)? It would be a good idea to add several caps along the way.
" int sensorValue = analogRead(A0); * int sensorValue2 = analogRead(A1);"*
Reading the two analog pins without a delay, could also be adding to the problem.
I see your solar panels is being read by A1, what is on A0?
WARNING: on the voltage divider, make sure the resistor to ground is secure, Before you attach the resistor to the higher voltage.
Arduino's A/D input impedance is very high. ~100Megohm. Those values are fine.
Good idea to use a 100n cap from analogue input to ground, close to the Arduino, especially if the wires are long.
If the wires are very long, I would use twisted pair, like Cat-5 or 6.
My code reads the analogue pin once, and doesn't use that value. That clears previous sh#t.
Then read it multiple times for averaging.
Leo..
"Arduino's A/D input impedance is very high. ~100Megohm.
I may misunderstand, but I thought the 100megohm was while no readings are being made by the arduino. Then when you are reading/sampling, the sampling capacitor has to be charged from the external pin, and that produces a larger load, so during the sampling time it is way below 100Megohms.
It is hard to charge that sampling capacitor through a 100M resistor fast enough to get an accurate reading. Maybe I misunderstand it tho.
I believe that one call to analogRead() will initiate several samples by the arduino that are averaged. Is that correct?
This is how I understand it.
There is just one A/D for all analogue inputs.
The analogue inputs are scanned by a MUX (multiplexer).
The MUX has a sample/hold capacitor.
It takes some time to charge or discharge (previous reading) that VERY SMALL capacitor (some pF).
A source with an impedance <10k has no problem with that, but a higher source impedance might.
Two ways to fix.
A 10-100n capacitor from analogue-in to ground. The cap has no problem charging a S/H cap that is thousands of times smaller.
Or one pre-reading that clears the previous "ghost charge".
100Megohm is just an estimated "leakage" from the MUX and the input protecton diodes.
Leo..
Using oversampling (the average os many measurments) doesnt really help because the measurements itself are so bad that the average is also bad and innaccurate.
The distance to the solar panel is long. The solar panel is in the roof of the building, so the lenght of the wire are probably 10meters at least.
I was not measuring anything in A0. I put it there because I changed the wire from A1 to A0 to see if it was a problem of one specific analog input but both measurements were similar.
I read a lot of things in the forums about the ADC, most of it is about the UNO.
They always say that the output impedance must be below 10k ohm. What I understood is that the resistance between analog pin and ground must be 10kohm or lower. Thats why I used this resistor values. Is this correct or it should be the whole voltage divider?
The main problem if I use 10k ohm as the whole voltage divider is that 100V/10000ohm is 0,01Amp and 100V*0,01Amp=1W so I need new resistors because I think the ones I have can only have 1/8 of Watt. Also I wanted this current to be as low as possible because later i want to measure the current of the panel but its ok if it works.
I tried to search if the output impedance for Due is also 10k ohm but could not find anything.
10 meters of cable is not a problem, but use twisted pair.
You don't want it to act too much as an aerial.
In this case, you have to use a 100n capacitor from analogue to ground, close to the Arduino.
Or even 10-100uF to smoothen things out. Hum is your enemy.
That cap also helps with the impedance/sampling problem.
If the solar panel is >48volt, I would split the 310k into two resistors.
e.g a 300k near the panel, and a 10k near the Arduino.
You don't want any dangerous voltages down the Cat-5 wire.
10x oversampling does not use much processor time, so why not.
Did you try the code?
Leo..
There is no need to change the resistor values of the voltage divider.
There is no need to use twisted cable such as Cat-5; any pick-up of hum or other interference can be dealt with by a capacitor across the 10kΩ resistor. I don't think interference is the problem here but it's worth trying about 100μF (with a fairly large capacitor such as this, it may be worth putting in resistor in series with the Arduino's input to limit the current that could flow when the Arduino is powered-down).
I think something else is causing the large variation in readings, even something like a faulty connection of the negative wire from the solar panel to Arduino's ground.
Maybe keep the resisters you are using, and put an op amp between the voltage divider and the analog pin. Put a small cap on the input of the opamp, but not on the analog pin since it is being driven by the op amp output. The op amp will have low impedance output.
[quote author=jack wp link=msg=2340537 date=1438517377]Maybe keep the resisters you are using, and put an op amp between the voltage divider and the analog pin. Put a small cap on the input of the opamp, but not on the analog pin since it is being driven by the op amp output. The op amp will have low impedance output.
[/quote]What is the op-amp supposed to do? If it is to drive the Arduino's input pin from a low impedance, then it's unnecessary.
[quote author=jack wp link=msg=2340577 date=1438519737]
Yes, it is to provide a low impedance to the analog pin (only the analog inputs need the low impedance).
[/quote]The impedance does not need to be less than 10kΩ, especially as the voltage will be only very slowly changing. The relevant part of the datasheet (for the ATmega328) is:
The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or
less. If such a source is used, the sampling time will be negligible. If a source with higher impedance
is used, the sampling time will depend on how long time the source needs to charge the
S/H capacitor, with can vary widely. The user is recommended to only use low impedance
sources with slowly varying signals, since this minimizes the required charge transfer to the S/H
capacitor.
I am getting stable readings with a source resistance of 500kΩ (digital value varying ±2).
@Archibald, quote "I am getting stable readings with a source resistance of 500kΩ (digital value varying ±2)."
is that +- 2 or 2% ? If it varies from 4 to 6, would be different than 2%.
what else do you have setup? Use a cap on the input? Can you show us the section of script where you take the reading(s).
There so many different factors to consider.
I am still think that one call to analogRead will trigger several actual samples internally. If that is the case then the script can't control the sampling time. Does anyone know this?