0

I'm making a device for the visually disabled that makes a sound when the water in a bowl reach certain levels.

I've already made the sensors for three levels of water and if statements to make the sound, but I need the sound to be played just once for every level change and it loops over and over. How can I make it to sound just one time?

Here is my code:

#include <PCM.h>
const unsigned char sample[] PROGMEM = { //Here goes the sample
};
int low = 0;
int mid = 0;
int high = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  low = analogRead(A0);
  mid = analogRead(A1);
  high = analogRead(A2);
  Serial.print("nivel agua: ");

  if (high > 50){
    Serial.print("Alto");
    startPlayback(sample, sizeof(sample));
  }
  else if (mid >50){
    Serial.print("Medio");
    startPlayback(sample, sizeof(sample));
  }
  else if (low > 50){
    Serial.print("Bajo");
    startPlayback(sample, sizeof(sample));
  }
  delay(100);
1
  • Have you ever think to use a boolean flag variable?
    – rebatoma
    Mar 30, 2016 at 21:33

2 Answers 2

3

A possible solution to your problem can be the following:

#include <PCM.h>
const unsigned char sample[] PROGMEM = { //Here goes the sample
};
int low = 0;
int mid = 0;
int high = 0;
bool first = true;
bool second = true;
bool third = true;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  low = analogRead(A0);
  mid = analogRead(A1);
  high = analogRead(A2);
  Serial.print("nivel agua: ");

  if (high > 50 && first){
    Serial.print("Alto");
    startPlayback(sample, sizeof(sample));
    first = false;
  }
  else if (mid >50 && second){
    Serial.print("Medio");
    startPlayback(sample, sizeof(sample));
    second = false;
  }
  else if (low > 50 && third){
    Serial.print("Bajo");
    startPlayback(sample, sizeof(sample));
    third = false;
  }
  delay(100);

In this way the sound for each level will be played only once. I hope this is what you were looking for.

2
  • Thank you!!, never came to my mind. I also added that when one flag comes false the others come true so i can go up and down
    – agos46
    Mar 30, 2016 at 21:55
  • @Mattia I've added an answer that includes my thoughts on speed. I'll delete my other comments to avoid having double-information and a garbage in the comment section.
    – Paul
    Mar 31, 2016 at 12:15
0

As an addition to the answer of Mattia.

I suspect you have something like:

void loop() {
  // put your main code here, to run repeatedly:
  low = analogRead(A0);
  mid = analogRead(A1);
  high = analogRead(A2);
  Serial.print("nivel agua: ");

  if (resetVariables){
     first = true;
     second = true;
     third = true;
     resetVariables = false;
  }

  if (high > 50 && first){
    Serial.print("Alto");
    startPlayback(sample, sizeof(sample));
    first = false;
  }
  else if (mid >50 && second){
    Serial.print("Medio");
    startPlayback(sample, sizeof(sample));
    second = false;
  }
  else if (low > 50 && third){
    Serial.print("Bajo");
    startPlayback(sample, sizeof(sample));
    third = false;
  }

  if(buttonPressed){
    resetVariables = true;
  }
  delay(100);
}

A better practice would be to use another function

void resetFlags() {
  first = true;
  second = true;
  third = true;
}

And the main code would be:

void loop() {
  // put your main code here, to run repeatedly:
  low = analogRead(A0);
  mid = analogRead(A1);
  high = analogRead(A2);
  Serial.print("nivel agua: ");

  if (high > 50 && first){
    Serial.print("Alto");
    startPlayback(sample, sizeof(sample));
    first = false;
  }
  else if (mid >50 && second){
    Serial.print("Medio");
    startPlayback(sample, sizeof(sample));
    second = false;
  }
  else if (low > 50 && third){
    Serial.print("Bajo");
    startPlayback(sample, sizeof(sample));
    third = false;
  }

  if(buttonPressed){
    resetFlags();
  }
  delay(100);
}

Would this be faster?

  • It would at least make your loop code more readable, instead of juggling flags around.
  • resetFlags(); would act immediately and independent from the flag checking etc.
  • It saves checking unnecessary if's (which equals a very little speed increase).
  • It saves 1 boolean (byte maximal in memory) which equals a very little memory/speed increase.

But why mind speed if you have a 100msec delay? You could make it only output the water level when it changes. Then you can run the water checking extremely fast! (It wouldn't spam your console, plus, writing to console takes considerable amount of time, compared to checking if's.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.