Go Down

Topic: Problem with reading voltages and possible code faults. (Read 835 times) previous topic - next topic

zdillman

Hello all,

I am making a device to read the voltage of a battery, detect whether it's a 2 cell or 3 cell Li-po, and do an action depending on the voltages.  The device reads the voltage, for a 2 cell or 3 cell and selects the "buzz" and "cutoff" voltages. The buzz and cutoff voltages are for a piezoelectric buzzer, and a MOSFET. The MOSFET controls whether the voltage is passed through to the output terminals for power to an external device. The buzzer buzzes if the battery gets too low and needs to be changed. The point of the MOSFET is to cut the power to the external device if the battery gets too low, so that it doesn't discharge more and destroy the battery. Now, with all of this said, I have written up this code, and it seems to be flawless. However, when I hook it up to my bench DC power supply set to 12.6v (Fully charged 3 cell Li-Po) it waits to take the voltage like it should, takes the voltage, then buzzes and cuts the voltage immediately. I have calculated the values I have used in the code from the information given on the Arduino page about AnalogRead. The voltage from the battery goes through a voltage divider and steps it down so the Arduino can read it. May I also point out that this code is being put onto an ATTiny85, which is why the pins may be different. If anyone has any insight on what the problem might be that would be much appreciated. Here is the code...

Code: [Select]
int val = 0, cut = 0, buzz = 0, val1 = 0, val2 = 0, val3 = 0, finalval = 0, addfloat = 0;
boolean buzzed = false, cutoff = false;

void setup() {

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  delay(3000);

  val = analogRead(2);
  delay(500);
  val1 = analogRead(2);
 
  addfloat = val + val1;
 
  finalval = addfloat / 2;

  if (finalval >= 700) {
    buzz = 591;
    cut = 570;
  }
  else if ( finalval >= 450) {
    buzz = 398;
    cut = 367;
  }
}

void loop() {

  val = analogRead(2);
  delay(300);
  val1 = analogRead(2);
  delay(300);
  val2 = analogRead(2);
  delay(300);
  val3 = analogRead(2);
 
  addfloat = val + val1 + val2 + val3;

  finalval = addfloat / 4;
 
  if (!cutoff) {

    if (finalval <= buzz && !buzzed) {

      tone(1, 4500);
      delay(250);
      noTone(1);
      delay(250);
      tone(1, 4500);
      delay(250);
      noTone(1);
      delay(250);
      tone(1, 4500);
      delay(1000);
      noTone(1);
      buzzed = true;
    }

    if (finalval <= cut && !cutoff) {
      digitalWrite(0, LOW);
      cutoff = true;
    }
    if (!cutoff) {
      digitalWrite(0, HIGH);
    }
  }
  delay(1000);
}

Cybernetician

Code: [Select]
void setup() {

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  delay(3000);

  val = analogRead(2);
  delay(500);
  val1 = analogRead(2);
 
  addfloat = val + val1;
 
  finalval = addfloat / 2;

  if (finalval >= 700) {
    buzz = 591;
    cut = 570;
  }
  else if ( finalval >= 450) {
    buzz = 398;
    cut = 367;
  }
}


setup() execute only one time
Code: [Select]

val = analogRead(2);
delay(500);
val1 = analogRead(2);

What is the status of your battery when you run this first time? it would be nice if you post all calculations with little detail ;)

Code: [Select]

val = analogRead(2);
delay(300);
val1 = analogRead(2);
delay(300);
val2 = analogRead(2);
delay(300);
val3 = analogRead(2);


val = val1 = val2 = val3 most probably why?

From Idea To Invention

zdillman

Thanks for the reply. The reason multiple readings are taken and then averaged is because the device that uses the voltage from the battery causes the battery voltage to dip sometimes.  I average three voltages so if there is a dip, it won't prematurely buzz or cut the voltage.

My calculations are as follows. I figured out what a fully charged cell for a Li-Po battery would be. (4.2v) and a dead cell. (3v). From there I can calculate what I need each number to be using a small table I made. I measured the voltages I got going through the voltage divider and recorded them to a table. Using that table I was able to divide the number of millivolts I wanted by 4.9mv (taken from AnalogRead info page) and that would give me the number of units I needed to use.

Any ideas?

Cybernetician

Code: [Select]

val = analogRead(2);
delay(500);
val1 = analogRead(2);

What is the status of your battery when you run this first time? because setup() execute only one time.
From Idea To Invention

zdillman

I know this. Right now, for troubleshooting purposes I am using a bench DC power supply that is set to 12.6v (fully charged 3 cell Li-Po). It runs this, then selects the buzz and cut voltages to be used. Could this be the problem? If setup() sets a variable like "buzz" to something like 575, can loop read "buzz" as 575 or is it still 0?

Cybernetician

lets start trouble shooting by using Serial

In setup()
Code: [Select]

Serial.begin(9600);
finalval = addfloat / 2;
Serial.print(finalval);

if (finalval >= 700) {
   Serial.print("Greater Than 700");
   buzz = 591;
   cut = 570;
 }
 else if ( finalval >= 450) {
   Serial.print("Greater Than 450");
   buzz = 398;
   cut = 367;
 }


In loop
Code: [Select]

finalval = addfloat / 4;
Serial.print(finalval);

if (finalval <= buzz && !buzzed) {
     Serial.print("finalval <= buzz && !buzzed" TRUE);
     tone(1, 4500);
     delay(250);
     noTone(1);
     delay(250);
     tone(1, 4500);
     delay(250);
     noTone(1);
     delay(250);
     tone(1, 4500);
     delay(1000);
     noTone(1);
     buzzed = true;
   }


Add these statments and find the reason and one important thing also share with me 8)
From Idea To Invention

zdillman

Unfortunately, I am using an ATTiny85 which is not, (as it is set up) capable of serial output. Gonna have to find a different way of doing this. Or buy some more parts and an FTDI chip and breadboard it. That was my last resort if I couldn't get it figured out here.

Coding Badly

Unfortunately, I am using an ATTiny85 which is not, (as it is set up) capable of serial output.


Do you have an unused pin?

zdillman

I do, I'm going to set it up on a breadboard and use an FTDI chip to get serial output. Thanks.

Coding Badly


Cybernetician

Oops but not a big problem

Use Pin 0 (to blink led) to check if() statements

first time in this
Code: [Select]
if (finalval >= 700) {Blink}

and so on one by one


From Idea To Invention

buteman

I think your code in setup()

Code: [Select]

if (finalval >= 700) {
    Serial.print("Greater Than 700");
    buzz = 591;
    cut = 570;
  }
  else if ( finalval >= 450) {
    Serial.print("Greater Than 450");
    buzz = 398;
    cut = 367;
  }


will always set buzz to 398 and cut to 367.
although I am usually wrong :smiley-roll:

Arrch


I think your code in setup()

Code: [Select]

if (finalval >= 700) {
    Serial.print("Greater Than 700");
    buzz = 591;
    cut = 570;
  }
  else if ( finalval >= 450) {
    Serial.print("Greater Than 450");
    buzz = 398;
    cut = 367;
  }


will always set buzz to 398 and cut to 367.
although I am usually wrong :smiley-roll:


Not with the "else if" there.

Go Up