Orangutan-lib buzzer timing off?

Newbie here again, this time trying out the buzzer-test program in orangutan-lib-0.3.

If I read the code and comments correctly, it should play a series of three notes, for one second each, and then repeat. But in fact, it’s not doing that for me. In ten seconds, it plays twenty notes or so.

This was true both for the default buzzer-test.hex, and for the one I built myself. Is there something wrong with my clock speed, or what?

Thanks,
- Joe

BTW, I did find device.h, and confirmed that it’s set for Orangutan, which is what I have. So, that’d be a good guess, but doesn’t appear to be the problem.

(Incidentally, it’s a bummer that the Orangutan is only 8MHz while its baby brother is 20MHz – what’s up with that?)

Best,
- Joe

Hey, glad you’re running through the code and catching all the bugs!

Lemme hook up my Orangutan and give the buzzer code a whirl.

While I’m doing that, on the whole 8MHz vs. 20MHz thing, one uses the internal RC oscillator (the Orangutan) while the other uses an external crystal (Baby-O). You CAN make an Orangutan use an external crystal, but it’ll eat up two I/O pins.

This is actually a pretty cool feature, to have the crystal pins available to play with and nothing soldered into them. You can use the internal RC oscillator and plug in a watch crystal, which is a very precise 32.768kHz oscillator, and do all sorts of fun realtime clock stuff. Or you can plug in the crystal of your choice and get a custom clocking rate. I wound up using the latter to fix an Orangutan that had funky fuse settings. It worked like a charm.

Okey doke, back from testing. You’re right. I get 23 tones per 10 seconds (hand-held stopwatch, so I can’t say how accurate that estimate is.) Let me set up some more tests to do tonight, and I’ll post a fix.

Tom

Got it. The math was dead-on, but the order of operations caused an overflow on long durations. In buzzer.c, inside buzzer(), change the “loops =” line to read:

	// Calculate the number of loops to execute in order to hit the
	// duration asked for.
	loops = (F_CPU / 8000UL) * duration / wait_units;

I’m getting one second tones now for 1000ms durations.

I’ll check the change into the source tree. Thanks for catching that, Joe.

Tom

That makes sense – an easy mistake to make when dealing with shorts.

Incidentally, other boards I’ve worked with in the past, using variants of PBASIC, supported a FREQOUT command typically used for driving a buzzer or speaker. But it supported generating a mixture of two frequencies. I really dig this, because you can either use it to produce real two-part harmony, or you can just add harmonics to single notes, producing a more pleasant tone.

buzzer.c and buzzer.h are pretty spartan at the moment – would you object to me adding a version of buzzer() that takes two frequencies instead of one? (I assume the linker would strip out any function you’re not actually using anyway.)

Of course I can do this just for myself, but I guess what I’m asking is whether you’d see this as a useful addition to orangutan-lib.

Best,
- Joe

Hey, I’d be interested!

I haven’t played around much with the buzzer. (Guess you couldn’t tell…) I mostly do coding at night after the kids are in bed, so I tend not to make noise if I can avoid it.

But I know what you mean about the frequency mixing. I’d be interested in seeing what you come up with.

Tom

P.S. Jim Remington, who wrote and posted his buzzer code, also came up with some seriously not-spartan code for playing melodies on the Orangutan’s buzzer. I haven’t tried to roll that into Orangutan-lib yet, though I’m tempted. I’m working on a new mini-sumo robot, and the thought of having it belting out Ride of the Valkyries as it tears out across the ring has serious appeal.

I have a similar issue – plus my wife is usually working on her laptop right next to me. You should have seen me jump for the power switch last night when I tried the buzzer test. :slight_smile:

But I know what you mean about the frequency mixing. I’d be interested in seeing what you come up with.

OK. Of course since posting that, I’ve come to realize that I’m not quite certain how to do it within the limitations of the device. I assume we don’t have any trig functions handy, right? What about some sort of system clock – is it possible to sit in a loop, and be able to tell how long it’s been since (say) the start of the waveform, or since the last iteration of the loop?

That’d be very cool! Was it also single-tone, or has he already solved the mixing problem?

Best,
- Joe

It was single tone, too.

There’s trig and floating point available, but it’s all done in software so it’s quite slow. You can do faster trig by doing a lookup table (100x speedup is possible), but when it comes back to the buzzer it’s still an on/off device.

There are all sorts of system clocks available. The ATmega168 has three timers, two are 8-bit one is 16-bit. Orangutan-lib uses up a fair bit of the timer resources available, depending on what modules you use, but the 16-bit stuff all runs at full clock speed. If you haven’t taken a look at the datasheet for the '168, it’s well worth the look. There’s all sorts of stuff you can do with the thing that I haven’t even touched yet. I seriously love these things.

Tom