If you're ok with starting with square wave signals, this can be done on an Arduino.
You need to do the following:
- Configure a 16-bit Timer to CTC mode
- Select the right prescaling
- Add a RC low pass filter to the output and voltage divider
Configure a 16-bit Timer to CTC mode
Assuming I'm using Timer 1 and OCR1A:
TCCR1A |= (1<<COM1A0); // Toggle OC1A on match
TCCR1B |= (1<<WGM12); // Clear to Compare mode
TCCR1B |= (1<<CS10); // No prescale
Select the right prescaling
In case you're wondering, prescales are used when the MCU clock is much faster than the output you desire.
Without prescaling, the highest frequency is 16MHz/2 = 8MHz, and the lowest frequency would be 8MHz / 2^16 = 122Hz . Which covers the range of frequencies that we want.
Setting OCR1A value to 80 gives you a frequency of 100kHz
Setting OCR1A value to 2667 gives you a frequency of 2.9996kHz
You can then control the chirp like so:
// Linear rise in wave period
int x = 10;
for (int x=80; x < 2668; ++x){
OCR1A = x;
delay(10); // 10ms delay
}
Add a RC low pass filter to the output and voltage divider
Making the perfect sine waves may be too troublesome, so we'll resort to the poor man's sine wave.
Here's the poor man's implementation by TI (still require quite a few parts.)
Personally, I'm cheap so I'd go for the RLC approach. ;-)