Hackerspace on Treasure Hill

Visiting FabLab Taipei and OpenLab Taipei


Though I griped about Chinese internet censorship, FabLab Taipei was the real reason I hopped on a plane for a detour the last few days of my trip. Their facebook group is always sharing amazing projects and a video I saw at Fab11 of their Maker Faire showed a big, active, and creative community. I messaged the group the day before I arrived but didn’t hear back, so I got in touch the old fashioned way and showed up at their door.

I was greeted by a man named Sega Liu, who was working on his iteration of a fold-up 3D printer. He gave me a tour of the multi-room facility, which was punctuated by a number of surprising projects: incredible corrugated cardboard & resin surfboard (Ah cardboard, always reminds me of home), intricate laser cut wood paneling and an impressive cardboard-folded giant frog mask. The lab was stocked with capable machines, including an assortment of 3D printers, the familiar Roland circuitboard milling machine, and a very heavy duty CNC machine that doesn’t get much use (it runs the unfortunate Roland software, though it accepts plain text serial data not so different from GCode, so perhaps the more modern & open source ChiliPeppr could be modified to control it.) There’s a sizable laser cutter, lots of electronics equipment, and in the basement: a comprehensive wood-shop.









I felt immediately at home in the space, which had a lot in common with CUCFabLab: it is open to the community relatively late at night (every day 6–10PM), has every machine you could possibly need to make awesome stuff, and a lot of the furniture, well, has a hand-me-down feel (which I like better than the try-not-to-scratch-the-table newness of some places. Gives it character 😉

I chatted with Sega about my work back at CUCFabLab. It always surprises people to think FabLabbing could be a full time job. FabLab Taipei, like many hackerspaces, is all volunteer. I told Sega about how CUCFabLab has grown from an all volunteer staff to employing a dozen people at times (though I’ll write another time about the trade-offs in establishing a paid staff among volunteers). At some point in all this he decided that Ted, the main benefactor of the lab, would want to meet me and called him back to the lab (I guess I had just missed him).

Ted told me about the history of the lab, and how they use to have membership fees but eventually switched to free membership after establishing that it was a hard sell and wasn’t helping much with rent anyway. Apparently, Taipei is awash with low-cost designers and prototypers to the point where even university students don’t design things for themselves, they can hire someone to work for them for the price of a typical hackerspace membership. It is an interesting problem in Taiwan as in China, when building things is seen as something of a lower-class occupation: how do you catch people’s interest with the prospect of “Do It Yourself!”

Of course, the premise of a FabLab is to create something new, and in my experience learning to use a machine gives you a lot of ideas about what can be created with it — so if you want to design something (even to have someone else build it), if you want to be innovative, you could start by learning the various styles of fabrication. I think as people’s interest is piqued by the surprising inventions exhibited at Maker Faires and workshops, they will be enticed to try it themselves.

After telling Ted that I was interested in learning about as many maker communities as possible, he said “We better get over to OpenLab then, you can come to FabLab any night but OpenLab is Wednesdays, lets go.”


Exterior of FabLab Taipei, Interior of cab across town.

Ted hailed a cab to take us across town to OpenLab Taipei, past a temple and through narrow corridors. I had just read about this neighborhood earlier that day: an illegal settlement of improvised architecture that the city chose to preserve and transform into a collective of artist studios called Treasure Hill. I was surprised to find out that a hackerspace was nestled among the concrete cubes stacked up here, but it certainly fit in among the artist studios.

The most striking project sitting on the shelf was a 3D printed Immorton Joe mask complete with ribbon cable hairdo. A very DIY shortwave radio built with point-to-point soldering on a copper board was being tuned into Chinese music. Scattered on the table were other projects in progress including a recycled CD drive pen plotter. A pile of vintage diagnostics gear completed the hackerspace aesthetic, and an impressive laser-etched stamp stood ready to print more banners for promoting the space.






We were just here for an hour before people were packing up. Ted and I took the metro one stop to the Shida night market to keep chatting about maker communities. There was some fantastic barbeque chicken (was that cinnamon? Five spice?) and instead of bars in this area there are convenience stores with barstools in a sitting area — kind of neat, you pay convenience store prices for a bar experience. We talked about 3Nod underwriting Fab12 and how Fab Academy would work for a Chinese student body (the material will be translated on a rolling basis and Chinese fab labs will work a few weeks behind English language labs).

The next day I visited the Treasure Hill artist village again, this time in the daylight. It has fantastic art scattered around the open areas and on top of roofs. I peaked into a small cafe called Tadpole Point and saw they had burgers with fried egg on the menu so I put in an order and browsed the art books lining the wall. The room had a great view out the screen door overlooking the interstate and the valley. According to wiki this location was originally fortified for anti-aircraft defense, but it’s a good place to enjoy the scenery, too. With a great burger served on a solid wood butcher block and a breeze through a window of the poured concrete room, I reflected on how cheap materials can be arranged so elegantly, in the case of architecture and for food.









Unfortunately I didn’t get to find out more about the Conductive Ink Experiment nor the More Than Useful Detective Lab.

Coding in Shanghai: Javascript Hackathon


One Friday night, googling (or, baidu-ing?) for “things to do in Shanghai,” I found out about a hackathon being held the next day: 24 hours using MeteorJS to build a web app. Perfect! I’d built a dirt simple sign-in sheet with NodeJS and Javascript, but my code was already getting messy so I shelved it until I was ready to rewrite it from scratch. The hackathon was just the excuse I needed to try a modern framework (i.e. someone else’s code that does most of the work for you) to rewrite my sign-in sheet for the FabLab’s many machines. And hey, if it’s polished enough, maybe other FabLabs would want to use it, too.

I was finally getting used to Shanghai’s metro system and found the Agora Co-working space without any trouble. It’s a beautiful office with a garden out back and the wifi was the fastest I’d gotten anywhere in China. I liked the place right away.

This was my second hackathon (after the People’s Music School Hack Music) so I was a little more proactive about introducing myself and what I wanted to do. Pretty quickly, a small team assembled around my laser-sign-in sheet project, but it was a bit every-man-for-himself as far as learning MeteorJS goes. We were all there for the same reason, to try out the new framework, but without any kind of guided introduction / classroom situation, we were left to read the docs and getting starter guides, which isn’t really a group project.

But after a couple hours, I felt like I was learning a lot and my teammembers felt they had worked through enough of the tutorials that were ready to work on something together, but then we were all new at collaborative coding, too! Especially for a one-page app, it’s difficult to divvy up the work. We didn’t figure that out until after an hour of learning to use github (another good learning experience, though, cloning and committing and all that, that’s definitely a good thing to work through with other people in the same room instead of just reading a getting started guide.) Once we could finally push and clone each other’s code we arrived at the question of how to split up the work. We all took a stab at creating a good foundation to work up from, but were all using our own preferred approaches and stepped on each others feet when we tried to merge our ideas together, so when were getting settled in after dinner and my team members asked what we should work on, I said:

“I want to suggest that we all do whatever we want to”

And that worked out pretty well. A sign in sheet is a simple enough app that we could all write it from scratch, and this way we could experiment with the approach that interested us instead of trying to come to agreement on what tools to use together. So from then on out we worked on our own thing, snacked in the kitchen on occasion, and put on our headphones to focus whenever we wanted, and I think we all had a good time. I stayed up late and slept on that giant beanbag in the first picture.

In the morning I showed my progress to a few guys (it works, but it doesn’t have a way of saving the data or reseting each day, yet), but had to bid them farewell before the end of the Hackathon to get across town for the Shanghai Maker Carnival. It was great to find some friends in such a big city and feel like I was on a programming team (however dysfunctional) for a day.

Pictures posted on their Meetup by Julian:






Voice Controlled Web Apps Pt. 2 (Windows)

NodeJS, Client Side Javascript, and Google Speech API

Part 2 in a 5 part series. Part 1 is here.

This section of the tutorial introduces “client side javascript” — running code alongside HTML in a web browser. We won’t be building a beautiful site. Instead, I’m going to introduce as little as possible to get results so you can move onto controlling lamps and motors and other internet-connected-things. Hopefully you can combine this with your own knowledge or other tutorials to build the application you want.

At this point you should have two files, a server.js and an index.html sitting in the same directory.

https://gist.github.com/jazzyjackson/6ae764d24ead285f9ba1https://gist.github.com/jazzyjackson/fed240a94065486427fa

For this part, we’ll just be working with index.html, so you could simply point your web browser to C:/your/file/path/index.html and it will work fine, but why not get in the habit of starting your node server? You’ll see changes to index.html reflected when you refresh the page either way.

The history of HTML is a jumbled one with many actors. Lots of people were taking stabs at building websites and lots of people were writing web browsers that did their best to render a useable website from everyone else’s code. The modern day result of this is that the web browser is a very forgiving platform that lets you leave all kinds of stuff out, and lets mistakes go without complaining too much. That’s actually one reason why I’ve heard some people discourage javascript as a first programming language: you can make a lot of mistakes and there’s not a compiler to tell you what you did wrong, the web browser will try to run anything it can and ignore whatever doesn’t work.

Use the “Inspect element” to find out how Chrome interpreted our 4 lines of HTML:


Our file only contained <h1> tags and the <script> tags. <html>,<head>, <body>, and this mysterious “#shadow-root” were all added by the web browser before rendering. On top of that, in the bottom-center there’s styling added on to the <h1> element: all of this display: block; font-size: 2em; -webkit-margin-before etc. is added by Chrome to make our barebones HTML code look presentable. So like I said, you can leave a lot out and modern web browsers will figure out how to render your page anyway.

OK, I promised an interactive web page, so let’s change that header <h1> into a button <button>. If you don’t know: in lots of text editors Ctrl+H will bring up a “find and replace” menu. We’ll also add an “id” attribute inside the opening button tag: this is a name you give individual elements so you can write javascript that acts (or listens to) those elements.


Here, ‘onclick’ listens to that ‘myButton’ element, ready to react to a click at any moment. This is different than, for instance, programming an Arduino, where we’d have to check whether a button is pressed continuously in an infinite loop. Instead, we can write a function that executes only in response to the web browser noticing that the user clicked their mouse while hovering over the button element. This is “Event driven programming.” (You actually can do event driven programming with Arduino, if you know about hardware interrupts.)

While chaining those identifiers and functions all together on one line works OK, programming like that quickly gets hard to read. It’s much better practice to break it into pieces.

https://gist.github.com/jazzyjackson/485a3e771b6488f85f77

  1. Create a variable called button and assign it the myButton element.
  2. Create a function called speak, which calls on the alert function to say hi.
  3. Attach the ‘onclick’ event listener to the button variable and assign the function named ‘speak’ as its action.

I included two ways you could create the speak function here that would work equivelantlly in this case. There are specific cases where you should choose one or the other that involve global vs local scope (great info on the subject here), but for now it’s just important to know that there’s more than one way to do it. Hopefully keeping that in mind will make reading other people’s javascript examples less confusing.

Buttons default to ‘block-inline’ style, and appear on the same line

Let’s move on to a button that changes the background — this will set us up for turning a lamp on and off. The buttons have separate IDs, and each button is assigned to a new javascript variable.

https://gist.github.com/jazzyjackson/b6b0ca575a6d295bcc6c

Header elements default to ‘block’ style and appear on separate lines

By the way, you don’t have to have a button element to be able to click on it. I like the look of h1 better, so I’ll just click on those. I’ll change the color style of the h1 elements with each click as well. (side effect: button elements default to a block-inline style whereas header elements default to block style)

https://gist.github.com/jazzyjackson/f5b280709ea785d8812b

In the next section, we’ll plug a lamp into an Arduino:


Recommended Reading:

http://eloquentjavascript.net/13_dom.html
http://eloquentjavascript.net/13_dom.html

Note: “Handling Events” recommends using ‘addEventListener’ instead of ‘onclick’, which is a better way to do it. Onclick events are limited to one-per-element, whereas you can ‘addEventListeners’ as much as you want. But for a simple example I like the syntax of .onclick better.

Voice Controlled Web Apps Pt. 1 (Windows)

NodeJS, Client Side Javascript, and Google Speech API


This series will introduce newcomers to web programming using a few of the latest tools available. I’ve dabbled in building web sites since Microsoft Frontpage 2003 came out, but always ran into frustrating inconsistiences (casualties of the browser wars) and intimidating combinations of programming languages to start a server and handle user interactions (PHP, AJAX, HTTP POST and GET, yuck).

Recently I’d been hearing a lot about Node.js, software for building web servers with javascript. When it was introduced at JSConf in 2009, it received a standing ovation. When was the last time you heard of a new technology receiving a standing ovation? With all of the hype surrounding NodeJS, I decided to dabble again and was swept off my feet by the fact that I only have to know one language. Javascript is used to create the web server, and javascript is used to make the web page interactive. With added libraries, we can use javascript to control lights, relays, and motors with the use of Arduino, Raspberry Pi, Galileo, and others, and we can use the relatively new HTML5 web speech components to control all that hardware with voice commands!

Part 1 of this tutorial will walk you through installing the bare minimum on a Windows system (linux and MacOS instructions will come later) and serve up a ‘hello world’ HTML page.

Part 2 will introduce client side javascript — that is, programs that run in a user’s web browser to make the page interactive. We’ll start with a button that changes the background color.

Parts 1 and 2 could be switched, you could start with html and then learn how to start the server, as long as you do both before part 3.

Part 3 will use the excellent Johnny-Five library (meant for programming robots with javascript) to allow our webserver to control an Arduino. It could just as easily control the GPIO of a Rapsberry Pi, BeagleBone, or Galileo. Socket.IO will be uesd to send messages from the client to the server.

Part 4 adds voice control to the mix, explaining how to use the Annyang library to execute javascript functions (and therefore control attached hardware) within the web browser. I’ll also cover creating an SSL certificate here so the browser listens continuously without timing out.

Part 5 moves all of this functionality to the Galileo platform, which can run our web server and interface directly with other hardware, via digital I/O and serial communication.


Without further ado:

Install the Basics

Visit the official NodeJS website and download the latest. I’ll be using 4.2.2, hopefully they won’t change too much by the time you read this.

Pick out a good text editor: I’ll use Komodo Edit because it’s open source and lets me use Vi keybindings, but Notepad++ and Sublime Text are popular. Any of these will give you helpful features like syntax highlighting and auto-completion which make programming a million times more pleasant than trying to use notepad.

Go through the Next →Accept →Next →Next →OK →OK →Finish rigamarole of Windows installations to get NodeJS installed.

Next we’re going to do a javascript hello world. NodeJS is simply a program that executes javascript files. We’ll write a command in a javascript file, and tell NodeJS to run that file for us. This first program is just one line of code:

console.log("Hello World");

Type that into your text editor, and save it as something like ‘firsttry.js’ or anything you want as long as it has that .js file extension.

Next, open Powershell (you can hit start and just type ‘powershell’ and hit enter). This is a program you might never have touched, but it comes with Windows and has a lot of powerful features — it’s how we’ll control the webserver. But first, try a few commands, see what ls, cd, and pwd do. They stand for List, Change Directory, and Print Working Directory.


Once you’ve navigated to the folder where you saved your first js file, you can type node followed by the filename. This uses NodeJS to execute firsttry.js, which simply prints “Hello World” to the console — another word for the command line. We’ll use console.log() a lot, it can give status messages from the server running in the command line, and it can also give status messages in the web browser, which has its own console we’ll see later.

So that’s a pretty boring program, but it’s important to make sure that ‘hello world’ works if we expect to run a web server on our machine.

Of course, there are whole books written on and whole careers based off writing and running web servers. For our purposes, I want to provide this working model: a web server is a program that listens for requests, and fulfills certain requests however you tell it to. The ‘listening for requests’ is mostly handled for us, we just have to write code to respond to them.

The NodeJS documentation provides dozens of functions for this purpose, but doesn’t give a simple example. I’ll use a stripped-down example from this awesome instructable to get us started. You could copy paste this example code into your editor, but I recommend typing it in yourself to spend some quality time with each component.

https://gist.github.com/jazzyjackson/6ae764d24ead285f9ba1

If you haven’t coded much, this is a little crazy, but thankfully we don’t have to come up with this ourselves. This chunk of code actually handles quite a lot: it uses require() to import or include the ‘http’ and ‘fs’ (short for filesystem) features of nodejs. It creates a server object and starts listening on port 80. It answers any request by sending index.html back, and delivers a nice error message if it has any trouble.

To get your first website up and running, save this javascript file, and create another file that contains nothing but the phrase “hello world.” Or, if you want to work ahead:

<h1> Hello World! </h1>

console.log("Hello Console!")

Save that file as index.html in the same directory as simpleserver.js and go back to Powershell. Remember how to use node to execute a file? Try it on the javascript file containing the web server code.

The very first time you run javascript code that creates a server, you’ll get the following message (unless you have Windows Firewall disabled):


Make sure “Private networks” is checkmarked before clicking Allow!

I checked Private and Public, since I want to try serving webpages on networks besides my own. Windows will only ask you once! If you don’t allow both networks now, it’s a bit of a pain to change the settings later.

Once you allow NodeJS to communicate, you can open a web browser and try it: just type in ‘localhost’ in the address bar.


If you added that console.log(“Hello Console”), you get to check out the web browser’s console. That line of code executes inside Chrome and writes its message to Chrome’s console, found in the Inspect element menu. We’ll use this a lot later on, so now’s a good time to find it.

That’s all for part one. Next up is writing our own javascript (don’t worry, it won’t be as complicated as the server function, at least at first 😉

References:

http://www.instructables.com/id/Javascript-robotics-and-browser-based-Arduino-cont/step6/Create-a-web-interface-with-Bootstrap/
http://www.instructables.com/id/Javascript-robotics-and-browser-based-Arduino-cont/step6/Create-a-web-interface-with-Bootstrap/
http://www.instructables.com/id/Javascript-robotics-and-browser-based-Arduino-cont/step6/Create-a-web-interface-with-Bootstrap/

And NodeJS Documentation for FileSystem and HTTP.

Preparing FFMPEG for free screen capture, time lapse, and GIF making.

Debian

Put together some info from here and here and here.

Add deb-multimedia non-free to your repo and install ffmpeg with the following commands in your terminal:

su
echo deb http://www.deb-multimedia.org jessie main non-free >>/etc/apt/sources.list
apt-get update
apt-get install ffmpeg

That’s all! You’re ready to make screen captures and gifs.

Windows 7/8/10

Download and Install

First, install WinRAR or 7zip so you can open 7z compressed files.

Download the latest ffmpeg.

Adding ffmpeg to your ‘PATH’

Add ffmpeg to your path so it can be executed anywhere. There will be only cosmetic differences between Windows 7 and Windows 10.


I found that one one version of Windows I was unable to edit the path if I simply hit Start and searched for “system environment variables” — instead I had to open the dialog via System (control panel) and then click “Advanced System Settings” and then “Environment Variables”. I guess by clicking on the ‘Advanced system settings’ with the little security icon it gives me the admin privilege I need to change the settings.


After clicking “Environment Variables…” You’ll get a list of user variables and a list of system variables. Scroll through the System variables until you find “Path” and click Edit, you’ll get the “Edit System Variable” dialog. Here each folder containing executables is listed in the format C:foobar;C:foobar; — that is, full file path, ending in a backslash, seperated by semicolons. So we’ll add our ffmpeg folder extracted from the 7z file, specifically, its bin folder. I dropped the whole thing in to my C drive, renamed the long folder name to just ‘ffmpeg’ and added the following to my ‘Variable Value’ (highlighted in the screenshot). The backslash at the end is important.

;C:ffmpegbin


After OK OK OKing out of there, you should be able to start powershell and start ffmpeg from anywhere. if you get the following when typing ffmpeg into powershell, then everything worked!


This stackoverflow discussion was helpful in figuring out how to do screen capture on Windows. I ran the following command to grab my Powershell window at 10 frames per second and saving to the file out2.mov. Here is the official documentation which details a few options.

> ffmpeg -f gdigrab -framerate 10 -i title=”Windows Powershell” out2.mov

I wrote a more thorough guide to screen capture here:

https://medium.com/p/3aeddbeb161b

FFMPEG is handy at converting video to gif, too!

> ffmpeg -t 2 -i out2.mov firsttry.gif

Pretty neat!


I wrote a guide to high quality gif making here:

https://medium.com/p/3aeddbeb161b

References linked:

https://medium.com/p/3aeddbeb161b
https://medium.com/p/3aeddbeb161b

Blending and Bending Prosthetic Leg Fairings

From Kinect scan to laser cutting

Opened the original scan in Blender, selected the portion of the scan we’re concerned with. Separated it from the rest of the mesh and exported as stl.

Used Netfabb to repair the mesh and cut into a top and bottom portion.

Found out netfabb decimates the mesh upon export, from 27000 triangles to 24000 triangles, and manages to make it pretty rough, so it looks like this in 123D Make.

Inspected the files before and after repairing in Netfabb…

Used MeshLab’s Filters → Remeshing → Surface Reconstruction to “Shrinkwrap” the model and fill in gaps and holes without losing the smoothness of the scan.

Used this guide to split the part in two using Blender’s newish “Bisect” function.

Played around with different options in 123D Make…

Drew a circle in Blender against the scanned cLeg and stool, confirmed that the units of the scan are in meters. (The circle is .355 units wide and in real life the stools are too.) But, since many programs interpret these STL units as mm, our objects are 1000 times too small. Let’s scale them up.

Settled on a slicing pattern in 123D Make. Used the Modify Form feature to hollow out the leg and picked out the Radial Slices construction technique. The arrangement has some collisions at the bottom, but I don’t want a closed model anyway, so will do some hand-tuning in Inkscape. Exported the model to Blender to check that the cLeg would sit inside it okay.

Using Inkscape to layout the the pieces onto less than 4 sheets of plywood… (nesting is apparantly a difficult problem for computers, and not one that many softwares implement, certainly not free ones. just have to eyeball it)

123D Make is sadistic and exports the objects as groups of thousands of lines instead of a single vector, so editing the exported PDF is really really slow. (It takes 20 seconds to select a text object and type in a new number. I counted.) Learned things:

On the left: the highlighted list of numbers 4,000 characters long describes a single path. On the right side, two coordinates of a single line segment are surrounded by markup. The file containing 2 objects takes 73 lines of text. The file exported by 123D Make takes up 6151 lines of text for the same object. Inkscape modifies this information in memory every time you move something.

Inkscape operates with SVG, which is plain text, ASCII, one character equals one byte. When a path is exported as 677 individual paths, each one of those line segments has 8 lines of markup surrounding it in the SVG file (between the g tags, with information for position and stroke and fill attributes). So what could be saved (and manipulated in memory) as 20 bytes if it was appended to the list of nodes in a single path instead takes 389 bytes to be kept in memory as a standalone object.

I found this forum post describing how to select all the separate objects, Path → Combine them into a single object, and in node edit mode you can select all nodes and click Join Selected Nodes and it simply merges overlapping nodes. Hallelujah!

So to downsize the files enough that they’re not a pain to work with:

Open the PDF. I learned that if you check the “import via Poppler” option Inkscape can detect the colors of the stroke (otherwise imported PDFs have “undefined” color unless you adjust it yourself). So check that box. CtrlA, CtrlU to ungroup everything. Click a blue line segment. Edit →Select Same →Stroke Color. Path →Combine. F2 (Edit Paths by Node). CtrlA. Wait for a minute. Join Selected Nodes (one of the buttons in the node edit toolbar, 3rd from the left, just after the delete node button. It might take a few minutes for Inkscape to chew on this one. It will probably become unresponsive. Let it do its thing. In my case this trimmed the file size by 97% and I could then translate and rotate and rearrange the objects without any lag.

Two hours later…have my minified cut file, fitting on 1.5 sheets instead of 4. I’ve trimmed the tops and bottoms off the vertical slices so the end result will be open.

20 minutes of lasering + 10 minutes of assembling: Hey I made a thing!

Met up with Shawna and learned the design constraints: how the leg has to move, what areas can’t be covered, etc. We picked out a pattern she wouldn’t mind having wrapped around her leg:

I took a few measurements of the wooden positives and drew the outer shape of the fairing in inkscape by hand (using auto-smooth of course!). A few booleans later I had my cut file, which took about 20 minutes apiece. To get the part ready to shape against the mold, I stuck it in our convection oven to bake at 300F for about 5 minutes (don’t worry, we keep one oven for circuit boards and plastics and a different oven for foods 🙂

So the process was: semi-soften the plastic in the oven, then roughly fold it over the wooden form, then stick the whole wooden form in the oven. If you let it soften all the way when it’s sitting on the metal it’ll stick to the metal. Better to have it roughly on the wood form when it reaches maximum droopiness. When it’s as soft as rubber, we take it out and push the plastic against the form, holding it in place as it cools.

I’m pretty happy with the second prototype. I think the next step is 3D printing some bracket system, and maybe taking more time to plan out how the plastic will fold against the form — this was pretty heavily eyeballed.

Continued with a rough prototype of a bracket here: Designing brackets for cLeg cosmetic fairings 

Sleeping In at Dragon Burn

Camping in Anji (安吉县) at the regional Burning Man


So that happened. A surprise opportunity to see what the Chinese interpretation of Burning Man would look like, for less than 100USD, tent & bus ticket included. Duh.

My friend had basically been camping at Xin Che Jian anyway, and he jumped at the opportunity to take the early bus out to volunteer and set up, which I’m a little jealous of, cause he got to build stuff. I woke up early the next day to make my way downtown to catch a bus. Unfortunately, I was feeling groggy when I descended to the subway platform during morning rush hour, and saw people stuffing themselves like sardines onto the southbound train and I thought to myself “Whoa. Good thing I don’t have to get on that train.” and took the path of least resistance onto the nearly empty northbound train. I took me 2 stops to realize I was going away from downtown when I had the opportunity to transfer to another equally stuffed train. I didn’t see how I would squeeze my full pack of luggage on and calculated that I probably wouldn’t make it in time anyway. The end of the line was called “Meilan Lake” and I thought that sounded nice so I just stayed on the roomy, quiet, wrong train.

Luckily I looked at a map (for once) to see that there wasn’t actually a lake anywhere near the Meilan Lake stop and got off at one of the University stops instead. I wandered around campus, trying to enjoy the streams and the sun and hoping I would run into something interesting, but ended up just heading back to Xin Che Jian after a half hour. The whole time I had a backup plan, of course: there would be a 7pm bus, and I had the feeling they would honor my bus ticket regardless.

Woman in native American headdress in Shanghai, telling people “Get the fuck on the bus” at once playfully and sternly. Chinese twenty-something in what I called “that hat people wear in rice fields” and she called “yeah, an asian hat.” carrying 40L of water. Sycamore trees in the French Concession.

Later in the afternoon, after killing time installing a different linux on my laptop (hooray! everything works on debian right away! ❤ debian) I decided to walk the mile and a half to the bus pickup spot, strangely enough an Australian sports bar. I later eavesdropped “there’s just not that many places in Shanghai to park a bus.”

So I meet my fellow burners. I shouldn’t have been too surprised but it was about 80% expats. People working in Shanghai from Copenhagen, Ireland, Canada, U.K. and so on. We shared some food, stood around while the luggage was loaded onto the buses. The ticket-taker couldn’t find my name on the list (since I bought a ticket for a different time) so she made me pinky-swear that I didn’t counterfeit my ticket and let me on the bus.

I picked a seat to myself, only now remembering that I have a hard time starting a conversation with someone without already having a reason.

I hadn’t slept much, and having just walked 2 miles with 30 pounds of stuff, I submitted to my exhaustion and closed my eyes for the first half hour of being on the bus. I tried to nap, ignoring the noise and the music of a bus on its way to a party in the forest, but eventually I opened my eyes to see the Chinese billboards and illuminated LED skyscrapers and was struck by the improbability and novelty of my rolling through Shanghai to the soundtrack of 1970s American Funk being played on a portable loudspeaker.

I decided that maybe it was a good thing I wasn’t talking to anyone, I could focus on the strange scenery out the window — the sprawling city and far off, inexplicable bright lights. At one point there was what looked like a half of a donut sticking out of the ground on the horizon, lit up like a televsion. I still have no idea what it was. Maybe it was just a giant, donut-shaped televison, maybe they have those here.

Eventually, though, the Canadian girl sitting by herself behind me tapped my shoulder, asking if I was travelling alone, and I traded in my excess legroom for a conversation partner. I told her about my work at FabLab and she told me about how she got a teaching job in Tripoli right out of college, owing to her double degree in History and Psychology. She says the job market wasn’t looking good for people who could only teach one thing, so she buckled down and double majored. She taught in Libya during a relatively peaceful period a year ago, but was evacuated soon after she started hearing gunshots at night aimed at her apartment bloc. Luckily, her contract was up soon anyway and she lined up a teaching job at one of the international (a.k.a. private) schools in Shanghai. I asked her about the curriculum difference between public schools and private schools, how China’s role in WWII was represented differently and the kids in private school were taught from U.K. textbooks. I wondered what conversations about history looked like between kids who had different educations, but she wasn’t around for that.

So of course I knew this bus was full of interesting people to talk to, you don’t get on a bus from Shanghai to a Burning Man by sitting at home all day, but still I couldn’t help but keep to myself. I tell myself that I have enough ideas I haven’t done anything about, and meeting people will just fill my head with new ideas before I’m done with any old ones. I know that’s dumb, I’m just rationalizing my introversion.

Anyway, this happened:

Pulled over in the middle of nowhere.

“Why did we stop? Did we lose the other bus?”

A few minutes go by.

“Does anyone know how to get to the campground?”

“Oh nooo, we’re the lost bus.”

“While we’re at it, does anyone on board know how to fly a plane? And also know how to get to the campground?”


My ‘VIP’ tent on the left, the more communal tent city on the right. There was food getting cooked in the tent city. You live, you learn.

But we made it, rolling up to a forest glowing bright green at half past midnight. People lined up to check in, renting tents and accepting the garbage bags being handed to each person. I opted to pay the extra ten bucks to rent a tent that was already set up on a platform so I could get right to dancing. That ended up being just a so-so decision, tho, since these ‘VIP’ tents were on a different part of the campground than everyone else. Not only was it removed from the easy community that comes with having a dozen people living a couple meters away from you, it was a lot closer to the main stage and the loudspeakers, which is pretty VIP until you want to sleep. In the morning when I was looking for a water kettle to cook my cup of noodles, I saw campers gathered in the walkways with propane hot plates and lots of finger food and again kicked myself for paying extra to stay at the top of the hill. I suppose I could have joined them, but I didn’t think I had much to offer and in general feel like I’m being rude if I insert myself into someone else’s situation.

Before I found out that I was going to be an introvert for the whole weekend, though, I did dance my butt off til 4am. I started recording the music just after that before crawling into my tent, too bad the recorder died after 7 minutes, the music played until noon. That was the most surreal part of the whole thing, waking up to gray light and looking out my tent to see a foggy forest at what I guessed was about 7am with like 8 people still dancing. Actually being able to lounge in my tent and watch the dance field was pretty cool, though.

I went back to bed, no longer phased by nonstop bass arpeggios. Actually I think it had an airplane-jet-engine-drone effect on me, where just the constant loudness lulls me to sleep. I’m pretty sure I woke up the second time when the music stopped, out of a confused “something’s different, what’s going on” kind of reaction to the quiet.

With the sun back in the sky, a few people stretching turned into an impromptu yoga class as people woke up and copied what the especially-stretchy guy was doing. We would follow him from one stretch to another, everyone laughing at themselves for not getting half as far into the stretch as our accidental class-leader.

More buses of people showed up, bringing the campground total to somewhere between 100–150 burners. People made art, offered their juggling clubs to people who wanted to try, and talked to each other during the quiet afternoon before the next DJ was scheduled. There was an awful lot of smoke circles that I didn’t want to participate in, so I felt put off from making friends, though in retrospect there were enough people sitting out that it wasn’t a good reason to keep to myself. I think what’s really happening with me is that I feel bad about not maintaining my existing relationships better, I know I leave people hanging a lot, maybe say ‘see you soon’ and never make plans. I imagine I’m doing a disservice to someone to introduce myself and make new friends knowing I won’t answer their messages either. It takes energy to reach out to people, and maybe I’m greedy with whatever energy I have, taking it for myself. I’m still trying to figure out how much I want to change that.

When I did want to socialize, though, there was a really great sunlit cabin beside the tent city and the dance field. The elongated honeycomb framing the windows overlooking the lake was really beautiful. The table was a giant slab of a single tree, 20 feet long and 4 feet wide, mounted on sawed off tree trunks. Really nice place to sit and boil water and chat. The regional’s organizer told stories of Burning Man back in the 90s, before they had rules about firearms, for instance. His old photos from the playa were strewn about the table, along with his choice comic books and various revolutionary propaganda. I borrowed a copy of Debord’s Society of the Spectacle and fell asleep in a hammock.


The next morning I noticed a ‘Moka Pot Coffee Workshop (free coffee)’ on the schedule and made sure to be back at the cabin at 10am sharp. Had a really pleasant time sitting with people from all over the world exchanging coffee rituals. The Italian running the ‘workshop’ showed us how his grandmother whipped sugar and a drop of coffee into a foam. We struggled to find cups and found out PET has a pretty low melting point. I figured out I have a much better time with people who are waking up on stimulants than people passing around narcotics.

That’s about all I have to report. It was loud, I slept a lot, the mountains are really pretty, I actually don’t have a lot of fun at parties. Had a great conversation concerning how you learn a lot about yourself when travelling just because you’re always putting yourself in new situations, and you get to see how you react to it. I react to lots of things by sleeping.







High Quality Gifs with FFMPEG

After getting FFMPEG installed, let’s try it out on a MOV downloaded from my google photos account:

ffmpeg -i MVI_6654.MOV firsttry.gif

We’re calling the ffmpeg program and telling it that MVI_6654.MOV is our input file with the -i flag. the filename at the end defines the conversion and creates the new file, resulting in:


Pretty cool. But I bet I can make it loop nicely by just using the first few seconds, so we use the duration flag, -t and specify the duration in seconds.

ffmpeg -t 2 -i MVI_6654.MOV secondtry.gif


So it loops! kinda slow tho, maybe we can drop every other frame? A-ha. Thanks to the -r flag, we can choose a frame rate for the output (note that these options do different things based on their order. -t is used before the -i input, -r is used after the input, so it affects the output.)

ffmpeg -t 2 -i MVI_6654.MOV -r “15” thirdtry.gif


That’s more like it. As an added benefit, the file is now 2 megabytes instead of 8 megabytes. I’ve got another one to convert that has kind of a long input video, so I’m going to specify a time to start the gif as well as the duration. The -ss flag defines the starting point. Oh yeah, and your seconds can be decimals. If you have a longer video and want to define the starting position in hours, minutes, seconds, you can use “hh:mm:ss” format, like “00:00:03” instead of “3”

ffmpeg -t 3 -ss 0.5 -i MVI_6663.MOV -r “15” fourthtry.gif


This has been pretty simple, but I know I’ve seen better looking gifs. Let’s find out how to make it look more like a video…

Learned a lot from this blog about the color palette algorithms.

Found a relatively simple example on stackoverflow.

We have to generate a custom color palette so we don’t waste space storing colors we don’t use (the gif file format is limited to 256 colors):

ffmpeg -ss 2.6 -t 1.3 -i MVI_7035.MOV -vf  fps=15,scale=320:-1:flags=lanczos,palettegen palette.png

You should recognize what -ss, -t, and -i do here, -vf is a way to invoke filters on our video. so we can describe fps and scale here. Hm. I’ll admit I don’t know what -1 does. But the flags describe what algorithm to use, more info in that blog. So that generates palette.png which we can use in our 2nd line in terminal (by the way, the backslash at the end of the line is if you run out of space and need to keep typing, hit backslash and return and you can keep going on a new line before hitting return to complete the command.)

ffmpeg -ss 2.6 -t 1.3 -i MVI_7035.MOV -i palette.png 
-filter_complex “fps=15,scale=400:-1:flags=lanczos[x];[x][1:v]paletteuse” sixthtry.gif

This uses our .MOV as an input but has a second -i flag to use palette.png as a 2nd input. Then, ok, I copy pasted the rest of it, but I’m happy enough with what this produces that I’ll stop asking questions 😀

Let me know if there’s anything I can explain in more detail, but don’t ask me for help installing things, just google it!






Side by side comparison of easy, default color palettes and head-scratching custom color palettes

I’d like to revisit this with more general advice and showing off other aspects of ffmpeg, but in the meantime here’s articles that others’ found helpful.

https://rigor.com/blog/2015/12/optimizing-animated-gifs-with-html5-video

Simple Sound Triggers with Arduino

This tutorial will allow you to play short samples (less than four seconds) from an Arduino with no extra hardware. It is based off the work of MIT group “high-low tech” and uses all free software. It will futher explain how to trigger the sound using sensors. It is generously translated into Chinese by Chris Zhang at Shanghai hackerspace Xin Che Jian:

https://medium.com/p/5065ee3de7c8

The necessary software is available for MacOS, Linux, and Windows. Arduino IDE and Audacity will need to be installed. The original tutorial provides two more pieces of code:

An Arduino library for audio playback.

A Java program for converting the audio file. Windows. Mac. Linux.

You can either open an existing file with Audacity, or record a new one, which is what Chris did to create our ghost sound. Freesound.org is a great website to download other people’s recordings. Try it out! Use the record, stop, and play icons at the top left of the program.


When deciding what sound to use, we have to consider the very small memory of Arduino — 32kB for our program + our audio. Audacity has a “resample” ability so our sound takes up less memory. In the bottom left corner, change the project rate from 44000 to 8000. Then in the Tracks menu, select Resample, and hit OK.


When powering a speaker directly from the Arduino, it won’t be very loud. In Audacity, if your sound waves aren’t very tall (low volume, low amplitude), it’s useful to use the Normalize effect. This boosts your levels as high as possible without clipping (overpowering the speaker resulting in distorted sound). Select Effect →Normalize and set the amplitude to zero before hitting OK.

Next, click and drag a portion of your sound wave (less than 4 seconds in length) and select File →Export Selected.


In the Export menu, you’ll have the option to change the file format. This is typically the difference between mp3, wav, and flac, etc. but we’re using a more uncommon file type, so in that menu choose “Other uncompressed files” and click options. Choose WAV (microsoft) as your header , and Unsigned 8 bit PCM as the Encoding.

This results in a very small .wav file that we can finally convert to store on the Arduino. The conversion program is written in Processing so for now it requires Java. Run “EncodeAudio”, which simply asks you to select that wav file you just exported. The results are stored on your clipboard, waiting to be pasted. We’re ready to open Arduino and save the file to memory.

Open the Arduino IDE and add the PCM library downloaded above. Open File →Examples →PCM →playback. It should look like this:

https://gist.github.com/jazzyjackson/08a0f968f616e589ea8b

That long list of integers is the example sound, we can replace it with the list of integers that resulted from Encode Audio. Triple-click on any of the numbers to highlight the entire line (thousands of numbers long) and use ctrl-v or cmd-v to paste our own sound.

Upload this code and the sound will play on a speaker connected to pin 11 and GND. You can either use a tiny speaker like in the doorbell tutorial, or if you have speakers with a headphone jack, wire it up like so:


GND gets attached to the tip, pin 11 can be attached to either (or both!) of the remaining silver bands. Be sure to start with the volume on your speakers turned way down, this will play full blast! Also probably don’t do this to your nice stereo cause I’m not sure if it’s safe, I just know it works.

With the current code, the sound will play once when the Arduino turns on: you can hit the ‘reset’ button on the circuitboard to play it again.

The simplest trigger possible is touching two wires together to connect GND to a sensor pin. In our loop we constantly check if our sensor pin is ‘LOW’ and if it is, we start the sound. So cut the ‘startplayback’ function from inside the setup and paste it inside a conditional statement in the loop, using digitalRead() to check if it’s connected to ground. To make sure it doesn’t go off when no one is at the door, we use the internal pull up resistor using pinMode(). This is our final code for using a simple switch to trigger a single sound.

https://gist.github.com/jazzyjackson/28fa0aaac29a8b1ba432

Notice that I changed the name of the array from ‘sample’ to ‘ghost’ — be sure to change the name in the startPlayback function as well — it’s used twice.

You’re not limited to this, of course! You can have as many different sounds as will fit on memory (so 4 seconds total) but trigger them at different times. Copy-paste that ‘constant unsigned char sample[] PROGMEM’ code and give different names to different lists of numbers. You can also use an external pullup resistor of 1 megaohm (the built-in one is only 10k) to make it touch sensitive instead of having to touch two wires together. Connect the megaohm resistor between the sensor pin (A0) and 5V. Delete the pinMode function from the setup.

The following code uses booleans to play a different sound each time the sensor is touched. This one includes our ghost sounds, so you can upload this and try it yourself. Megaohm resistor between A0 and 5V, speaker on pin 11 and GND.

https://gist.github.com/jazzyjackson/f0dac125813235e8bfa5

Have fun!

The doorbell has a boring sound. We can fix it.

ATmega328 + JQ6500 MP3 tutorial


Fellow Xin Che Jian member LuFeng came in with a good project and a stack of microchips: Microduino modules that can be programmed to play music off a memory card and a wireless doorbell that made a boring old doorbell sound. He’s new to arduino and the tutorials for these modules are fairly vague, so I thought this would be a good opportunity to write up a tutorial on using an Atmega328 and a JQ6500 to trigger sounds with a really simple program.

From left to right: UART serial programmer, ATMEGA328P, JQ6500 MP3 module, microSD module, and 2 channel amplifier

Here’s the tools we had, a really neat set of stackable modules called Microduino programmable with the standard Arduino IDE (though you might not know that by reading their website — for this ATmega328 at 5V and 16Mhz clock, you can tell the IDE that it’s an UNO, no extra hardware files are requried.)

While I used these modules to get this project to work, if you get these parts in a different format (maybe an Arduino UNO and a JQ6500 on a breakout board) the following instructions should be relevant to you, too.


So we’ll deal with two stacks separately first: the audio module with the usb port stacked on top of the memory card module and the ATmega328 stacked on the UART.

When you plug in the audio + memory card stack, two drives will show up on your PC: one is the internal storage on the MP3 decoder, you probably don’t want to touch that one. But the drive that shows up called “SD” is where we can drop our MP3s. Microduino’s wiki has some information on the necessary naming scheme: Our file will be called “001.mp3” and be placed in a folder simply named “01”


Audacity makes it easy to grab a short clip of our chosen sound: a nice piano arpeggio from a longer song. If you’ve never used Audacity, no problem, you can visit their website for a Mac or Windows executable, or if you’re on debian (ubuntu / kubuntu / mint etc) you can just open a shell and type “sudo apt-get install audacity” and it will magically be installed on your OS. File → Open your song, click and drag across its sound wave to select a portion of it, and hit play to listen to your selection. Once you’ve selected the few seconds you want to play, you can hit File → Export Selected Audio and choose your file type as MP3, save it with the filename ‘001.mp3’

With your mp3 moved to the ‘01’ directory of the SD card, we can unplug that module and start programming our ATmega328. The microduino wiki was really vague on how to write code to control the MP3 module, but thankfully it gives the model number of the IC it uses: JQ6500. So I searched for a “JQ6500 arduino library” and found something really well documented here. So download that library and add it to the arduino IDE in the usual way (Sketch →Import Library →Add Library… or unzipping into your sketchbook, whatever works for you.) Check out the example sketches, “Full Demo” and “HelloWorld”, but here’s my code to simply play the first file on bootup. (01/001.mp3)

https://gist.github.com/jazzyjackson/de8f905636a6a3a05fb5

The only part that may be different based on your hardware is line 5, the object declaration that defines what Arduino pins will communicate via software serial to the JQ6500 chip. Looking close on the underside of this particular breakout board, the default TX and RX serial pins (the ones not in parentheses) are labeled next to D2 and D3, which in Arduino IDE language corresponds simply to 2 and 3.


So I declared my object as mp3(2,3) but if you’re using a different breakout board for the JQ6500 you will have to determine which 2 pins are wired to JQ6500’s RX and TX and use those pin numbers in your “JQ6500_Serial mp3(tx, rx)” declaration. By the way, ‘mp3’ is a user definable name, it can be called whatever you want.

Once you’ve got that figured out, you can load the code to the little stack of UART + ATmega. Unplug it once it uploads, and join the two stacks together, and add the amplifier module on that, so you have a whole tower of modules. Oh, important thing to know at this point: if you try to power the stack via the audio module’s USB, it won’t work, it will try to boot into file transfer mode, so power it with the UART module or otherwise.


If everything has gone right so far, you can plug a little speaker (the aluminum 3W style pictured at the top is perfect and easy to get a hold of) into the amplifier and give it power you’ll hear your sample. Did it work for you? I hope so.

To get the sound to play only when our original doorbell rings, we have to add a conditional to our program: instead of just mp3.play() in the setup, we use an if statement in our loop so that the ATMega328 is constantly checking for an input, it’ll look something like this:

void loop(){
if(AnalogRead(A0) > 400){
mp3.play();
}
}

Our input will be the two wires that use to be the doorbell’s speaker. For this, I cut off the original speaker and soldered new wires into its place. One of these wires should just be grounded, and the other wire can be stuck into A0 for measuring.

To make a sound, the speaker is pushed and pulled by changes in voltage. ATmegas have a 10-bit analog-to-digital converter that is super useful for measuring changes in voltage. Instead of measuring if something is turned on or off (like a button, which is strictly on or off, digital, 1 or 0) the A0-A7 pins let you measure subtler changes like a speaker buzzing around in between high and low voltage (between 1 and 0 😉

The readAnalog function performs this measurement for us, and if you want to experiment with this you should try the File → Examples → Basics → AnalogReadSerial program, which lets you open the serial monitor and see what voltage the ATmega328 is measuring. When you have what-use-to-be-a-speaker wired to GND and A0, and watching your serial monitor when you ring the doorbell, you’ll see a number jump around and settle back to 0 once the doorbell stops ringing. So in the code snippet, our mp3 will be triggered whenever the voltage jumps above 0V. (the 400 is a number we pick. In arduino-land, zero volts reads as 0, and 5 volts reads as 1023. That’s just because the hardware on the chip has 10bit precision, which is to say, it can distinguish between 2¹⁰ different voltages. 2 to the tenth power equals 1024, and if you have 1024 numbers and want to start at 0, you get the range 0–1023. So any voltage it measures is returned as some number between 0 and 1023.)

However, this simple way of waiting for change in voltage is susceptible to a electronic hobbyist’s worse nightmare: noise. Even if things are wired correctly (but especially if they’re wired loosely) little spikes in charge from humans handling things or other more mysterious sources can cause a spike in measurement, thereby triggering our doorbell when no one is at the door.

A slightly more reliable way to wait for changes in voltage, then, is to use a handy feature of ATmegas called an ‘internal pullup resistor.’ This phrase didn’t make sense to me for a long time so I’ll elaborate a little: if there’s a signal that may naturally fluctuate and you want to prevent it from fluctuating, you can wire a resistor in between that signal and a power source (thereby “pulling the signal high”, making it a “pull up resistor”) or wire a resistor in between the signal and a ground source (thereby “pulling the signal down to ground” making it a “pull down resistor”). If I didn’t explain it well enough, search for more articles about it, it’s a super useful thing to understand.

ATmegas have one of these resistors built in inside the chip and it can be programmed to be connected to a power source or not (this is the magic of programmable computers…they are machines that re-wire themselves). It can keep the analogRead measurement pinned to 1023 until some other active component, like our speaker signal, interferes and pulls the voltage low (remember how the speaker gets voltage pushed and pulled? That’s why this can work by measuring from 0V or from 5V, we just want to wait for a change in voltage, doesn’t matter what direction.) So to set that internal pullup resistor and wait for a change away from 5V, our code will look like this:

https://gist.github.com/jazzyjackson/8996d6519b7cd0cbf965

Oh, and the pinMode(6, OUTPUT) and digitalWrite(6, LOW) is kind of silly, I’m giving myself an extra place on my tiny MicroDuino modules to ground the speaker. Arduino UNOs have 3 different places to GND things, but if you ever need more, you can set a pin low and it will work just the same as a GND pin. Just don’t ground something that uses lots of power, because this forces current to go through the chip.

But that’s the final program, and the final necessary wiring: old speaker pins plugged into GND and A0, JQ6500 connected to pins 2 and 3, and I’m using the 5V pin to power the doorbell. It use to be powered by 220V mains, but that part exploded for reasons I don’t need to go into detail about here. Did you ever see Wayne’s World? Fireworks. Suffice to say, this almost become a blog about how to build a replacement full wave rectifier out of diodes until it occurred to me that the parts that I want to use can be powered off 5V.

Now when the doorbell makes a sound, it triggers the arduino to command the JQ6500 to play its mp3 and we hear a nice piano arpeggio instead of a boring old simulation of a doorbell.