## Maker Wedding: Bachelor party wireless accelerometer Stab-O-Meter

Since I had disassembled the Wine-O-Meter I’d made for a friend’s bachelor party I needed to come up with something else for my own, I wanted to do an updated strongman competition. I decided to put together a wireless accelerometer to hopefully measure the speed and impact of various activities such as swinging a baseball bat, a sledgehammer, a hatchet, a tennis racket — get the idea? Sort of like the measurement tools used on shows like MythBusters or Deadliest Warrior. Along the lines of the Wine-O-Meter I dubbed the project the Stab-O-Meter as measuring arm movements reminded me of one of my favourite Futurama characters, Roberto.

My plan was to use an Arduino to read an accelerometer and use a pair of XBees to wireless relay the information to a laptop. The laptop would be running a Processing sketch to handle the high score display, reset and current readings. It took a little bit to find the right Arudino code to read the LIS331 Triple Axis Accelerometer I’d selected but it worked well once I found it. I don’t know a whole heck of a lot about accelerometers, but this one measures g-forces on three axis, x, y and z. After some trial and error I decided to add all positive g-force readings together and then add all negative g-force readings together. If the positive total was higher I used that as the current amalgamated reading otherwise I used the absolute sum of the negative values. Comment if you’re aware of a better way to translate x, y, z g-forces into a single number representing the speed of the motion (see Hank’s comment below).

Hank Cowdog

A neg X Acc means acc along the negative X axis. The magnitude of the acc is the important measurement, so a better approach would be to sum the squares of each X,Y,Z component and then take the square root (as per the Pythagorean Theorem). This computes the magnitude of the Acc regardless of the direction (or orientation of the accelerometer chips).

result = sqrt(xAcc*xAcc + yAcc*yAcc + zAcc*zAcc);

The Arduino sent the single number amalgamated reading in realtime (or as close as possible) via it’s serial connection to a XBee which in turn wirelessly relayed the serial data to a laptop running a processing sketch to read and deal with the data. The Processing sketch displayed a realtime reading bar on the right, the highest reading yet recorded in large numbers in the center and a RESET button to clear the current highest reading. With this system each contestant could reset the high score using the RESET button or the spacebar and the proceed to swing a bat or stab a tree or whatnot to find they’re personal best, which was then ranked against other’s scores on a white board.

This part worked great, however in impact scenarios (actually hitting something) it was too easy to max out the sensor, which has a max of 24g, so we restricted our games to non-impact swings. I had added hand wrap to the sensor case in order to secure it to the implement of choice, however I quickly realized that it also needed a non-slip surface for grip, I epoxied some rubber salvaged from a guitar effect pedal. Even with the hand wrap and the rubber footing the first full-force swing with a baseball bat sent the sensor soaring into a neighbouring house — duct tape provided the necessary upgrade in grip, but downgrade in polish.

The video below is, aside from my Roberto impression, an early test using a preliminary Processing sketch and no cases for the components. When I get a chance I’ll record a video of the finished setup, perhaps as I demolish my garage this weekend. Yes, it’s an odd video, but that’s what YouTube is for, right?

#### Arduino Sketch

```// 3-axis Accelerometer
// Sparkfun Electronics Triple Axis Accelerometer Breakout - LIS331
// Arduino UNO

/* Wiring:
UNO LIS331

3.3V VCC
GND GND
10 CS
11 SDA/SDI
12 SA0/SDO
13 SCL/SPC
*/

#include <SPI.h>
#include <stdlib.h>
#include <stdio.h>

#define SS 10 // Serial Select -> CS on LIS331
#define MOSI 11 // MasterOutSlaveIn -> SDI
#define MISO 12 // MasterInSlaveOut -> SDO
#define SCK 13 // Serial Clock -> SPC on LIS331

#define SCALE 0.0007324; // approximate scale factor for full range (+/-24g)
// scale factor: +/-24g = 48G range. 2^16 bits. 48/65536 = 0.0007324

// global acceleration values
double xAcc, yAcc, zAcc;

void setup()
{
Serial.begin(9600);

// Configure SPI
SPI_SETUP();

// Configure accelerometer
Accelerometer_Setup();
}

void loop()
{
readVal(); // get acc values and put into global variables

int pos = 0;
int neg = 0;

if(xAcc > 0)
{
pos = pos + xAcc;
}
else
{
neg = neg + abs(xAcc);
}

if(yAcc > 0)
{
pos = pos + yAcc;
}
else
{
neg = neg + abs(yAcc);
}

if(zAcc > 0)
{
pos = pos + zAcc;
}
else
{
neg = neg + abs(zAcc);
}

int result = neg;

if(pos > neg)
result = pos;

Serial.println(result,1);

/*
Serial.print(xAcc, 1);
Serial.print(",");
Serial.print(yAcc, 1);
Serial.print(",");
Serial.println(zAcc, 1);
*/

delay(10);
}

// Read the accelerometer data and put values into global variables
{
byte xAddressByteL = 0x28; // Low Byte of X value (the first data register)
byte readBit = B10000000; // bit 0 (MSB) HIGH means read register
byte incrementBit = B01000000; // bit 1 HIGH means keep incrementing registers
// this allows us to keep reading the data registers by pushing an empty byte
byte b0 = 0x0; // an empty byte, to increment to subsequent registers

digitalWrite(SS, LOW); // SS must be LOW to communicate
delay(1);
SPI.transfer(dataByte); // request a read, starting at X low byte
byte xL = SPI.transfer(b0); // get the low byte of X data
byte xH = SPI.transfer(b0); // get the high byte of X data
byte yL = SPI.transfer(b0); // get the low byte of Y data
byte yH = SPI.transfer(b0); // get the high byte of Y data
byte zL = SPI.transfer(b0); // get the low byte of Z data
byte zH = SPI.transfer(b0); // get the high byte of Z data
delay(1);
digitalWrite(SS, HIGH);

// shift the high byte left 8 bits and merge the high and low
int xVal = (xL | (xH <<8));
int yVal = (yL | (yH <<8));
int zVal = (zL | (zH <<8));

// scale the values into G's
xAcc = xVal * SCALE;
yAcc = yVal * SCALE;
zAcc = zVal * SCALE;
}

void SPI_SETUP()
{
pinMode(SS, OUTPUT);

// wake up the SPI bus
SPI.begin();

// This device reads MSB first:
SPI.setBitOrder(MSBFIRST);

/*
SPI.setDataMode()
Mode    Clock Polarity (CPOL) Clock Phase (CPHA)
SPI_MODE0    0    0
SPI_MODE1    0    1
SPI_MODE2    1    0
SPI_MODE3    1    1
*/
SPI.setDataMode(SPI_MODE0);

/*
SPI.setClockDivider()
sets SPI clock to a fraction of the system clock
Arduino UNO system clock = 16 MHz
Mode SPI Clock
SPI_CLOCK_DIV2 8 MHz
SPI_CLOCK_DIV4 4 MHz
SPI_CLOCK_DIV8 2 MHz
SPI_CLOCK_DIV16 1 MHz
SPI_CLOCK_DIV32 500 Hz
SPI_CLOCK_DIV64 250 Hz
SPI_CLOCK_DIV128 125 Hz
*/

SPI.setClockDivider(SPI_CLOCK_DIV16); // SPI clock 1000Hz
}

void Accelerometer_Setup()
{
// Set up the accelerometer
// write to Control register 1: address 20h
/* Bits:
PM2 PM1 PM0 DR1 DR0 Zen Yen Xen
PM2PM1PM0: Power mode (001 = Normal Mode)
DR1DR0: Data rate (00=50Hz, 01=100Hz, 10=400Hz, 11=1000Hz)
Zen, Yen, Xen: Z enable, Y enable, X enable
*/
byte ctrlRegByte = 0x37; // 00111111 : normal mode, 1000Hz, xyz enabled

// Send the data for Control Register 1
digitalWrite(SS, LOW);
delay(1);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// write to Control Register 2: address 21h
// This register configures high pass filter
ctrlRegByte = 0x00; // High pass filter off

// Send the data for Control Register 2
digitalWrite(SS, LOW);
delay(1);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);

delay(100);

// Control Register 3 configures Interrupts
// Since I'm not using Interrupts, I'll leave it alone

// write to Control Register 4: address 23h
/* Bits:
BDU BLE FS1 FS0 STsign 0 ST SIM
BDU: Block data update (0=continuous update)
BLE: Big/little endian data (0=accel data LSB at LOW address)
FS1FS0: Full-scale selection (00 = +/-6G, 01 = +/-12G, 11 = +/-24G)
STsign: selft-test sign (default 0=plus)
ST: self-test enable (default 0=disabled)
SIM: SPI mode selection(default 0=4 wire interface, 1=3 wire interface)
*/
ctrlRegByte = 0x30; // 00110000 : 24G (full scale)

// Send the data for Control Register 4
digitalWrite(SS, LOW);
delay(1);
SPI.transfer(ctrlRegByte);
delay(1);
digitalWrite(SS, HIGH);
}
```

#### Processing Sketch

``` import pitaru.sonia_v2_9.*;
import processing.serial.*;

Sample beep;

float high;
int count;

int inside = -1;
int bx=850; // position in X of the up corner of the botton
int by=460; // position in Y of the up corner of the botton
int h=40;
int w=100;

float inByte=0;
float drawByte=0;

PFont f;

Serial myPort;         // The serial port
int xPos = 10;         // horizontal position of the graph

public void stop()
{
Sonia.stop();
super.stop();
}

void setup () {
// set the window size:
size(1024, 550);

high = 0;
count = 0;

f = createFont("Verdana",6,true);

// List all the available serial ports
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my  Arduino, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
// set inital background:
background(0);

Sonia.start(this);
beep = new Sample( "beep-02.wav" );
}

void draw()
{
if(keyPressed)
{
if(key == ' ')
{
high = inByte;
}
}

background(0);

//stroke(255,0,0);
rect(xPos, 500 - inByte, xPos+20, inByte);

textFont(f,25);
fill(255);
text(inByte, xPos - 10, 500 - inByte - 25);

count = count + 1;

if(count > 2)
{
count = 0;

if(drawByte < high - 200)
{
beep.play();
drawByte = drawByte + 100;
}
else if(drawByte < high - 10)
{
beep.play();
drawByte = drawByte + 10;
}
else if(drawByte < high - 1)
{
beep.play();
drawByte = drawByte + 1;
}
else if(drawByte < high - .1)
{
beep.play();
drawByte = drawByte + .1;
}
else if(drawByte < high - .01)
{
beep.play();
drawByte = drawByte + .01;
}
else if(drawByte < high - .001)
{
beep.play();
drawByte = drawByte + .001;
}
else if(drawByte < high)
{
drawByte = high;
}
}

if(drawByte > high)
{
drawByte = high;
}

textFont(f,140);
fill(255);
text(drawByte, 200, 325);

rect(bx,by,w,h); // Button

textFont(f,25);
fill(0);
text("RESET", bx+10, by+30);
fill(255);
}

void mousePressed(){
if(!(((mouseX > (bx+w))
||(mouseY > (by+h)))
||((mouseX < bx)
||(mouseY < by))))
{
high = inByte;
}
}

void serialEvent (Serial myPort) {

if (inString != null)
{
// trim off any whitespace:
inString = trim(inString);
// convert to an int and map to the screen height:
inByte = float(inString);
inByte = map(inByte, 0, 1023, 0, 500);

if(inByte > high)
{
high = inByte;
}
}
}
```

## Maker Wedding: Vinyl “flexi” record wedding invitations

My wife and I enjoy music immensely and are both enthusiastic musicians, with that in mind we decided to have vinyl “flexi” records cut for our wedding invites. You probably remember the flexible records or flexi-discs that sometimes came in magazines, or with children’s books — turns out the rumours of their demise are greatly exaggerated, they’re still around, perhaps even making a comeback.

After some preliminary investigation of the process we realized that dealing with a commercial recording just wasn’t going to work, copyright issues and permission issues would’ve bogged us down for months — so we decided to write and record our own collaborative instrumental song. A fun little tune we titled “Invited” was the result of a feverish week of writing, re-writing and recording (and re-recording).

The next hurdle was finding out the who and how of having them pressed, cut, printed, etc. The first place we found was Pirate Press but they were somewhat unresponsive and not at all impressed with our timeline or order size. We needed only about 150 and we were hoping to have them in 3 to 4 weeks, the regular turn-around is 5/6 weeks. Another place overseas (Northern Record Pressing, Norway) was quickly crossed off the list due to distance and our time constraints, in retrospect they may have worked out since we ended up dealing with international shipping anyway. With time running out I contacted David Read, The Vinyl Record Guru. David was friendly, helpful and while cautious regarding our timeline was willing to take on the project.

Once David was on board we mastered the recording and handed them off along with the printing template. We decided to print white ink on clear flexis to contrast the silver and black of various other items in our invite packages. Vinyl mastering was minimal as flexi audio quality leaves much to be desired we decided not to belabour the process, though some simple tips may have gone a long way, ie: center any low frequencies and assume anything below 40Hz or above 16Khz ain’t going to make it in. You can find more info here and here. You can also “simulate” what a recording is going to sound like on vinyl by either applying both a low and high pass filter or by running it through a VST such as iZotope’s Vinyl, which is what I’ve done for the simulated version below.

As it turned out, even though David is based in Canada, a lot of international shipping is required, the plates from Europe and the flexis themselves from the U.S. (perhaps from Pirate Press after all, I’m not sure), but in the end it took about 4 weeks to get the flexis after providing everything required — and they looked great!

A new needle for our portable record player from the good folks at Ring Audio in Toronto and we were off to the races. We paired the flexis with a sheet of translucent white vellum and stacked them with the rest of our invite package. The flexis are 7″ x 7″ and fit nicely into 7.5″ x 7.5″ envelopes — though these didn’t fit so nicely into some mailboxes. Another thing to keep in mind is that most paper places won’t stock this size of envelope, you’ll probably have to order them. We ordered ours from Paper-Papers and were quite pleased with the price and expedience, your local paper shop will most likely offer to order them for you but they’ll be ordering from the same supplier you can find online where you can have them shipped directly to you, without a markup.

All said and done, the flexis alone came in around \$750, we had to settle for a minimum order of 250, by no means the most inexpensive invites but they came with the added benefit of having our original song on vinyl and, as musicians, that gives us the warm fuzzies.

Invited (MP3, Simulated Vinyl Version)
Invited (MP3)

Ester Pugliese (Lead Guitar, Electric Air Organ)
Phil Tucker (Rhythm Guitar, Lead Guitar Two/Three, Percussion)

## Maker Wedding: XBee remote relay as photobooth RF camera trigger

If I didn’t have XBee’s kicking around from some other fanciful endeavour I probably would’ve purchased an inexpensive Aputure remote trigger for the photobooth at my wedding reception — but instead I decided to make an RF camera trigger system from parts I had around, mainly two XBees and a relay. XBee’s are great little wireless mesh transmitter/receivers, much like Tomax and Xamot what you do to one is instantly reflected by the other, so you need only connect a pin to high on the transmitting XBee and the same pin on the receiving XBee will go high — perfect for remotely triggering a relay.

The plan was to have one XBee with a simple pull-down button which would trigger a relay on the receiving XBee and whaddya know — it worked. The receiver relay was attached to a wired camera remote (Canon TC-80N3) I already had from a previous project which allowed the relay to trigger both a Canon Rebel XT and, after splicing in the original connector, a Canon 5D Mark II.

With this setup, two AA batteries for both the transmitter and receiver lasted for days. The only issue I found was that the Rebel XT needed about a 500 millisecond signal whereas the 5D Mark II would trigger instantly on a contact of any duration, I thought about a capacitor, timed-delay relay or 555 solution to keep the relay open longer, but never got around to implementing any solution — after all the 5D would capture the shot if not both cameras.

To be honest, this project survived to the night before, but I decided to scrap the photobooth entirely from the wedding reception to reduce complexity — the lighting turned out to be insufficient and, as the groom, I had no time left to deal with the camera setup. That being said, the theory is sound and it worked quite well for days in my living room, taking shot after shot of me and my fiancée lounging on our couch.

## Maker Wedding: Rustic Edison-style hanging light fixtures

After deciding to have our wedding in a barn which had been converted into an event space my thoughts turned to lighting. With the rustic nature of the barn and the impressively high ceilings, one type of lighting sprang to mind instantly — Edison-style bulbs.

I’ve long been a fan of cloth covered wire, so I decided to make each bulb a separate hanging fixture with twisted cloth covered wire, an outlet and a bulb socket. This made the setup completely modular, allowing us to adjust for electrical loads and support almost any arrangement of bulbs. Each fixture would be plugged into a multi-outlet extension cord and secured with a small electrical tie. Each multi-outlet extension cord was plugged in through a lamp dimmer, which was also affixed with an electrical tie to avoid disconnections.

The parts I sourced are below, feel free to comment with better prices. These sockets are three-stage but the bulbs are not, bulbs could be swapped for three-stage bulbs or the sockets for single stage, but it all works regardless. Three-stage bulbs may eliminate the need for the dimmers, but having the dimmers made adjustments quite easy.

To wire the hanging fixtures I first slipped one piece of heat shrink tubing (without heating yet) over the cloth ends encompassing both leads. I then worked the cloth back, stripped the insulation inside and then attached the leads to the socket and plug. Once the leads were secured I shimmied the heat shrink as close to the connections as it would go and blasted it with the heat gun (or, oh my, harassed it with the soldering iron).

Before you go wild with these, do some math to see how many fixtures you should be plugging into each extension cord, and how much wattage your dimmer can support — watch dimmers closely at first, they may heat up, but make sure they’re not melting!

If you’re interested in other Edison-style lighting ideas and/or wondering what I did with all these lights afterwards check out DIY steampunk-style iron pipe Edison fixture and DIY reclaimed lumber hanging Edison bulb chandelier.

Update: Close to a year following our wedding we sent these lights, along with a simple handcrafted fixture, to family and friends as a token of our appreciation and as a keepsake from our wedding. Details about the Edison light thank you packages can be found here.

Parts

## Video: Triggering lights with guitar frequency levels

Had an idea after catching this post on Hack a Day, why not use the frequency level values to trip a 120 volt relay? So I ordered some parts and did it. The audio analyzing chip, the MSGEQ7, is easily accessed using DFRobot’s DFR0126, which, being in Canada, I got from RobotShop. Connecting the breakout board to an Arduino Nano was a 5 minute job, sample code and a library is linked from the DFRobot product page. I initially used a potentiometer to input the threshold levels for the relay, but then realized I could use a momentary switch to sample the desired threshold and then use that to compare the real-time input to.

The circuit is simple, when a button (momentary stomp) is depressed, and we all get depressed sometimes, the code saves the input values from the audio analyzer. There are seven frequency bands it records, but I found only three or four of them are applicable to guitar, so ignore the lowest and perhaps the highest two. After a threshold has been recorded simply check the input against the recorded levels and trip the relay (or not).

I gave the thresholds a grace of 5 (on a theoretical input range of 0-1023), I may add a pot for this adjustment as it may vary based on guitar signal types. The result is quite versatile, you could have the relay turn off a mellow light and turn on a spastic light when the signal goes loud. If you pay close enough attention to EQ bands and levels you could trigger various lights based on a variety of guitar effects. This setup would also allow, albeit in a roundabout way, you to engage a guitar effect based on the frequency band levels, as long as the effect will pass-through without power then connecting it to the relay would engage the effect — or you could redesign this circuit to route some audio signals based on the input levels.

The pedal I stomp in the video is the MP-1 fuzz from Inductor Guitars, the EQTrigger pedal is connected to the extra output on a Boss TU-2 tuner and is reacting auto-magically to the change in guitar signal when I play louder or engage the fuzz.

#### Parts List

Okay, so I didn’t spend a lot of time working out a clean circuit diagram — at least I didn’t use as much electrical tape in the diagram.

#### Arduino Sketch

```
#include <AudioAnalyzer.h>
Analyzer Audio = Analyzer(4,5,0);

int FreqVal[7];
int FreqThreshVal[7];

int switchPin = 3;
int switchValue = 0;

int relayPin = 2;

void setup()
{
pinMode(relayPin, OUTPUT);
pinMode(switchPin, INPUT);

for(int i=0;i<7;i++)
FreqThreshVal[i] = 512;

//Serial.begin(57600);
Audio.Init();
}

void loop()
{
Audio.ReadFreq(FreqVal);//return 7 value of 7 bands pass filiter
//Frequency(Hz):63  160  400  1K  2.5K  6.25K  16K
//FreqVal[]:      0    1    2    3    4    5    6

if(switchValue == HIGH)
{
for(int i=1;i<5;i++)
{
FreqThreshVal[i] = FreqVal[i];
/*
Serial.print(max((FreqVal[i]-100),0));

if(i<6)
Serial.print(",");
else
Serial.println(" SET ");
*/
}
}
else
{
boolean thresholdMet = true;

for(int i=1;i<5;i++)
{
//Serial.print(max((FreqVal[i]-100),0));

if(FreqVal[i] < FreqThreshVal[i]-5)
thresholdMet = false;

/*
if(i<6)
Serial.print(",");
else
*/
}

if(thresholdMet == true)
{
//Serial.println(" MET ");
digitalWrite(relayPin, HIGH);
}
else
{
digitalWrite(relayPin, LOW);
}
}
}```