Wow, it’s been a while since I posted anything. In the last four or so years since I’ve posted, we’ve moved out of NYC to North Carolina, have had two additional children (Micah and Anna) and are still making videos, though less frequent. Here is a recent one of a pool build project in our backyard.
Skittle Sorter
I had been working on a machine that sorts skittles by color. It’s made out of 3D printed parts, PVC pipe and some aluminum extrusion. It was a fun challenge, since I have given myself only a week to work on it. The entire design is from scratch, some parts are scavenged, some parts are there because it was all I could find. Between bouts of exhaustion, I remember how much fun and gratification there is in building something that exists physically, with the challenge of a deadline and the creativity that comes from using whatever is available.
My Four Year Old Can Solder
AngularJS: Tool for Invoicing Customers
I was looking for a light-weight tool for generating HTML invoices. I wanted the tool to be easy to theme. What could be easier to theme than an HTML document? I ended up rolling my own, it’s a project in progress. As of now, all of the functionality is client-side. It uses AngularJS and nicely separates the layout from logic in true MVC fashion. Check out the preview:
In the future, there will be some sort of backend for saving common elements, sending invoices to clients and keeping track of paid / unpaid and accounts receivable. Until then, invoices can be printed to PDF and JSON data is generated that can be loaded up again to edit later. The interface allows for editing in place. Follow and contribute on GitHub https://github.com/randysofia/invoice/
Try it out here: http://www.randysofia.com/invoice/client/src/template.html.
Fisherprice Record Player Hack (Schematic and some code)
It’s been a while since I’ve posted progress on replacing the childrens songs in my son’s toy record player with full albums. Many who have seen it have asked to see schematics and code. When I get more time, I’ll post another video.
Schematic:
Code:
This code is running on an Arduino Uno. On the SD card I have named each track sequentially: track001.mp3, track002.mp3 etc.. Regarding nomenclature, tracks are not separated by albums. Instead, records[] is an array with each element containing the number of tracks in each album. needle[] is an array of inputs from the needle head (analog pins A0-A3) that I treat as binary and convert to decimal using the bit() function. This is how I map physical records to a particular set of mp3 tracks. It calculates what track to start on depending on how many tracks are in each album. So for example track012.mp3 starts the first track in the ‘Who’ album, which has a decimal equivalent of 6 represented in binary by the buttons on the physical player’s needle. The physical record has grooves that push down on the buttons on the needle (see video in last post). I use speaker_onoff to turn off / on an opamp to stop an annoying click that I encountered when changing tracks.. There is a physical pull down resistor (see schematic) to keep it off by default and pull it high with the controller only after it starts playing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include <SPI.h> #include <SdFat.h> #include <SdFatUtil.h> #include <SFEMP3Shield.h> SdFat sd; SFEMP3Shield MP3player; // Inputs correspond that correspond to head on record player int needle[]={A0, A1, A2, A3}; int old_album=99; int speaker_onoff=5; // Pin to turn off the op amp void setup() { pinMode(speaker_onoff, OUTPUT); digitalWrite(speaker_onoff, LOW); for (int i=0; i<4; i++) pinMode(needle[i], INPUT); randomSeed(analogRead(4)); Serial.begin(9600); //start the shield if(!sd.begin(SD_SEL, SPI_HALF_SPEED)) sd.initErrorHalt(); // newly required in 1.01.00 and higher MP3player.begin(); } void loop() { int album=0; // convert record player needle buttons to decimal for (int i=0; i < 4; i++) if(digitalRead(needle[i])) album+=bit(i); Serial.println(album); // Check if user change the record if (album!=old_album && album!=0) playalbum(album); else if (album==0) MP3player.stopTrack(); old_album=album; delay(100); } void playalbum(int album) { digitalWrite(speaker_onoff, LOW); MP3player.stopTrack(); int album_begin, album_end, track; album_begin=0; //0zeppelin, 1who, 2jethro, 3doors, 4deep purple, 5sabbath, 6clapton, 7queen int records[] = {0,0,0,0,0,11,10,8,0,6,7,8,12,5}; // Calculate what track to start on depending on the album for (int i=0; i<album; i++) album_begin+=records[i]; album_begin++; album_end=album_begin+records[album]; // Pick a random track in the album and play it. track=random(album_begin, album_end); MP3player.playTrack(track); digitalWrite(speaker_onoff, HIGH); } |
Hacking the Fisherprice Record Player, 2010 Version
Isaac Masters the Drill Press
Making an Engineer
Isaac was two years old here:
Luke was just barely one years old here: