

The timer thread updates the seconds since boot on the TFT using a while loop and a millisecond yield. To communicate with the DAC, we complete SPI transactions at the end of the ISR with the output data. We also precomputed all constants and used the fixed point data type _Accum where possible. The number of cycles used to calculate and send out the current amplitude must be at most 909 minus the cycles needed to context switch, so we used a sine lookup table with 256 entries instead of the math sine function.

We also applied a linear ramp to each note to avoid popping sound caused by large jumps in the DAC output amplitude.

We took care to transform our time variable note_time to generate exactly half a period for the swoop, using the pi_time constant. time graph is modeled as the top half of a sine function, and for the chirp, the graph is exponential (which we calculated by multiplying, rather than using a square or power function). Since we allow our integer accumulator to overflow as an input to the sine function and we generate audio samples at a certain rate, Fs, we scale our target frequency, Fout, by 2^32 / Fs, to get our phase increment per interrupt. We increment our phase accumulator variable, DDS_phase, by a certain amount for each audio sample generated, or during each interrupt of the ISR. The algorithm we used to calculate the correct frequency is outlined on the course website. Our ISR calculated the next amplitude based on the note to generate encoded by a global volatile variable (named button). We programmed an ISR to generate audio at a 44k sampling rate, so on a 40 MHz timer, we generated interrupts every 909 cycles.
NORTHERN CARDINAL SOUND ON BIRDCLOCK SOFTWARE
Our starting point for our system is the DDS_Accum_Expander_BRL4.c example code on the course website, making use of the DAC, port expander, TFT display, system interrupts, Protothreads, and a software keypad decoder. This wiring allowed for RB0 to read a digital 0 when the switch was in the left position, and for RB0 to read a digital 1 when the switch was in the right position. Finally, the middle pin was wired to RB0. Then, the left pin was tied to ground and the right side tied to +3V3. To toggle between record and play modes, a single pole double throw switch was placed on the breadboard. Then, a speaker was plugged into the 3.5mm jack and sound could be heard. Using an audio socket like the one pictured below, DAC_A was wired to the rear pins and the front pin was connected to ground.

Once the desired sound was calculated, it was output on DAC_A. We aimed to achieve good modularity and testability with our approach, making small incremental changes and testing for controlled, specific results. Finally, we implemented the play and record modes to enable song recording and playback. We sketched out a state machine for the debouncing algorithm, and implemented it. Then using the algorithm described on the course webpage, we generated a swoop on the ‘1’ keypress and a chirp on the ‘2’ keypress, and implemented a silence note for the ‘3’ keypress. We then integrated the keypad example code on the course website, and generated a sound on any keypress. We first attempted to generate a sine wave at target frequency, by sending the correct data to the DAC to control the output on the speakers. Our end goal is to generate songs using swoops, chirps, and silence notes to mimic songbirds.
NORTHERN CARDINAL SOUND ON BIRDCLOCK SERIES
The system can also record a song consisting of a series of notes and silences to be played back later. Pressing ‘1’ on the keypad generates one note of a song (swoop), ‘2’ generates another note (chirp), and ‘3’ 130ms of silence. Using a PIC32 microcontroller, a DAC, a keypad, and a speaker, we were able to create a system to generate sounds identical to the ones made by the northern cardinal.
