The Incredible Instructobotronical Wonder Box!
by SpenceWilder in Circuits > Electronics
8801 Views, 39 Favorites, 0 Comments
The Incredible Instructobotronical Wonder Box!
As a designer, you hear clients ask "can you make the logo spin?" a lot, and it sticks with you. As I pondered this challenge, the Muse whispered in my ear: "can you make that adorable robot into a noise box?" Challenge accepted.
I'm a teacher, and I encourage students to embrace the iterative exploratory nature of the creative process. Instead of a concrete goal with specific predetermined steps, I took advantage of this prompt to play. Fearlessly. That said, this is an Instructable after all, so here is my thought process that led to the steps outlined herein.
First I would make a 3D model of the robot. Then I would 3D print the robot to use as an enclosure for not only a contact mic based noise box, but also an Aruduino synthesizer of some kind, using the Mozzi synth library. The robot has some buttons, and a cartridge slot, something to ponder as I began making the 3D model. And with no more of a plan than that, I began.
Supplies
After some experimentation, this is what made it into the final project:
(Note: not all parts pictured above)
- 3D printer filament (glow in the dark is fun!)
- Arduino Nano or equivalent (Uno pictured would have fit in the enclosure, but I used a Nano)
- Arduino compatible audio amplifier (HW-301 or similar)
- Piezo contact mic (I had 35mm on hand)
- 1 x 1/4" mono audio output jack
- 2 x resistors 10k ohm (for combining the audio outputs of the mic and the synth)
- 3 x potentiometers 100k (to control pitch, rate, and modulation)
- 3 x pushbuttons (to stop, start, and hold synth output)
- 3 x resistors 1k ohm (for the buttons)
- 2 x LEDs (so the eyes pulse with the audio, duh!)
- 2 x resistors 220 ohm (for the LEDs)
- An assortment of strong magnets (for holding the enclosure together)
- Solderless breadboard, wire, solder, heat shrink tubing
Software used:
- Autodesk Maya
- UltiMaker Cura
- Arduino IDE + Mozzi Audio Library
- Fritzing (for the circuit diagram)
3D Modeling
I downloaded an image of the robot and imported it into Autodesk Maya to make a reference plane. From there I used simple shapes to block in the form. I used cubes for the head, body, and arms; and cylinders for the legs, buttons, and eyes. Adding subdivisions and smoothing the cubes, I began refining the shapes to more closely match the logo. Finally I manipulated individual edges and edge loops to add details and personality. I exported the elements as separate STL files for preparation for printing. While I created the antennae and fingers, I knew that I would use wire for those, so I omitted them in the exported files.
3D Printing
I imported the STL files from Maya into Cura, my go-to slicing software. After scaling and arranging optimally, I exported print-ready GCODE files to use with my Creality Ender 3 Pro. The head was the only part that needed supports, as it's curved with no flat suface to align to the printer bed. In hindsight I could have made the back of the head more square. Also of note, I printed the body with no bottom, so I'd have access to the inside. I figured "I'll make that later, easy peasy". I subsequently made two bottom parts that were each a little too small, and that's how I ended up with the elaborate base!
Painting
First I sprayed one thin coat of yellow on all the robot parts. And I sprayed the base a brownish bronze color. Having painted glow in the dark filament pieces before, I've learned that it glows even through a coat of paint. Pretty cool.
Then I carefully drilled the holes for my components.
Next I painted the red details and added the wire elements. He's really starting to come alive!
Noise Box Prototype
While I've used contact microphones to amplify acoustic instruments, I've never built a proper noise box. There are lots of examples on Instructables if you're interested in a more thorough overview. I simply wired a piezo contact mic to a 1/4" output jack to test the audio output.
The Arduino Synth
While this may seem like the most time consuming step, thanks to the generous example code provided with the Mozzi library, it went pretty quickly. I was going to add 3 potentiometers to the back of the robot. But during the 3D printing process, it occurred to me that I could use the pots to attach the head and arms! So I built a circuit on a solderless breadboard that included 3 buttons and 3 potentiometers.
After installing the Mozzi library from within the Arduino software, I tested several example files until settling on this file as a starting point: Knob_LightLevel_x2_FMsynth (located under Files>Examples>Mozzi>3. Sensors). This sketch uses light sensors for input. I simply replaced them with potentiometers.
I incorporated some code from the Start_Stop example file (Files>Examples>Mozzi>2. Control). And I added some code to pulse the LEDs when the output was above a certain level.
/*
Tim Barrass 2013.
This example code is in the public domain.
*/
#include <MozziGuts.h>
#include <Oscil.h> // oscillator
#include <tables/cos2048_int8.h> // table for Oscils to play
#include <Smooth.h>
#include <AutoMap.h> // maps unpredictable inputs to a range
// desired carrier frequency max and min, for AutoMap
const int MIN_CARRIER_FREQ = 22;
const int MAX_CARRIER_FREQ = 440;
const int MIN = 1;
const int MAX = 10;
const int MIN_2 = 1;
const int MAX_2 = 15;
// desired intensity max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_INTENSITY = 700;
const int MAX_INTENSITY = 10;
// desired mod speed max and min, for AutoMap, note they're inverted for reverse dynamics
const int MIN_MOD_SPEED = 10000;
const int MAX_MOD_SPEED = 1;
AutoMap kMapCarrierFreq(0,1023,MIN_CARRIER_FREQ,MAX_CARRIER_FREQ);
AutoMap kMapIntensity(0,1023,MIN_INTENSITY,MAX_INTENSITY);
AutoMap kMapModSpeed(0,1023,MIN_MOD_SPEED,MAX_MOD_SPEED);
AutoMap mapThis(0,1023,MIN,MAX);
AutoMap mapThisToo(0,1023,MIN_2,MAX_2);
const int KNOB_PIN = 4; // set the input for the knob to analog pin 0
const int LDR1_PIN=5; // set the analog input for fm_intensity to pin 1
const int LDR2_PIN=6; // set the analog input for mod rate to pin 2
const int LDR3_PIN=4;
const int LDR4_PIN=3;
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aCarrier(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, AUDIO_RATE> aModulator(COS2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kIntensityMod(COS2048_DATA);
int mod_ratio = 5; // brightness (harmonics)
long fm_intensity; // carries control info from updateControl to updateAudio
// smoothing for intensity to remove clicks on transitions
float smoothness = 0.95f;
Smooth <long> aSmoothIntensity(smoothness);
#define STOP_PIN 2
#define START_PIN 3
#define EXTRA_PIN 4
boolean pause_triggered, paused = false;;
unsigned int count = 0;
void setup(){
Serial.begin(115200); // set up the Serial output for debugging
pinMode(STOP_PIN, INPUT);
pinMode(START_PIN, INPUT);
pinMode(EXTRA_PIN, INPUT);
pinMode(5,OUTPUT);
startMozzi(); // :))
}
void updateControl(){
int freqVal = mozziAnalogRead(LDR3_PIN); // value is 0-1023
int FRQ = mapThis(freqVal);
int knob2 = mozziAnalogRead(LDR4_PIN); // value is 0-1023
int knob2Val = mapThis(knob2);
// read the knob
int knob_value = mozziAnalogRead(KNOB_PIN); // value is 0-1023
// map the knob to carrier frequency
int carrier_freq = kMapCarrierFreq(knob_value);
//calculate the modulation frequency to stay in ratio
int mod_freq = carrier_freq * mod_ratio * FRQ;
// set the FM oscillator frequencies
aCarrier.setFreq(carrier_freq);
aModulator.setFreq(mod_freq);
// read the potentiometer on the width Analog input pin
int LDR1_value= mozziAnalogRead(LDR1_PIN); // value is 0-1023
int LDR1_calibrated = kMapIntensity(LDR1_value);
// calculate the fm_intensity
fm_intensity = ((long)LDR1_calibrated * knob2Val * (kIntensityMod.next()+128))>>8; // shift back to range after 8 bit multiply
// read the potentiometer on the speed Analog input pin
int LDR2_value= mozziAnalogRead(LDR2_PIN); // value is 0-1023
// use a float here for low frequencies
float mod_speed = (float)kMapModSpeed(LDR2_value)/1000;
kIntensityMod.setFreq(mod_speed);
// Stop Mozzi when STOP_PIN is pressed
if (digitalRead(STOP_PIN) == HIGH) {
pause_triggered = true;
}
// Start Mozzi when START_PIN is pressed
if (digitalRead(START_PIN) == HIGH && paused) {
paused = false;
startMozzi();
}
}
int updateAudio(){
long modulation = aSmoothIntensity.next(fm_intensity) * aModulator.next();
return aCarrier.phMod(modulation);
}
void loop() {
updateControl(); // Update control logic
if (pause_triggered) {
paused = true;
pause_triggered = false;
digitalWrite(5,LOW);
delay(100);
stopMozzi();
if (paused) {
//Serial.println(count++);
delay(100);
} else if (!paused) {
audioHook();
}
if (fm_intensity > 50 && paused == false){
digitalWrite(5,HIGH);
} else{
digitalWrite(5,LOW);
}
while (digitalRead(EXTRA_PIN) == HIGH){
fm_intensity = 100;
}
}
}
Once I had the knobs and buttons working, I added the contact mic, which wasn't as loud. So I added a little amp to the contact mic output.
In the circuit I added 10k resistors to the output from the contact mic amp and the output of the Arduino synth. That combined output was soldered to the 1/4" mono output jack. I chose this type of output, as I intend to use it with guitar pedals. Noise box + delay pedal = instant horror movie soundtrack!
Wiring the Head
Fishing the LED eye wire through the head was perhaps the most challenging part of the project. I drilled out a wire channel, which with the infill made it tricky to push the wires through. If I were doing it again, I would include provisions for the wiring in the 3D model design.
I sanded the bell lip at the bottoms of the LEDs to insure they'd slide in to the eye sockets. I cut the legs shorter, AND I remembered to put the heat shrink tubing on before soldering! Tinning thin braided wire makes soldering easier. Testing at every step is always prudent, and it's a good motivator. It's aliiiiive!
Putting It All Together
I had two questions from the onset of the project:
- How's he going to stand on those tiny wheel feet???
- Shall I use a small breadboard, or solder everything onto stripboard?
I decided to try strong magnets for attaching the robot to the base. I carefully drilled holes and glued in the magnets.
Next I soldered wires to the buttons and pots, and affixed them to the robot body.
And since my Arduino came with header pins, I used a combination of a small breadboard and resistors soldered into the wiring to the components. And because of the relative small size of the enclosure, it's a kind of a mess in there.
I Guess There's a Base Now?
The two first attempts at printing a bottom for the robot enclosure fit together to make a nice little box. Hey, I can make a base for the little guy to stand on! One of my favorite parts of the tabletop miniature gaming hobby is making the bases. So I have small rocks and grass flock on hand. As I worked, I was using the extra parts as a tray for my small components, noting how resonant thin 3D printed boxes are. It occurred to me to make the base do double duty as a shaker. So I took a fresh air break to get some canna lily seedpods to put inside. Hobbyists take note, they also make excellent miniature cannonballs.
Let's Play With It Already!
Behold! A demonstration of The Incredible Instructobotronical Wonder Box, in all of its glow in the dark splendor!
Reflection
I had a blast making this thing. And I enjoy "playing" it almost as much as my modular synth system. I already have some improvements in mind. Here are my thoughts for version 2:
Add springs and other metal bits to the outside of the enclosure, to give the noise box aspect more variety. I intended the antennae and fingers to transmit more sound, but that resonance was lost in the move to make the head and arms the knobs.
Add a second contact mic to the base, to pick up the shaker sound. Experiment with running the wiring through the magnets that secure the base, which could lead to adding LEDs to the base!
Last, I'd like to come up with a lo-fi "cartridge" system, to take advantage of the slot in the belly, flat plastic parts with copper strips that make contact with parts inside to alter the sound somehow.
I thought of adding battery power, a speaker, and delay or reverb effects from Mozzi to make it self-contained. But as it is, it's a welcome addition to my other odd desktop synths and noise boxes. I hope you've enjoyed accompanying me on this creative journey, and I hope it's inspired you to try something similar!