Commit 27d05474 authored by Erik Strand's avatar Erik Strand

Update all link numbers

parent cc26743d
......@@ -34,19 +34,19 @@ The extra degree of freedom (from using slots instead of tabs) allows more than
## A Practical Analysis of Vinyl Cutting Machines
Files: [shannon.svg](/designs/03_shannon.svg)
Files: [shannon.svg](/designs/02_shannon.svg)
This past week we learned how to use a vinyl cutter. This is a new tool for me and I'm excited to try it out. As a small token of appreciation for formalizing digital circuit design, I decided to cut a portrait of Claude Shannon to apply to my desktop computer.
Not surprisingly, there aren't many vector images of Claude Shannon online. So I edited a raster image in Photoshop until I had a nice looking two tone version. I also managed to vectorize this image in Photoshop, but whenever I tried to save the results the program got stuck. So I installed Inkscape and used it for bitmap tracing.
Despite all the detail, the vinyl cutter only took a few minutes to cut my design. Weeding, however, took two hours. Finally I removed a panel from my desktop's enclosure and transferred the image.
I'm quite pleased with the result! The vinyl cutter is a tool I now see myself using regularly.
......@@ -2,7 +2,7 @@
title = "Electronics Production"
date = "2018-09-22"
menu = "main"
weight = 5
weight = 4
## Making a Microcontroller Programmer
......@@ -15,34 +15,34 @@ This week's topic is how to make printed circuit boards (PCBs). Our assignment i
We're using a Roland Modela MDX-20 milling machine, controlled with [mods]( The mods interface takes black and white PNG images as input, calculates toolpaths, and sends the resulting G-code to the milling machine.
In groups we milled test patterns to characterize the design rules for our PCB milling capabilities. As expected, with a 1/64" end mill traces must be at least 1/64" apart. Traces thinner than a few thousandths of an inch lack structural integrity and are easily knocked off.
The height of the end mill as loaded is Z home, so it's important to make sure it's flush with the surface to be cut. The first time we loaded the 1/64" tool, the act of tightening the set screws pulled it up a few thousandths of an inch. It still looked flush with the material, but as can be seen below it did not cut the traces properly. Later we realized we could slide a sheet of paper between the end mill and the PCB.
After the test pattern, I milled a programmer.
### Stuffing
I had never tried to solder surface mount components before, so I wasn't sure how it would go. My first attempt was a disappointment: crystallized joints across the board (ha).
A few hours later I realized that I had used lead-free solder, so I decided I'd stuff another board using good old fashioned leaded solder. It was far easier, and the results were much more satisfying. Now I know firsthand why lead is still a common ingredient in solder.
Here are both boards next to each other; lead-free on top, leaded below.
Looking forward to programming these programmers!
......@@ -50,5 +50,5 @@ Looking forward to programming these programmers!
Our PCBs are a bit thinner than the spec for USB connectors. So I cut out the profile on the vinyl cutter and stuck 8 layers on the bottom of my boards. This makes them stick in USB ports much more firmly.
......@@ -7,7 +7,7 @@ weight = 6
## Printing
Files: [](/designs/ (render with [libfive Studio](
Files: [](/designs/ (render with [libfive Studio](
This week's primary assignment is relatively unconstrained: design and print something that couldn't be made with subtractive techniques. I decided to explore curved surfaces with severely constrained accessibility. This was also a good excuse to learn [libfive](, since functional shape representations enable a more diverse palette of interesting deformations than traditional b-reps.
......@@ -15,7 +15,7 @@ This week's primary assignment is relatively unconstrained: design and print som
I modeled a small stellated dodecahedron, where each of the stellations is twisted along its axis. In the end, the model I printed looks like this.
Designing it was mostly a matter of working out trigonometric relations to ensure the various pieces
would correctly mate. There were many times I made errors in my calculations, and built shapes with
......@@ -30,23 +30,23 @@ Using libfive also means that my model is inherently parametric. To give it the
printed without errors, I chose to make it quite chunky. It's also interesting with much thinner
### Fabrication
My design was brought to life by CBA's Stratasys Eden printer, using a translucent plastic.
(The indentations on the ends of some of the spires are my fault, not the printer's. The part lasted about 10 minutes before I dropped it.)
The way this material transmits and diffuses light is quite nice. With the right lighting, it almost looks like ice.
The layers aren't noticeable from afar, but they are quite apparent up close.
## Scanning
......@@ -56,5 +56,5 @@ candidate for 3d scanning. Which is exactly why I wanted to try it.
Results were... as expected.
......@@ -7,7 +7,7 @@ weight = 7
## PCB Design
Files: [echo.sch](/designs/06_echo.sch) [echo.brd](/designs/06_echo.brd) [echo_top.png](/designs/06_echo_top.png) [echo_cutout.png](/designs/06_echo_cutout.png) (both 2000 dpi)
Files: [echo.sch](/designs/05_echo.sch) [echo.brd](/designs/06_echo.brd) [echo_top.png](/designs/06_echo_top.png) [echo_cutout.png](/designs/06_echo_cutout.png) (both 2000 dpi)
This week we're learning how to go all the way from pcb design through milling, stuffing, and programming. I should end up with a board that can talk to a computer over a serial connection (masquerading as a USB device).
......@@ -17,11 +17,11 @@ Since I've been using Fusion 360 so much, I decided to give EAGLE a try. (I'm al
Drawing the schematic was simple enough. From the [reference design]( I just added a switch and an LED (with current limiting resistor). I checked that all GPIO pins on the ATTINY44 have internal pullup resistors, so I'm going to rely on those to pull my input high when the switch is open. To get a value for the current limiting resistor, I plugged in the current rating and forward voltage drop of our LEDs to an [online calculator]( I found that 330 ohms would be ideal, so I went with the closest value we stock in bulk: 499 ohms.
Drawing the traces was more challenging. It took me a few tries before I was able to pack the components in a reasonable amount of space with relatively short routes. I'm still not super pleased with how indirect the ground path to the microcontroller is. I look forward to designing more boards and getting a better intuition for circuit layout.
### Production
......@@ -33,9 +33,9 @@ At this point I feel comfortable stuffing boards. It went by pretty quickly and
It had been a few years since I've flashed a microcontroller so I was uncertain how many issues I should expect to run into. Luckily things went pretty smoothly. I encountered a few "device not found" errors that were circumvented by unplugging and replugging the programmer and boards. I just used Neil's [echo code](
Communication with my computer was achieved!
......@@ -18,20 +18,20 @@ I want a shelving unit that fits exactly between two doors in my bedroom, and oc
I started by drawing a parametric model in Fusion 360.
I then wrote my own code to generate the 2d profiles of each piece, rather than exporting them from Fusion. This is mostly because I'm curious to think about what primitives a code based CAD environment for panel structures should provide. But it also means I don't have to fix a few nuisances in the Fusion model, such as some infinitesimally thin surfaces left over from extruded cuts, and the fact that some beams repeatedly move to new locations despite the fact that they're in a rigid group (the only fix I've found is deleting the pattern feature and recreating it, with identical settings).
My code exports SVG images, because they're easy to write. (On this site it's in a raster format, since my SVGs don't respect the viewport defaults that browsers use.)
### Test Model
To ensure that my generated 2d patterns are correct, I cut a 1/4 scale model out of cardboard with a laser cutter. It fits together nicely. This is a great way to ensure that the model doesn't have any glaring mistakes. Though in this case, I actually found a few minor issues later that were too small to detect at this scale.
### Machining: First Try
......@@ -58,21 +58,21 @@ On Wednesday I returned to the shop. When I first started trying to machine, I w
After that, it was smooth (if loud) sailing.
<video controls src="/img/07_shopbot.mp4"></video>
<video controls src="/img/06_shopbot.mp4"></video>
First I cut a quick slot joint test piece. Normally this would require re-exporting files from CAD, and doing the CAM again in VCarve. But since my design and gcode generation take place in one software pipeline, I just had to rerun my code to get all my updated ShopBot files.
After that it was just a matter of waiting for the machine, and feeding it stock. I had four panels in total (oops, looks like I forgot to take a picture of one).
Here's the start (and end) point of one of the longer pieces. The effects of hysteresis and tool deflection are clearly visible (yes, the lines are programmed straight).
### Assembly
......@@ -80,7 +80,7 @@ Remember when I mentioned that cutting climb vs conventional had a noticeable im
I'm really happy with the end result. Here's my room, before and after. I can't imagine going back.
TODO: after
......@@ -40,7 +40,7 @@ If this doesn't work after programming, there are the usual suspects to check.
- Are your solder joints smooth and shiny?
- Is your schematic ok? Your LED will need a resistor of an appropriate value (I used 499 ohms) in parallel.
### Using the Button as a Contact Switch
......@@ -77,7 +77,7 @@ int main(void) {
{{< /highlight >}}
<video controls src="/img/08_button_contact.mp4"></video>
<video controls src="/img/07_button_contact.mp4"></video>
### Using the Button as a Toggle
......@@ -183,5 +183,5 @@ int main(void) {
{{< /highlight >}}
<video controls src="/img/08_button_toggle.mp4"></video>
<video controls src="/img/07_button_toggle.mp4"></video>
......@@ -5,7 +5,7 @@ menu = "main"
weight = 9
Files: [](/designs/ (render with [libfive Studio](
Files: [](/designs/ (render with [libfive Studio](
This week we're machining 3d wax models on a desktop ShopBot, using them to make [silicone]( molds, and using those to cast a variety of materials.
......@@ -14,11 +14,11 @@ This week we're machining 3d wax models on a desktop ShopBot, using them to make
For a research project I've been interacting with a lot of functional representations of gears, so I thought it would be nice to make one physically. For research I've been using extruded gears like the one below, but that doesn't make a very exciting 3d model.
So I tapered the top, to produce a simple bevel gear. Now while it's true that the simple extruded gear is a proper involute gear (up to some imperfections introduced in the meshing process), the tapered version is not a proper involute bevel gear. But I won't be using this for mechanical purposes anyway ([Drystone]( is not an engineering material) so I can live with the imperfection. I also plan on machining deeper than the model into the wax, so that I'll essentially end up with a regular gear attached to a bevel gear.
I sized the gear keeping in mind that the smallest slots between teeth would still have to admit an eighth inch end mill. I didn't bother filleting the sharp inside corners, since the [CAM software]( I'll be using will implicitly add them to the toolpaths (as a by-product of only machining where the tool fits).
......@@ -27,7 +27,7 @@ I sized the gear keeping in mind that the smallest slots between teeth would sti
I used an eighth inch flat end mill for both roughing and finishing. My finishing passes used a 10% stepover. I could get a smoother model with a ball end mill and smaller stepover, but this isn't rocket fabrication. Here's what my part looked like after roughing.
As you can see I made one mistake: I thought my toolpaths were relative to the corner of my stock, but instead they expected me to have set home to the top center. Hence the random cut through the side. It turns out this is because I clicked on the button for the corner in PartWorks 3d, which updates the UI, but neglected to hit apply, which makes it actually take effect for the toolpaths. I ended up filling the extra little hole with hot glue to ensure no uncured OOMOO could leak out.
......@@ -40,13 +40,13 @@ The [OOMOO]( comes in two separate
The mold holds very fine detail. Though in my case, most of this detail is comprised of the cusps from my stepover.
### Casting
I decided to start with drystone. I found mixing it a little easier than the OOMOO, since it's not as goopy. The container indicated 100 parts drystone powder to 20 parts water, but I found that this produced a paste so thick I was worried about losing detail. So I added a bit more water until it had the consistency of a thick batter. I didn't do anything to clear bubbles, but this doesn't seem to have caused any issues.
......@@ -5,7 +5,7 @@ menu = "main"
weight = 11
Files: [audio_input.sch](/designs/10_audio_input.sch) [audio_input.brd](/designs/10_audio_input.brd) [audio_top.png](/designs/10_audio_top.png) [audio_cutout.png](/designs/10_audio_cutout.png) [sampler.c](/designs/10_sampler.c)
Files: [audio_input.sch](/designs/09_audio_input.sch) [audio_input.brd](/designs/09_audio_input.brd) [audio_top.png](/designs/09_audio_top.png) [audio_cutout.png](/designs/09_audio_cutout.png) [sampler.c](/designs/09_sampler.c)
This week we're exploring input devices, so our microcontrollers can start sensing the physical world. Since my final project involves manipulating signals from steel bass guitar strings, I will use an [electromagnetic pickup]( as an input.
......@@ -23,33 +23,33 @@ To gain experience with analog circuitry, I'm going to make an off-chip preamp t
I mostly followed Amanda's [Instructables article](, but added some modifications I found on [Electronics Stackexchange]( To amplify the signal, I use an op-amp in a non-inverting configuration, and to provide a DC offset I pass the amplified signal through a capacitor that's connected to a voltage divider circuit. I'm using the MISO ISP pin for my input, and MOSI for output.
I think I found a pretty good layout for the board. By routing signals underneath capacitors and resistors, I can keep the traces pretty short. As you can see I cheat a little with the design rules: mods is generally happier when the clearances are much larger than the diameter of the end mill, but using these rules globally would prevent me from routing under standard 1206 components (edit: not sure why I didn't use the 1206FAB variants here...). So I changed the design rules as I worked.
### Testing
I connected my bass guitar's output to the preamp, in a maximally professional manner.
As an initial test of the preamp, I measured its input and output with a [Saleae Logic Analyzer]( It looks promising!
Upon closer inspection, however, it's clear that there are some serious problems. Though the output's DC bias does appear to be at 2.5V, it gets much closer to 5V than it does to 0V. Even the input appears altered: the waveforms are clipped on the bottom end.
### Sampling
Ignoring for the moment the strange preamp behavior, I connected the output of my preamplifer to a spare input on my microcontroller board.
On the software side, I started with Neil's [echo program]( This way I have all the serial communication ready to go. Here is my new main method.
......@@ -116,22 +116,22 @@ int main(void) {
This reads samples and spits them out over the serial connection.
## Circuit Design Revisited
A friend pointed me to Mark Feldmeier's wonderful [op-amp guide](, which I relied on for a total redesign of my preamp. It includes a number of improvements. First, my voltage divider gets a buffer (i.e. an op-amp wired so that its output is always the same voltage as its input). Once I'm processing audio from multiple strings at once, this will help prevent crosstalk via the bias voltage rail. I'm also biasing my signal before amplification, which means the bias voltage rail is only connected to the high-impedance op-amp inputs, and that the low-impedance op-amp output can be used directly.
I also made a number of improvements for my instrumentation. I connected header pins not just to the output, but also to both sides of the guitar input and my bias voltage. This should help with debugging if there are still problems. I also soldered some jumper wires to proper audio jacks, so that I can plug my bass in without clips.
This board's output looks a lot better than the previous one's.
I decided to plug it into my (commercial) audio interface so I could listen to the output directly. It [sounds](/audio/10_bass_test.mp3) just like the untreated output of my bass.
I decided to plug it into my (commercial) audio interface so I could listen to the output directly. It [sounds](/audio/09_bass_test.mp3) just like the untreated output of my bass.
......@@ -39,6 +39,6 @@ put_char(&serial_port, serial_pin_out, 100);
To test it, I sent the serial data to my computer using an FTDI friend. I made use of [Hairless MIDI]( to interpret the serial signals and transform them into inputs that the music production software on my laptop can understand. Sure enough the notes are coming through!
Here is my first "hello world" [MIDI recording](/audio/11_microcontroller_midi.mp3) (rendered to audio in Logic Pro).
Here is my first "hello world" [MIDI recording](/audio/10_microcontroller_midi.mp3) (rendered to audio in Logic Pro).
......@@ -5,7 +5,7 @@ menu = "main"
weight = 13
Files: [temp_control.sch](/designs/12_temp_control.sch) [temp_control.brd](/designs/12_temp_control.brd) [temp_control_cutout.png](/designs/12_temp_control_cutout.png) [temp_control_routes.png](/designs/12_temp_control_routes.png) (both images are 1000 dpi; ignore the embedded metadata) [code](
Files: [temp_control.sch](/designs/11_temp_control.sch) [temp_control.brd](/designs/11_temp_control.brd) [temp_control_cutout.png](/designs/11_temp_control_cutout.png) [temp_control_routes.png](/designs/11_temp_control_routes.png) (both images are 1000 dpi; ignore the embedded metadata) [code](
It's here: machine week. Even with some [helpful structure](, it's a lot. Let's see how far we get!
......@@ -16,7 +16,7 @@ My group's collective documentation lives [here](../../../mechanical-machine-des
Having the most Fusion 360 experience in the group, I did most of the modeling work. This was largely an exercise in arranging Jake's parametric axes. However we did have to fix a few sketches in the axes after modifying parameters (since they would rebuild with errors). I also changed Jake's parametric angle bracket into a box bracket. The original purpose of this part was to lift the X axis above the Y axes (to gain additional Z travel), but we ended up leaving it out in order to increase stiffness. Design files are linked on the group page. The video below is from our late-night design session.
<video controls src="/img/12_disco_cad.mp4"></video>
<video controls src="/img/11_disco_cad.mp4"></video>
The main flaw in our design is that the end effector is much more massive than our axes can reasonably support. This was mostly due to our aggressive design timeline: we wanted to finish our design in the first day, so the end effector and gantry system were designed completely in parallel. So by the time we combined them, there wasn't time to go back and stiffen up our axes. Though clearly we would have benefited from some additional communication between Filippos and I during the design process.
......@@ -36,18 +36,18 @@ The heating pad is essentially a giant resistor: push current through it and it
Here's the board and thermistor, before attaching the heating pad. Also visible are the RNDMC router and the dedicated power supply.
Here's the chocolate syringe, wrapped in a heating blanket. You can also see the leads of the thermistor, which is tucked inside.
#### Thermistor Software
Jake's breadboard board programmed fine on the first try, and its test function worked fine.
My first priority was getting some samples from the Xmega's ADC. So I was happy to find a command called `DELIM_KEY_ADCGET` in the existing [packet handler]( Unfortunately when I ran it the board became unresponsive -- not even the test commands would get through afterward unless I did a hard reset. After much datasheet diving, and getting some additional example code from Jake, I figured out that it was getting stuck in `get_adc()` because the bit that should indicate a sample is ready was never getting set. Fixing it should just be a matter of modifying the appropriate ADC registers.
......@@ -81,9 +81,9 @@ But the values I got sent back in my terminal were obviously wrong. I should see
In the image below we get the response 142, 13, 244. The first byte (142) is just echoing the command for an ADC conversion. The second two bytes encode the 12 bit reading from the ADC (right packed). So 13, 244 is 0b1101, 0b11110100 in binary, meaning the ADC read the value 0b110111110100 or 3,572. This represents 3572 / 4095 * 2.0625V = 1.8V.
To convert this value to a temperature, we first need to convert it to a resistance. From Ohm's law and Kirchhoff's laws I derived `R = 75 * v / (3.3 - v)` where `v` is the voltage measured by the ADC. (75 is the value of the fixed resistor in kilo-ohms; 3.3V is our logic level; the resulting resistance is also in kilo-ohms.) Online I found an informal [datasheet](/reference/12_NTC-3950-100K.pdf) for our thermistor, which includes a table of temperature and resistance values. Ravi fit an exponential model to the data that converts from resistance to temperature. So our final temperature reading code is as follows.
To convert this value to a temperature, we first need to convert it to a resistance. From Ohm's law and Kirchhoff's laws I derived `R = 75 * v / (3.3 - v)` where `v` is the voltage measured by the ADC. (75 is the value of the fixed resistor in kilo-ohms; 3.3V is our logic level; the resulting resistance is also in kilo-ohms.) Online I found an informal [datasheet](/reference/11_NTC-3950-100K.pdf) for our thermistor, which includes a table of temperature and resistance values. Ravi fit an exponential model to the data that converts from resistance to temperature. So our final temperature reading code is as follows.
{{< highlight c >}}
float temperature_from_adc(uint16_t adc_reading) {
......@@ -107,9 +107,9 @@ After getting reasonable temperature values, controlling the heating pad turned
Since the temperature of the chocolate changes extremely slowly relative to the timescale of the microcontroller, I went with the simplest possible control logic. If the thermistor reading indicates the chocolate is below a set temperature, we turn the pad on. If it's above that temperature, we turn it off. I also co-opted the orange error LED on the breadboard board to serve as an indicator for the heating pad. This makes it easy to tell visually when the chocolate is at the right temperature: the light flickers, as opposed to being all the way on (as it is when the chocolate is too cold) or all the way off (when the chocolate is too hot). I used a digital thermometer to verify that we were keeping the syringe at the right temperature. Our system was able to hold the temperature to within a half degree Celsius.
<video controls src="/img/12_temp_control.mp4"></video>
<video controls src="/img/11_temp_control.mp4"></video>
Here's the final system: syringe, temp control board, and all.
......@@ -51,7 +51,7 @@ int main() {
To my surprise it worked immediately. It found my board at `/dev/cu.usbserial-AC01YB5P`, which I confirmed via `ls /dev | grep serial`.
Now to listen to it.
......@@ -108,14 +108,14 @@ int main() {
Now my computer can tell when I press the button.
### An Impractical Application
I have a parametric shelf design from [CNC week](../07_cnc_machining). Why not generate a new shelving unit every time I press the button?
<video controls src="/img/13_shelf_button.mp4"></video>
<video controls src="/img/12_shelf_button.mp4"></video>
In the video above I'm just reloading one of four generated SVG files (since the shelves at their biggest require four panels of material). But it's also generating ShopBot code for each panel as well. So after pressing the button you're fully ready to cut. All of this happens in less than the blink of an eye -- the delay is just from Chrome being slow at reloading.
......@@ -5,7 +5,7 @@ menu = "main"
weight = 15
Files: [audio_interface.sch](/designs/14_audio_interface.sch) [audio_interface.brd](/designs/14_audio_interface.brd) [audio_interface_2.sch](/designs/14_audio_interface_2.sch) [audio_interface.brd_2](/designs/14_audio_interface_2.brd) [serial_cpp]( [lufa]( (see Demos/Devices/ClassDriver/VirtualSerial)
Files: [audio_interface.sch](/designs/13_audio_interface.sch) [audio_interface.brd](/designs/13_audio_interface.brd) [audio_interface_2.sch](/designs/13_audio_interface_2.sch) [audio_interface.brd_2](/designs/13_audio_interface_2.brd) [serial_cpp]( [lufa]( (see Demos/Devices/ClassDriver/VirtualSerial)
This week we're making machines talk to each other. I've used I2C before, so I'm curious to venture into the wonderful world of USB.
......@@ -14,11 +14,11 @@ This week we're making machines talk to each other. I've used I2C before, so I'm
For part of my final project I want to make my own USB audio recording device. So I'll try to develop all the necessary electronics this week. I have the analog circuitry I need from [inputs week](../10_input_devices). But I don't have a board ready to go with a USB-capable microcontroller (bit-banging will not suffice, since I need the CPU to be available for audio processing). I've heard that [LUFA]( is much nicer than ATMEL's own USB [libraries]( so I'll try to use that. I'd like to use an XMEGA board, since they are fast, have a good amount of memory for audio applications, and I've used them [recently](../12_machine_week). LUFA's [XMEGA support]( is technically experimental, but people have been using it since [2013]( So I think it should be ok.
On the left I have my microcontroller. I'm using an external 16MHz crystal to give it an accurate clock signal. High speed USB 2.0 requires a 48MHz clock, which I can get by multiplying the crystal's output by 3 using the XMEGA's phase locked loop (PLL). On top I have my power section, including a regulator to bump USB's 5V power down to 3.3V, some filtering capacitors, and a power indicator LED. The two circuit groups with op-amps together amplify and bias the audio input, as I learned in [inputs week](../10_input_devices). Finally I have some headers that provide convenient debugging access to certain signals, and a 0-ohm resistor I needed to connect all my ground signals.
Laying out the board took a long time, since this is the most complex circuit I've designed from scratch. I'm using thinner traces than before, so that they can reach all the XMEGA's pins without shorting and so that I can route multiple traces under a single 1206 component. I kept the USB signal traces as short as possible. One open question I have is what to do with the USB connector's shield. Plenty people have [asked]( this [question]( online, but the answers are split between grounding it directly and connecting it to ground via a capacitor and a large (ex 1MΩ) resistor. I don't yet have the expertise to know which makes more sense in this situation. [This]( document looks like it might help, but I haven't had time to read it all yet.
......@@ -27,26 +27,26 @@ Laying out the board took a long time, since this is the most complex circuit I'
I milled the board on a Roland SRM-20. For the most part the smaller traces worked fine. However the end of the power trace for the USB port did get pulled off. (The same is true for part of the 'S' in the text, but that won't require any jumper wires.)
I soldered the XMEGA and the USB connector first, since I knew jumping the USB power wire and dealing with the tiny XMEGA traces would be the trickiest tasks. The XMEGA's leads are smaller than anything I'd soldered before, but it still went fine. Most of them I soldered individually, but in a few places I globed pins together and later removed the excess solder to unshort them. Generous amounts of flux were essential, since I used a very fine gauge of solder that doesn't have a flux core. To connect the USB power, I took a small piece of wire and used it to jump directly from the USB connector pin to the trace. It was so short that it was almost impossible to solder one side without melting (and thus destabilizing) the other, but eventually I got it to stick in place with good quality joints on both sides. (In the photo below it looks like it's shorted to the USB plug chassis, but the jumper wire is safely above the leftmost lead.) After these I soldered on the minimal number of other components to get the power indicator LED working (ok, the crystal wasn't necessary but I had already taken it out).
From here it was a routine soldering job.
## Software (First Attempt)
I started by flashing it with an empty hello world program, to verify that it could be programmed at all. Then I cloned LUFA and started trying to adapt an example to work for my board. Unfortunately, disaster struck: I accidentally tore off the USB connector. I knew this was a risk, since I had waited to solder on the
I figured it was worth a shot at repairing.
I think I got most of the leads reconnected, though in the image above the power jumper has some really ugly (and maybe cold) joints. Eventually I decided I should save myself the frustration of working with a damaged board. Especially since I learned of a few things I could have done better.
......@@ -62,8 +62,8 @@ Or back to board drawing, as it were. Anyway, I wanted to make a few changes bef
The first is just good practice for microcontrollers. I added 0.1uF caps near all the XMEGA's power pins, and a few 10uF caps near potentially large current sinks (i.e. LEDs and op-amps). I had added the 22ohm resistors because all the [examples](../../../../../863.17/CBA/people/tomasero/index.html) I [looked at](../../../../../863.14/people/andrew_mao/week11) had them. But after going through the XMEGA's datasheet in more detail, I found that it has an "integrated on-chip USB transceiver, no external components needed". I wanted to go to a single-ended op-amp configuration to make it simpler to add a potentiometer to control gain. With my current differential setup, I would have to use a double-ganged pot, and if the two resistances didn't stay exactly the same at all times there'd be additional error in my output. So I'll just connect one side of the input to ground, and send the other through an AC-coupled non-inverting amplifier with a DC bias. Finally, the gain control knob and audio jack will be better off mounted to the chassis of the device rather than the board, so that the board doesn't bear any unnecessary mechanical load. It would be nice to attach the USB jack to the chassis as well, but the USB jacks we have in stock are surface mount, and since it's good to keep the data leads as short as possible, I'll leave it on the board.
If I lay this out a third time, I'll make more careful use of the grid. I could also move the LEDS to the left of the XMEGA, and connect the audio signal to a pin on its bottom side, to shorten my critical analog traces. Speaking of which, I could have a separate analog ground plane and voltage rail. But this will definitely work for now.
......@@ -72,13 +72,13 @@ If I lay this out a third time, I'll make more careful use of the grid. I could
I hoped that the ripped leads on my first board were a fluke, so I milled the second one just like the first. But the same thing happened, in the exact same place.
Rather than deal with jumpers again, I thought I'd fix the manufacturing. So I grabbed a 0.01" endmill to use just for the USB pads.
## Software (Second Attempt)
......@@ -89,7 +89,7 @@ Though the LUFA code looked quite daunting at first, I only needed to change a f
After programming, my serial port code detects a new device: `/dev/ttyACM0`. When I open the port, I get see a constant stream of "hello world" as expected.
Since this week is ultimately about networks with addresses, let's try to find the address that my board is assigned by my computer. I grepped for "address" in LUFA and after following a few function calls found my way to `LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h`. At line 217 LUFA is writing the newly assigned address to one of the XMEGA's registers.
......@@ -102,5 +102,5 @@ static inline void USB_Device_EnableDeviceAddress(const uint8_t Address)
Instead of spamming hello world, I can read back this register and make my board output its own address.