Gerrit Niezen

Maker of open-source software and hardware.

Feature image

This morning I got a Pixl.js Espruino board for Father's Day. My son is not even two years old – how did he know that is exactly what I wanted?

The Pixl.js is a SoC (System-on-Chip) with a 64Mhz microcontroller and Bluetooth Low Energy module. It's an Espruino board, so you program it in JavaScript. It has a little LCD screen just like the ones in those old Nokia phones. Pixl.js's form factor is Arduino compatible, so you can plug in Arduino shields like WiFi or GSM. It can run on a coin cell battery or is powered via USB (power-only).

It works over Web Bluetooth, so you connect to it from the Espruino Web IDE. The only thing I had to do to get it working on Ubuntu 18.04 was to enable the “Experimental Web Platform Features” under chrome:flags on Chrome and then go to espruino.com/ide.

I then tried to get it working on my iPad. Unfortunately Web Bluetooth is not yet supported on Safari, but there is a WebBLE browser you can download from the app store (for £2) that does. It's a very basic browser, but all you really need it for is to run the Espruino Web IDE. That I can program a little microcontroller over Bluetooth from my iPad blows my mind!

#Electronics

Comment on this post

Feature image

This morning I was watching Estefannie Explains it All on YouTube making a Daft Punk helmet using her new 3D printer.

She was 3D printing a mold and using that to vacuum form a visor out of a PETG plastic sheet. What I love about her videos is that she shows everything, including her failures, like completely melting the plastic sheet or gluing the box to her workbench by accident.

I've watched other makers on YouTube and usually feel inadequate when I look at their amazing skill set, even though I have a Masters degree in computer engineering and a PhD in industrial design. With Estefannie, it's refreshing to see how she's learning as she's making and sharing the whole process.

As she was making the vacuum forming box I noticed many things that could be improved, for example how she was clamping things to her workbench. Instead of pointing that out in the comment section (which I'm sure many people will do) it reminded me that I don't have to know how to do everything perfectly before starting, and that even if you make mistakes you can still make something awesome.

I used to think that looking at great maker projects will inspire me to make things. That's not true – looking at the process, including all the failures and mistakes, is what provides true inspiration.

#Making

Comment on this post

Feature image

I first came across solarpunk on the decentralized social network Scuttlebutt[1]. Like steampunk, and later dieselpunk, solarpunk is a certain narrative and aesthetic about the future. The article “What is Solarpunk?” does a pretty good job at explaining what it is.

On Scuttlebutt I discovered a whole community interested in solarpunk, and someone mentioned that there was a Kickstarter project to translate a Brazilian anthology of solarpunk stories into English. I backed the project, and ended up with two collections of solarpunk short stories in e-book format:

I'm actually reading both of them at the same time. I've found “Glass and Gardens” a bit easier to read as it was originally written in English, with “Solarpunk” being quite awkward in places due to the translation from Portuguese. Hey, maybe I'll put a review up here once I finished reading them!


  1. You can access Scuttlebutt with a software client like Patchwork. For more on Scuttlebutt, see “An off-grid social network” ↩︎

Comment on this post

Feature image

I enjoy listening to podcasts when I'm out on a run or walking to town. Overcast is my podcast player of choice, at least until Apple releases the next version of their Podcasts app that will let me store podcasts on my watch.

In no specific order, here are my favourite three podcasts at the moment:

  • Do by Friday: Merlin Mann, Alex Cox and Max Temkin (the last two from Cards Against Humanity) have a weekly show where they discuss tech, politics and pop culture. And there's a weekly challenge.
  • The Prepared: Spencer Wright and Zach Dunham created The Public Radio, a single-channel station FM radio in a jar. In this podcast they talk to designers and engineers about manufacturing.
  • Thorougly Considered: Dan Provost and Tom Gerhardt are Studio Neat, creators of the Glif tripod mount for smartphones (amongst other things). They talk about product design, crowdfunding and indie manufacturing, with host Myke Hurley of Relay FM.

Comment on this post

Feature image

There has been a noticeable trend from people reading blogs towards reading e-mail newsletters instead. I use Feedly to subscribe to blogs[1], but if you don't use a blog reader I guess e-mail makes more sense. Here are a few newsletters that make it into my inbox, even if I prefer blogs.

  • Offscreen Dispatch is a once-a-week newsletter with an assortment of products and articles on design and the web by Kai Brach, maker of Offscreen magazine. Coincidentally Offscreen is also my favourite magazine at the moment.
  • The Prepared is a manufacturing newsletter targeted at engineers and entrepreneurs by Spencer Wright, who also hosts The Prepared podcast.
  • Sunday Dispatches is a little bit of everything by Paul Jarvis. He usually writes about freelancing and small businesses.

  1. Hint: You can subscribe to this blog by clicking the Subscribe link at the top of the page. ↩︎

#Reading

Comment on this post

I discovered a customizable design for a door stop on Thingiverse, where you can resize it to fit the door holes in your house. I measured the holes, modified and 3D-printed the design, and it turned out to work much better than expected.

I then needed a way to keep our wardrobe door closed. I couldn't find anything on Amazon or any existing designs on Thingiverse that would work. So I started creating some baby-proofing designs of my own.

I noticed that there is a small gap at the top of the wardrobe door, with a knob just behind it. So I thought “why not make something that clips to that knob that prevents the door from opening”? Ladies and gentlemen, I present to you the wardrobe door holder :

wardrobeDoorHolder

It should work with any IKEA PAX hinged wardrobe doors. I posted the wardrobe door holder on Thingiverse if you just want to download the STL file to print it yourself. Here is the OpenSCAD code to make or modify your own wardrobe door holder:

$fn=50;

difference () {
  cylinder(5, d=16);
  translate([0, 0, -1]) {
      cylinder(7, d=11.9);
  }
}

translate([-4,6,3]) {
  cube([51,10,2]);
  translate([0,0,-3])
      cube([7,10,3]);
  translate([41,0,-10])
      cube([10,10,10]);
}

I also made a simple hook that clips over two IKEA PAX door handles:

handleHolder

And here is the OpenSCAD code, which is easy enough to modify by changing the variables for width, thickness and height:

width = 82;
thickness = 5;
height = 25;

cube([width+thickness,thickness*2,thickness]);
cube([thickness,thickness*2,height]);

translate([width+thickness,0,0]) {
  cube([thickness,thickness*2,height]);
}

Comment on this post

Feature image

I've been looking for a way to very easily write and publish posts. I've tried static page generators like Hugo and and Jekyll on GitHub Pages in the past, but there are just enough steps to create too much friction.

First you have to write your markdown files in a text editor. Then you have to compile it and publish it using a computer. I was looking for a quick way to write posts, even on my phone or iPad (with a Bluetooth keyboard). SimpleNote came close to what I needed, except that each post exists completely separate to other posts.

Enter Ghost. I spun up a Digital Ocean instance and followed the tutorial for setting up the one-click application. Easy peasy.

Now I am self-hosting my own content and I can type away on any device that can load Ghost's web-based Markdown editor. Adding header images is super easy thanks to built-in Unsplash integration, and then publishing a post is one click away.

In future I hope that decentralized solutions like Beaker browser and the Dat project will make it much easier to publish blogs in a decentralized fashion, but until then running my own Ghost instance seems to make the most sense.

Comment on this post

Feature image

I've been adding updates to the wireless temperature sensor code I posted last week, mainly adding timestamps to the sensor readings.

canvas

I first tried using an array of objects of the form { time: <timestamp>, temp: <temperature>}, but for some reason the ESP8266 would reboot every couple of hours. My guess is that it was some kind of memory or buffer overrun issue, so I used two separate array (one for time, one for temperature) instead.

Getting accurate time from microcontrollers is notoriously difficult. At Tidepool we have an entire guide dedicated to working with timestamps coming from diabetes devices, and we use a pretty complex algorithm to convert local timestamps to UTC time.

Any microcontroller timer is susceptible to clock drift, so it was nice to discover that Espruino has a feature where it auto-updates the time on the device every time you push new code to it. While this is not necessarily going to work that well in real-world environments where you're not frequently pushing code changes, it works great for my prototype where I'm pushing new updates all the time.

Currently the prototype is sitting in our nursery, measuring the room temperature overnight to see if the baby is getting too hot, as Swansea is currently experiencing a very unusual spell of warm weather. I still can't get over how cool it is to program the ESP8266 over WiFi in another room two floors up.

So, how did I go about getting those timestamps? The first step is to set your timezone on the device, offset from UTC, so for the UK it would be 1 for UTC+1:

E.setTimeZone(1); // UTC + 1

Also remember to check the box next to “When sending code, set Espruino's clock to the current time” in the Espruino Web IDE. Getting the current time is then just regular JavaScript code:

var dt = new Date(Date.now());
var time = dt.getHours() + ':' + dt.getMinutes().toString().padStart(2,'0');
console.log(time, temp);

Note that on the ESP8266 I had to use the padStart polyfill as Espruino does not yet support ES8/ECMAScript 2017. Here is the entire script, taking sensor readings every 10 minutes and printing the timestamp and value every 5 readings:

var wifi = require('Wifi');
var http = require('http');

var led = Pin(NodeMCU.D4);
var toggle=1;
var ow = new OneWire(NodeMCU.D3);
var sensor = require("DS18B20").connect(ow);
var history = new Float32Array(60);
var timeArr = new Array(60);

function updateLed(){
  digitalWrite(led, toggle);
  toggle=!toggle;
}

// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
if (!String.prototype.padStart) {
    String.prototype.padStart = function padStart(targetLength,padString) {
        targetLength = targetLength>>0; //truncate if number or convert non-number to 0;
        padString = String((typeof padString !== 'undefined' ? padString : ' '));
        if (this.length > targetLength) {
            return String(this);
        }
        else {
            targetLength = targetLength-this.length;
            if (targetLength > padString.length) {
                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
            }
            return padString.slice(0,targetLength) + String(this);
        }
    };
}


setInterval(function() {
  updateLed();

  var temp = sensor.getTemp();
  var dt = new Date(Date.now());
  var time = dt.getHours() + ':' + dt.getMinutes().toString().padStart(2,'0');
  console.log(time, temp);
  // move history back
  for (var i = 1; i < history.length; i++) {
    history[i-1] = history[i];
    timeArr[i-1] = timeArr[i];
  }
  // insert new history at end
  history[history.length-1] = temp;
  timeArr[timeArr.length-1] = time;
}, 600000); // every 10 minutes

function onPageRequest(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.write('<html><head><meta charset="utf-8"/><meta http-equiv="refresh" content="600"></head>'+
            '<body><canvas id="canvas" width="400" height="200" style="border:1px solid #888;"></canvas><script>');
  res.write('var d='+JSON.stringify(history)+';'+
            'var t='+JSON.stringify(timeArr)+';'+
'var c=document.getElementById("canvas").getContext("2d");'+
'c.moveTo(0,100 - (d[0]-d[d.length-1])*10);'+
'for (i in d) {'+
'var x = i*400/(d.length-1); var y = 100 - (d[i]-d[d.length-1])*10;'+
'c.lineTo(x, y);'+
'if (i % 5 === 0) {'+
'c.fillText(Number.parseFloat(d[i]).toFixed(1),x,y - 5);'+
'c.fillText(t[i],x,y + 20);}}'+
'c.stroke()'+
'</script>');
  res.end('</body></html>');
}

function onInit() {
  wifi.restore();
  http.createServer(onPageRequest).listen(80);
  console.log("Server created at " + wifi.getIP().ip);
  E.setTimeZone(1); // UTC+1, remember to select "set current time" in IDE
}

onInit();

Update: Using NTP

Justin from Swansea Hackspace pointed out that I could use NTP to get the time:

I assume this is an internet enable device, so why not just use NTP? For arduino based code the standard Time library has an example of an NTP SyncProvider callback

— Justin Mitchell (@popemadmitch) June 11, 2018

I looked it up in the Espruino docs, and low and behold, it's as easy as wifi.setSNTP('uk.pool.ntp.org', 1); (for UTC+1).

#Electronics

Comment on this post

Feature image

While drinking my Sunday morning coffee I read an article in the Guardian with the title Underpaid and exhausted: the human cost of your Kindle.

One thing that struck me is that the while the richest man in the world, Jeff Bezos, is worth an estimated £102 billion, there are people making Amazon products for £1.69 an hour. Why are poor people being exploited both directly (workers in Amazon warehouses and delivery drivers) and indirectly (people working for companies like Foxconn)? Is it fair to blame Jeff Bezos? Or maybe it is really just a symptom of late stage capitalism.

It reminds me of a paragraph in Jay Rayner's book “A Greedy Man in a Hungry World” that has been bothering me for a while, because I disagree with it but couldn't exactly say why:

China does one thing really well: making stuff. America does a different thing really well: growing corn and soya beans. So they trade. This is called utilizing comparative advantage.

If China's comparative advantage is just being able to pay people peanuts and companies getting away with not following labour laws, does it really make them better at making stuff?

What would it look like if e-book readers were made in an open source, decentralized fashion instead of in one factory in China? What would it look like if voice assistants were made in the same town were they are being used, sold directly instead of paying the Amazon tax?

Comment on this post

Feature image

Now that I've made it a week with blogging every day, I should probably explain why. I was re-reading a post by Austin Kleon on daily blogging. There's this one bit I found quite inspiring:

I had forgotten how wonderful blogging is as a mode of thinking. Blogging is, for me, more about discovering what I have to say, and tweeting more about having a thought, then saying it the right way. It’s also great to be able to go as long or as short as you want to go.

Writing more should help me communicate with others more effectively. Most of my communication is done via chat as I work remotely, and being able to write clear and unambiguously will be very helpful.

Austin's blog post also lead me to this nugget that summarizes Seth Godin's thoughts on daily blogging. He should know, he's been blogging daily since 2002:

Everyone should write a blog, every day, even if no one reads it. There’s countless reasons why it’s a good idea and I can’t think of one reason it’s a bad idea.

I don't need anyone's permission. I don't need to go out and promote it. I don't use any analytics. I don't have comments. It's just: this is what I noticed today and I thought I'd share it with you.

Let's see how long I can keep this going.

Comment on this post

Enter your email to subscribe to updates.