Variable frequency buzzer

24 June 2018
One of the issues with my PIC16F88 LED alarm clock is that the Multicomp MCABI-020-RC sounder it uses requires 8+ volts to operate, so I had been looking at sounders that can operate at lower voltages. Two I had picked out to try were the Multicomp ABT-414-RC (Farnell 2098836) and ABT-416-RC (Farnell 2098837), but then found out that rather than DC they need to be powered via a square wave. On the plus side this meant that the sound frequency could be adjusted — to generate the required wave-form the PWM (Pulse-Width Modulation) functionality of the Cypress CY8C95xxA will be used, and it is the latter that this article will focus on.

As with the previous article that introduces the Cypress chip itself, it is assumed that the expander chip is being driven by my I2C-serial adapter via its associated control script, and is wired up to use 0x40 as its device address. This is due to an incompatibility between the Cypress chip and the USB-ISS adapter. It is assumed that the adapter has been attached to /dev/ttyUSB0.

Chip setup

For demonstration purposes Pin 15 (Bit 2 of Port 2, the one in the corner) of the CY8C9520A will be used to drive the sounder. The first command selects Port 2 as the target of configuration; the subsequent commands configure Bit 2 to use PWM output rather than general-purpose I/O, and for it to use active-high (i.e. sources current) open-drain:

./ttyI2C.py /dev/ttyUSB0 40 1 18 1 2 ./ttyI2C.py /dev/ttyUSB0 40 1 1a 1 4 ./ttyI2C.py /dev/ttyUSB0 40 1 1f 1 4

The next commands select PWM module 0 as the target of PWM configuration, and then set it to use the fixed 93.75kHz clock source. There is also a programmable 93.75kHz clock source that also includes frequency-division (register 0x2c, range 1-255), but for this circuit it is of no practical benefit.

./ttyI2C.py /dev/ttyUSB0 40 1 28 1 0 ./ttyI2C.py /dev/ttyUSB0 40 1 29 1 c

As an aside PWM output can only generate interrupts if the programmable clock source is chosen and the frequency divison is set to the maximum 255 (i.e. 367Hz), but the use of such functionality is beyond thr scope of this article.

Frequency selection

Choice of sound frequency is somewhat subjective, but I found 1.9kHz to be a nice frequency, which is the approximate notional operating frequency of the MCABI-020-RC. I used this as a starting-point, and the rtable below gives configuration for various frequencies around the 1.9kHz ball-park, although which one to use is down to personal preference. Since the period and duty cycle registers are next to each other, the setup command uses a single I2C transaction to update both at the same time. A 50% duty cycle is assumed, so the pulse-width is half the period.

Period Notional frequency Setup command
20 4.7kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 40 20
23 4.0kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 23 11
24 3.9kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 24 12
27 3.5kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 27 13
31 3.0kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 31 15
37 2.5kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 37 18
47 2.0kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 47 23
60 1.6kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 60 30
93 1.0kHz ./ttyI2C.py /dev/ttyUSB0 40 1 2a 2 93 46

From brief investigation using a duty-cycle other than 50% results in two tones rather than one. i do not have access to an oscilloscope, so could not verify the accuracy of the notional frequencies.

Activating & deactivating

When pulse-width modulation is enabled for an output pin, the associated bit within the output register acts as an enable flag. As a result the following will enable and disable signal output respectively:

./ttyI2C.py /dev/ttyUSB0 40 1 a 1 0 ./ttyI2C.py /dev/ttyUSB0 40 1 a 1 4

Remarks

I think the pulse-width modulation functionality is a very nice I2C-controlled square-wave generator, but it suffers for much the same reasons that I cited as issues with the Cypress chip as a whole: It is part of a device that tries to pack in too many features, so has many hall-marks of overengineering. Ideally I would want the I2C-controlled pulse-width modulation functionality as part of a much smaller stand-alone chip, but I have yet to come across such a chip. The nearest thing I have found is LED controllers such as the Texas Instruments TCA6507, but they are much more complex since they target specific use-cases rather than being generic pulse generators. It is a pity Cypress don't make a 8/10-bit variant of the chip alongside the 20/40/60-bit variants, as at least then the chip would be a good size for a dedicated pulse generator, even if somewhat pricey.