How to make cheap wooden 6-sided dice

2013-09-29 20.36.59b

I’ve been thinking to switching to a different dice system for my role playing system, FudgediceMEGAPOMPS.  I’m not sure yet, but I think I want to try using Fudge dice, which have two plus signs, two minus signs, and two blank sides, as shown in the pic to the right.

The problem is that while these aren’t very expensive for a set of four (about $5 on ebay), I’m not about to ask everyone I play with to buy a set of weird dice just to experiment.  But they’re simple enough, so I thought I’d make some.

All I needed was a bunch of wooden cubes — about 5/8″ to a side (15mm).  I found an ebay sale for 36 of them for $3 shipped.  These cubes won’t have the precision of real plastic dice, but they’re cheap in bulk — much cheaper than even blank plastic dice.  I had to throw 5 of the 36 out for being uneven or chipped, but who cares.

To mark them, I just used my soldering iron.  I put in a medium-sized chisel tip, but most any would work.  I held them in place with a needle-nose, and slid the broad side of the iron over the face of the cube to burn in a + on two opposing sides, and a − on two others.  It was easiest to do this with the grain of the wood.  On some of them, I stabbed a dot into the blank side just for effect.

2013-09-29 20.38.18b

When they were done, the burned wood had a sticky texture, so I briefly washed each face with a wet rag, and they were fine.

Also, I had a few extra, so I made some standard numbered d6’s by just stabbing in the right number of pips on each side:

2013-09-29 20.37.41b

Boom, $3 and an hour of time and I have some neat homemade Fudge dice, plus a few regular d6’s to throw in the bag.

2013-09-29 20.36.37b

Draw anything on an oscilloscope

2013-09-21 10.15.01b

I have an old analog oscilloscope I got from university surplus, and it’s been more than enough for all the work I’ve done so far.

One thing I’ve wanted to do for a while was draw arbitrary stuff on it using X/Y mode, recreating the vector graphics systems of the past, especially stuff like the seminal Tennis for Two.  Unfortunately, a plain Arduino can’t output true analog signals–the analogWrite function just sets pulse-width modulation (PWM) so the pin is up x% of the time rather than truly being x% of the voltage.  So I needed a digital-to-analog converter (DAC).

I was originally going to build a R-2R DAC out of resistors, but that eats a ton of pins, so I wouldn’t be able to scale down to a smaller controller later if I wanted.

Instead, I decided on getting a dedicated serial DAC, which is an IC that receives the voltage level via serial digital communication, then outputs it.  Originally I tried to get a super-cheap audio DAC, the TDA1543, but the protocol for that is weird, and I got a non-standard “japanese interface” variant, and also I may have fried it.  Anyway, it didn’t work, so I got the much more standard MCP4802.

The MCP4802 is from the MCP48xx line (datasheet), with the model number indicating it has 8 bits of resolution and two independent channels.  It communicates over plain SPI, a well known standard with hardware support on Arduino.  I found a ready-made library for it here. (I had to fix one thing in it — it didn’t include SPI.h in its own header file. I also renamed CHANNEL_A/B to CH_A/B for brevity.)

I wired it as described here, and it worked perfectly.  With this, I hooked up the X and Y lines to the two outputs of the DAC, and set about drawing some stuff.  After getting it to draw a circle (x=cos(theta), y=sin(theta), scale output to 0..4095), I decided to draw some arbitrary stuff.

To encode the art, I wrote a small Processing app to let me mouse-draw some stuff, with the coordinates being saved to a file in CSV format.  Code:

PrintWriter output;

void setup()
{
  size(256,256);
  output = createWriter("positions.txt");
}

// x0=-1 means "the next click is the start of a new line segment"
int x0=-1,y0=-1;
int x,y;

void draw() {}

void mouseDragged() {
  x = mouseX;
  y = mouseY;
  output.println(String.format("%d,%d",x,(256-y)));
  output.flush();
  if (x0>=0) {
    line(x0,y0,x,y);
  }
  x0=x;
  y0=y;
}

void mouseReleased() {
  x0=-1;
}

So now I can draw stuff:

rad

I wrote a small Python app to convert the CSV list of coordinates to array declarations for Arduino. (I could have done this formatting in Processing directly, but that would have involved arrays and a save function, and I’m not very familiar with Processing yet, so this was faster.)  This code also drops every other coordinate to improve the refresh rate.

import fileinput

X=[]
Y=[]

every_n = 2 # we throw away every other pixel to improve the refresh rate

i=0
for line in fileinput.input():
	i += 1
	if i%every_n != 0: continue
	x,y = line.strip().split(",")
	X.append(x)
	Y.append(y)

print "byte X[] = {%s};" % ','.join(X)
print "byte Y[] = {%s};" % ','.join(Y)

I run it with:

  $ python pos2code.py positions.txt > rad.txt

I then dropped those two lines into the top of my Arduino program:

// MCPDAC relies on SPI.
#include
#include
#include

int i=0;

byte X[] = {...INSERT VALUES HERE...};
byte Y[] = {...INSERT VALUES HERE...};

void setup() {
  MCPDAC.begin(10,9); // CS pin, LDAC pin (latter only needded for x/y sync)

  MCPDAC.setGain(CH_A,HIGH); // Set the gain to "HIGH" mode - 0 to 4096mV.
  MCPDAC.setGain(CH_B,HIGH); // Set the gain to "HIGH" mode - 0 to 4096mV.

  MCPDAC.shutdown(CH_A,false);
  MCPDAC.shutdown(CH_B,false);
}

void loop() {
  int x,y;

  x = X[i]*16; // *16 to go from 0..255 to 0..4095
  y = Y[i]*16;

  MCPDAC.setVoltage(CH_A,x&0x0fff);
  MCPDAC.setVoltage(CH_B,y&0x0fff);
  MCPDAC.update(); // this toggles LDAC, actually changing the outputs -- you can omit this if not using the LDAC pin (leaving it grounded)

  i++;
  if (i>=sizeof(X)) i=0; // wrap around the array

}

The program cycles through the values, sending them to the MCP4802, thus driving the oscilloscope, which was set to XY mode.  Now I can play with the code above to start trying out some effects, like this “crawling ant” pattern:

My setup:

2013-09-21 09.43.28c

Cache up internet radio for later *skippable* playback

If there’s an internet radio station you like, you might want to listen to it on the move, even when you don’t have internet.  It’s fairly trivial to slurp the MP3 stream with a tool like wget, but then you end up with a 4GB single file.  It’ll play fine, but when a crappy song comes on, it would be nice to skip ahead without having to hold down the “forward” button for a while. Worse, many MP3 players don’t keep track of position in a song, so when you start back up, you’ll be at the start of the stream again.

What I do is slurp the MP3 stream, but divide it into fixed chunks, like 5MB.  You can tell how much runtime per chunk based on the bitrate.  A 128kbps stream means there are 128*1024 bits per second, or about 0.983 megabytes/minute.  So 5MB is roughly 5 minutes.

This means I have a directory with a few hundred MP3 files to be played in sequence.  If you have gapless playback, you don’t even notice the track changes. If you’re listening to a lousy song, you can skip 5 minutes into the future just by pressing next track.  Even lousy MP3 players keep track of which song you were on, so your radio picks up where it left off, and even if you lose your place, it’s easier to find your way back, since you can just skip five minutes at a time until you start hearing new content.

To do this chunk download approach, I use this old perl script I wrote a few years ago. It’s a little ugly…if I were to write it today, it would probably be 10 lines of Python, but it works well enough, even on Windows (provided you have perl and wget).

#!/usr/bin/perl

use strict;

if (!@ARGV) {
	die < [basename] [size]
EOL
}

my $url = $ARGV[0];
my $basename = $ARGV[1] || "save";
my $chunksize = $ARGV[2] || 5*1024*1024;
my $blocksize = 4096;

my $chunkleft = $chunksize;

open STREAM, "wget -O- $url |" or die;
my $n=1;
while (1) {
	my $buf;
	my $filename = sprintf("%s-%03d.mp3",$basename,$n);
	open OUT, ">$filename" or die "$filename: $!\n";
	while ($chunkleft > 0) {
		my $r = read(STREAM, $buf, $blocksize);
		if ($r == 0) { die "EOF, exiting.\n"; } 
		elsif ($r<0) { die "stream: $!\n"; }

		$chunkleft -= $r;
		print OUT $buf;
	}
	close OUT;
	$chunkleft = $chunksize;
	print "\nFinished writing $filename.\n";

	$n++;
}

How to trace circuit boards easily

Circuit boards, even small ones, look crazy complicated. But they really aren’t — they’re just efficiently packed. Most circuit boards have just two “layers” of copper traces running around: top and bottom. Something sophisticated like a computer motherboard can have more copper sandwiched in the middle, but most of the things a hobbyist would want to trace are just have a top and bottom.

What can make tracing complicated is that the two sides work together, with a single connection flipping between top and bottom multiple times.  But we can use a camera and an image editor like Paint.NET, Photoshop (the CS2 version is free now), or GIMP to make it easy.

As an example, let’s trace this USB device.  It’s an off-brand programmer for AVR chips that had no documentation and didn’t work in a standard way like similar products, so I had to figure to figure out how it was wired up.

I started by taking good, high-resolution pictures of each side, trying to keep the camera a fixed distance from the board on each side.  Using a document scanner didn’t work for this, because the board didn’t lie flat on the glass…you might be able to use a scanner for a flatter circuit board.

side1side2

We’re going to superimpose the bottom (simple) side over the top (complex) side in the image editor.  Take the picture of the simple side, copy it, and paste it as a new layer over the complex pic.  Set it to semi-transparent, flip it vertically, then use the layer transform or move tool to get it to line up exactly over the top side of the board.  Be sure to match up key landmarks, like vias (the little holes that connect top and bottom) and through-holes.

Once they match, turn the simple side opacity all the way back up, add a new empty layer, and paint all the traces you see in a high-contrast color (like red, for green boards).  When you’re done, you should be able to slide the opacity of the simple & red layers up and down and have it look like this:

anim2a

Now, turn off the simple layer, but keep the red trace layer.  Now you have a picture of the top of the board with all the bottom-side traces super-imposed:

together

Now you can add another layer and draw additional annotations that you need until you’ve discovered everything you need to know.

together-more

What I needed to know for this board was this: I was dumb to buy this $4 programmer just because it had a fancy case when the well-known good model was nine cents cheaper.  It’s a crappy nonstandard board nobody’s ever heard of, and though I could fix it by adapting custom firmware for it, I’m better off just throwing it in the bin and getting the good one (which I did).

But it was a good exercise in circuit tracing.

Hilbert curves are cool

Hilbert curves are cool.  They’re a form of fractal comprised entirely of 90 degree angles. It’s a way to make a single continuous line fill up any given space (2D, 3D, and beyond).

hilbert1

The background to this blog is a hilbert curve I rendered myself (code).  Above is a simpler version of the curve, blown up so you can see it, with the color of the line changing so you can see how it flows.

It has a some cool properties.  For example, if you subdivide the image width-wise and height-wise by a power of two, you get squares that also contain one contiguous part of the line.  It turns out this is important in computer simulations.  Because of how CPU caching works, it’s faster to read a bunch of bytes next to each other than ones far apart. So if you’re simulating weather patterns or particle physics or whatever, you have to map memory (which is one-dimensional) to 2D or 3D space.  If you use a hilbert curve to do that mapping, then when you divide the space up to work on it, each little square or block will live on a continuous piece of memory, and your program will run much faster.

Also, I just think they look cool.  I played with a few filters and came up with some cool images of the 2D hilbert curve:

hilbert-10-lavender-sin729x hilbert-10-rainbowedges-sin81x hilbert-10-rainbowedges-sin81x-quadmirror-rot45 hilbert-10-ice-sin81x hilbert-10-ice-sin9x hilbert-10-ice-sawtooth hilbert-10-fire-sin81x

Also, they work in 3D too.  I wanted to see this, so I wrote a program to build a 3D hilbert curve in Minecraft:

2011-01-17_22.34.05 2011-01-17_22.31.40 2011-01-17_22.31.332

The code to render these is here.  This code is two years old (Jan 2011), and it’s based on the pymclevel Python module, which may be dead or different by now.  Also, it outputs schematic files, which was a format you fed to a Minecraft map editor to plop the object into an existing world.

I also rendered another cool fractal, the Menger sponge:

2011-01-17_17.58.03 2011-01-17_17.58.30 2011-01-17_17.58.48 2011-01-17_17.59.40

Code to generate that is here.

How to hack the Sandbox game

The Sandbox” is a powder game recently ported to Android. It’s fun, but they try to get you to buy “mana” to unlock stuff that you need to use in the normal course of the game. Nope, not gonna do that.

We can hack the Android version to drop the price of elements to near-free.

To do this:

  1. Get the Sandbox APK by backing up the installed game (ES File Manager’s App Manager can do this)
  2. Transfer APK to PC
  3. Extract it as a ZIP file
  4. Edit assets/shop.plist to drop prices to 3 mana for each element
  5. Rezip the files
  6. Use the “testsign.jar” tool to sign the ZIP, thus making it an installable APK:

    java -jar testsign.jar hacked.zip ready-to-install.apk
  7. Uninstall the non-hacked game from your device
  8. Copy the hacked APK to your device
  9. Install the hacked APK.

All the elements should now cost just 3 mana, so head to the element store and unlock them all.

Getting around stability/sound issues

On my Nexus 7, the hacked version of the game didn’t have sound for some reason and I saw a few glitches.

To fix this, I just:

  1. unlocked all the elements,
  2. backed up the profile data (/sdcard/Android/data/com.pixowl.thesandbox.android),
  3. uninstalled the hacked APK,
  4. installed the normal APK, and
  5. restored the profile data.

After re-launching the game, the unlocked profile remains with sound restored.

Methods which didn’t work

There is a guide to hack the iPhone version by editing rewards.plist, a file which exists in the Android version too, but making the change suggested in that guide had no effect, which is why I hit the shop.plist instead. Perhaps they left that file as a red herring?

Also, you may be tempted to try to edit the player profile.dat directly to change your mana, and you can find the binary number to do it (offset 0x94), but the file is hashed with a 160-bit hash (probably SHA-1), and the hash is salted or something, because I couldn’t figure out how to re-sign it.

Tortilla Pad: A touch pad made out of a tortilla or wet lumber

I’ve been trying to build a touchpad that appears to be different than those I see online.

Normal touchpads, both capacitive and resistive, have multiple layers, so they can be operated with a plain finger or stylus.  This is good, but costs a non-trivial amount of money.

I want to build one with a single layer of simple resistive material (a material with electrical resistance in the 100-100000 ohm range, see here for a list), with a probe connected to an analog voltage sensor (metal pen with a wire on it OR the finger of someone holding said pen).  The advantage would be that you can make ANY resistive material into a touchscreen, regardless of size, just by putting four conductors in the corners hooked up to a microcontroller.

My first prototype was with a fresh tortilla, and I’m very sorry I didn’t get a picture of it.  It looked dumb as hell…I cut a rectangle out of it, hooked alligator clips to the corners, and toggled voltage at the corners with Arduino data pins, reading the voltage of a probe placed on the surface with an analog pin.  It worked okay, but then stopped working when the tortilla dried out, and re-wetting it didn’t work. (I later found out from a food scientist friend that the reason re-wetting it didn’t work was that the water needs to be entangled in the starch molecules to get the electrical conductivity effect — heating the wet tortilla may have helped.)

I needed a new sort-of-conductive material to use.  Metal was out, since it is TOO conductive.  A chunk of steel has resistance so low I can barely measure it — assume 0.1 ohms corner to corner.  If I put 5V across it, that would be:

V = I * R
5 = I * (0.1)
50 = I

50 amps!  The arduino pins are rated for 40 mA (0.04 A), so that’s no good – the chip would either fry or shut down, depending on if the over-current protection works.  Worse, how much power is that?

P = I * V
P = 50 * 5
P = 250

250 watts, enough to fry the wires or heat the metal, even if the chip didn’t die.  So how much resistance do I need to be safe, let’s say 20 mA over 5V:

V = I * R
5 = 0.02 * R
R = 250

250 ohms minimum.  However, if it’s much more than a few megaohms (1000000 Ω), there will be so little current I won’t be able to measure the voltage accurately. So I need a pretty mediocre conductor…something between 10^2 and 10^7 ohms.  I found a list of materials with different resistances on Wikipedia.  The ρ figues are in Ω·m units, indicating that resistance depends on the dimensions of material used (see that page for details), but I just had to get the right order of magnitude.  In the key range I needed, I saw a bunch of esoteric materials I don’t have, plus one thing that I do have, or rather could make easily:

Wood (damp): 1×10^3 to 1×10^4

So I got out a chunk of particle board from the parts bin, wetted it down with a damp rag, screwed four wires down in the corners, drew a grid, and got started, and it actually worked…as long as I kept it wet.

Further, when I say it “works”, I mean I get meaningful coordinates out of it, but I have some physical and mathematical problems.  Let me run down the setup:

My code flips the X and Y pins shown above high and low to measure X and Y coordinates:

Here’s a pic of the values I get when I trace the grid drawn on the board, graphed with a Processing program:

So it “works”, sort of, but I have two problems:

1. Messed up coordinates: I get 2D values that correlate to where the probe is, but they aren’t nice rectangular coordinates — I need help on the math to turn these readings into real XY coordinates.  I know the basics (resistors in parallel, voltage divider basics), but the solution involves solving a system of equations, and I get stuck.  Help?

2. My “resisitive surface” sucks. My first prototype was a damn tortilla, and it only worked until it dried out.  Now I’m using wet particleboard, which is very inconsistent (~30kOhm on the bottom X axis, ~50kOhm on the top X axis, etc.).  It also constantly needs to be rewatered to stay conductive. What’s a good, cheap resistive surface I can get?  I need it to be between 500Ω-1MΩ end-to-end.

I’m excited to get this working, because it’s incredibly cheap and made of just one simple material instead of layers.  If I can find a resistive paint, I could make whole walls into touch pads.

If anyone wants to weigh in, I’m discussing the project on the Arduino forums here.

MEGAPOMPS: Table-top role playing for lazy people

A few years ago, some friends and I tried D&D at PAX East (a gaming convention).  We wanted to try a tabletop game when we got home, but oh god, D&D has way too many rules.  We just want to dick around and shoot/stab things.

I searched for a game system simple enough to just let us have fun, but even the ones claiming to be simple had 50+ page rule books.

So I developed MEGAPOMPS: The game system with just one table. No classes, no attributes, no hit points; just doing stuff. If you want to do a thing, figure out the skill & difficulty, roll a d20, and check the one table. The GM will figure it out. This one system covers shooting a dude, jumping over a hole, buying a car, fixing a robot, sneaking into a bakery, spotting a rat, stabbing a rat, cooking a rat, and treating diarrhea—MEGAPOMPS does it all. MEGAPOMPS is based loosely on (and also plagiarizes) J.E. Sawyer’s “Simple” system, which was just not simple enough. There isn’t a specific game world tied to the MEGAPOMPS system, though it was designed with an eye toward “Fallout”, a post-apocalyptic nuclear survival series.

To get the full rule book (just 11 pages, 6 of which are just examples of how to do stuff), character sheet, and more, visit MEGAPOMPS.COM!

Here’s a teaser I made for my group in preparation for the next leg of their adventure: