Maker Pro
Maker Pro

running project on lithium battery and reading constant battery voltage adc

wrinke

Feb 25, 2023
19
Joined
Feb 25, 2023
Messages
19
you'll require stable 5 V for correct operation of the Arduino anyway, so you can use this as is default in analogRead().
If the project have no critical "timing" operations, the atmega328 can work fine with floating voltage between brown detector value and 5 or 6v (I don't remember exactly) so could be right choice use internal voltage reference
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,098
Joined
Nov 17, 2011
Messages
13,098
the atmega328 can work fine with floating voltage between brown detector value and 5 or 6v
It may work in some situations, not in others. What with e.g. variations of ambient temperature. Even if it "works", it is not a good, even less a stable design.
 

wrinke

Feb 25, 2023
19
Joined
Feb 25, 2023
Messages
19
It may work in some situations, not in others. What with e.g. variations of ambient temperature. Even if it "works", it is not a good, even less a stable design.
Yes, it depends on kind of project, but the mcu till not reach brown value, works
 

wrinke

Feb 25, 2023
19
Joined
Feb 25, 2023
Messages
19
Another Note: The Arduino's internal reference voltage has an accuracy of 10 %. Assuming you use 1 % resistors, that adds at least another 1 % error to your measurement (an exact calculation will yield up tp 2 % depending on the values). SO the total measurement error will be up to 12 %! If you can't accept that error, you will have to add an external precision voltage reference with much less error and use precisin resistors (0.1 % or better).
To get you started with as little additional effort as possible I suggest you stick to your present configuration but keep the possible measurement error in mind.
The swinging values shown seem lack of precision not accuracy. The accuracy can be tared, the precision can be fix using average of many reads
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
1677745497867.png
Please check the full circuit, it is with attiny IC.


I tried the same code with attiny, it did not work :(. I added a few commands to it now atleast the led is coming ON and OFF before with arduino code it used to remain full ON.



int led = 3;
#define solar 2
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
pinMode (led, OUTPUT);
pinMode (solar, INPUT);
//analogReference (INTERNAL);
}

void loop() {
// ADMUX = (1 << REFS1) | (0 << REFS0) ; // Sets ref. voltage to internal
analogReference (INTERNAL);
int sensor = analogRead(solar);
float voltage = (sensor/1023*(1.1)*(5.7));
ADCSRB = (1 << ADLAR);
int ADC_value = ADCL | (ADCH<<8);
Serial.print ("solar panel voltage");
Serial.println(ADC_value);

delay(1000);

if (ADC_value<=1023){
digitalWrite (led, HIGH);
}
else{
digitalWrite (led, LOW);

}
}
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
1677745991076.png



This is my entire circuit with attiny. Please check :/


Just an update, the code works perfectly for arduino but not for attiny and therefore, i had to edit a few lines but unfortunately it is still not working as needed :(

int led = 3;
#define solar 2
void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
pinMode (led, OUTPUT);
pinMode (solar, INPUT);
//analogReference (INTERNAL);
}

void loop() {
// ADMUX = (1 << REFS1) | (0 << REFS0) ; // Sets ref. voltage to internal
analogReference (INTERNAL);
int sensor = analogRead(solar);
float voltage = (sensor/1023*(1.1)*(5.7));
ADCSRB = (1 << ADLAR);
int ADC_value = ADCL | (ADCH<<8);
Serial.print ("solar panel voltage");
Serial.println(ADC_value);

delay(1000);

if (ADC_value<=1023){
digitalWrite (led, HIGH);
}
else{
digitalWrite (led, LOW);

}
}


can you point out error?




Opps!!!!! sorry for reposting same question i thought it got deleted.
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,098
Joined
Nov 17, 2011
Messages
13,098
You have the voltage divider R3/R4 connected incorrectly. In this setup the factor is
[math] sc = \frac {4.7 k\Omega}{4.7 k\Omega + 1 k\Omega} = 0.825 [/math] which results in an input voltage to the Arduino of Vin = 6 V × 0.825 = 4,95. But using the internal 1.1 V reference the input voltage should not exceed 1.1 V. Therefore: swap R3 and R4.

R1 at 10 k is probably much too high. Assuming a voltage drop of 1.6 V across the LED and 5 V output from the Arduino, the current will be only [math] I_{LED} = \frac{5 V - 1.6 V}{10 k\Omega} = 0.3 mA[/math]Usually you'll want 5 mA to 10 mA for the LED. Use e.g. R1 = 1 k for approx. 3 mA which should give a good indicator light from the LED.
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
You have the voltage divider R3/R4 connected incorrectly. In this setup the factor is
[math] sc = \frac {4.7 k\Omega}{4.7 k\Omega + 1 k\Omega} = 0.825 [/math] which results in an input voltage to the Arduino of Vin = 6 V × 0.825 = 4,95. But using the internal 1.1 V reference the input voltage should not exceed 1.1 V. Therefore: swap R3 and R4.

R1 at 10 k is probably much too high. Assuming a voltage drop of 1.6 V across the LED and 5 V output from the Arduino, the current will be only [math] I_{LED} = \frac{5 V - 1.6 V}{10 k\Omega} = 0.3 mA[/math]Usually you'll want 5 mA to 10 mA for the LED. Use e.g. R1 = 1 k for approx. 3 mA which should give a good indicator light from the LED.
okay i interchanged.

1677747057515.png


Could you please check my attiny code


int led = 3;

void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
pinMode (led, OUTPUT);
pinMode (2, INPUT);
//analogReference (INTERNAL);
}

void loop() {
// ADMUX = (1 << REFS1) | (0 << REFS0) ; // Sets ref. voltage to internal
analogReference (INTERNAL);

float voltage = (analogRead(2)/1023*(1.1)*(5.7));
ADCSRB = (1 << ADLAR);
int ADC_value = ADCL | (ADCH<<8);
Serial.print ("solar panel voltage");
Serial.println(ADC_value);

delay(1000);

if (ADC_value<=1023){
digitalWrite (led, HIGH);
}
else{
digitalWrite (led, LOW);

}
}




This command
ADCSRB = (1 << ADLAR);
has some issue, if i remove it, system read 1023 all the time but if i add this is works (not accurately at all).
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,098
Joined
Nov 17, 2011
Messages
13,098
Could you please check my attiny code
Checking code is time consuming. My time is limited. Why don't you test it and report errors back. Then we have a strting point to investigate further.
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
Checking code is time consuming. My time is limited. Why don't you test it and report errors back. Then we have a strting point to investigate further.
Okay, i have checked the code, it is reading 1023 under little light which it should not. I tried adding ADCSRB register to overcome and to direct my register storing to right or left hand side but that did not help much. The system seems extra sensitive. Removing ADCSRB register results into 1023 reading always.
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,098
Joined
Nov 17, 2011
Messages
13,098
C:
const int PinLED = 3;
const int PinADC = 2;

void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
pinMode (PinLED, OUTPUT);
pinMode (PinADC, INPUT);
analogReference (INTERNAL); // this instruction needs to be run only once, tehrefore it belongs into setup()
}

void loop() {

    int ADC_value = analogRead(PinADC)
    float voltage = ADC_value/1023*(1.1)*(5.7));

    Serial.print ("ADC value: ");
    Serial.println(ADC_value);
    Serial.print ("solar panel voltage: ");
    Serial.println(voltage);

    delay(1000);

    // what is the purpose of the following lines? What do you want to indicate?
    // the Arduino has a 10 bit ADC which will _always_ give you a value between 0 ... 1023
    // therefore the if statement will always be true and the LED will always be on.
    
    if (ADC_value<=1023){
        digitalWrite (PinLED, HIGH);
    }
    else{
        digitalWrite (PinLED, LOW);
    }
}
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
C:
const int PinLED = 3;
const int PinADC = 2;

void setup() {
// put your setup code here, to run once:
Serial.begin (9600);
pinMode (PinLED, OUTPUT);
pinMode (PinADC, INPUT);
analogReference (INTERNAL); // this instruction needs to be run only once, tehrefore it belongs into setup()
}

void loop() {

    int ADC_value = analogRead(PinADC)
    float voltage = ADC_value/1023*(1.1)*(5.7));

    Serial.print ("ADC value: ");
    Serial.println(ADC_value);
    Serial.print ("solar panel voltage: ");
    Serial.println(voltage);

    delay(1000);

    // what is the purpose of the following lines? What do you want to indicate?
    // the Arduino has a 10 bit ADC which will _always_ give you a value between 0 ... 1023
    // therefore the if statement will always be true and the LED will always be on.
   
    if (ADC_value<=1023){
        digitalWrite (PinLED, HIGH);
    }
    else{
        digitalWrite (PinLED, LOW);
    }
}
I tried the code it showing full ON led because the ADCSRB register has been removed. It is working just like my old code.
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,098
Joined
Nov 17, 2011
Messages
13,098
I tried the code it showing full ON led because the ADCSRB register has been removed.
No, the problem is elsewhere, see my comment on top of the for-loop. Look at the output of the print statements. You'll see the ADC value is always <= 1023.

You will not learn by simply copying code (or circuits). Try to understand what the code does. That's what comments are for. In this case my comment contains a question which you need to consider plus an explanation why exactly this happens: LED is always on.

I presume you know what a 10 bit ADC means, do you?
10 bits = numbers from 0x000 (0 decimal) to 0x3ff (1023 decimal). This ADC will never ever output values above 1023.
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
No, the problem is elsewhere, see my comment on top of the for-loop. Look at the output of the print statements. You'll see the ADC value is always <= 1023.

You will not learn by simply copying code (or circuits). Try to understand what the code does. That's what comments are for. In this case my comment contains a question which you need to consider plus an explanation why exactly this happens: LED is always on.
sure, i will try rectifying, i have recently changed my attiny library file also let me go back to the old one and play with crystals because maybe 8mhz internal cannot provide us with accurate readings. i will update you, once i am done. Thank you.
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
The accuracy of the ADC does not depend on the clock frequency of the µC.
Hi there,

i tried the code in different manners and obtained several results.


#include <SoftwareSerial.h>
int led = 7;
#define rx 1
#define tx 0
SoftwareSerial serial (rx,tx);

void setup() {
pinMode (rx, INPUT);
pinMode (tx, OUTPUT);
serial.begin (9600);
pinMode (led, OUTPUT);
analogReference (INTERNAL);
}

void loop() {
float voltage = (analogRead(2)/1023*(1.1)*(5.7));
ADCSRB = (1<<ADLAR);
int ADC_value = ADCL | (ADCH<<8);
serial.print ("solar panel voltage");
serial.println(ADC_value);
delay(1000);


if (ADC_value<=1023){
digitalWrite (led, HIGH);
}
else{
digitalWrite (led, LOW);

}
}


if i make
ADCSRB = (1<<ADLAR);
i get the following results on the serial monitor
solar panel voltage704
solar panel voltage320
solar panel voltage384
solar panel voltage7040
solar panel voltage6272
solar panel voltage8256
solar panel voltage8576
solar panel voltage8576
solar panel voltage8576
solar panel voltage7936
solar panel voltage6336
solar panel voltage28096
solar panel voltage28416
solar panel voltage17856
solar panel voltage0
solar panel voltage0
solar panel voltage320
solar panel voltage0
solar panel voltage0
solar panel voltage0
solar panel voltage1152
solar panel voltage16256
solar panel voltage15872
solar panel voltage15422

whereas, if i make
ADCSRB = (1<<ADLAR);
it does not work at all, showing full ON led.

solar panel voltage21
solar panel voltage11
solar panel voltage79
solar panel voltage19
solar panel voltage118
solar panel voltage112
solar panel voltage88
solar panel voltage131
solar panel voltage113
solar panel voltage95
solar panel voltage132
solar panel voltage110
solar panel voltage106
solar panel voltage31
solar panel voltage0
solar panel voltage1
solar panel voltage13
solar panel voltage0
solar panel voltage23
solar panel voltage52
solar panel voltage145
solar panel voltage181
solar panel voltage153
solar panel voltage118
solar panel voltage1023
solar panel voltage1023
solar panel voltage1023
solar panel voltage1023

and as you can see at the end (1023) it reads this value under my phone torch light.
 

electronoobb

Feb 11, 2023
26
Joined
Feb 11, 2023
Messages
26
Hi there,

i tried the code in different manners and obtained several results.


#include <SoftwareSerial.h>
int led = 7;
#define rx 1
#define tx 0
SoftwareSerial serial (rx,tx);

void setup() {
pinMode (rx, INPUT);
pinMode (tx, OUTPUT);
serial.begin (9600);
pinMode (led, OUTPUT);
analogReference (INTERNAL);
}

void loop() {
float voltage = (analogRead(2)/1023*(1.1)*(5.7));
ADCSRB = (1<<ADLAR);
int ADC_value = ADCL | (ADCH<<8);
serial.print ("solar panel voltage");
serial.println(ADC_value);
delay(1000);


if (ADC_value<=1023){
digitalWrite (led, HIGH);
}
else{
digitalWrite (led, LOW);

}
}


if i make
ADCSRB = (1<<ADLAR);
i get the following results on the serial monitor
solar panel voltage704
solar panel voltage320
solar panel voltage384
solar panel voltage7040
solar panel voltage6272
solar panel voltage8256
solar panel voltage8576
solar panel voltage8576
solar panel voltage8576
solar panel voltage7936
solar panel voltage6336
solar panel voltage28096
solar panel voltage28416
solar panel voltage17856
solar panel voltage0
solar panel voltage0
solar panel voltage320
solar panel voltage0
solar panel voltage0
solar panel voltage0
solar panel voltage1152
solar panel voltage16256
solar panel voltage15872
solar panel voltage15422

whereas, if i make
ADCSRB = (1<<ADLAR);
it does not work at all, showing full ON led.

solar panel voltage21
solar panel voltage11
solar panel voltage79
solar panel voltage19
solar panel voltage118
solar panel voltage112
solar panel voltage88
solar panel voltage131
solar panel voltage113
solar panel voltage95
solar panel voltage132
solar panel voltage110
solar panel voltage106
solar panel voltage31
solar panel voltage0
solar panel voltage1
solar panel voltage13
solar panel voltage0
solar panel voltage23
solar panel voltage52
solar panel voltage145
solar panel voltage181
solar panel voltage153
solar panel voltage118
solar panel voltage1023
solar panel voltage1023
solar panel voltage1023
solar panel voltage1023

and as you can see at the end (1023) it reads this value under my phone torch light.
i wrote another code to check.

#include <SoftwareSerial.h>
int led = 7;
#define rx 1
#define tx 0
SoftwareSerial serial (rx,tx);
#define solar 2


void setup() {
// put your setup code here, to run once:
pinMode (rx, INPUT);
pinMode (tx, OUTPUT);
serial.begin (9600);
pinMode (led, OUTPUT);
pinMode (solar, INPUT);
analogReference (INTERNAL);
}

void loop() {

int ADC_A0 = analogRead(solar);
float A0Voltage = (ADC_A0 *1.1)/1023;
float solarVoltage = A0Voltage * 5.7;
serial.print ("ADC A0 = ");
serial.println(ADC_A0 );
serial.print ("A0Voltage = ");
serial.println(A0Voltage );

delay(1000);

if (A0Voltage<=1023){
digitalWrite (led, HIGH);
}
else{
digitalWrite (led, LOW);

}
}


OUTPUT

A0Voltage = 0.22
ADC A0 = 358
A0Voltage = 0.38
ADC A0 = 391
A0Voltage = 0.42
ADC A0 = 210
A0Voltage = 0.23
ADC A0 = 392
A0Voltage = 0.42
ADC A0 = 393
A0Voltage = 0.42
ADC A0 = 394
A0Voltage = 0.42
ADC A0 = 657
A0Voltage = 0.71
ADC A0 = 995
A0Voltage = 1.07
ADC A0 = 1023
A0Voltage = 1.10
ADC A0 = 1023
A0Voltage = 1.10
ADC A0 = 1023
A0Voltage = 1.10
ADC A0 = 1023
A0Voltage = 1.10
ADC A0 = 1023
A0Voltage = 1.10

under little light (mobile torch) it reads 1023.
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,098
Joined
Nov 17, 2011
Messages
13,098
float voltage = (analogRead(2)/1023*(1.1)*(5.7));
ADCSRB = (1<<ADLAR);
int ADC_value = ADCL | (ADCH<<8);
Why do you keep messing with the ADC registers? The analogRead() function will do all the necessary settings.
 
Top