Final Project¶
Hero Shots¶
Initial Conception¶
Spiral Development of Electronics¶
After speaking with Neil, Tom, Fagan, and Adam about the project, It seemed time to develop a roadmap of spiral development for the project.
This will allow me to break up this daunting project into managable bite-sized pieces. This roadmap is of course subject to change later on, in light of new understanding and findings.
Note: I will refer to the different stages by there given abreviations throughout my documentation. E.g O1 for Output spiral 1
Building O1 - Driving a Bone Conduction Transducer¶
First I set about driving the BC transducer in any shape or way possible. This process is documented here, as a part of Output Devices week.
Building I1 - Receiving microphone Signal with Arduino¶
My first experiences getting a microphone to work can be found here, as a part of Input Devices week.
Building I2 to receive microphone Signal with ATTINY¶
I then attempted the simplest possible circuit using an ATTINY chip, documentation found here.
Building Int1 - combining O1 and I1 on Arduino¶
Having gotten the microphone to register with Arduino and the speaker to play music, it is time to integrate the two into one circuit. Ideally, playing the microphone input through the speaker for starters. I tried this both with the 412 board and the Arduino, and achieved similar results.
I got similar results with Arduino, first using datasheet commands and then trying the simplest possible code imaginable.
int incomingAudio;
int NormalizedAudio;
void setup(){
Serial.begin(9600);
}
void loop(){
incomingAudio = analogRead(A0);//read input from A0 to a 10-bit value between 0 and 1023
//do stuff with the variable "incomingAudio"
NormalizedAudio = (incomingAudio*0.25); //prepare value for analogWrite which is 8-bit and between 0 and 255
//Serial.println(0);
Serial.println(NormalizedAudio);
//Serial.println(6);
analogWrite(3, NormalizedAudio);
}
Here were the results,
So now I’ve made a noisemaker with a mic and speaker 3 different ways, but nothing beyond static. I have two good theories as to what is occuring.
- I need to use a DAC before attempting to output the signal. This would be possible with a resistor ladder (arduino) as in this example or using the onboard DAC (412) with Pulse code modulation (PCM) as described in this article.
- I don’t think analogWrite() is setup to be used as I’m using it.
- To reduce background static, I need to op-amp high and low pass filters.
Building Int4 - AVR chip¶
If you follow along the documentation from Inputs week, you will see that I was able to spirally develop concepts and circuits until I produced an integrated circuit which fufills Int4 on the spiral development map. That is to say, an integrated circuit with microphone input, BC transducer for output, and an AVR chip for digital signal processing and the inversion of the signal.
This completes the original spiral development map outlined above. Certain steps were skipped over because they became less relevant as deeper spirals became feasible. E.g, Int3 was omitted since Int4 proved that the inverted DAC output signal and the microphone Output signal were relatively in-phase (see pic above).
Next step will be to produce a new spiral development map that guides next steps.
New Spiral Dev. Maps¶
Having completed my I/O board (Int4) to satisfy Inputs and Outputs week, it was time to develop a new Spiral Development road map. I split it into 3 main categories.
- Hardware (Hn) - Attempting to build out the headset
- Active Noise Cancelation (ANCn) - Attempting to actively cancel incoming disturbances
- Music (Mn) - Attempting to play music through the headphones overtop of the cancelation signals
Note, these maps as well as all of my spiral development maps evolve as I learn and my priorities change. As such, you may notice that these maps are referenced later on but have different steps listed.
Hardware¶
For a while, I was hoping to create a device that could simply interface with my existing bluetooth BC headphones. Neil cautioned this idea due to the lag that would be inevitable with bluetooth. So it would be necessary to build new bone conducting headphones from scratch, where the ANC could be processed within the same hardware as the sound is output.
While working with Dr. Adam Harris, we discovered bone conducting transducers are not such an uncommon component afterall, and creating such headphones should not be very difficult. Much to my suprise, even Adafruit has an offering and related tutorial. This 3D printed housing and tutorial will offer me a great headstart. Better yet, I found a GrabCAD user Josh Chang had created an aesthetic to-scale CAD model for this exact transducer. I will be careful to verify these dimensions once I have the transducer in hand, but still, what luck!
H1 - Cover Production and results¶
From these resources, I was able to begin designing a covering for the transducer to be molded out of rubber. Progress and results of that process can be found on my page for week 09, molding and casting.
This molding/casting project was definitely a success. However the BC transducer is behaving unexpectedly now that it is pressed up against a hard cover. It seems that I’ve given it a woofer to project sound from. In theory, we want the skull to be that woofer, not the cover. So not only does this reduce transmission to the skull, it increases noise leakage to the ambient environment. Per Fagan’s advice, I will compare the 3 materials I molded on 4 metrics using a decision matrix.
- Sound transmission
- Noise leakage
- Robustness
- Comfort
Unfortunately, as I was beginning to run these tests, I noticed that one of the wires for the transducer had ripped off. Worse yet, it had actually ripped a trace off of the little breakout board. Luckily, the board had another solder joint where the speaker coil connected. Therefore, here is my shotty temporary fix connecting to that secondary solder joint. Additionally, I replaced the wire with thicker gauge wire.
Then came time to run the quality tests. Note, these tests were quite subjective and therefore will only be treated as a guide.
The big suprise of these tests were how much noise leakage I was getting from the covers. The other suprise was that the softest material, Moldstar 31T, did not exhibit this leakage as bad. The noise leakage to sound transmission trade-off on the hard materials (Smooth-Cast) is really bad and almost makes them nonstarters. Hence the high weight placed on these two characteristics. The results of this test makes me want to explore more soft materials and other silicone options in the Smooth-on family. If I could find a material with the noise properties of 31T, but with better robustness and equal comfort levels, then I think we’d have a winner. As it stands, the 31T has already torn in one area and does not feel like it would last long, making it a non-starter.
I have a theory as to why the soft material had less leakage than the hards. I think it was flexible enough such that it was not pressed against the transducer until the entire assembly was pressed against the head. Therefore, the transducer has ‘room to breathe’ when not in-use. The next question might be, how much noise leakage does each option exhbit once it is pressed against the head, because that is the more important property.
The other variable which I have not yet played with is thickness. Specifically, I could thin out the section in front of the transducing element and see if the characteristics change for the better. One way I might acheive this without adjusting the mold is via sanding.
As you can see, the cover production/results fulfills the H1 spiral, but the performance of the speaker was negatively affected by the cover. Therefore, H2 will be an attempt to modify the molded pieces and/or the mold itself such that the metal component of the transducer can poke through the cover. The hope is that with such a setup, the headphones will get the best of both worlds. A bare metal connection to the cheek bone for optimal conduction while surrounded in a silicone material for optimized comfort.
H2 - cover modification¶
First I had to make sure that it was possible to modify the existing covers. I wasn’t positive there was enough material there to hold in the transducer, once I had removed the necessary material. Taking a look back in a split-view in CAD, it does seem that even after removing the lower section, there will be a sufficient lip to retain the transducer face.
By slicing the body along that plane, we can get an idea of what it will look like,
Then, by carefully taking a razor blade, sand-paper, and rounded file, I was able to get these results.
Looks great and all, but how does it perform?
Perhaps the best option yet! Best of both worlds if you will. And thats with the 65-D material, which was the lowest rated material originally. I think the results would only improve from here. Time permitting, I will modify or reproduce the mold to produce this new geometry, and try it with the Smooth-Cast 300 or other hard materials. I think the Mold-star 31T is too soft to retain the transducer in this setup.
Revisiting the hardware spiral dev. map, this fufills H2. I’ve also added H6, to revisit the molding, should time allow it.
Building H3 - Headstrap¶
By this point, for simplicities’ sake, I had decided to create a mono headset with output on only one side of the head. This decision was made for a few reasons,
- Disturbance signal will be sent into the back molars and primarily propogate to one side or the other for the purposes of this prototype
- LM386 speaker amp is designed for mono output
- adjusting delay for both sides of the head really increases the complexity.
As such, I started looking at one-sided headphones for inspiration. This is not a novel problem and to treat it as one would be a mistake. Looking around the house, I found the perfect piece of inspiration. Our old Xbox headset is nearly exactly what I was picturing. Also, seeing as how it was already broken, it’s just asking for a teardown.
I only see a few issues with a design like this.
- The overhead strap relies on its flexibility to fit around the head. This is a clever design because it allows for multiple head sizes while minimizing the need for multiple adjustable joints. That said, it relies on its flexibility which might prove difficult with the tools/materials we have available.
- This form factor packs all-of-the electronics into the earpiece on one-side. In my case, this could become overly bulky and weighty. For instance, my design will more than likely incorporate a 9V battery. This might make the most since on top of the head or as a counterbalance to the main electronic package. Even still, this leads to problem #3.
- The adjustable joint on these is great, but feeding electronics through it may prove difficult. One option may be to widen the pieces and make them hollow such that flexible wires can feed through them, similar to this design by SONY. That said, this will require using the right amount of wire to provide slack, while avoiding pinching the wire. A teardown of such headphones may also be useful to understand how they account for this issue.
Upon closer inspection, it’s even more clever than I first realized. The head strap slides in and out of the headpiece to adjust for different headsizes. It uses a rack-pinion type lock to lock this position into discrete levels of adjustment, which relies on a small compliant pinion to overcome these hills/valleys. Another compliant piece runs into the end-stop to stop the slider and opening of the headstrap. The compliance of this piece appears to be a D.F.A (Design for Assembly) technique, because the two pieces can be pulled apart (as pictured) when this piece is compressed. Finally, a hard-end stop constrains the slider to stop the closing of the headstrap.
While super clever, I am worried that the compliant mechanisms are a bit precise for my needs. I can always add them in future spirals as needed. For now, I will rely on friction to hold the position of the headphones. Additionally, I will add a third removable piece to trap the knub in, rather than a compliant mechanism.
Some help from GrabCAD
A few hours into this design, I realized I was starting to hate it.
Not only were the industrial design aspects going poorly, but the electronics were not even close to fitting where I had hoped they would. For one thing, the potentiometers I purchased were huge and take up the majority of the speaker box. This would mean most of the electronics need to go up in the headstrap. Routing the wires between the two while leaving it adjustable is also a problem. The one thing I like about this design is the adjustment method that was modeled after the Xbox headset. At this point, I realized it was time I go back to the drawing board to discover what I’d like to create before spending too much time in CAD. CAD is great, but not a great place to fail fast and iterate. Here is that progression.
I like this concept, but I’m not sure the current adjustment method will do a good job of keeping the transducer flush against the cheekbone.
I then had a good discussion with Dr. Fagan about it. He wasn’t sure that the above concept would restrict enough degrees of freedom. We then began talking about an ear strap to keep the device secured against the extra degrees of freedom. Later on, this actually reminded me of a very old concept I had long since written off. Why not build the device right into a pair of sunglasses? Afterall, people already where sunglasses at the dentist. Better yet, this should solve the degrees of freedom issue in question. I have updated this concept to include a snapshot of what the internals could look like.
Adam Harris recommended 4 AAA batteries rather than a 9V, for any application that draws significant power. I believe these could quite easily be built into the arms of the glasses.
Next, I will find a pair of glasses to purchase, remove the arms and reverse engineer them.
Building H3 Again - Glasses shaped circuit boards¶
See section ANC8.
Building H4 - Printed case design¶
Its worth mentioning that this entire mechanical design process occurred in the 3 days preceding the presentation. This clamshell was designed on the second of those two days and printed on the last day.
By this point, I had milled and stuffed the glasses shaped circuit boards and purchased a pair of sunglasses to reverse engineer. I was able to export the CAD files from KiCAD as step and import than into Fusion. It seems I had never connected the footprints of the components to CAD files, so I was only able to import the shape of the board. This was quickly remedied by mocking up the shapes of the larger components. Additionally, some components such as the Wemos D1 mini were easily found on GrabCad and imported into the model. I went ahead and modeled all the components on one board, thinking that the shell should accommodate both boards. Here is a picture of that model.
Additionally, I took some reference images of the sunglasses and loaded them into Fusion360 on the respective planes.
Between this model and these reference images, I had everything I needed to begin designing the shell.
This first spiral was a test of the general shape and attachment to the circuit board and glasses. This piece was FDM 3D printed
It was a suprising success. The shape of the profile was nearly spot on. Additionally, the attachment to the glasses was perfect and did not need changing. On the other hand, the attachment of the circuit board would need to be redesigned.
With this new spiral in-hand and seemingly fitting on my head, I was able to take additional reference images that would aid in the next spiral.
Next, it was time to make the piece a bit more ergonomic and less flat. This was done mostly parametrically with 1 surface used to cut a complex curve into the form.
Then I turned my attention to modeling the clamshell that would cover the boards and house the components. The clear option to design this would be surface modeling. That said, all of my surface modeling experience to-date was in Solidworks, and I simultaneously nervous to try and learn a new tool at this point. Luckily, I quickly found out that the surface modeling in Fusion 360 was very similar to that in Solidworks, albeit simpler. Even still, it is surface modeling, which is a difficult time-intensive process I’m still getting the hang of. I started by creating a 3D spline that I wanted the profile to follow. Then I created a series of planes and splines at each major junction of the original profile piece. Each of these splines collided with the original 3D spline, which was projected using the intersect command. With these splines created, I then lofted surfaces between them, using the FDM profile as guide rails. I slowly worked my way towards the back of the glasses. I had the most difficulty at the ends, because suddenly the “rectangular” sections converged to a “triangular” end-point. I’ve learned that surfaces must have 4 sides to them and triangles are notoriously problematic in surface modeling. Due to time constraints, I decided to leave the ends open.
I had some trouble when it came time to stitch these surfaces together and thicken them. Specifically, the thicken command seemed to work for the individual surfaces but not when they were stitched together. In hindsight, I think I realized that these surfaces were lacking tangency and curvature constraints at the interfaces, which would’ve made for a more seamless stitched surface and perhaps less issues when trying to thicken. Oh well, perhaps a fix for a future spiral. I was able to eventually get it to work by thickening the individual surfaces and using combine to join them parametrically.
I hastily added some clamshell tabs so that the piece would grab on to the FDM inner piece. Design for printability was a focus here, I did not want to add any features to either piece that would struggle to print. I added some tolerance so that these tabs could move left-right, but none in the up-down direction. This was with hopes that the clamshell would somewhat grab onto the FDM piece.
This resulted in mixed success, which I will address further down after the pieces were printed.
Additionally, I attempted to add some mounting posts for the circuit boards to mount to.
These posts failed to print completely. Additionally, in hindsight, this was a bad design. These posts should’ve come from the FDM ‘flat’ side rather than the complex curved clam-shell side.
I was trying a new slicer that had been recommended to me, Slicer. I found this slicer much more usable and friendly than the Photon workshop.
It wasn’t until I was slicing the model that I noticed hairline cracks all around the model. In hindsight, I believe this was a result of my thicken method and lack of tangency between the surfaces.
It wasn’t until I saw it on video that this was very apparent. With only one day to go, there was no time fix the issue. So there was a little more crossing of fingers than I’d care to admit.
Anyhow, with one day to go, my Anycubic resin printer came in clutch.
What a beautiful sight to wake up to in the morning.
These pieces cured in about 1 hour each and were ready for final assembly. See assembly section. But first, here’s a bonus picture. I thought it was cool how the supports remained intact on this second piece. I found in some ways, that these were actually more easily removed by hand than by using handtools.
Building H5 - Headstrap/connectors¶
During ANC7 and ANC8, I was attempting to connect the two boards with a ribbon connector that also served as a headstrap. I used vertical surface mount headers to interface with the connectors. I found it easiest to use the connector itself as a jig to space the pins correctly while soldering. The legs needed to be cut short for this to work. I proved all of this out with ANC7.
With ANC8, I needed to redesign the layout such that there would be no twists and turns in the connector. I confirmed with a conductivity test that the top-left position correlated to the top-left position, bottom-right <-> bottom-right, etc. Here are the final layouts for the connectors.
Interestingly, I think this is a big reason why my controls board design (1 jumper) turned out to be a far better design than the audio board (5 jumpers). This is because when designing the first board, I had the freedom to rearrange these traces as needed. That said, the positions were fixed by the time I was working on the audio board, which made for a tougher design process.
Building H6 - Remolding the covers¶
Luckily, remolding the speaker covers was uneventful. Per the findings in earlier spirals, I used Mold Star 300 and white dye for the new coverings. I did not have time to adjust the mold design, so cutting the hole in the part and sanding it down as still done as during post-processing. During this remolding process, the 2nd piece broke while taking it out of the mold. Therefore, I decided to continue using the original molded cover which was beige. This was quickly remedied with some white spray paint. For pictures of the results, see the hero shots section.
With that, I consider the hardware tree of spirals to be complete.
Active Noise Cancelation¶
This is the core of my project. Therefore, it is very important that I can prove ANC before spending too much time on other aspects of the design such as hardware and music. Without ANC, the project simply becomes a pair of bone conducting headphones… significantly less cool.
Building ANC1 - Achieving clean results with IO Board¶
Perhaps this would be better called ANC0. Before I can begin work on active noise cancelation, I have to prove that my I/O (Int4) board can produce intelligible output. So far everything looks good on the scope, but the output from the transducer is still messy. Follow this progress on my outputs week page here. It turned out to be an issue with the voltage regulator providing Vin for the microphone. With this issue solved, ANC1 is effectively complete.
Building ANC2 - MVP ANC¶
Per Adam Harris’ suggestion, it now makes sense to try to build an MVP ANC setup. He suggested trying to cancel a known signal coming from a known speaker. Therefore, I will attempt to output an analog signal from one speaker and an inverted DAC output signal from another. Then I can position them in various ways in 3D space to see how/if cancelation occurs.
To this, I decided to replace mic input with aux input. This would allow me to drive one speaker straight from the aux chord and another from the MCU DAC output to try and cancel the original sound. In other words, this would allow me to try and cancel a known entity played through aux. Before that, I wanted to confirm I could drive the two speakers using 2 mono pre-amps, connected to the one AUX output.
This indeed worked fine, so next I attempted to drop the MCU in between the aux and one of the pre-amps, to create the signal inversion. However, upon doing that, this speaker was playing strange audio. Taking a closer look, I noticed an interesting error on the scope.
The bottom half of the wave was being cut off before the signal was coming out.I suspected this was because the Aux signal was +/- 2.5V whereas the MCU can only handle positive Voltages, such as 0-5V. With a little research, I found I needed to create a level-shifting Op-Amp circuit in order to turn this signal into one that the MCU can handle. I followed this guide here to build the noninverting level-shifting circuit suggested by user stevenvh, using our labs LM358N Op-Amps. This worked beautifully.
At this point, Avery mentioned I should consider creating the inversion in hardware rather than software. This could be beneficial because the hardware version should be lossless and instantaneous. Therefore, I quickly adjusted the circuit to be an inverting level-shifting one. Here are the results of the different methods.
The middle and left panels are scoping the same circuit at different points (before and after the MCU). Clearly the DAC is distorting the signal to some extent. That said, pay less attention to the change in Amplitude, since I believe that has to do with reference voltages. More important is the shape of the wave being distorted. By this point, I was using a known 120 HZ signal on youtube.
So with the hardware inversion, here is my synopsis,
So since I wasn’t getting the noise cancelation I had hoped for, Avery urged me to go simpler. Let’s try going back to the Aux + 2 pre-amps + 2 speakers setup and simply feed one of the lines through a zero-gain non-level-shifting Op-Amp circuit. Following this guide, I attempted to build this circuit. However, this took me some time to dial in. I was getting very weird results until I made the following connections
- Aux Ground <-> OP-AMP+
- Aux Output (scoped in yellow) <-> 10k Resistor <-> OP-AMP-
- +Vcc <-> +2.5V supply
- -Vcc <-> -2.5V supply
- OP-AMP Out (scoped in blue) <-> 10k Resistor <-> OP-AMP-
The tough realization was that my power supply needed to be +/- 2.5V instead of 0-5V. Luckily the analog discovery kit made this easy. Here are the results with the simple 120 Hz Sine wave.
Now to add in the speakers.
After this mixed success, I decided to go even simpler.
Building ANC1.5 - Active Voltage Cancelation¶
Since I am having trouble canceling soundwaves, I will take a step back and attempt to do Active voltage cancelation using 1 speaker as output. If I get it right, the speaker should output no sound or just the base-level noise, despite being fed a combination of two input signals.
The thinking was simple. Simply take the incoming wave and split it into two parallel tracks. Invert the signal on one of those tracks before summing them together. And my process for building these circuits is continually evolving. This time, due to the complexity, I decided to draw the circuit diagram first.
Below, you can see the first signal in blue and the signal intended to be inverted in yellow.
As you can see, the Op-Amp seems to be unable to process the negative voltages coming from the aux input. This is a similar result to as before, and I remembered that I would need a level-shifting amplifier as well. Before I made any changes, I wanted to check if separating the grounds would have an effect. In other words, this first circuit had all grounds connected to one ground. I then tried separating the power-supply ground from the rest of the grounds. In other words, the op-amps were now powered between 5V and GND1, whereas the ground being used in the actual circuit was now coming from the aux cable sleeve. This did not solve the negative voltage issue, but did lead to different and interesting results.
To resolve the negative voltage issue, I added on a third, level-shifting op-amp circuit using one of the two op-amps since each technically has 2 integrated op-amp circuits. The idea was to raise the incoming signal by 2.5V to shift it between 0 and 5V, before the inversion/sum circuits.
Where,
The results seem close, but no cigar. I set about scoping the circuit before and after each op-amp. It seems the level-shifting op-amp was working as intended.
However, I have not been able to get a good reading before and after the inverting op-amp circuit. Specifically V,out,A (in yellow below) is not showing a sign wave even though I would expect it to be the same sine wave but simply inverted. Perhaps using both sides of the Op-Amp could be creating interference? After some troubleshooting, still no luck.
For time sake, I will need to move on…
Building a Test Stand for ANC2¶
Even though the previous example didn’t work perfectly, it was time to move back to attempting to cancel actual sound waves. Again using two speakers, I planned to try to create destructive interference at a point. This time, after talking to Dr. Fagan, I decided to get a bit more scientific about it. Therefore, I’m building a quick test-stage to control the location of the speakers and place a microphone directly in between them.
By mounting all 3 elements to a rail, I can play around with the location of all 3 elements while keeping them aligned. Luckily, we had some left over aluminum extrusion from the Ender 3 we salvaged, and I was able to pull the CAD file accordingly. Additionally, I found Eagle files available for the microphone I am using. This was my first experience using eagle so it was overwhelming at first. Luckily, I quickly found the button I was looking for, Push to 3D PCB which helped me generate a usable 3D CAD model.
Here is the first iteration design for the test stand, where the stands are 3D printed and held down with 3D printed T-nuts.
Building ANC 2 - MVP noise cancelation¶
Then I set about giving another go at building ANC 2. That is, a minimum viable product noise cancelation to prove its possible. The plan was to play a known wave through one speaker, send that same wave through my I/O board (built during inputs/outputs week) to invert it, send that signal through another speaker, and try to have them both sound waves converge on a microphone. All good in theory, but I quickly started noticing some strange results.
At first, I couldn’t get the sound wave to register on the microphone. I started to get very worried that the electret microphone was super directional an unable to pick up the sound waves coming from other side. However, this issue resolved itself at higher frequencies. I believe the issue was that the 1st attempt was with a super low frequency wave (20 hz) that was likely below the cutoff frequency for the microphone module. A quick glance at the datasheet confirms the operating frequency range is 20 ~ 20,000 hz.
If only this were the only issue. When I started running one speaker and measuring the output on the mic, I started getting very unexpected results. Even across a few different tests, I was unable to measure a perfect sine wave coming from this speaker. I verified that a perfect sine wave is what I should expect by using a tuning fork app and holding it directly up to the mic, which did produce a clean sine wave.
At this point, I’m starting to get worried that I misunderstand how sound works completely. Does a perfect sine voltage not produce a perfect sine sound wave?! In reality, this should have been my first sign that something wasn’t right about this speaker/amp set up. I then tried feeding the same signal through the 1614 IO board. This seemed to be producing much cleaner output. So it was unrelated to the incoming/outgoing signal because when I swapped speaker/amps and the issue seemed to follow one of the speaker/amps… Now to swap amps and the issue seemed isolated to one of the speakers.
And that’s when it hit me. Maybe I should’ve paid a bit more attention to the words “busted” written in sharpie on one of the speakers a few days prior. At this point, I realized there was literally a hole in one of the woofers and I threw my hands up.
All in all this is good news. It means my mic isn’t overly directional, my test stand should work, and the physics of sound work more or less how I understood them. I simply need to grab another speaker and try again soon.
The next day, working with 2 intact speakers, I had some luck! This setup uses the waveform generator to send a 232 Hz wave out one speaker. The same signal is inverted by the DAC on the AVR 1614 and sent out the other speaker (in yellow). Both are detected by the microphone (in blue). Here was my first sign of true noise cancelation.
66% is a good start, but I wanted to do better. I noticed the top portion of the DAC wave was being chopped off. So I was able to improve upon these results by reducing the offset of the incoming wave such that it fell entirely within the range of the DAC.
75% cancelation. If I can get that happening in someone’s ear canal, I will be more than happy!
Building ANC3 - Tuning¶
This spiral assumed that I would need a delay signal to improve the cancelation. As it stands, with the two speakers equidistant from the microphone, and the AVR chip processing the signal very quickly, it seems that a delay is not necessary. I confirmed that the waves were in time by scoping the incoming signal next to the DAC output. In the top pane, I abruptly paused the incoming signal, which shows that the two are effectively in lockstep (but inverted of course). In the bottom panel, a more complex signal seems to confirm this.
So building in a delay does not seem necessary to get a base level of noise cancelation. That said, it is still possible that it will improve it. Additionally, adding in a delay will be useful for accounting for placing the speakers at two different differences. This will all be useful for the final result, where the microphone and transducer are very different distances from the ear canal. This will be my focus for ANC5. For now, here is an update to my spiral development map.
Building ANC4 - Testing ANC2 on more complex signals¶
I wanted to replace the waveform generator with something more real. So I setup the aux chord breakout board to be the incoming signal. However, I quickly realized that this wave was getting chopped off (because it includes negative voltages). Therefore, I wired in the same level shifting op-amp circuit used in ANC 1.5 to shift the Vin up by 2.5V.
Building ANC5 - Adding a Delay¶
Next up, it was time to try and add a delay function to the DAC output signal to be able to tune the noise cancelation for different distances and mediums. After talking to Adam Harris and Adam Durrett, I had gathered two ideas on how to build this. In either event, I gathered that blocking code would be bad practice here, because we don’t want to slow down the signal processing or get in the way of other chip functions. Adam Durrett recommended using the system clock and potentially interrupts, to avoid using the Arduino delay() function, which is technically blocking code.
On the other hand, Adam Harris recommended using a sample buffer array (e.g. 50 samples stored in a pointer array) and simply offsetting the read/writing to that buffer by a certain number of samples. For instance, while writing into position 25, the program my be reading from position 1. This would allow for a delay of 25*sample Period. However, for this to work, it would be important that the sample period and rate remain constant. I do not believe my current code is setup that way. I must test to see if this sampling rate is constant. The only challenge here is analogous to the Heisenberg principle. Whatever method used to read the sampling rate, should not drastically effect the sampling rate. Adam Harris suggested flipping a separate pin every single reading, and scoping that pin. I was able to quickly set this up, borrowing from Neil’s code here.
pinMode(3, OUTPUT);
//toggle a pin to read how many readings/sec
if (digitalRead(3))
digitalWrite(3,LOW);
else
digitalWrite(3,HIGH);
Using the Analog Discovery kit, I was able to scope pin 3 (PA7) with a few different input sources.
As expected, the sample rate seems to vary based on different input signals. If I go with the buffer method, this brings an additional challenge whereby I need to accurately quantify the sample period so that I can know a delay of x samples corresponds to a time delay of y microseconds.
The rest of this development can be found as a part of week 15, for interfacing and applications week.
Eventually, I was able to achieve ANC with a delay.
This result was exciting and more than enough to satisfy my ANC5 sprial. I can now tune the cancelation to account for variable distance between the disturbance and the cancelation wave. To do this, I followed a process that I found in this Army Research report. The process is to first equalize the volume between the speakers one at a time, and then adjust the delay until cancelation occurs. This first step is important because without equal volume, near complete cancelation is not possible. Additionally, it is important to note that we mean subjective volume, as seen by the microphone, rather than objective ambient volume. In later spirals, this subjective volume will be interpreted and set by the user.
Building ANC6 - Replacing known signal with mic.¶
Next step in the spiral development map is to replace the disturbance speaker with a microphone taking in an external disturbance. I have decided to focus on a known signal first. See the development of a mock-drill/function generator (Spiral D2).
Building ANC7 - Test bed for final circuit¶
Next, I will attempt to build the entire circuit off of the breadboard. This will not be the final form factor. Layout optimization will come in a future spiral. For now, I will focus on creating the correct hookups and board designs. Once again, here is the circuit I will be formalizing.
I began by modifying the ANC5 circuit in KiCad. This mostly involved swapping out connector types and adding a few components. A big addition is the addition of batteries, power switch, and 5V regulator. For the batteries, I plan to use this component we have in the lab, 55K-ND clip battery AAA SMD holder. That product page contains a drawing which allowed me to draw a custom footprint in KiCad.
Here are the completed KiCad circuits.
And the milled/stuffed boards,
The only issues I had milling these out were with the size of the board and the op-amp. Originally, the X-dimension of these boards were too large for the machine (>127 mm). This was an easy fix. After milling however, I noticed that the holes for the summing op-amp had not milled properly. After checking the design, I realized these holes were drawn to 0.7 mm, which was too small for the 1/32nd bit to drill out. Therefore, these features were ignored. No fear, I was able to rig the through-hole op-amp to be surface mounted for now.
These boards taught me a lot. Firstly, the core design of the boards was sound. The connector element (and headstrap), worked as intended and allowed the boards to transfer power, signal, and controls (over I2C). Secondly, the summing op-amp seemed to be working well and combined the DAC output with the Wifi Radio nicely. Speaking of the WiFi radio, I mounted it to the back of the controls board for this spiral. I think this would sandwich the radio between the copper board and the users head, which could hurt the signal. For the final spiral, I will move this to the outside of the copper board.
I also learned a good lesson with this spiral related to the batteries. My “power switch” was not actually a power switch. The off position connected the hot end of the battery stack to ground. This of course, shorts the hot end of the battery stack to the cold end. This was noticed because the batteries began getting very hot, very quickly. And they seemed to be quickly drained. Luckily, the chips were undamaged and it was only the batteries that were ruined. I resolved this by cutting the trace to ground with a razor blade and updating the schematic for the future.
All told, this spiral taught me everything I needed in order to build the final circuit boards, ANC8/H3.
Building ANC8 - Glasses shaped¶
This spiral involved building ANC7 boards into roughly the shape of glasses. The controls board is much more-dense with components, so I decided to begin there. I would then take the shape of this board, flip it horizontally, and design the audio components within that same footprint. I began by laying out the components for the controls board, next to the arm of the glasses I had decided to reverse engineer.
It was starting to feel like a tall order. I decided to stack the ESP module over top of the 1614 board and headers for better density. One point I was stubborn on was keeping my anodized aluminum knobs, despite their obnoxious size.
With this spiral, I put an emphasis on taking out any twists/turns in the ribbon connector/headstrap. See H5 on this point.
For designing the 2nd of these two boards, I was able to copy/paste the 1st board into KiCad to use as reference material. Additionally, it was useful to “group” these components together so that they could be manipulated as one. This made designing the 2nd board much easier. However, it was much more difficult design despite there being fewer components. See H5 on this point.
Here are the finish ANC8 circuit designs.
And here are the milled and stuffed boards.
I have yet to run these boards off of battery power, for fear of frying components.
The way the ESP module was attached seemed good were it not for two complications. The feather stacking headers positioned the board too high off of the original board. In future spirals I will try to get these two more flush. Additionally, at the last minute, I removed the black pieces off of the backside of the headers and attempted to snip off the backside of the headers using wire cutters. I believe this stress caused the solder joints and traces to rip off of the front side. As such, the WiFi radio is currently out of commision on this current iteration. These issues will be addressed in an eventual ADC9.
Until then, I consider the hardware tree of spirals to be complete.
Music¶
Since these are intended to be headphones for the user to play music of their choosing, a secondary input is needed. This needs to be combined with the cancelation signals such that the final result will simply be music. So theoretically,
Disturbances - Cancelation + Music = > Music
Building M1 - Aux port¶
The simplest possible way to add music will be to use the aux port module I’ve been occasionally using to test my I/O circuits. I believe I will need to create a summing amplifier to combine this signal with that of the cancelation signals, before sending both to the speaker. Depending on time, I may skip this step in favor of jumping straight to M2 to fufill the assignment for Network/Comms. week. After running through the experimentation with ANC1/2, I believe this step will be somewhat trivial to build using the aux module and a summing op-amp circuit to sum it with the DAC output.
Building M2/M3 - WiFi Radio¶
For sake of time, I would like to begin playing with Wireless. This progress will be documented here, as a part of Network and Communications week.
I was able to get an MVP WiFi radio running pretty quickly on the ESP8266 Node MCU module. Evetually, I will try to switch over to a smaller package such as an ESP8266-01 module (see spiral M6).
Building M4 - Connecting ESP to ANC5 board¶
Now that the WiFi Radio is up and running, I would like to connect it with the output coming from my I/O ATTINY board (ANC5). I found out during networking week that connecting ESP to ATTINY over I2C is difficult. Additionally, I’m unsure that I2C could handle the data rate necessary for WAV files. Perhaps I2S is the answer? For the sake of time, I am going to build what I know how, which is a summing op-amp circuit to sum the two signals into one. So first, I wanted to check the magnitude of the two signals I am summing. That is, the output of the I/O board when the mic is used as the input, in other words the inverted DAC output, is to be summed with the output of the ESP8266 WiFi radio.
It appears that both are on a 0 to 3.3V scale, which is good. That said, the magnitude of the music is smaller than that of the I/O board. This summing op-amp also may be a good opportunity to adjust the relative gain. This brings up a good point, which features do I need this circuit to have:
- low noise non-inverting summing op-amp circuit such that both signals output of the same speaker
- ability to adjust relative volume of two signals
- ability to cut the music without affecting volume of I/O signal
So to build a non-inverting summing op-amp circuit, I will be following the schematic here. Noting that the output voltage has the potential to be double the inputs, further signal conditioning may be necessary before sending the signal to the speaker, which is still expecting 0 to 3.3V. In practice, I found it best to power the op-amp off of the 5V and ground coming from the I/O chip, which itself was being powered from an Arduino. Here is the circuit I eventually drew.
This initial try did not work. It seems that the waveforms are getting chopped off near the top. Instead, I will now try what is suggested here, which is to build the inverting summing op-amp followed by another inverting op-amp. This version did not work because it seemed that the inverting amplifier wished to invert the signal about zero. This resulted in clipping issues.
Finally, returning to the original plan, I was able to get the non-inverting summing op-amp circuit to work. Here are the results,
Next, I will attempt to add a switch that allows the music signal to be turned on and off. Ideally, this would be done with something other than a kill-switch so that the music quickly resumed when desired. With a kill switch, the ESP would need to boot up and reconnect to WiFi. I determined the easiest way to do this might be to bypass the op-amp circuit entirely using a switch. The only issue here is that the voltage of the microphone then doubles. Therefore, I will add a voltage divider to the bypass path, that halves the voltage of the microphone. This should keep the microphone output line between 0 and 1.65V regardless of the position of the switch. The speaker pre-amp can then be used to amplify as needed.
As mentioned in the video, this did not operate as intended. The voltage divider correctly cut the voltage in half, but also shifted it it downward. I then went down a rabbit hole of trying to level-shift that value back upward.
Somewhere along the way, I discovered that the resistor Rf was not the value I thought it was. This explains something that has been subconsciously puzzling me the entire time. I had expected the original Summing op-amp circuit to produce an overall gain of 2. Instead, it seemed to cut each signal in half, in effect having no gain. This happy little accident of a resistor explains the phenomenon. Since the gain equation is as follows,
and Rf was much smaller, it explains a negligible gain. I replaced this resistor with a wire and achieved similar results. I wonder if I put the correct 10K resistor in its place, and then divide the output voltage by two using a voltage divider, will my signal be correct.
Nope. It seems the signal is clipped before I can bring it to the right scale. Ok, how about if I halve each signal with a voltage divider before sending it through the summing circuit.
This resulted in results all centered about 1.65V, but the microphone amplitude was double when isolated as compared to when it goes through the op-amp. Next I tried adding a voltage divider on that bypass line as well. This brought the signal to the right scale, but now offset incorrectly. (centered around 0.825 mV). It seems I am struggling having the mic signal come through with the same amplitude and offset.
Finally, I found my answers. While searching forumns, I stumbled upon this great op-amp calculator at earmark.net. You give it the desired inputs and outputs, and it tells you the sort of op-amp circuit you need. Here is what I took from it.
This circuit would go into the “bypass circuit”. Again, the goal is to retain the characteristics of the mic. output, regardless if the music is on or not. Therefore, here is my complete circuit and relevant values.
You will see that I removed the voltage dividers and made Rf = 0, since these elements canceled eachothers effects out. So now, the switch essentially selects which op-amp circuite we are reading from. And here are the successful results!
As you can see, the magnitude and offset of the mic signal is not affected, regardless of the mode. Theoretically, this will allow the user to first set the volume ande delay of the cancelation signal, and then choose to turn music on/off without affecting that original volume. Now its time to take a look back at the music column of my spiral dev. map, and making some updates to it.
As you can see, by combining M3 with the I/O board, this neatly fufills M4. Next, will be to define and add volume controls, transfer the radio code over to a smaller ESP8266-01 board, and formalize everything into KiCAD for production.
Building M5 - Adding volume control¶
Of the many options for volume control I have available, I hoped to control volume of the cancelation signal in a very similar method as I control the delay function. That is with a potentiometer connected to a separate analog pin. This has a few major advantages,
- Code is easier to change later on than analog circuitry
- Delay function is proven
- I can even use my existing ANC5 board to prove out the new function
However, I pretty quickly realized that I have already used up the two ADC instances available to me with the 1614 chip. Oh well, I guess I’ll simply add a potentiometer to the line anyway. And man I’m sorta glad that was the case because adding an in-line potentiometer sure was easy. I loosely followed the instructions here.
Using what I had on hand, 100k potentiometer and a 1 uF capacitor produced clean results at minimum and max. volume, but very noisey results from the mid-low volume ranges. See results below.
This noise seems to occur with or without the capacitors. The article mentions that the capacitor leaving the potentiometer is useful as a D.C. blocking capacitor. I’m not sure about the second capacitor’s function. There is some debate whether its needed on this thread here. For now, I will label it C?. Both capacitors are 1 uF for now. My next step will be to try a 10k potentiometer instead of a 100k, per the advice of the above link. I have to wait for the 10k Pot to come in the mail, but the theory was pretty easily checked with a simple voltage divider, using one 5k and one 10k resistor.
Not easily seen in these pictures, but the noise is certainly less than with the 100k pot, but still not zero. Those waves seem to dance around the screen a little more than I’d like. It’d be a shame to make it this far, and induce a bunch of noise into the cancelation signal with a simple volume slider. Even still, I think this is sufficient to call the M5 step tentatively done. Here is my updated circuit diagram for M5.
However, when I plugged the speakers, I now get music regardless of which position the switch is in. Albeit, much larger when the music slider is turned on. Interestingly, this is more than likely the noise I was seeing earlier. This could be due to some cross-talk within the op-amp or something.
I now believe I understand the issue here. Looking at the node labeled V1, it is possible for V2 to affect V1, even when the switch is in the positive position. My first instincy was to switch the position of the switch to this node and simply have the outputs from both op-amp circuits join up and feed directly into the amplifier. I attempted this but it did not work. In hindsight, I see now that this scenario sees V2 fed through to the end, regardless of the switch position. I returned the switch to its original position. Next, I swapped out the 100k potentiometer for a 10k. This vastly reduced the affect. There is still very faint music that can be heard when the volume of the mic. Signal is turned all of the way down, but very faint. The affect was even lessened when using a 5k potentiometer. This makes sense because the relationship between Rin and Rpot is affecting whether V2 gets pulled-in to the upper op-amp circuit. Using the 5k potentiometer, these results are acceptable for now. That said, I will be sure to ask Adam Harris if anything further can be done to isolate these circuits.
After speaking with Adam, we agreed that I probably had the switch in the wrong place. After some deliberation, he suggested placing the switch between the incoming ESP signal and ground, see below. This circuit negates the need for a 2nd op-amp circuit.
I quickly built this and found that the issue was related to the scale issue. When the music slider was turned off, the scale of the cancelation signal seemed to double. The op-amp circuit operated differently depending if the slider was on or off. This was not acceptable.
Then I tried one more option. Basically, a simply summing amp with variable resistance on each input leg.
The problem with this circuit, as far as I could tell, was back to the offset issue. With one volume knob turned all of the way up, and the other down, the signal no longer hovers around 1.65V. I don’t believe such a signal drives the speaker properly. My assumption is that the output must remain hovering around 1.65V in order to properly drive the speaker. Therefore, I think my best results so far are M4_circuit_4, see below.
I briefly tried building these circuits using the LM386 instead of LM 358, but decided this might not be worth the trouble. So far, I am having trouble adding the volume control in the way I would like. Previously, I had written off the idea of using the ADC to read a potentiometer because I had run out of ADC slots. That said, I just got the idea to make a separate controls board with a separate 1614 chip and network it together with the main board over I2C communication. In the end, this might be the cleanest approach anyhow. This second board could be very simple, and would look something like this.
This led me to also add a potentiometer as a volume control for the ESP WiFi radio. For this, I needed to use one of our labs WeMos ESP boards, since my ESP-01 module did not have a pinout for A0 (the ADC). This WeMos board is a tad wider than I would like, but should be able to be concealed within the glasses to an extent. The on-chip ADC for the ESP can only handle 0-1V. That said, the node MCU module and the WeMos board have on-board voltage dividers that protect this pin. See tutorials here and here.
With those potentiometers added and network connections made, I drew the complete circuit. This may need tweaks here and there, but I believe this to be nearly finalized.
A few notes, the child board has an extra potentiometer than is currently needed. However, I am undecided on where to put the delay potentiometer (parent or child). Therefore, I will leave the pinouts for both in so that a near game-time decision can be made. This leaves out the input device. I have included both a 5V and 3.3V pinout for this in case it becomes necessary to switch between the microphone or an ATtiny input device. Next, I will draw these boards in KiCad and begin making it clear which components go on each side of the head.
Building M6 - Formalizing M5 in KiCad¶
Designing a place for the WeMos board on the ANC7/ANC8 controls board was quite easily accomplished using rows of headers. See those sections for more details. I have run into issues with this design ripping traces. In future spirals, I plan to better support these headers using hot glue.
Here is proof that this design and the summing amplifier works.
With that, the I consider the music tree of spirals to be complete.
Disturbances and Testing¶
I realized late in the process that I would want multiple options for testing different disturbance signals. Therefore, this spiral development map was created.
ANC7/8 were created in a way that would be modular and receptive of both function genertors and microphones. To ensure this, the headers for the incoming signal to plug into can supply both 3.3V or 5V.
Buiding D1 - Using function generator¶
Nothing needed to be built here since the digital to analog kit has a robust waveform generator module. This was useful for early testing.
Building D2 - ‘Mock Drill’¶
I realized that an old board could be used to create the mock drill. Specifically, ANC5 had both a hookup for the DAC and a potentiometer which could be used for volume control. Better yet, this board had debug headers coming out of the bottom side for Power, ground, and DAC output. By jacking into these ports, I was able to supply the mock-drill power from the main headset as well as send the DAC signal from the mock drill and into the ADC of the headset.
With the electronics taken care of, all that was needed was to create a quick housing to contain ANC5, an amplifier, BC transducer, and speaker cover. I began this design off of the initial speaker housing created during H1.
Unfortunately this shell took a few iterations to get right. Mostly due to print quality and thin walls breaking.
This mock-drill is seen used during my final presentation video.
Unfortunately, I have yet to create the noise cancelation effect I am looking for. Perhaps it is hard to detect due to noise leakage through the air. I will update my findings here. Needless to say, testing is ongoing lol.
Building D3 - and future spirals¶
Since I have still yet to get the noise cancelation effect I am looking for with the function generator and ‘known signals’, I have yet to move on to using an input device such as a microphone to capture/cancel an ‘unknown signal’. If this is ever revisited, I will provide updattes here
Assembly¶
At the last minute, I laser engraved some notations on the anodized aluminum knobs for style points.
I then glued these knobs to the potentiometer posts and the board to the inner FDM shell.
As previously mentioned, the clamshell tabs and mounting posts did not all print well. Therefore, the final assembly involved a bit more glue than intended.
I thought the above pictures would be my final hero shots. However, upon presenting them to Tom, he quickly pointed out the awkward gaps at the front of the shell. Seeing how it was midnight before this was due, to say that I rolled my eyes at him would be putting it lightly. Luckily, this is fab academy. Laser cutting additional shields took no more than 20 minutes and really brought the entire project together. In hindsight, I am grateful he did. While these pieces were originally designed in Fusion, they did not come out perfectly sized on the first attempt. I made the necessary adjustments in coreldraw before cutting them again. The adjusted .SVG files can be found in my repo here. This last minute adjustment demonstrates 2D modeling capabilities. To see the final hero shots, near the top of the page.
Application and Implications and BOM¶
This section has moved to week 17 page here. The final Bill of Materials can also be found on that page, here.
If you’ve made it this far, all I can say is you rock and thanks for taking this journey with me!
Note: All design files and images can be accessed in my git repository found here.
All works shared on this site 'A Fab Academy Journey with Charlie Horvath' by Charles W. Horvath are licensed under Attribution-NonCommercial-ShareAlike 4.0 International