Go Down

Topic: Timing Question (Read 709 times) previous topic - next topic

zdillman

I am working on a device to monitor the voltage of a battery and do an action when it gets to a certain point, and another action when it gets to another point after that. It detects what type of battery it is (2 cell, or 3 cell) when the battery is plugged in. It is programmed on an ATTiny85 but written in Arduino. The program works very well except for one problem, when the device that the battery is hooked up to is being used the voltage dips and the computer sees that and performs the second action, skipping the first because of a false read in the dip. Is there any way to modify this code to force the computer to have to read the voltage level for a certain number of seconds before it confirms it and continues with the appropriate action? I am reading the voltage through a resistor voltage divider and it works great. I just need the computer to read the voltage for a certain number of seconds before it does any action. Hope you can see what the device does through the code better than I could explain it. Thanks in advance!

Code: [Select]
int buzzer = 1, voltpin = 2, val = 0, mosfet = 0, cut = 0, buzz = 0;
boolean buzzed = false, cutoff = false;

void setup() {

  pinMode(mosfet, OUTPUT);
  pinMode(buzzer, OUTPUT);
  delay(3000);

  val = analogRead(voltpin);

  if (val >= 560) {
    buzz = 580;
    cut = 566;
  }
  else if ( val >= 364) {
    buzz = 387;
    cut = 363;
  }
}

void loop() {

  val = analogRead(voltpin);
  if (cutoff == false) {

    if (val <= buzz && buzzed == false) {

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

    if (val <= cut && cutoff == false) {
      digitalWrite(mosfet, LOW);
      cutoff = true;
    }
    if (cutoff == false) {
      digitalWrite(mosfet, HIGH);
    }
  }
  delay(1000);
}

Jack Christensen

Don't base the decision on a single reading. Require two or three in a row, or use a moving average, etc.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

zdillman

Thanks, I did this to my code, it should work, right?

Code: [Select]
int buzzer = 1, voltpin = 2, val = 0, mosfet = 0, cut = 0, buzz = 0, val1 = 0, val2 = 0, val3 = 0, val4 = 0, finalval = 0;
boolean buzzed = false, cutoff = false;

void setup() {

  pinMode(mosfet, OUTPUT);
  pinMode(buzzer, OUTPUT);
  delay(3000);

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

  if (finalval >= 560) {
    buzz = 580;
    cut = 566;
  }
  else if ( finalval >= 364) {
    buzz = 387;
    cut = 363;
  }
}

void loop() {

  val = analogRead(voltpin);
  delay(300);
  val1 = analogRead(voltpin);
  delay(300);
  val2 = analogRead(voltpin);
  delay(300);
  val3 = analogRead(voltpin);
  delay(300);
  val4 = analogRead(voltpin);
 
  finalval = val + val1 + val2 + val3 + val4 / 5;
  if (cutoff == false) {

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

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

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

Jack Christensen


Thanks, I did this to my code, it should work, right?


Best way to find out is to try it!
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

PaulS

Why are val and val1 global? There are not used outside of loop(), are they? Why are they not called something meaningful like volt1 and volt2? In other words, why is only one numbered?

If you are looking for the type of a variable, by the time you get to the end of the line where finalval is defined, the type has scrolled off the screen. It is far better to declare one variable per line. Then the type is right there next to the variable.

zdillman

Hey, I built a device to monitor battery voltage and do certain actions depending on what the voltage was at. If it passes a certain voltage it does one thing, then past that another thing. Right now, no matter what, it performs both actions. Is there a fault in my code? I can't find any.

Code: [Select]
int buzzer = 1, voltpin = 2, val = 0, mosfet = 0, cut = 0, buzz = 0;
boolean buzzed = false, cutoff = false;

void setup() {

  pinMode(mosfet, OUTPUT);
  pinMode(buzzer, OUTPUT);
  delay(3000);

  val = analogRead(voltpin);

  if (val >= 560) {
    buzz = 580;
    cut = 566;
  }
  else if ( val >= 364) {
    buzz = 387;
    cut = 363;
  }
}

void loop() {

  val = analogRead(voltpin);
  if (cutoff == false) {

    if (val <= buzz && buzzed == false) {

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

    if (val <= cut && cutoff == false) {
      digitalWrite(mosfet, LOW);
      cutoff = true;
    }
    if (cutoff == false) {
      digitalWrite(mosfet, HIGH);
    }
  }
  delay(1000);
}


Thanks

zdillman

Also, this is programmed in Arduino, for an Attiny85.

Nick Gammon

Please don't start a new thread posting the exact same code as a previous thread, and a very similar question. This is called cross-posting which wastes people's time.

Threads merged.

- moderator
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PaulS

Quote
Right now, no matter what, it performs both actions. Is there a fault in my code? I can't find any.

You need to confirm that the "no matter what" part is true. I suspect that it isn't. Serial.print() the value read from the pin.

Code: [Select]
  if (cutoff == false) {
Using the == false in that statement makes it appear that you don't understand if statements, booleans, or the equality operator correctly.
Code: [Select]
if(!cutoff)
{

does the same thing, and looks correct to programmers.

Code: [Select]
    if (val <= buzz && buzzed == false) {
should be
Code: [Select]
    if (val <= buzz && !buzzed)
    {


Code: [Select]
    if (val <= cut && cutoff == false) {
should be
Code: [Select]
    if (val <= cut && !cutoff)
    {


Now, look at val, buzz, and cut. Suppose, in setup, that val was 800. What values are in buzz and cut? Suppose val was 500. What values are in buzz and cut? Finally, suppose that val was 300. What values are in buzz and cut?

Now, explain why the values in buzz and cut depend on the original value of the battery being above some level. It seems to me that buzz and cut should be relative to the original val (as measured in setup), not constant values only if the original voltage is above some amount.

There may be other issues, but you need to address these, first.

Those other issues? Look at the fact that you have to ifs in loop, rather than if/else if.

Go Up