Introduction: Spartan Voice Changer Helmet
Hello dear reader!
We are a team of 4 students from the Ecole Polytechnique de la Sorbonne gathered around this project. It is realized as part of our studies, and aims to take in hand a number of tools, as well as demonstrate our theoretical achievements.
The famous object takes on the appearance of a helmet resembling that of the hero of a certain video game whose name will be lost. For the design side also we have a screen that displays the Fourier transform of the audio signal coming out of the speaker. The purpose of this headset is to change the voice of the carrier in real time using a number of selectable effects.
- Capture the sound from a microphone
- Amplify, filter, digitize the signal
- Realize the FFT of a signal
- Show this FFT on a screen
- Signal synthesis
- Take a sound out of a speaker
- Realize effects on the audio sound (reverberation, echo, etc ...)
Now that we have put the background and presented the project, it's time to get your hands on it!
Step 1: Requirements 1/3 - Hardware
In order to build sucessfully your helmet, we will need some hardware to run the device.
- DE0-Nano-SoC Development Board by Terasic + Adafruit TFT LCD Screen ( Arduino )
- Access to a 3D printer to make the helmet (If you are a university student move closer to your university, some have labs accessible to students)
- A computer with an internet connection and a minimum of connectivity (USB, Ethernet) . Your computer also need to have a strong processor as compiling programs on Qsys take a lot of time.
- (Not required) A printer that makes Printed Circuit Boards ( PCB ) from Gerber files in order to shrink the circuit size + a soldering iron to put the components on the PCB.
- (Strongly Recommanded) : A good coffee to enjoy your work with our Instructable :)
Step 2: Requirements 2/3 - Components for Your Circuit
Here are the components needed for your circuit :
- Texas Instrument LM386 AB class audio amplifier
- Set of Male-Male , Male-Female cables
- LM358P Digital-to-Analoh converter ( DAC )
- Small Microphone used in analogical circuit
- A game set of resistors from 1kOhm to 220kOhm
- Capacitor 1.5nF
- Capacitor 50nF
- Capacitor 100nF
- Capacitor 100uF
- Capacitor 220uF
- x4 Capacitors 10uF
Step 3: Requirements 3/3 - Software
Last but not least , you will need software :
- Quartus 15.1: Lite version
- A C compiler ( gcc for example )
- Altium for PCB Design
Altera's SoC embedded suite to communicate with the SoC map
Step 4: Input Circuit
Let's build the circuit. Use the above picture of the circuit in order to assemble it on your breadboard. You will also see the picture of the BreadBoard and the circuit inside to see how pins are connected. The whole circuit is powered with a 5V Direct Current ( DC ) . For this, you can use a 5V battery with a USB-B converter or a function generator.
Some reminders :
- 5V power supply and the ground are connected on separate horizontal lines of the breadboard
- If you want to connect 2 components in parallel, put them in a common line of the breadboard
- If you want to connect 2 serial components, the compoments must only one pin in a common line of the breadboard.
Do not hesitate to watch dedicated tutorial on how to use a breadboard and buold a circuit on it. Also don't forget to read carefully the pin position of the LM358P Audio Amplifier ( see picture above )
Step 5: Output Circuit
Quite the same instructions as Step 4. The four inputs : SDI , not CS , SCK, not LDAC are from your DE0-Nano-Soc Board. We will see later how to generate them.
Don't forget to read carefully the pin positions of the LM386 Audio Amplifier ( see picture above )
Step 6: [OPTIONAL] Creating Printed Circuit Borad and Soldering Components
If you are lucky enough to own a Circuit Board Printer or able to use one, we are going to create our own Printed Circuit Board ( PCB ). Note that this step is optional. This step only consist to move your circuit from a breadboard to a PCB.
You'ill need these 2 GERBER files.
These files were made on Altium. Use them on your PCB printer software in order to print your PCB. Once you get your PCB, make sure your PCB is clean and that tracks are correctly printed.
Now here comes the real deal : Soldering. The 2 pictures above is the map of the circuit on the PCB. Each components have names ( R6, C4, MK1 etc. ) . Pictures in Step 4 and 5 shows the components parameters ( Resistance, conductance.. ). Place each component from your breadboard to the PCB according to their names.
Once you have soldered everything with your soldering iron, test every components with a voltmeter to check if there are any short circuit.
Step 7: SoC Setup
Concerning the SoC setup, you will need to run some commands and scripts included in the SoC embedded suite within a terminal. To do this, you will need to add some $PATH. PATH are used within a terminal to say to search for a file in the directories given by path when you are running a command. To do so, type the following command line :
Then type the command line to generate headers from a sof file. You obtain the sof file by compiling your project on Quartus. To do so , type : ./generate_header.
Step 8: Programming C HPS
We need to realize 2 things in this part, namely read read the value of the ADC and write it in the SPI.
1. Read the value of the ADC
The address of the memory in which the ADC is contained is not directly accessible, in fact the linux system present on the card sets up an abstraction of the memory. To really access the ADC address we will use the mmap function.
"h2p_lw_spi_addr=virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + SPI_0_BASE ) & ( unsigned long)( HW_REGS_MASK ) );"
This instruction allows an offset to be added at the beginning of the base address to reach the address of the memory allocated for the ADC, and to perform on the resulting address a logic AND to take into account the masking.
After that, it will only be necessary to dereference the pointer in the program to obtain its value.
2. Write the value of the ADC in the SPI
The manipulation is identical, this time we give the mmap the offset to land on the address allocated by the SPI. While writing in the SPI, the technical documentation specifies that you must write to the address + 1 the value of the adc.
" *(h2p_lw_spi_addr+1) = ((0x1 << 12) | *h2p_lw_adc_addr); "
This instruction allows you to write to the SPI. Indeed bit 4, so 1 << 12, is the bit that allows to activate the SPI. With a logical OR, we therefore give both the activation bit and the value of the ADC to the SPI.
Step 9: Digital Acquisition of the ADC From the Card
First of all, you will have to set the Ethernet IP address of your computer through Control Panel -> Network -> Card Parmesals. Select the ethernet interface of the card, property, ipv4 address and enter a fixed IP, a mask etc ...
Next, connect the card from the power jack side with the micro USB cable. Open the Quartus programmer and launch the export. This manipulation will be redone after each power off of the card.
Change the micro USB plug cable, to connect this time next to the Ethernet jack. Now, with Putty it will be necessary to connect to the card by serial link. The configuration is visible in the photos, the idea being to replace COM5 by COM followed by the number that you can find in your device manager (right click on the windows logo to open it).
Press enter, you are connected.
Info to restart project: - Fix ethernet ip corresponding to the card - Turn on the card, each time you turn on the power, it is necessary to put with "program" under quartus the project compiled in the card. This is done via the micro-USB port - To be able to display the result of the program we use more micro USB but UART - With putty configured for serial COM5 (or 6 watch gestinnaire periph) Connect to the card. - Set a password (passwd) - Set IP address ifconfig ethxx IPchoice (IP not far from that for the eth of the PC) - Generate the header according to Qsys with the terminal embedded (export PATH) - make - scp l exec in the map - execute under putty the prog
Step 10: FFT Calculation
In order to get the Fast Fourier Transform in our C program, we will use a library written by Mark Borgerding : Kiss FFT. You can download the library here : http://kissfft.sourceforge.net/ . Applying a FFT on a signal is necessary in order to modify and apply signal effects. It can also serve to display the spectrum of a signal.
First step in your C program consist to allocate memory in order to store the FFT result. The size of memory depends on the number of point used to calculate the FFT. The more you have points, the more pecise the FFT will. However, the program will run slower and will use more memory. Note that you will get two arrays from the kiss_fft function : the input and the output of the function ( cx_in and cx_out )
Once our array is filled with new FFT values, ie when r = Win - 1, we are processing the FFT. Concerning the display, we are only displaying the positive part of the spectrum, as there is a symetry between the negative part and the positive part.
Concerning the horizontal axis, we are reducing peak values by 100*height/(height²) in order to distinguish the main frequencies' peaks.
We are using the using the usleep system call in order to define a reading frequency for the ADC values. This frequency is currently set at 1,5 Hz.
Step 11: Displaying the FFT
Based on an example give on the Adafruit TFT LCD Screen available here: http://www.terasic.com/downloads/cd-rom/de0-nano-s... we have programmed the NIOS of our Board so he is able to read the ADC value.
So the ADC register is shared between the NIOS and the HPS because the ADC values will be used to display the FFT on the NIOS screen, and those same values will be written on the SPI in order to be outputted of the board and finally be converted by the DAC to get an analogic signal.
Step 12: Assembly
We are nearly done ! You will need to assemble every part of the projet ( entry circuit, output circuit and the Board ). Ensure to connect the parts to correct pins according to the Quartus Project.
- The input circuit will send the audio signal captured by the microphone, amplified, filtered and offset.
- The program C present on the card will read the values of the ADC as we have seen previously, and will write it on the SPI so that we can recover the value on the GPIO of the card.
- Then the output GPIO of the SPI will transmit the information that will be decoded by our DAC and amplified by running to reach the speaker.
Step 13: Sound Effects
The only step left are sound effects.
Availlable effects are:
- High Frequency Filter
- Low Frequency Filter
You can switch between effects thanks to a button. This button will change a variable in our C program, so it can apply the right effect.
Step 14: [OPTIONAL] Making the Helmet
Here we are in the most manual step of the project:
- First we glued the different 3D printed parts of the helmet.
- To fill the gaps between the glued pieces we added a finish using a 3D pen.
- We polished the interstices filled with the pen and the helmet more generally so that the painting holds well afterwards.
- We painted the helmet with 2 layers: The first in anthracite black, up close, and a second of primary green from further to give shades of darker green.
- Finally we printed the logo of our school on the side of the Helmet