Final Project tracking page
On this page, I track progress toward my final project idea: a self-assembling geodesic dome, as a proof-of-concept cubesat payload for future space habitation structures. The final model created for this class includes: 3D printed tiles assembled via a defined logic for magnet jointing, surface-mount circuitry on a "sensor" tile that both reads input data and gives output information via LED, networked communication over BLE and a Processing App that visualizes a live rendering of the sensor data over time. I will continue work on this prototype next semester, including condensing the circuitry to a single PCB and replicating the circuit for each tile in the assembly (with a coordinated BLE comm protocol across the tiles).
Materials for this Project
- Custom desgined 3D printed tiles (12 pentagons, 20 hexagons printed via the EDEN Objet) - $100
- Neodymium 3mm cube magnets (10-12 per tile x 22 tiles, plus extras)- $100
- Standard CBA circuit components (documented in detail below), to include an ATMega 328p, 8MHz oscillator, LSM303dlhc sensor, LEDs, resistors & capacitors, voltage regulator - ~$15 (low price thanks to bulk orders)
- HM11 BLE modules x 2 ($12 per) - $24
- Mini-USB cable + Adafruit "FTDI Friend" - $15
- Raw copper for multiple iterations of board milling & vinyl cutter- ~$5 (low price thanks to bulk orders)
Prior Work in this Area
I was inspired for the self-assembly mechanism of this project by Skylar Tibbits and his Self-Assembly Lab at MIT. I hope to collaborate with him on future iterations of this project, as I prepare it for launch readiness with Blue Origin in late 2017. Regarding prior work related to my circuit approach, I worked off of Amanda Ghassaei's IMU approach from the year she was in HTMAA-- thank you Amanda for an incredibly well-documented page! I'd also like to thank Brian Mayton, Eric VanWyk, Caroline Jaffe, Jasmin Rubinowitz, Tomer Weller, Miguel Perez, Tom and John for their troubleshooting help throughout the semester!
Throughout this semester, I plan to explore a theme of Space Exploration and DIY space hacking technologies. My final project idea for How To Make Almost Anything is also a research project I am pursuing for cubesat deployment. The Solidworks assembly shown below is a proof of concept, self-assembling buckyball. This set of magnet-jointed tiles serves as the payload for a cubesat launch, testing a passive self-assembly in zeroG design for future space habitats (likely paired with an inflatable BEAM habitat for the ISS or other space-bound applications). In subsequent weeks, I look forward to 3D printing test assembly parts, embedding neodymium magnets, and exploring pcb design for circuitry on the surface of the tiles. When assembled, the final structure should enable an emergent functionality as all surface ciruits are connected.
I began by sketching the individual tiles, and the bonding faces where the pentagons and hexagons would meet. I based the tile edge slope angle on the published dihedral angles for buckyballs, 138.189 degrees for hex-hex bonding and 142.62 degrees for pent-hex bonding. For example, the Hex-Hex edge slope should be: [360 - (138.189 + 180)]/2 + 90 = 110.90 degrees. Similarly, the Pent-Hex edge slope should be: [360 - (142.62 + 180)]/2 + 90 = 108.68 degrees. See sketches below for calculation details and geometries. I also used sketching to plan the magnetic joints (both the logic of distinguishing between hex-hex and hex-pent bonds, and how to recess magnets in the tile edge).
Tile slope angle (based on dihedral angle)
- Pentagon to Hexagon bond: 108.69 degrees
- Hexagon to Hexagon bond: 110.90 degrees
Next, I started modeling the individual pentagon and hexagon tiles. After several attempts at other ways of defining the geometry and edge slope angles, I settled on plane-mediated surface cutting (thanks to advice from several solidworks gurus). Below you can see the approach of defining reference geometries at set angles, and the remaining shapes after the straight-sided edges were cut away.
Then, I sketched squares on the surface of the tile edges and used extrude-cut to make the magnet recesses. In the parametric design, I made affordances for the apoxy I plan to glue the magnets in with, so the recessed holes are .012 in larger than the explict dimension of the magnets. I designed the magnets to be paired in the center of each tile edge, to avoid unnecessary interference from rogue bonding (e.g. if I had placed the magents near the edge vertices, other magnets not intended for that joint might be attracted to it). Finally, I modeled the tiles to be thick enough to accomdate the sloped, recessed magnet holes and include sufficient material on the top and bottom to dissipate any magnet force outside of the mating faces.
With the base tiles now ready, I transitioned to an assembly file and mated the hexagon and pentagon tiles, generally using face mates and edge mates. You can see two intermediate stages of the assembly below:
Tile Fabrication Stage
This week, we explore additive manufacturing and the objects that are uniquely made possibly through the addition/accretion of multiple layers, rather than through the subtractive processes of cutting and grinding. We also explore 3D scanning technology, using sensors (often infrared) to detect depth and light scattering and recreate a 3D model of a real world object.
For this module's 3D printing assignment, I returned to my final project concept: the self-assembly, geodesic dome (for ultimate deployment in zero-gravity via a cubesat). Working from the solidworks models from the first week, I saved .stl files and submitted these for printing. Due to equipment issues with the Stratasys Dimension printer, we used the Eden objet printer. This proved to be a particularly fortuitous choice, as the objet printer produces a rubber-like printing material that provides a tighter, more forgiving fit for interlocking parts. Below, you can see the pentagon tile and hexagon tile. I printed only three of each, to test the fit with the magnets. The test was successful, and I can now move on to printing the rest of the parts!
Why are these pieces worthy of additive manufacturing?
The parts you see below include recessed holes for magnet joints. These holes are angled with respect to the top and bottom faces, meaning they recess in and produce a flush mating face for the magnet to magnet bonding. This hole angle would be particularly difficult to achieve with a traditional 3 axis mill, as the mill could not simply go down straight into the part. We would have to arrange the part on it's side, and have the mill drill into the edge surface...but the other side of the object is not flat, so we would not be able to set it down on the milling surface. This would require custom clamping, or perhaps a 4 axis mill to achieve the recessed hole angle. With these considerations, I believe these parts merit additive manufacturing.
With the tiles now printed, I began inserting the magnets and testing the magnet joints! I'm happy to report that the magnet strength is more than sufficient to keep the tiles bonded, and that the dimension tolerances I accounted for in SolidWorks were correct. The tiles' angled edges mate smoothly with the relevant hexagon and pentagon neighbors, and the magnets fit snugly in the holes. As mentioned above, the slight give and rubber-like property of the Eden prints also help the mating fit.
This week, we explore "inputs" for circuits, or sensors that read data from environmental conditions on/in/around the circuit and send results over serial data connection for use in later analysis.
In keeping with the goal of making progress on the final project, I tried to make this week's circuit applicable for the self-assembling buckyball project.
Each tile will include surface mount circuitry, enabling an emergent functionality when all tiles have been successfully connected. I began this week's (extensive) design process by selecting a 6DOF acceleromter/magnetometer sensor. In the final design, I would like to measure the linear and angular position data of the tiles, as they tumble in zero gravity in a LEO orbit, the temperature (in both the sun and out-of-sun portions of the orbit), and magnetic field (via magnetometer). This will likely require a 9DOF sensor, that includes both an accelerometer and gyro, but there were no 9DOF sensors stocked in the lab. Both the 6DOF sensor and 9DOF sensor typically come with an extra temperature sensor embedded, so I should be able to I decided to use the LSM303DLHC stocked in Fab Inventory. To prepare for ultimate replacement with the 9DOF sensor, I decided on a modular approach. I would design the sensor on a breakout board that could be replaced by a new breakout board, when I later wish to upgrade the sensor. For the brains of the circuit, or the main "chip board" I selected the ATMEGA328PGA 328P, primarily for the number of pins and readily available firmware code from many adafruit/arduino tutorial projects.
Sensor schematic and board (separated into a breakout board for modularity)
Chip (aka the brains) schematic and board
Attempt at milling--first pass tool path for modela (clearly not clean enough)
Notes to self on considerations for the circuit (to write up in more detail): FTDI cable voltage must now be 3.3V and explain why, connect the interrupt pins for future use, Zero Ohm resistors as an non-ideal way to get around circuit layout puzzle, DRC check, milling concerns for the ATMEGA and sensor pads, programming over the ISP header, Arduino bootloader and, make sure future sensor also wants to communicate over I2C for the SDA and SCL lines already connected.
Finally, after several milling attempts and an exploration into even finer bits than 1/64", I was able to get a cleanly milled board, with distinct traces for the delicate ATMEGA328P legs.
This week, I am continuing work on my accelerometer/magnetometer board for the self-assembling tiles final project. To see the work up to this point, please see Circuits with Input Devices
Though my "output" is relatively simple initially (just an LED), I have designed the board to be primarily a sensor (aka input) device, with flexibility for testing new sensors in the future, and a responsive LED to indicate information about the status of the sensors and final project tile neighbors. By choosing a modular design and separating the processor from sensor via a breakout board, I am able to rapidly test new sensors without redesigning and fabricating a new board each time. My output LEDs give important status information for two things initially: a red LED for power status (post voltage regulator) and a green LED on digital pin 13 (I'll explain the mapping between chip pins and Arudino "digital pins" below) for programmable function based on scripts loaded onto the board. This programmable function can be dependent on the sensor data, thus offering a visual mode of interpretation.
Finishing up Board Design Steps & Soldering
Continuing from where I left off in the Inputs week, I needed to first re-design the sensor board, mill and stuff it. I realized after making the initial design and milling an early sensor board, that I had not flipped the directionaliy of the pins as required for proper mating with the female headers on the chip board. You can see the redesigned sensor board below, freshly milled, partially "stuffed" and fully stuffed:
A tip for soldering on pin headers that will need to match precisely with the distance of the receiving (female) pins: In eagle, make sure the distance between the two rows of pins/female headers is the same on each board. Then, when soldering, solder on both sets for one board and only one of the matching sides for the second board. Connect the two boards gently, and get a visual idea for where the final piece will need to be soldered for good alignment.
A note on soldering the 6 or 9DOF LSM packages. These sensors have very tiny pads on the underside of the "package", making them quite difficult to solder. The technique that worked for me (luckily the first time) was to "tin" the board layout where the chip should be placed, gently lower the chip over the cold solder pads with proper orientation, and bring the heat gun in until the solder melts and the chip bonds to the board. You'll want to be careful that you don't hold the heat gun on too long, lest you fry your board, but this technique seems to be the most reliable method of firmly soldering on these sensor packages. Thanks to Caroline Jaffe for the tip on this one!
Now, for assembly of the "modular" chip board + sensor board:
With both boards milled and the soldering complete, we can first test the connections via the continuity setting on the multimeter and then test the modular function. I carefully checked each board for shorts (there were none, yay!) and checked that the pins on the microcontroller that had traces going under the chip were properly connected. You can see that the boards fit together nicely, below:
Programming the board!
There are many approaches you can take for programming the chip on a homemade board. I chose to treat my chip like an arduino, and wanted to be able to load sketches directly onto my board via the ardunio IDE. This saves some of the pains of the straight C file approach, though both have their merits.
Programming Steps for ATMEGA 328p
- You will need to burn the Arduino "bootloader" onto your board. To do this, you'll need a programmer (like the FabISPs we made in a prior week, or a commerical programmer like the AVRISP mkii).
- Make sure your board is separately powered (this is usually done over FTDI), and connected to the programmer over the ISP header. Then connect the programmer to the computer where you will be working with the arduino software.
- For the arduino software to recognize the type of chip you are working with, you'll need to add a new "board" in the "boards.txt" Ardunio config files. The text to add to the file is below. These entries define a custom board, with the internal clock speed and proper fuse settings. You can determine whether you'll want different fuse settings by reading the datasheet of your processor for which bits are used in the "Low", "High" and "Extended" fuse profiles. You can check the same for unlock bits. The text below assumes you are using an ATMEGA 328p chip, which is a chip commonly found on Arduino boards (like the Uno and Pro).
hello.name=hello.arduino, ATmega328P, 5V, 8MHz internal oscillator
- With the boards.text file edited, you should now be able to select the correct board, programmer and port selection as shown in the screen shots below and then "Burn Bootloader" onto your chip.
- For additional programming help and other approaches, I recommend Yuval's and Amanda's pages, which I found quite helpful in going through this and last week's assignment.
- If your prior step was successful, you should now be able to load programs onto your chip by just using the FTDI serial connection to your board and the Arduino IDE (i.e. you no longer need a separate programmer). Test this with the Blink Sketch provided in the Ardunio Examples library. Make sure to both Compile and Upload your new code, and check to see if the LED is blinking as expected.
Reading sensor output
Now that your board is able to receive new programs, you can begin reading data from your sensors. It's helpful to start with a sample sketch for your sensor, if you have picked a sensor for which there are adafruit tutorials (such as the LSM303dlhc, that I'm using on this breakout board set). To get started, you'll also want to download the arduino/adafruit libraries for the sensor in question, if they're available. I downloaded the generic Sensor and LSM303DLHC-specific adafruit libraries, and saved the unzipped folders to the proper Arduino "libararies' folder in your application's data files. In addition, it's helpful to know that Arduino programs have their own numbering systems for the 328p pins, as seen below:
Below, you can see the sample arduino sketch that prints out the X,Y, and Z coordinates of the accelerometer data to the serial output window (behind the Tools menu selection pane), and what this output looks like. The output for the magnetometer is quite similar.When you first open the serial output window, make sure the baud rate is set to match what is defined in the script. .
"Outputs" for this ciruit
Because I am using this week to continue design work on my final board, I did not explore more complex "output" options like servos. I am most interested in outputing sensor data from the self-assembling geodesic dome and analyzing this properly. I did however include an extra output LED on digital pin 13 to be able to communicate status visually, either based on sensor data (what it's currently programmed to do) or based on an independently defined function that uses this output (say, to blink only when all the tiles have joined and assembled correctly...presaging my work in the networking week).
Processing Application over Serial
The Application Approach
I decided to try various attempts at visualizing both the X, Y, Z accelerometer data and the X, Y, Z magnetometer data. My idea for using the former is to detect free-fall conditions in the accelerometer data and depict a free-falling ball on the screen when these conditions are met (i.e. acceleration only due to gravity). For both sensors, I will also do a straightforward plot of X, Y and Z values over time. For the magnetomer, I'm envisioning a data viz of the earth and simulated magnetic field rings, where the apparent thickness of the rings get stronger or weaker depending on the Gauss readings. Eventually, I am looking for my sensors to measure the magnetic field strength of the earth from LEO, and these values should change slightly over the course of an orbit. I will need to procure special sensors for this, as the sensitivity of detecting changes in Earth's magnetic field from LEO requires magnetometers with a different baseline sensitivity. Below is an example concept drawing of the magnetic field, and the idea would be to dynamically vary the appearance of the field lines:
Processing is a great tool for getting started with visualizing sensor data. The basic approach is as follows:
- Plug in your sensor board to Arduino, open serial window to ensure sensor is writing data over the serial port (at the expected baud rate), and close serial window after verifying (or else processing won't be able to read the data in when the port is busy).
- Download processing, and open or write a script using the processing Serial library (availabe for input directly from the processing file menus)to read data from the serial port on your computer (you can check which port your computer is using by checking the bottom right corner of the arduino gui, or by running a USB serial list command in your terminal/command prompt of choice.
- Use the traditional processing draw() methods to visualize the data that the script is reading in from your board.
Digging into the code
Here's my Arduino script (chunked by function) that is reading the accelerometer data and formatting my board's sensor data for transmission over the serial port. A few notes on what it's accomplishing:
- I have intentionally formatted the serial stream to use parameters, for later robustness for dropped packets or a processing script that is a little smarter in what elements of data it wants to pull from the sensor in the future. By chunking the serial stream in segments preceded by these parameters (1,2,3, etc) I can lay a foundation for a smarter communication protocol. I also chose to send ASCII data (normal characters), but could have transmitted the data in raw byte format as well (which is often better for conserving memory and requiring less processing).
- Other than the Serial.print() lines, most of this code is boilerplate from the Examples menu that is included with the Arduino IDE once you have loaded the LSM303dlhc library.
- Use the serial monitor to read the SensorDetails section and check for any errors. This is how you'll know whether the sensor is a) outputting any data at all and b) whether it is outputting reasonably reliable, consistent data (or not).
Arduino libraries, global variables and displaySensorDetails function:
Arduino void Setup() loop, with baud rate setting and sensor detection:
Arduino main loop, writing sensor data from the board to the computer's serial port:
Here's my Processing script below that is receiving data over the serial port and graphing it. A few notes on what it's accomplishing:
- Expecting specific parameters to aid in parsing the serial string
- Using the ControlP5 library for a live-rendering gui of the sensor data (allows incremental "pushing" of data)
Processing libraries, global variables and setup() loop for serial connection and canvas creation:
Processing draw() loop, checking for data on the serial connection before trying to parse and push data to a chart:
Processing parseInput() function, testing for comm protocl parameter variables and assigning variables to store the serial stream values of interest:
Processing initiatlizeGraph() function, setting graphing parameters particular to the ControlP5 library and loading data for the chart:
Output from processing script
Below, you can see the visualized graph, overlaying the X, Y and Z coordinates of the accelerometer data over time. The two subsequent photos show physical flips of the board where the green (), blue (), and red() lines swap positions as the board is turned over.
A few notes on this week's assignment
- Beware trying to reprogram a chip that is running a constant-send serial output. Because the chip is programmed over the tx and rx pins, you may catch the chip while in a loop that's using those tx and rx pins for the previously-programmed serial output.
- To make this processing script more robust, I will eventually modify it to request only the data it needs from the sensor (via parameter selection), rather than accepting all data that is sent
- Instead of setting separate global variables to capture the various serial inputs, I should create an event data structure (like events.accel.X, etc)
- In the future, I could improve this code by considering edge cases (such as when it doesn't find an /n character to end the line, what should happen so it doesn't get stuck in that test loop)
- May need to check the sensor initialization values for proper calibration later (some values were not making sense and might be an overflow range issue)
Attempt at using p5.js for the sensor visualization
Trying a second method, now that the Processing method was successful--> First, I'll need to download some p5 libraries and examples to work off of. Because this application will be built for the browser, I don't need a special application or programming environment--rather, just an editor and the ability to pin samples up to Chrome or Firefox. Below, you can see the rich list of examples from p5, the p5 serial library (required for being able to read from the serial port that my board is sending data over) and a read-me for this library. You can find these materials here
Below, you can see some getting started code, for reading from the serial connection and drawing an output based on this data. I am still working on troubleshooting the proper connectivity in p5, as the p5serialserver utility that is part of the install instructions does not appear to be successfully relaying the serial data from arduino to the browser application (browsers, obviously, cannot read data over a computer's serial port, so this extra node server step is required)
This week, we design and build a wired and/or wireless network connecting at least two processors. I am hoping to use this week for my final project board, where tiles will communicate over Bluetooth Low Energy. I'm planning to use an HM11 module, pictured first below, but also considered the ESP-32 for its many integrated functions (pictured below, underneath).
The bluetooth scenario for my tiles is as follows: Use a BLE connection to send data from the sensor to a nearby computer running a processing script for data visualization. For my final project demonstration, I plan to broadcast the accelerometer and magnetometer data from a specially outfitted tile to my laptop's Bluetooth receptor, where processing will then read in this input as if coming from a serial port. In considering the HM11 for the chip design, I am primarily interested in the ability to hook up the BLE module over the Tx and Rx lines. However, size considerations (I want the full circuit to fit on a tile just a few cm across) also led me to choose this smaller BLE module (over say, the more complicated ESP32).
My networked, final project board will include:
- 6 DOF LSM303dlhc accel + magnetometer (plus a built in temperature sensor)
- Gyro (perhaps in a later version, did not make it into this particular design)
- ATMega 328p
- Voltage regulator, 8MH resonator, 3 Leds, capacitors & resistors as required
- Programming ISP header and FTDI
To begin, I needed to mill a new sensor board, building on the design I fabricated in the Inputs & Outputs week (prior version here.) Below, you can see the redesigned primary circuit, condensed to fit within a hexagonal perimeter that fits my 3D printed tiles and a narrow, powered interface board for the HM11 module. Regarding the interface boards I'll need for this week--one bridges the chip board and the BLE breakout board providing power to both and connecting the Tx and Rx lines, and Neil's design for the HM11 "hello world" board provides a way to interact with this module.
Below, you can see the PCBs assembled on the tile, powered with a 9V battery to allow operation without requiring power over FTDI and connection to my laptop (as in my previous boards).
Below, you can see a close-up of the bluetooth module that will be connected over FTDI to my computer, to act as the "receiving" channel for the data sent over the BLE HM11 attached to my main board. After this photo, I ended up connecting the module to the computer in a different manner, as documented later.
The following photo shows the full hardware setup, with the sensor board (a modular component) attached to the headers on my main chip board (the hex tile), connected over FTDI-style vinyl cut copper hinges (to allow freedom of motion and the bonding angle of the assembly) to the HM11 bluetooth module. This first HM11 communicates the data from the chip board (sent over I2C from sensor to the chip) to the HM11 wired directly to my computer. The module wired to my computer receives the data over BLE and my computer reads it in over a COM port (as I'm using the FTDI serial connection) and can display a live rendering of the sensor data over time via a processing script.
For the code I'm using on the 328p chip and the processing script, see the prior Application Programming week. I have made minor modifications to also show magnetometer data, and to match the baud rate from Arduino defaults to the baud rate of the BLE modules (in my case, 115200). Note on the baud rates for BLE modules---if you are trying to communicate between two BLE modules that come with different default baud rates, you can set a new baudrate via "AT commands." More on this in a moment...
For more on AT commands and how to configure the HM11 module, read the datasheet here. Below, I show the result of giving AT commands over the arduino serial monitor to the BLE module currently connected to my computer. I connected both BLE modules (at different times) to program them at the same baud rate, name them and confirm they were exhibiting the expected behavior. I programmed the BLE module that was to be connected to my computer as the orchestrator/host or, due to the unfortunate standard BLE protocol naming, the "master" (while the other module is by default the peripheral or "slave").
Once my sensor+chip board is powered on and transmitting data over BLE, I need to tell the two BLE modules to connect. You can do this with the following sequence of commands, also shown in the picture below:
- AT (response should show "OK")
- AT+DISC? (for discovery of other nearby devices, should show a list with MAC addresses)
- AT+CON[MAC address from prior result, for the device you want to pair with] (should look like "AT+CON123456789101" with 12 digits that correspond to your other device)
The screenshot below shows the result of a successful pairing, where sensor data is being received by the computer's local BLE module connected over FTDI, and successfully interpreted by the arduino serial monitor (over COM port) at the 115200 baud rate.
The three following videos summarize the successful BlueTooth pairing, communication of sensor data over BLE and demonstrate the live responsiveness of the accelerometer and magnetomer to appropriate stimuli
Final Project Complete!
My final project is now complete, with a fabricated prototype that includes magnet-jointed tiles (for later self-assembly testing in zero gravity), augmented with circuitry that reads sensor inputs, communicates a visual output via LED, sends data over BLE, and visualizes the data by an application coded in Processing.
Summary of weeks represented by this project:
- Computer-Aided Design/Modeling
- Computer-Controlled Cutting (vinyl cutter could be used for the copper hinges)
- 3D Scanning & Printing
- Electronics Design
- Electronics Production
- Embedded Programming
- Interface & Application Programming
- Networking and Communications