Generating piezo tone, higher & higher

Hi,

I’m a noob when it comes to arduino. So don’t be to complicated in your comments please :smiley:
I’m trying to make a loading sound for my iron man project, it has to start low and go higher and higher in tone,
so I made this little program with a for loop :

int piezo=10;
int pitch=100000;


void setup() {
  // put your setup code here, to run once:
pinMode(10, OUTPUT);
for (int pitch=100000;pitch<=10;pitch--)
{
  digitalWrite(piezo,HIGH);
  delayMicroseconds(pitch);
  digitalWrite(piezo,LOW);
  delayMicroseconds(pitch);
  }
digitalWrite(piezo, LOW);
}

void loop() {

digitalWrite(13,HIGH);  
delay(100);
}

But when the program starts, it makes the right sound output, but after it reaches a high frequency it suddenly drops back at a frequency like 60Hz

can’t find out why?

100000 is too big to be held in a 16-bit signed int. Make pitch an unsigned long and that might work better.

Also, pitch<=10 would make more sense if it was pitch>=10.

Also, pitch is not a good name since this is really the half-period, which is more like the inverse of the pitch.

You have defined a global variable named pitch and also a local variable of the same name. The global variable is not used; you could get rid of it.

Since you have defined a variable piezo to record the pin number, it would make sense to use that in the call to pinMode() rather than duplicate the value. For extra brownie points, make piezo a const.

delayMicroseconds() only takes an unsigned int as a parameter. If you want to do more than 65535, you’ll have to call delay() instead. It uses milliseconds.

PeterH is right about the <= 10. I think what’s happening is that pitch starts at 100000, which when converted to a signed integer, is -31072. And when converted to an unsigned integer, is 34464. As you decrement that, it goes down to -31073, which is 34463. You keep decrementing until you roll over, at which time the pitch becomes positive (a very LARGE positive) and drops out of the loop. Then your setup() function can finish and the loop() function takes over. I expect THAT is where your “frequency like 60Hz” happens.

Try declaring pitch as an unsigned int, and starting at something like 40000. And switch the <= around like PeterH suggested.

Got it working, thanks for the replies! it was indeed the value that needed a change. I tried making it a long variable, but that didn’t work out as well.

int piezo=10;
void setup() {
  
pinMode(10, OUTPUT);

for (int count=0;count<=100;count++){
 digitalWrite(piezo,HIGH);
  delayMicroseconds(800);
  digitalWrite(piezo,LOW);
  delayMicroseconds(800);
}
for (int pitchinv=800;pitchinv>=100;pitchinv = pitchinv-1)
{
  digitalWrite(piezo,HIGH);
  delayMicroseconds(pitchinv);
  digitalWrite(piezo,LOW);
  delayMicroseconds(pitchinv);
  }
digitalWrite(piezo, LOW);
}

void loop() {

}