Switch Case + Potentiometer + Piezo

Hi people. I’m new around here, and also new about the introduction to arduino and C.
In this little “project” i’m asked to have a analog sensor which is the potentiometer, regulating the tone of a piezo buzzer using five switch cases according to the analog reading.

Here’s what i came up with.

#define pi 6
#define pot A0
int cont = 0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("Move o potenciómetr");
  

}

void loop() {
  // put your main code here, to run repeatedly:
  int potValue = analogRead(pot);
  switch(cont){
    case 0:
      if(potValue = 0){
        tone(pi, 440,5);
        delay(30);}
       break;
     case 1:
      if(potValue > 0 || potValue <= 256){
        tone(pi, 494,10);
        delay(60);
      }
      break;
     case 2:
      if(potValue > 256 || potValue <= 512){
        tone(pi,523,15);
        delay(90);
      }
      break;
      case 3:
      if(potValue > 512 || potValue <= 768){
        tone(pi,587, 20);
        delay(120); 
      }
      break;
      case 4:
        if(potValue > 768 || potValue <= 1023){
          tone(pi, 622, 25);
          delay(150);
        }
  }

}

The code compiles, but there’s no tone at all. I don’t know if it’s the buzzer or the code, or both, but i’m only gonna test again tomorrow since someone took my other piezo and this one only heats up.

Glad for the help

Do you really think that you'll hear much with the durations you coded?

https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/

Two big problems in your code.

  switch(cont) {
  case 0:
    if(potValue = 0) {

The ‘=’ is an assignment. It sets potValue to zero and then the statements in the if clause are not executed because potValue is zero. Use ‘==’ for the comparison operator.

The other problem is that your switch statement depends upon the value of ‘cont’ which you initialize to zero and never change.

The result of the two problems together is that your code does even execute a tone function.
If you fix the first problem you will at least hear something from the piezo buzzer.

Pete

Will try to correct that then, thanks for the help.
About the transition of the count in this case, what if i edited the case 0 to start, read there the potValue, and put some elif and if comparing the values to the other cases, which in that case, goes to the specific case like case 3, and at the end of case 3 to do an analogRead again maybe? Is it workable ?

L2FTP:
About the transition of the count in this case, what if i edited the case 0 to start, read there the potValue, and put some elif and if comparing the values to the other cases, which in that case, goes to the specific case like case 3, and at the end of case 3 to do an analogRead again maybe? Is it workable ?

Ummmm

In this little “project” i’m asked to have a analog sensor which is the potentiometer, regulating the tone of a piezo buzzer using five switch cases according to the analog reading.

You’re not following what your code as is does. Once that sketch is running right it should always be making a tone to match the pot setting, changing only to match turning the pot.

You need to ditch the switch-case structure, just turn those lines into comments until later.

This next technique I call slicing off possibilities, it’s code to cover a set of conditions:

(pseudocode – just to show some logic)

lastQuarter = -1
if ( read < 256 ) // read could be 0 - 1023
{
if ( lastQuarter != 0 ) // only evaluates this if the read is < 256
{
lastQuarter = 0;
print “1st quarter” // or whistle middle C?
}
}
else if ( read < 512 )
{
if ( lastQuarter != 1 )
{
lastQuarter = 1;
print “2nd quarter”
}
}
else if ( read < 768)
{
if ( lastQuarter != 2 )
{
lastQuarter = 2;
print “3rd quarter”
}
}
else // as in all possible values left
{
if ( lastQuarter != 3 )
{
lastQuarter = 3;
print “last quarter”
}
}

See the braces line up? Everything is on the same level.

The 1st if() covers the low end of the range of possibilities and each next if() only sees reads higher than those taken by the one before.

The if ( read < 512 ) does not need to be if (( read < 512 ) && ( read > 255 )) because the previous if () covered all reads < 256.

You could slice from the top down starting with if ( read > 767 ) just as well. Sometimes you want the higher or lower values to process a bit quicker and then bottom up or top down does make a difference but here it doesn’t.

Get rid of the duration values in your calls to tone() and the note will play until changed.
Get rid of those delay() calls. They only make reading the pot jerky. You will notice times when the sketch is blinded to the pot.

You might see ways to use fewer lines. With enough slices, you’d want to. Those if ( lastQuarter… blocks look pretty regular, maybe a single function you write could generalize them all and you call that for each slice?

Standard C switch-case is more for distinct single values so of course Arduino switch-case does cover ranges. Look it up.

If this is an assignment and must use the switch/case (which is basically pointless) then surely the simple way to do it is to use your string of if statements to set values in cont and THEN put the switch in to produce the tones. E.g.

      if(potValue = 0){
        cont = 0;
      }

      if(potValue > 0 || potValue <= 256){
        cont = 1;
      }
     //   etc....and when they're all done
switch(cont){
    case 0:
        tone(pi, 440,5);
        break;
    case 1:   // etc.

Except the = should be == and all the || (or) should almost certainly be && (and). Oh and if you want to hear the tones you’ll have to increase the duration to more than 5 or 10 milliseconds.

Steve

Already tested your options and it's functional. Just gotta modify the tones now. Thanks for the help guys

One thing: in the pseudocode it says

if ( read < ### )

Do ONE analog read into a variable and use that variable in all the if() statements.

Why? Because analog read takes a long time in Arduino cycles, 1 analog read per if() would be wasteful.