This device is, in essence, a standard voice recorder. It is designed to record and hold a specified amount of tracks which then can then be played back at a later time. The recorder has a 2-digit LED display, displaying the track the user is on, a forward button to loop through the tracks, a play button to play the current track, a record button that should be pushed or held while the user is recording their message, a microphone for vocal input, a speaker to play back vocals, and buttons for volume control. The ways in which this device differs from a regular voice recorder is mainly in functionality. First, the recorder will only hold a pre-defined amount of information (5 tracks) which will be of a specified length each (Approx. 12 seconds). When the device reaches the end of the track, regardless of whether or not the user is finished recording their message, the recording will be stopped. Furthermore, because the number of tracks is so small, this device will not utilize a backward button, but will only loop through the tracks going forward.
The hardware within the system consists of the controller (ATTINY44), the flash memory chip (SST25VF020), an integrated circuit for audio playback (KX1400), a voltage converter (TPS61221), a 2-digit LED display, a controller for the LED display (PCF8566), 5 tactile buttons that perform various tasks, a microphone and a speaker (headphone).
Schematic | PCB top view | PCB bottom view | ||
The controller is used to communicate with all of the different hardware components to allow them to perform tasks such as recording audio, playing back audio, changing the current track, setting the volume and displaying the current track with the LED display. The audio the user desires to record is brought into the processor by way of the microphone. Using pulse-width modulation the processor takes in samples of audio at the rate of one every 33 μsec. However, only every fourth sample is sent to the KX1400 to be transmitted to the memory for saving. An issue we ran into here is that we must send two bytes of data at a time to the memory chip but each sample was only one byte in size so we had to compensate with this in the software for the processor.
The KX1400 we used in the project is a powerful audio playback integrated circuit that houses a number of features that were useful for our project. These features we used were the KX1400's ability to play back pre-recorded 8Khz audio, control volume, drive a speaker, generate tones, and its built in low pass filter. The KX1400 was operated in slave mode to work with the processor and memory to record audio as well as play it. The KX1400 was also used to generate a 3 tone sequence marking the beginning of a recording session for a user when the record button is held down. This allows the user some lead in time before the device actually begins recording the data. Furthermore, the KX1400 is able to drive the speaker of the device to provide an output interface for the audio track the user wishes to listen to and was used to control the volume level at which a track is played back. To facilitate this process pushing a volume button on the device raises an interrupt flag and from there the software makes adjustments to the volume by way of the KX1400's built in volume controlling capabilities.
The flash memory chip is a 4 megabyte SPI serial flash. To record the audio we needed to set the KX1400 in pass thru-mode to allow the micro-controller to process the audio and write it into the flash memory via the KX1400. The memory chip also needed to be set to the Auto Address Increment mode so that two bytes of data could be sent for writing at a given time and be stored in contiguous addresses. To retrieve the audio from the memory for play back the KX1400 needed to be reset to the default state and brought out of pass-thru mode. From there the KX1400 was able to work in conjunction with the memory and processor to play the audio track.
The LED display and driver are used to display the track we are currently using to record to or playback. We used the I2C interface of the driver to connect the LED display. The updating of the screen occurs when the button is pushed which loops through the recorded tracks. When the button is pushed the interrupt flag is raised in the processor and the software takes care of updating the digits on the display.
Finally, a DC/DC voltage convertor was used (TPS61221) to boost the voltage up to 3.3V for the hardware devices and so that we could use two AAA batteries to power the device.
The device's functionality was implemented in the assembly code for our processor (ATTINY44 from Atmel). Some of the code, including the compression algorithm for the audio, was originally written in C and ported to assembly.
Writing the software for the device involved many different routines. First we programmed the interrupt routines for our input buttons. During the reset interrupt we initialize the device by setting up the input and output ports, setting up the clock, configuring the ADC, and clearing the circular buffer.
The interrupt generated by pushing the play button was rather simple thanks to the pre-loaded features of the KX1400. With the KX1400 we just needed to load the instruction code for play into an 8 bit register and the track number to play into another 8 bit register. We then used a routine that transmits a 16 bit value to the KX1400 as a 16 bit value is required by the KX1400. From this point the KX1400 takes care of the rest of the work by retrieving the data from memory and playing it back through the speaker.
The recording routing was more complicated. The first thing to occur when the record button is held down is the generation of three tones to signal that recording is about to begin. In our record routine we set the duration of the tones to one second and then loaded the 16 bit values of the tones into two registers and set them to the KX1400 through the SPI. At this point the device needs to start writing the audio data to the memory and therefore the KX1400 must be bypassed by switching to pass thru mode. The next step was to erase the data in the current track or to erase all of the memory in the chip if it was the first time the device was used and to set up the mode in which we wanted the data to be written to the memory. It turned out that the memory chip had many measures embedded in it to keep the user from writing to the memory <93>by accident<94> when they hadn't intended to. To enable writing we first had to send the write enable command to the memory, then enable writing to the status register of the memory. We then sent the hexidecimal value 0x0001 ( 1 in decimal ) to the status register to set the BPL (Block Protection Level ) to 1 which will block writing to the memory as we erase the memory needed for the audio track. We then sent the write enable command once more and sent the instruction code for setting the memory to Auto Address Increment (AAI) mode. This mode allows us to pass audio data two bytes at a time to the chip and the chip will store them in sequence in the memory addresses. From here, we entered a recording loop routine that is responsible for taking in the audio samples as discussed in the hardware section. The processor takes in samples from the microphone every 33 nanoseconds (32Khz) sample rate and collects every fourth sample. Two of these samples are then put through the filter and brought down to 8khz which is the necessary rate for the KX1400. At this point the data is run through the compression routine and finally it is sent to the memory to be stored. While the bytes are stored by the memory chip its busy bit is set to 1 so we added a routine to wait for the flash to finish executing its storage routine before sending the next two bytes for storage. During the routine we waste some clock cylces and then check the busy bit of the memory chip to see if it has completed its task. If it has we move on to the next set of samples and if it isn't we loop back into the wait routine.
It should be noted that the compression algorithm we ported from C is a large routine in and of itself and its implementation should be explained. The idea behind the algorithm is to convert the input data in 16-bit, 8Khz, PCM format into a 4-bit ADPCM format for storage into the memory.
The rest of the interrupts were much simpler to implement. To loop through the tracks we just needed to update the LED display by passing the correct values to the LED controller and keep track of the track number to send to the memory if we wished to play back or record. The volume controls are implemented in a similar manner to playing back a track. We just send the appropriate command to the KX1400 and the in house functions there will do the work for us.
Last modified:Mon, Jan 23, 2023.