-2

EDIT NEW PICTURE

void setup() {
  Serial.begin(9600);
  Serial.println("Setup completed.");
}

void loop() {

  // Read external battery VCC voltage
  Serial.print("Bat: ");
  uint16_t batVolts = getBatteryVolts();
  Serial.print(batVolts);
  Serial.print(" - ");
  Serial.println(getBatteryVolts2());

  delay(500);
}

// One way of getting the battery voltate without any double or float calculations
unsigned int getBatteryVolts() {
  //http://www.gammon.com.au/adc

  // Adjust this value to your boards specific internal BG voltage x1000
  const long InternalReferenceVoltage = 1100L; // <-- change this for your ATMEga328P pin 21 AREF value

  // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc external reference
  // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG)         -Selects channel 14, bandgap voltage, to measure
  ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);

  // Let mux settle a little to get a more stable A/D conversion
  delay(50);

  // Start a conversion
  ADCSRA |= _BV( ADSC );

  // Wait for conversion to complete
  while ( ( (ADCSRA & (1 << ADSC)) != 0 ) );

  // Scale the value - calculates for straight line value
  unsigned int results = (((InternalReferenceVoltage * 1024L) / ADC) + 5L) / 10L;
  return results;
}

// A different way using float to determine the VCC voltage
float getBatteryVolts2() {
  // You MUST measure the voltage at pin 21 (AREF) using just a simple one line sketch consisting
  // of:  analogReference(INTERNAL);
  //      analogRead(A0);
  // Then use the measured value here.

  const float InternalReferenceVoltage = 1.1; // <- as measured (or 1v1 by default)

  // turn ADC on
  ADCSRA =  bit (ADEN);

  // Prescaler of 128
  ADCSRA |= bit (ADPS0) |  bit (ADPS1) | bit (ADPS2);

  // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG) - Selects channel 14, bandgap voltage, to measure
  ADMUX = bit (REFS0) ;
  ADMUX |= B00000000;       //I made it A0   //ADMUX = bit (REFS0) | bit (MUX3) | bit (MUX2) | bit (MUX1);

  // let it stabilize
  delay (10);

  // start a conversion
  bitSet (ADCSRA, ADSC);

  // Wait for the conversion to finish
  while (bit_is_set(ADCSRA, ADSC))
  {
    ;
  }

  // Float normally reduces precion but works OK here. Add 0.5 for rounding not truncating.
  float results = InternalReferenceVoltage / float (ADC + 0.5) * 1024.0;
  return results;
}

I tried executing this program but it did not work i believe there is some issue with my pin declaration or circuit. Please check. I want the code to read my voltage but it constantly reads wrong value and it is not even reading from A0

enter image description here

I just changed this part of the code enter image description here

1 Answers1

0

Unfortunately you did not follow my advice to study the linked information at https://github.com/RalphBacon/Arduino-Battery-Monitor. Especially those provided at http://www.gammon.com.au/adc

Instead you obviously messed with the first snipped you found without understanding what it does.

Otherwise I cannot explain why you would change

 ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);

to

ADMUX = bit (REFS0) ;
  ADMUX |= B00000000;

You don't want to read analog channel 0. You want to read the bandgap voltage (which is used as internal reference voltage).

There's the reference voltage, the ADC value and the measured voltage.

Usually you would use a known reference voltage and the ADC value to calculate the measured voltage.

V = ADC * Aref / 1023

But in this case you use the ADC voltage and the known measured voltage to calculate the reference voltage, which is the voltage of your battery connected to Aref.

Aref = V_bandgap * 1023 / ADC

But in order to do that you must set the ADMUX register to measure the internal voltage reference (1.1V) using an external reference voltage.

Piglet
  • 27,501
  • 3
  • 20
  • 43
  • i understood that we dont have to take reading from channel 0 ( i am using UNO board) i went through the files too and was able to obtain internal voltage of 1.092V i added that to the code as well. The issue here is where do i connect my battery???? and how do i measure it, i am sorry for irritating you, i am new to adc registers, i have added my serial monitor collected data in the main post top side. (Bat-109 -5V) this is what serial monitor is showing – electro_nooobbbb Feb 10 '23 at 11:05
  • okay i followed the video and have connected aref pin (21) to decoupling cap and A0 to my battery while shorting all grounds together but the code still reads wrong value. – electro_nooobbbb Feb 10 '23 at 12:49
  • which part of `battery connected to AREF` is unclear? if you understand that we don't read from A0, why do you connect your battery to it? I mean it won't hurt the measurement if you also connect it to AREF but it isn't necessary – Piglet Feb 10 '23 at 13:23
  • Then please tell me where do i connect battery to read the voltage (i read online they say that it must be connected to any defined analog pin) I have not connected anything to AREf (just the decoupling capacitor) since AREF is internally connected to1.1V (our bandgap voltage) if possible can you a draw a circuit because i know that there is something wrong with my connections – electro_nooobbbb Feb 10 '23 at 17:55
  • circuit picture attached in the main post above. – electro_nooobbbb Feb 10 '23 at 18:34
  • Connect the battery to AREF. How often do I need to say this? You still haven’t read the linkend information or really thought about my answer. Otherwise this would be clear. You have 2 values and calculate the third unknown value. What is unclear about this? – Piglet Feb 11 '23 at 20:54
  • Note that once you do an analogRead if you use either of the internal voltages references (5V or 1.1V) it is connected to the AREF pin internally. You should not connect any other voltage sources to that pin or it will be shorted to the internal reference. (These data has been taken from the link you shared) then please tell me how can I connect battery directly to AREF pin won't it damage my IC? I don't have constant external reference voltage( it's alternating) – electro_nooobbbb Feb 12 '23 at 21:30
  • I followed the procedure, it worked but it is showing me current battery voltage, i don't want to measure the current battery voltage , all i want is the battery voltage to remain constant irrespective of battery voltage level – electro_nooobbbb Feb 13 '23 at 04:45
  • as long as you don't connect a voltage to AREF that is higher than your supply voltage or negative you won't damage anything. this just means that you should not connect a voltage to AREF unless you want to use it as reference voltage. if you don't want to measure battery voltage, what is this post all about? you cannot have a constant battery voltage as batteries discharge. if you want to generate a constant voltage from a battery you need to use a voltage regulator. it is unclear what you actually want to achieve. https://xyproblem.info/ – Piglet Feb 13 '23 at 08:10
  • I need stable voltage for my analog pin, How do i do that. I know the basic formula int voltage = ( readVal * (VOLTAGE)) / 1023; The (VOLTAGE) value must be stable so that the formula is never disturbed. ( I think that i explained it properly). i need to read constant battery voltage irrespective of the current battery value. I was successful in doing so (stable or unchanged battery voltage value) but the problem is that arduino is just for prototyping, mainly i'd be using attiny and i dont have any spare analog Pin. – electro_nooobbbb Feb 13 '23 at 08:51
  • you cannot "read constant battery voltage" a battery voltage always drops over time especially under load because it is being discharged. if your actual question is how to get a constant voltage from a battery the answer is a voltage regulator or a voltage reference ic. alterantively use the internal voltage reference and a voltage divider. but again this is not a programming problem and hence off-topic here. using a voltage regulator will increase the required supply voltage so you will probably not be ok with a single lithium battery. – Piglet Feb 13 '23 at 09:46
  • Oh God! yes, exactly that is the issue, if i use any external component such as regulator the power consumption would increase. – electro_nooobbbb Feb 13 '23 at 10:45