Sunday, December 11, 2016

Electronic Signatures - Snake Oil

Electronic signatures are commonly used in the more advanced enterprises to sign documents - PDF files mostly.  Unfortunately, the implementation is broken and it doesn't work.  The broken implementation reduces it to snake oil.

A typical IT system is set up and managed by one or two overworked computer geeks who clicked through a setup wizard to configure a key server on the company LAN.  The public and private keys are distributed on the company workstations and laptop PCs by Active Directory and GPG and once it looks like it is working and some users can sign a document, the whole universe shakes, angels and birds sing, flowers fall down from heaven and all is well... or is it?

I wanted to be able to sign documents on my engineering laptop PC which runs Linux, not just my office PC, which runs Windows (and which usually has some problem or another).  So I asked IT for a copy of my Private key.  After a few months, they emailed me my Public key.  So clearly, the IT geeks don't understand the basics of public/private key systems, yet they are entrusted with managing it...

Consequently, I spent a few minutes looking into the setup and as far as I can figure, the Private key resides somewhere on my Windows PC, but I don't have administrator rights to it, so I cannot recover it and I don't want to have admin rights on a Windows PC, since then I would be responsible for everything that goes wrong with it.

Thinking about it a bit more, I realized that it is my key, so only I should have access to it, but on a Windows PC, the IT administrators can do anything, so the key is not mine only, it is theirs too.  They can take my supposedly private key and do with it what they want.

The only thing that prevents the corporate IT administrators from misusing my private key and impersonating me, is their incompetence.

Therefore, I can sign a document on my office PC and everyone will then think that it was me, but it could have been someone else, because IT has access to the private keys of everybody and Windows machines are not exactly known for their security.

Furthermore, since the PDF reader can only verify signatures when the LAN and Key Server work properly, it frequently happens that one opens a document and gets a warning that the signatures cannot be verified - so all users are used to ignoring that.  The result is that anyone can subvert the keys and sign anything with any made up key and no-one will notice, or care.  Also, since the company key server is private, anyone outside the company, cannot verify the signatures at all, which considering, is probably a good thing.



Saturday, November 5, 2016

Grajcar Slovak Folk Band Does Metallica

Well, evidently good artists can play anything on any instrument.  Here is the Slovak folk dancing band Grajcar, playing Metallica on three violins, a double base, clarinet and cymbal.

I recorded a minute or so of Nothing Else Matters, at Sheik Maktoum's Majles at the Emirates Golf Club in Dubai, during a Czech and Slovak party. (The horrid video quality is due to Google, not me!).

Here is more of them in what looks like Bratislava: 

Saturday, September 24, 2016

Rover2: Serial Motor Controller

My new rover is supposed to be simpler than the first one and something that irked me with the first design was the motor controllers.  They worked, but they are ridiculously complicated.  So I bought a Sparkfun Monster Moto Controller and hooked it up - much simpler.

The only hassles with it is that if you would plug another board on top of it, then it could short to the tops of the capacitors and the VIN connector could short to the Arduino ICS pins underneath it.  I stuck a rectangle of clear plastic cut from some screws packaging between the boards and snipped the ICS pins off - done.

Serial Control

Controlling a DC motor is straight forward, using two pins to switch the H bridge direction (INA1, INB1) and one for speed PWM (PWM1).  There is also a current sense input (CS1) that you can set to turn the motors off if they get stuck and the current increases too much.  You'll have to set the sense level with trial and terror.

Here is an example for a serial motor control interface, using simple two character messages:
  • ms - stop
  • mf - forward
  • mb - backward
  • mr - turn right
  • ml - turn left
  • mu - speed up
  • md - slow down
This is also a good example of how to parse a serial data protocol efficiently with a switch-case statement in C.  A switch statement is easy to read and understand by humans and very efficient on computers.  Each case compiles to a check and a conditional jump.  It doesn't slog through all the code from top to bottom.

// Monster Moto Board
// Herman Oosthuysen, Sep 2016

// Monster motor controller with simple two character ASCII serial interface
// Controls two motors to make a rover run forward reverse and turn
// Turns are executed by speeding up the motor on one side and slowing down (or reversing) on other side
// A command starts with M and ends with Enter (CR or LF)
// MS - Stop, short the motors to ground
// MF - Forward, best to slow down and stop before going backward
// MB - Backward, best to slow down and stop before going forward
// ML - Turn Left, cancel a left turn with a right turn
// MR - Turn Right, cancel a right turn with a left turn
// MU - Speed Up, only three speed steps, stop, slow and fast
// MD - Slow Down, only three speed steps, stop, slow and fast

// Literals
#define BAUD  9600
#define RATE  200
#define CR    0x0D
#define LF    0x0A
#define MAX   2
#define MIN   -2
#define INC   0x20
#define MAXCS 0x80

// Pins
// Motor 1
#define INA1  7
#define INB1  8
#define PWM1  5
#define EN1   A0
#define CS1   A2

// Motor 2
#define INA2  4
#define INB2  9
#define PWM2  6
#define EN2   A1
#define CS2   A3

// Global Variables
int cs1 = 0;  // 0 to FF
int cs2 = 0;  // 0 to FF
int spd1 = 0; // -2 to 2
int spd2 = 0; // -2 to 2
int pwm1 = 0; // 0 to 1023
int pwm2 = 0; // 0 to 1023
char ch = 0;  // ASCII character received
char adr = 0; // ASCII M start of Motor message
char cmd = 0; // ASCII command

void setup()
  Serial.println("Monster Moto, eh.");
  // Stop the motors
  pinMode(INA1, OUTPUT);
  digitalWrite(INA1, LOW);
  pinMode(INA2, OUTPUT);
  digitalWrite(INA2, LOW);
  pinMode(INB1, OUTPUT);
  digitalWrite(INB1, LOW);
  pinMode(INB2, OUTPUT);
  digitalWrite(INB2, LOW);

  // PWM zero speed
  analogWrite(PWM1, 0);
  analogWrite(PWM2, 0);

void loop()
    ch =;

    // Message starts with M and ends with Enter
    // eg: ms[enter]
    // Ensure that the serial terminal sends the line ends
    if((ch == CR) | (ch == LF))
      adr = 0;
      cmd = 0;
    else if((ch == 'M') | (ch == 'm'))
      adr = 1;
      cmd = 'M';
    else if(adr)
      cmd = ch;
      Serial.print("cmd = ");

          case 'S':
          case 's':
            spd1 = 0;
            spd2 = 0;
            pwm1 = 0;
            pwm2 = 0;
          case 'F':
          case 'f':
            spd1 = 1;
            spd2 = 1;
            pwm1 = spd1 * INC;
            pwm2 = pwm1;
          case 'B':
          case 'b':
            spd1 = -1;
            spd2 = -1;
            pwm1 = abs(spd1) * INC;
            pwm2 = pwm1;
          case 'L':
          case 'l':
            if(spd1 < MIN)
              spd1 = MIN;
            if(spd2 > MAX)
              spd2 = MAX;
            pwm1 = abs(spd1) * INC;   
            pwm2 = abs(spd2) * INC;  
          case 'R':
          case 'r':
            if(spd1 > MAX)
              spd1 = MAX;
            if(spd2 < MIN)
              spd2 = MIN;
            pwm1 = abs(spd1) * INC;
            pwm2 = abs(spd2) * INC;        
          case 'U':
          case 'u':
            if(spd1 > MAX)
              spd1 = MAX;
            if(spd2 > MAX)
              spd2 = MAX;
            pwm1 = abs(spd1) * INC;
            pwm2 = abs(spd2) * INC;       
          case 'D':
          case 'd':
            if(spd1 < MIN)
              spd1 = MIN;
            if(spd2 < MIN)
              spd2 = MIN;
            pwm1 = abs(spd1) * INC; 
            pwm2 = abs(spd2) * INC;       
            Serial.print("Err = ");
        Serial.print("spd1 = ");
        Serial.print("spd2 = ");
        Serial.print("pwm1 = ");
        Serial.print("pwm2 = ");

  // Periodic Motor Control Update
  direction(spd1, spd2);
  speed(pwm1, pwm2);

// Left and right hand motors rotate in opposite directions
void direction(int spd1, int spd2)
  if(spd1 >= 0)
    digitalWrite(INA1, HIGH);  // CW - Forward
    digitalWrite(INB1, LOW);
    digitalWrite(INA1, LOW);  // CCW - Reverse
    digitalWrite(INB1, HIGH);         
  if(spd2 >= 0)
    digitalWrite(INA2, LOW);  // CCW - Forward
    digitalWrite(INB2, HIGH);
    digitalWrite(INA2, HIGH);  // CW - Reverse
    digitalWrite(INB2, LOW);         

void speed(int pwm1, int pwm2)
  analogWrite(PWM1, pwm1);
  analogWrite(PWM2, pwm2);

void sense(void)
  cs1 = analogRead(CS1);
  cs2 = analogRead(CS2);

  if((cs1 > MAXCS) | (cs2 > MAXCS))
    spd1 = 0;
    spd2 = 0;

PWM motor control is not linear.  The motors need a minimum amount of power to start turning and after that, the speed increases rapidly until a maximum is reached.  So the performance curve is S shaped and some experiments are required with your motors if you want to have meaningful speed steps for crawl, walk and run for example.

Seriously High Power

MOSFETs can be paralleled, so if you need to control a very big motor, then you can wire the two channels together, so this is a really nice controller board that could control a winch, a scooter or a wheel chair for example.  So it would be good if you need to build something to help a disabled friend - Sparkfun to the rescue!

A high powered motor controller should be close to the motor because of the high currents in the wires.  So in a big system, you may need one Arduino per motor controller.  If you use the same serial interface protocol on multiple Arduino powered actuators, then you can multi-drop the serial line from the main control computer to the various actuator computers.  For this example, the messages start with M and for something else, it could start with S or whatever else you like.

For a simple toy, error checks are a waste of time, so I just send a message and hope it works.  I don't bother with CRCs and Retries on toys, but if you want to control a winch or a wheel chair, then you should be more careful!

BTW, if you need to build something serious operating at 12V, then I recommend that you get Anti-Gravity batteries.   These are light weight and will ensure that one can still manhandle the thing - lead-acid batteries make it impossible to lift a wheel-chair into a car.

La Voila!


Saturday, September 3, 2016

DSP on an Embedded Processor

Doing digital signal processing on a teeny weeny Arduino processor requires some trade-offs, since it is slow and doesn't have much memory.  However, bear in mind that today's embedded processors are faster than yesteryear's DSPs, so all you need to do, is use yesteryear's methods!

What it mostly amounts to, is careful use of integers and shifts, instead of floating point numbers and multiplies.  If you can, limit multiplies, divides and buffer sizes to powers of 2.  That affords enormous speed optimizations.

Circular Buffers

For example, let's filter input from an 8 or 10 bit A/D on a little 16 bit embedded processor.  This usually requires a low pass filter.  A simple low pass filter is a moving average and to do that, you need to keep a buffer of old data values.

If you are smart, then you will set up a circular buffer with 10 values, but if you are smarter, then you will use a buffer with 8 or 16 values instead - why?

If the buffer size is a power of 2, then you can make the index wrap around automagically with a simple bit wise AND function, thus making management of the circular buffer quite trivial.

Say the data buffer size is 16, with a read and write index r and w:
unsigned int buffer[16];
unsigned int r = 0;
unsigned int w = 0;

Then you can post increment the index with w++ and make it wrap with AND 0x000F, like so:
buffer[w++] = data;
w &= 0x000F;

The index w will then wrap around to zero when it reaches 16, without the use of any complicating ifs, thens elses or buts!

Do the same thing when you read from the buffer.

How do you know when the buffer is full/empty?

Easy, when r == w, then you are in trouble and the buffer is either full or empty, depending on what you are doing.  As easy as pi...

Maintaining Precision

When doing mathematics in integers, the fractional amounts that you can lose during calculations can add up over time and cause wild inaccuracy.  You can mitigate this problem by scaling.

Simply multiply the A/D input value by 16 immediately and eventually when you output a result, divide by 16.  That provides 4 fractional bits for precision on the bottom end and you still have a few bits on the top end for overflows.

The above example then becomes:
buffer[w++] = data << 4;
w &= 0x000F;

Hanning Filter

Everybody uses some sort of moving average low pass filters, so just to be different, I'll describe a Hanning filter instead.

y[k] = (x[k] + 2x[k-1] + x[k-2]) / 4

This filter only needs 4 variables, and you can multiply with one shift and divide with two shifts:

y[k] = (x[k] + x[k-1]<<1 + x[k-2]) >>2

You can use a 4 long data buffer and rotate the index through it in a circle, same as above:

Save new data, pointer++, pointer & 0x0003
Read old data, pointer++, pointer & 0x0003
Read older data, pointer++, pointer & 0x0003

You are now ready to save new data again.

So with a little bit of head scratching you can implement a Hanning filter very efficiently.

Moving Average

A rolling mean can be calculated on the fly without a buffer:
Take 1/8 of the current input data x(k) and add it to 7/8 of the previous output data y(k-1).  
This yields the new output data y(k).

y[k] = (7 * y[k-1] + x[k]) / 8

Now how do you do that on a small processor that cannot multiply and divide efficiently?

Divide by 8 is easy:
y = x >> 3

Multiply by seven?  Multiply by 8 and subtract again
y = x << 3
y -= x

The result has similar complexity to the Hanning filter above.

GPS Position Filter

To use a GPS receiver in a toy, one needs to stabilize the received position data.  The cheap toy GPS data typically varies by +-7 meters or worse.  Considering that a typical backyard is not much bigger, this makes it hard to use GPS for navigation of a model car or airplane.

A toy car moves slowly, so you can use a heavy handed low pass filter on the latitude and longitude as above, but it really is only useful when you play in a large park and you have a large battery and good obstacle avoidance sensors, since GPS alone won't keep your toy on a pathway.

La voila!


Thursday, September 1, 2016

Pleasant Random Jingle Generator

Beeping Computer

Way back during the time of the dinosaurs, circa 1975, when one turned on a desktop computer, it would go Beep!  That fell out of favour once Microsoft figured out how to make a computer take 3 minutes to boot up, before finally being able to emit a simple beep.   However, it is still common practice to test a new little embedded controller by flashing a LED.

Music vs Noise

Now for those tinkerers who are a little more adventurous:
How about pleasant sounding random noise? 

There are two things that help to make noise sound acceptable:
  • Use a tonal scale that everyone is used to.
  • Avoid obvious dissonance.


We could use a Pythagorian scale with 7 notes per octave and perfect harmony, but then it will sound weird - like a Scottish bag-pipe and I don't have enough Scottish genes in my ears to prevent them from bleeding.

The equal tempered (logarithmic) scale of Johan Bach (Das Wohltemperirte Clavier, 1722) ), with concert pitch (1939), is used in modern pianos and synthesizers.  Everyone in the western world is used to it - except maybe the Scots - and it is easy to calculate on the fly, using the formula:
  • fn = A * 12th root of 2 ** n
where A = 440 Hz for concert pitch.

Dissonance and Consonance

According to my namesake O'l Hermann von Helmholtz, maximum dissonance occurs when a beat between two tones is 33 Hz.  So avoid that and it should be less annoying.  This is effectively what is done in musical 'chords', which are designed for best consonance.

My old piano teacher will spin in her grave...

Here is a simple Arduino random jingle generator door bell where I tried to exercise the above rules.

// Teensy2 LED, Serial, Muzak
// Herman Oosthuysen 2016
// To enable the debug serial port:
// Go to Tools, Port and select cu.usbmodem12341

#include <math.h>

// A pleasant sounding random noise generator
// using the equally tempered scale and a simple test to reduce dissonance.

// Helmholtz: Maximum dissonance occurs when a beat = 33 Hz
// In a chord, one should watch the 2nd, 3rd and 5th harmonics also - most power

// Concert pitch: A4 = 440Hz (55, 110, 220, 440, 880, 1760...)
// CENT = 12th root of 2
// fn = A * CENT ** n

#define A1    55
#define CENT  1.059463094359
#define SPKR  8
#define LED   11
#define BAUD  9600

#define FMIN  200
#define FMAX  1200
#define TMIN  4
#define TMAX  8

int flsh = 0;
int tim = 0;
int fold = 0;
int fnew = 0;

void setup()  
  pinMode(LED, OUTPUT);

  Serial.println("Teensy2, Muzak, eh.");

void loop()                    
  // A Pololu IRS05A proximity switch, makes it a funky door bell

  // or pet detector/terrorizer
  prox = analogRead(A0);  

  if (prox < 500)
    digitalWrite(LED, flsh);
    flsh ^= 1;

    // Helmholtz: Max dissonant if beat = 33 Hz
    // So avoid consecutive notes that are 'too close'
    // and since 42 is the answer to everything...
    while (abs(fnew - fold) < 42)
      fnew = random(FMIN, FMAX);

    tim = random(TMIN, TMAX);

    tone(SPKR, fnew);

    fold = fnew;


// Bach's Equal Tempered frequency calculator
// 12 intonations per octave
// A1 = 55 Hz: n=1
// A4 = 440 Hz: n=12*4
int freq(int n)
  double t;

  t = A1 * pow(CENT, n);
  return (int)t;

Well, that actually sounds better than most of the stuff on Nights with Alice Cooper!


The Arduinos are very easy to interface with little sensors.  In this example, I used a proximity switch to make it into a door bell of sorts.  I actually added it as a simple way to turn the silly thing on and off while experimenting.

Similarly, one could use a Sonar or IR Range sensor and modify the tune depending on the range of someone approaching your front door.  Sonar is sensitive to wind, so it may give false alarms if you use Sonar as the main detector, but you could aim it at a tree and listen to the wind sing.

It would also be fun to make a wacky proximity sensor Xilophone with Sonar tone or rhythm control, which could lead to children bouncing around your door playing - good for Halloween:  Twick or Tweet!

Pseudo Polyphonic

I can leave this toy running for a couple minutes, without getting annoyed by it - bored yes - but it isn't too grating on the ears, which was the whole intent of the exercise.

The weird thing is that while the program is obviously monophonic, it sounds somehow polyphonic, probably because the program also changes the metrum of the tones, which the brain then interprets as two or three melodies playing simultaneously.

I have not encountered anything in the literature describing this pseudo polyphonic effect.  Maybe it is indeed a new discovery.  It sounds monophonic when I slow it down only.

Music is not simple applied mathematics, it is psychological too.

If you are interested in computer generated music and want to be wowed beyond belief, then install a MIDI plugin in your browser and go the Wolfram Tones web site.  Dr Wolfram, is the creator of Mathematica - a real genius.  His music generator is based on Cellular Automata.  Others have used Fractals to much the same effect.

Elevator Muzak

Please just don't install this muzak generator in a 100 floor elevator, eh...

Have fun,


Saturday, August 27, 2016

Arduino Rover #2

My second rover is coming together.  The advantage of a ground rover is that it cannot fall out of the sky, so one tends to get rather more hours of amusement out of it than from a helicopter or fixed wing toy aircraft.

The first rover worked, but it was too complicated.  The problem with all toy projects is that I tend to forget what I was doing with it and I like to 'work' on multiple things at the same time.  My shop currently has a glider, a valve guitar amplifier, a VU meter, multiple radio transceivers and this rover all in various stages of incompletion.  Therefore any project needs to be modular and simple, so that I can see what is going on at a glance.  Otherwise, it ends up in a corner, gathering dust, rather sooner than later.

Rover #2 uses the Sparkfun Arduino Redboard for its brains and it is meant to be completely autonomous.  Addition of RC makes it too complicated and hard to maintain, so I ripped all that out (and it can now go back into the 2m electric glider!).

I re-used the Pololu 100:1 geared DC motors, enormous wheels and high power controllers, 7.8V
NiMH batteries, forward MaxSonar and Sharp IR range finder and a reverse Vishay IR Proximity sensor.   The sensors all have analogue outputs, so they are easy to hook up to an Aurduino A0, A1 and A2.  The motor controllers are serial and hooked together onto the same SW Serial Tx port used for the GPS Logger.  I only use the serial Rx for the GPS, so I use the Tx for the two motor controllers on a free pin D7.

The two wheels on the right are on one controller and the two on the left on another.  It simply turns with brute force - like a tank.

The chassis is my trademark olde skool wooden breadboard (It is rectangular, with rounded corners!) and the only parts that are screwed, wired and glued down with any sense of permanence are the 4 wheels, since having a wheel come off during a run, is disappointing.  The motors and wheels are of course totally oversized for this little toy, but it sure looks cool, eh...

The batteries, electronics and sensors are simply stuck on with 'chewing gum' (blue Tack-It).  Most wiring are plug in, using Berg 0.1" headers.  Only the batteries have polarized connectors so I can't plug them in the wrong way around (well, I still managed to do something like that regardless).

This way, it is easy to reconfigure this hoosammawhatsit and pull it apart to reprogram or solder something, without having to break out a pile of tools.


Three sensors should be enough for obstacle detection: IR Range finder, Sonar range finder and IR Proximity detector.

Here is some example code to read the simple sensors:

// Sharp IR Range Finder
// MaxSonar Range Finder
// Vishay proximity sensor
// Herman Oosthuysen, 2016

// IR values range between about 0x0165 with wheels touching a wall, to 0x0003 to the end of the room.
// Sonar values range between about 0x000b with wheels touching a wall, to 0x0190 to the end of the room.
// The proximity sensor shows about 0x03c0 when there is nothing and 0x003c when there is something.

void setup()

void loop()
  int   ir = 0;
  int   sonar = 0;
  int   prox = 0;
  char  res[5];

  ir = analogRead(A0);
  sonar = analogRead(A1);
  prox = analogRead(A2);
  sprintf(res, "%04x", ir);

  sprintf(res, "%04x", sonar);

  sprintf(res, "%04x", prox);


...and here is what the whole mess looks like once things are more or less connected:

Hmm, eye drops and non-alcoholic beer - both very important debug tools...

Pololu Motor Controller Setup

The motor controller needs to be configured (RC/Serial/Potentiometer control, ASCII/binary protocol and more).  This requires special software, which of course is not available for a Mac.  Curiously, they do have both Linux and Win32 versions of the control program.

So I fired up my trusty WinXP virtual machine on Virtualbox.  When plugging the USB cable in, it comes up as an unknown, so I created a USB port filter with only a Name: Pololu, Product: 0098 and Vendor: 1FFB, while ensuring everything else is completely blank.  Then replug the cable and wind up the Windows.  The Pololu program wants to run as administrator (unsurprisingly) and install a device driver twice, each time you plug the motor controller in.  I guess regular users of Windows would be used to this nonsense.

These motors are powerful enough that the buggy could do a wheelie.  I proved that with the first version.  So I would like to add an accelerometer and get it to flip onto its hind legs.

For the Arduino interface I set it to Serial/USB, Fixed 9600 baud, Binary, No CRC and made sure that the ID for the two controllers are different (mine are 13 and 14).  Save it and hope for the best.


Well, for a moment there anyway.  I plugged a motor controller in wrong and fed 7.8V into the 5V supply, blew the Arduino out of the water and it went to join the crowd in the great computer heaven in the sky.   My Mac even rebooted - but is still working - fortunately.

This is why I like playing with thermionic valves - they can take a lot of abuse - little embedded processors not so much.  So it looks like I'll be making the courier company rich, unless I order multiples of these things as spares, a handful of zener diodes and whatnot for protection, but that feels like planned waste - sigh...

Monster Moto

Eventually, I replaced the two Pololu controllers with a Monster Moto board from Sparkfun.  This way, I just have three boards plugged together and one battery pack - simpler.

The Monster Moto control is described in another post.

Arduino Rover Pins Used

The GPS board has a lot of breadboard space and places where tracks can be cut and reconnected.  To get everything connected, I had to do a little surgery with a knife on the bottom of the GPS board, and remove two 810 Ohm SMD resistors from the top of the Monster Moto board, as explained below.

A0 - (EN1 Motor remove 810R); Sonar range
A1 - (EN2 Motor remove 810R); LED range
A2 - CS1 Motor
A3 - CS2 Motor
A4 - IR proximity
A5 -

D0 RX - USB Serial; (RX GPS switch to SW)
D1 TX - USB Serial; (TX GPS switch to SW)
D2 -
D3 -
D4 - INA2 Motor
D5 - PWM1 Motor
D6 - PWM2 Motor
D7 - INA1 Motor
D8 - INB1 Motor; (SW RX GPS cut track)
D9 - INB2 Motor; (SW TX GPS cut track)
D10 - (ICSP MISO GPS cut track); SW RX GPS
D11 - (ICSP SCK GPS cut track); SW TX GPS
D12 - (ICSP MOSI GPS cut track); SW RX 9DOF Sensor
D13 - SW TX 9DOF Sensor


Items in brackets were cut or moved.

A Friggen Laser Beam!

Just the day after I received my packet of spare Arduino Redboards, Sparkfun announced that the Garmin LIDAR is back - really bad timing, but I just have to have one.  What is a Rover without a Friggen Laser Beam?

Wow, this toy is sure getting expensive...

Have fun,


Thursday, August 25, 2016

Arduino LCD Button Shield

The Sparkfun LCD shield works very well.  It has five buttons wired to a single analogue input, which is a neat pin saver. 

However, the example code is much too complex to my liking.  Granted, it can handle multiple simultaneous button clicks, but who on earth will ever do that?  So I made something simpler:

#include <LiquidCrystal.h>

// LCD uses D4 to D9 and A0 for buttons

LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );

void setup()
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("C'mon click it!");

void loop()
  unsigned char key;
  unsigned int sensorValue;
  sensorValue = analogRead(A0);
  if(sensorValue < 1000)
     sensorValue = analogRead(A0);
     lcd.setCursor(0, 1);
     lcd.print("                ");
     lcd.setCursor(0, 1);

     if ((sensorValue > 600) && (sensorValue < 620))
       lcd.print(" Select");

     if ((sensorValue > 840) && (sensorValue < 870))
       lcd.print(" Left");

     if ((sensorValue > 920) && (sensorValue < 940))
       lcd.print(" Up");

     if ((sensorValue > 890) && (sensorValue < 910))
       lcd.print(" Down");

     if ((sensorValue > 800) && (sensorValue < 830))
       lcd.print(" Right");


Have fun!


Minimalist Arduino GPS Parser

The Sparkfun Redboard and other toys can be a lot of fun indeed.  What I like about the Arduinos, is that the board support packages are very good and it is very easy to intersperse regular C with the simple Sketch code.

Here is a minimalist on the fly parser for NMEA GPS data positioning that I've been playing with.  It receives and analyzes one byte at a time, so there is no delay.  You have the data the very moment it is available:

// Minimal GPS Parser
// Herman Oosthuysen, 2016

#include <string.h>
#include <SoftwareSerial.h>

// GPS serial: 9600N81
// Example GPS data capture

//Time, Lat, North, Long, East, Fix:

//Heading true, heading magnetic, speed knots, speed kph

const int rxpin=8;
//const int txpin=9;
const int txpin=255; // Rx only, frees up a pin
SoftwareSerial serial_gps(rxpin, txpin);

char ch = 0;
int cnt = 0;
int csv = 0;
int fix = 0;
int res = 1;
char dat[16];
char tim[16];
char lat[16];
char lng[16];

void setup()

void loop()

    // simple parser, start with $
    if(ch == '$')
      cnt = 0;
      csv = 0;
      fix = 0;
      dat[cnt++] = ch;
      if(ch == ',')
        dat[--cnt] = 0;
        cnt = 0;

        if(csv == 1)
          res = strcmp(dat,"GPGGA");
          if(res == 0)
            fix = 1;

        // Assume N, E
        if(fix == 1)
          if(csv == 2)
            strcpy(tim, dat);
          else if(csv == 3)
            strcpy(lat, dat);
          else if(csv == 5)
            strcpy(lng, dat);
          else if(csv == 6)
            Serial.print("Tim: ");
            Serial.print("Lat: ");
            Serial.print("Lon: ");
            fix = 0;

The result is:
Tim: 154417.000
Lat: 2413.4364
Lon: 05541.2907

Cool, now you all know exactly where I live.

In days gone by, there were phone directories, now, there is GPS.

There are Arduino GPS libraries available, but they are too complex for my liking.  For a toy, one can make some assumptions to simplify things, which saves processing cycles and memory.  I don't see the need to verify the checksum, or check whether the position is north and east - I'm not going to drive my toy car to the other side of the globe.

The Arduino software and Redboard works pretty good on my Mac, but if I unplug it from the USB port, then I have to reboot the Mac to get the USB serial port to work again when I plug it back in.  There should be a way to force the Mac to reload the driver, but I haven't gotten round to diving into the OSX weeds to figure it out yet.

Have fun!


Thursday, August 11, 2016

Audio VU Meter

I have a bunch of dinosaur era Magic Eye tubes which I got from the Tubes-Store in Chellyabinsk and was wondering what to do with these roughly 100 million year old little cathode ray bulbs.  An audio VU meter with a microphone pickup could make a nice magical flickering display as I originally described here: An Angel Dancing On a Pin Head.

Audio VU Meter - The First Flickers

The example Rusky circuit works, but it needs much more gain to work with a microphone, instead of a direct hook-up to the preamplifier of a guitar amplifier and it needs a power supply of sorts.  So, I dusted the old circuit off, hooked up a little triode as a preamplifier to drive the display tube and my prototype worked.   Moving the resultant rat's nest from the breadboard into a proper display case was another matter though.

Eventually, I redesigned the whole circuit when I rebuilt it, and rewrote most of this article.

Note that at audio frequencies, any old tube will work.  If you have a weird and wondrous looking UHF or microwave tube, go ahead and try it - it will probably work just fine at baseband audio frequencies and will make your project look snazzy.

The 6E1P / EM80 cathode ray tube is super simple, since the Target and Anode are connected together internally, so you don't have to.  It operates at a rather high 250V:
  • Pin 1: Gate
  • Pin 2: Cathode
  • Pins 4, 5: Heater
  • Pin 7: Anode
  • Pin 9: Screen 
Viewed from the bottom pin side, the pins are numbered clock wise, starting at the gap on the right.

The 6N21B miniature dual triode valve pin-out is as follows:
  • Pin 1: k1
  • Pin 2: s
  • Pin 3: g1
  • Pin 4: a1
  • Pin 5: h
  • Pin 6: k2
  • Pin 7: no pin
  • Pin 8: g2
  • Pin 9: a2
  • Pin 10: h
Because the double triode is physically small, the operating voltage is lower than normal at 'only' 100V to 150V.

Since the little valve doesn't have a socket, I used a ferrite toroid as a heat insulating base for it.

For a little toy like this, a pair of huge transformers will increase the cost and their bulk will detract from the whole idea, so I made a simple direct mains powered supply - shocking, eh...

Valves are very forgiving.  The voltages need not be exact.  When they work, they work.  I've never managed to blow up a valve.  That would require special skill.  Caps and resistors though...

Magic Eye Tube VU Meter Circuit

A Magic Eye tube is a tiny cathode ray tube as in old TV sets and requires a very high operating voltage.  Rectified 230 V mains results in +335 VDC, which is bright enough, as you can see in the picture.

The miniature triode needs a much lower voltage, so I used a large Anode resistor of 470 kilohm.  The triode output is envelope detected to create a 0 to -2V negative voltage to drive the display tube gate - any small signal diode will work - a 1N4148 works.

Note that when you build high voltage circuits, you should use big parts.  A 1/4W resistor is rated at 50V only.  A 2W resistor is rated at 500V, which will prevent smoke signals. Ditto for small ceramic capacitors - be careful where you put a 50V cap.

A single triode has a gain of around 50.  That should work with a dynamic mic.  If you use a condenser mic, then you may need more gain (if it doesn't have an internal transistor amp).  The small 6N21B is a dual triode and a two stage amplifier will result in a gain of around 2000, which should work.  (These dual triodes are the world's first integrated circuits!) However, with a gain of 2000, the amplifier may oscillate if you don't take care with the wiring.  I use RG316 coaxial cable for everything when I play with valve amplifiers (including the heater wiring), to ensure that all signals are screened properly.

Even if you do take great care with the wiring, the dual triode may still howl its head off.  An alternative is to use a small transistor as a pre-amplifier and use only half of the triode (ground all the unused elements).  The idea of this circuit is to display some glassware and two tubes look nice, while three may be too much of a muchness, hence the transistor suggestion.

Microphone Preamplifier (Gain about x50)

With the above preamplifier (I used an ancient CAD program, called a pencil), you should have a signal that the triode can do something with, to get the needed 2 V at the envelope detector. Keep the coupling capacitors small, to suppress 50 Hz mains hum!

I have a couple of electret inserts, but they are so small, I could not find them!  Rp provides phantom power for an electret - not needed for a dynamic microphone.  Using a little CR-7 dynamic microphone insert, I measured 200 to 600 mV ptp when I whistle, which is very insensitive.  A good 25 dBA electret will need much less amplification.  So you got to tweak things to ensure that the resulting microphone level is good enough to drive the 6N21B valve amplifier for the VU meter.  

Eventually, once the circuit started to work, I replaced the 10 nF capacitors with 100 nF, to improve the bass response and the 1M resistor in the envelope detector was replaced with 3M3 to make the decay time slower.  You need to tweak it for a pleasant visual response.

The envelope detector works with a single diode, but you need two for a full wave rectifier.  If you need more sensitivity, a couple of BAT42 Schottkey diodes will work better than a 1N4148 junction diode.

The heaters require about 350 mA (I have measured 280 to 370 mA) at 6.3 V.  So for that, I made a simple capacitor ballast circuit using a 4u7 Safety Capacitor, which is rated to supply AC current continuously, in series with a 22 Ohm resistor to trim it to roughly 12 V and 300 mA.

For a fuse, I always use resettable polyfuses, since they don't blow permanently.  For example Vishay PTCTL7MR100SBE, a 1A, 600V fuse.  I always end up making mistakes and a resettable fuse is rather better than having to find a new glass fuse every time...

As with any thermionic valve circuit, this one is dangerously 'hot' and noisy.  So when this toy is running, keep yer cotton picken fingers in yer pokkets - else you will be sorry.  Mount the whole kaboodle in a plastic box for good insulation.  I have a rubber mat on my shop floor - got zapped a few times and I'm still here...

La voila!


Saturday, August 6, 2016

FM Crystal Varicap Tuner

I like to keep things simple, but I also like to make things that are a little unusual.

To go with my Valve Amplifier, I wanted to make a simple radio tuner.  Where I live, there is a powerful FM transmitter almost in my back yard.  It is very strong and overpowers all other transmissions, so the only FM station that I can receive is Abu Dhabi Classic.  That gets rather trying after a while, but why not turn it into an advantage?

Since the radio transmission is very strong, it can be detected with a simple tuned circuit and a non-linear element - there is no need for a complex discriminator or PLL.

For an intuitive explanation of how it is possible to demodulate FM with an AM detector: If you tune an AM receiver adjacent to an FM signal, then when the FM signal is closer, the AM signal will be stronger and when it dithers further away, the AM signal will be weaker - that way, a simple envelope detector can detect a FM signal.  Some call this a slope detector.

Crystal sets are normally associated with shortwave radio, which require enormous coils, air capacitors and high impedance headphones.  In the 100 MHz FM band (88 to 108MHz), everything is much smaller, but a high impedance headphone may still be a problem to find.  Piezo electric speakers are commonly used in laptop computers and can be obtained from Digikey or Mouser, so you can use one of those, but do put a resistor in parallel, since it won't pass DC.  Mike's actually has everything you may need.

Variable capacitors are somewhat hard to get and air capacitors are still manufactured by at least one US company, but are expensive.  Using varicap diodes to tune a circuit is also expensive, but LEDs and zeners are cheap and make fairly decent DIY varicaps.

This circuit looks like a FM crystal radio with a 9V battery.

The battery is needed to charge the tuning capacitor, which is made from two red LEDs, used as varicap diodes.  Red LEDS provide about 10 to 30 pF capacitance with  9V bias (You have to take a handful of LEDS and try them - some patience required).  Other options are large rectifier or zener diodes, but a couple of 5mm LEDS look nicer.  Of course a real varactor will be better and more linear, but who has a varactor in his junk box?

If you want something a bit more predictable than a LED, then you could use 1N4001 rectifier diodes. The 1N4001..7 all exhibit the same curve, as shown in the data sheet here on page 2.  However, you would have to double them up to get sufficient capacitance.   To make a 100MHz RF circuit work, it is important to keep all wires short (just a few millimeters) and the parts very close together, otherwise stray capacitance and inductance will detune it and it won't work as intended.

The result is a FM crystal radio that can be tuned with a potentiometer.

In my eventual circuit, I used two LEDs and tune the tank with a 22k potentiometer.  Some more playing with a coil design tool settled on 5 turns, 10 mm diameter and 12 mm length for 150 nH and a Q of 600.  That improved the selectivity much.  I wind coils around a drill bit to get a precise diameter and the biggest bit I got is 10 mm, so...

BTW, a 1/4 wave antenna needs to be 75 cm in length and a 1/20 wave antenna needs to be 15 cm. On a receiver, a bad antenna affects both the signal and the noise, so the S/N ratio stays the same, but a longer antenna will certainly catch more signal.  If you solder the antenna on the top end of the coil, then it will load the coil and you won't be able to tune to the high end of the band, so solder it to the first turn from the bottom.

So, how weird is that?


Saturday, July 30, 2016

Twin Otter

If you ever visit British Columbia in Canada, then do yourself a favour and take a sight seeing trip with Harbour Air.

They operate a large fleet of old and new De Havilland seaplanes flying out of lakes and harbours all over BC - providing a delightful experience.

In this older plane, an original De Havilland, circa 1970, the upgraded turbine engine has about 50% more power, which provides seemingly effortless take-off and landings, while the cockpit is a museum piece with some essential updates.  Note the fuel flow indicator hose at the top of the panel - the ultimate in low tech!

The planes are simple and reliable aluminium sheet metal constructions, supported by Viking Air, which is continuing the De Havilland mission.  Since 2010, Viking Air builds completely new Twin Otters.

Yours truly, in the co-pilot seat.
A view of Victoria, with the snowy peaks at Vancouver in the distance.

You can literally fly from downtown Victoria, to downtown Vancouver, have a meeting and fly back again, in less time than a one way trip with BC Ferries and it won't cost you much more either.

Have fun!


Tuesday, July 12, 2016

Why Globalization Doesn't Work

One doesn't need to be a wizard to realize that when you take a large amount of wealth and divide it amongst four billion people, then nobody has anything.

Globalization is a form of Communism.  It didn't work in the USSR or China and it won't work for the whole world.

Recently, the Limeys voted to exit the EU - which confirms that although common sense isn't common, it usually prevails in the end.

The multi-national companies seem to be the only entities that profit from globalization.  The rise of these behemoths are amazing and appears to be a rerun of the two East India Companies, which became so big, they had their own governments, money and armed forces.  Eventually the corruption ran so deep that they became indistinguishable from their parent countries (Netherlands and UK) and it took major wars to get rid of them.  Maybe one day there will be a real war between Apple and Amazon, with Pepsico running away with the spoils and all restaurants will become Taco Bell?

It is economics 101 really:  Free trade benefits large international corporations, while trade barriers protect small national corporations.  Small businesses create employment.  Large companies destroy employment as they drive productivity up.  Therefore, ever increasing productivity is not necessarily a good thing - one has to find a happy medium.

Some sanity is returning to the USA now also it seems.  Let's see what Prez Trump will do.  I expect more trade barriers to go up and countries to become a little more insular, while employment and local innovation will improve.

Liberals are complaining that democracy is not working since people are not voting the way they want them to vote!

The pendulum is swinging...

Or not?
Exxon Mobil chief Rex Tillerson is so bad, they are paying him 180 Million Dollars to please leave and go work for Prez Trump.  At least, that is what it looks like to me.  Why do ExxonMobil shareholders put up with these hugely wasteful payments to self aggrandized executives?  Sue the board of directors!  Get your money back!

. -.-. .-. .- ... . --..   .-.. .   .. -. ..-. .- -- .


Tuesday, June 14, 2016

Slackware Linux

One of the first Linux distributions I ever tried was Slackware, some time before the dinosaurs, circa 1995 - it was quite an adventure, since in those days, nothing worked the first time.  Yesterday, I gave the latest Slack a spin and it felt like donning an old frumpy jersey - for that comfy, warm, lived in feeling and nowadays, everything 'Just Works', TM.

What hooked me, was that the ethernet port is named eth0, so all my old scripts work.  The boot loader is LILO.  The boot code is in the MBR.  The initialization system is in /etc/rc.d and rc.local works right off the bat.  SELinux is nowhere in sight.  The log files are plain text and I can watch my system with 'tail -f /var/log/messages'.  Systemd?  What is systemd??? Never heard of it, sorry...

In short, everything works totally Olde Skool, the way the Fates intended and Slack is Fast.

Slackware is the ultimate Long Term Support Linux, since for the better part of the past quarter century, it has been the same.

I haven't realized how much the other bloated and slow Linux systems were annoying me all the time and I think that from now, on, I'll be a Slacker again.

If you have no idea what you are doing, then maybe Slack isn't for you yet.  Rather go and experiment with PCLinuxOS, Fedora or Suse Linux for a bit, then come back later.  Slack doesn't have training wheels.

Where To Get Slackware

The Slackware installer is not unfriendly.  It simply assumes that you know what you are doing and basically just gets on with it.  Installing Slack takes only a few minutes (or a few weeks/months/years, if you are new!).

The first problem is downloading an ISO file to install:

See the mirror information page here:


I then made a Virtualbox VM with name Slackware and OS type Linux 2.6 / 3.x (64 bit) with 1 GB RAM and VDI disk size 20 GB.

Under Storage, Controller: IDE CDROM, I selected the downloaded ISO file and started her up.

Once booted up and logged in as root, you will get a nice, friendly, self explanatory prompt:

An interesting observation is that Slackware is much faster than other Linux versions.  Slack with KDE runs fine in a virtual machine, while with most any other distro, one should stick to XFCE to get non-frustrating speed in a VM.  Pat's keep it simple and don't fix it if it ain't broke principles, really pay a dividend.

Partitioning the Disk

Slackware uses LILO which writes to the MBR, so you need to configure the disk as DOS with MBR and then create at least two partitions for swap (type 82) and linux system (type 83) and set the bootable flag on it, just like in the good old, bad old days.

So run fdisk /dev/sda, type o to create a MBR DOS partition, type n to make a new partition for +18 GB and again, for 2 GB, type t to change the 2 GB partition to 82 (Linux Swap), type a to make the 2nd partition bootable and type w to write it to disk.  Easy as borscht!

Deviate from the above, and LILO won't install.  You may be able to get it going in Expert mode, but good luck with that.


Now run setup and accept all the defaults, the way Pat intended, so that you have a full system with compiler and source code, about 9 GB.  Eventually, set the hostname and domainnameThe setup program is so simple, that there isn't any point in trying to describe it.


Log in as root and create a user account:
# useradd -m username
# passwd username

Log out and log in as the new user, then run startx to get your graphical desktop. 

I chose XFCE, but KDE works fine in a VM too - you can change with xwmconfig.  It will be a bit sluggish until you install Guest Additions below.

Guest Additions

Select Mount Guest Additions CD Image from the Virtualbox Devices menu, open it with a file manager and note the path. Open a terminal, su - to root, cd to /run/media/username/VBOX... and run the file.

The system will build itself and install the faster Virtualbox aware mouse and video handlers.

Log out and log back in.

That is all there is to it.  You are now an official Slacker.

A Few Slack Links

Slackware is community driven like no other Linux distribution.  Patrick Volkerding manages the essential system.  Others provide the niceties.  You don't need to be a genius to use Slackware, being a subgenius is sufficient...

The default Slackware system works and does most anything, but after a few days, you may start to look around for a missing tool or tenSlackbuilds is the answer and sbopkg is the aspirin for the resultant head-ache.  Otherwise, if you are extremely lazy and want a Slackware desktop system that is screaming fast and 'Just Works', install Absolute Linux, referenced down below.

Package build scripts:

Slackware Forum:

The forum is hilarious.  There can be multiple years between questions and answers, since Slackware changes so slowly.


Everything about Slack in a few brief chapters:

Slackermedia book:

Absolute Linux, a screaming fast simple desktop distro based on Slackware with IceWM:

Dependency Management

Slackware is interesting in that it has a very simple package management system that doesn't seem to care about dependencies.  Usually, it just works.   The package managers of other systems will sometimes try to pull in (or remove!) a whole desktop system when you want to install/remove a simple program.  Slackware sidesteps this hassle.  Once in a blue moon however, you may find a broken package and then need to figure out what the dependencies are to install a missing library.

You can run ldd and look at the dependencies yourself, but here are three tools that could make things easier:
Dependency Finder:
Slack Build Binary Dependencies:
Slacky Downloader:

Have fun!

. -.-. .-. .- ... . --..  .-.. .  .. -. ..-. .- -- .


Saturday, June 11, 2016

Conventional Wisdom

Everybody knows that palm trees don't make branches, right?

Uhm, yeah, well, no fine?

There are many such trees actually.  This one is close to our home.

If a palm decides to make branches, then there is no stopping it.  The city workers have to keep cutting the branches off, but sometimes, when it is nice and symmetrical, they let them grow.

If this tree was at my old university, then I'm sure we would have used it as a catapult to shoot water balloons at passing cars.  Fortunately here water is hard to come by and it is usually too hot for anyone to do mischief outside.

Have fun!


Monday, May 16, 2016

Whole Disk Encryption

Many people, even card carrying computer geeks, do not understand why a computer hard disk must be encrypted and why a computer must be shut down for the disk encryption to be effective.

This applies, whether you are using Bitlocker, Filevault, PGP, GPG or LUKS.

Why Encrypt Your Disks?

If the disk is not encrypted, then a miscreant can boot the computer with a USB stick or CD and read everything on the disk, or plant incriminating data on your disk, and then call the police, or wait for you to go through a border post where your machine may get searched - then watch you end up in the slammer.

Also, if the disk drive controller would fail and you replace the disk and chuck it in the trash, then the data is still accessible, if someone would replace the drive controller from an identical disk bought on Ebay.

If your laptop PC gets stolen, then it can end up on Ebay, with all your data and the buyer can empty your bank account, order a bunch of credit cards in your name, or sell your house for you and run away with the money.

Even if you are a broke student with no money, someone can still order a credit card in your name and use it.

Therefore, if you don't want to incur thousands of dollars in losses, a ruined credit rating and huge amounts in legal fees to sort out the resulting mess, then you have to encrypt your data.

Protecting Data at Rest

When the machine is powered on and running, the encryption keys are kept in RAM and the data is accessible to you, and an attacker.  So obviously, you should never leave a running computer alone.

When the machine is shut down, the RAM gradually loses power, the keys get lost and your data is safe and 'at rest' - or that is the idea anyway.

On a server, the memory has error correcting capabilities and always powers up in a zero state.  On a cheap laptop computer, the memory doesn't have error correction and the RAM can retain data for several minutes after the machine was powered down.

Therefore, it is possible for a miscreant to quickly boot a recently abandoned laptop PC and read the memory using a special tool (, recover the passwords and keys, then dump the disk and go away and analyse it at his leisure.

Suspend (save in RAM) / Hibernate (save on disk)

When you slam the lid of your laptop, it typically suspends by writing CPU data to RAM and then partially powers down, leaving the memory powered up to preserve the data.  When the battery gets low, it will wake up, write the data to the hard disk and then power down completely.  When you power up again, it will restore itself and get going again.

If the machine suspended, then it can be (quickly) rebooted from a USB stick or CD and the contents of RAM can be read.  The data in RAM is in plain text and a search through the raw data will reveal your passwords and encryption keys, the last files you worked on, even the last PGP encrypted email you sent may have a plain text copy in RAM.  Therefore, suspend is risky and should be avoided.

If the machine hibernated, then the hibernate file can be read from disk, by booting from a USB stick or CD and a search through the raw data could reveal your passwords and encryption keys.  However, if the disk is encrypted, then the hibernate file will be unreadable. Therefore hibernate is potentially secure, if the encryption is done right.

BIOS Boot Options and Password

It doesn't help locking the front door of your house and putting the key under the carpet, or leaving the back door open.  Disk encryption must be done properly and all loopholes must be closed, else it is ineffective.  As shown above, suspending a machine to RAM and leaving it on your desk, is like leaving a slowly vanishing key under the carpet.

It is therefore important to buy yourself time - 10 minutes or more - and make it hard for an attacker to bypass the encryption, by making it difficult to boot from a TFTP server, CD or USB stick.

Therefore, in the BIOS, change the boot order so that the machine will not boot from a network server or removable media and set a BIOS password, so that an attacker cannot easily change the boot order.

Another interesting factoid, is that enabling a BIOS RAM check option - if available - would also help to destroy the RAM data while rebooting.

A determined attacker can open the PC, and reset the BIOS memory chip using a link, or by removing the battery, but that is hard to do on a laptop and it means that the perp needs to do multiple attacks - first to change the BIOS settings and later, to recover your keys and dump the disk.  Therefore setting a BIOS password makes it much more likely that he'll get caught.

Also, if dragoons are bashing your door down, or if you have to cross a border post, it may be a good idea to pull the battery from your laptop PC.

Note also that Windows has special features in the UEFI BIOS that makes it less secure, by allowing the installation of code that always gets loaded and executed before the system starts up. This was supposed to be used as an anti-theft system, but as always, MS botched it, thereby creating a very bad, low level, built-in, universal exploit vector.

Is This For Real?

I just tried it on my Windows 7 laptop PC with PGP encrypted disk using the McGrew CD to boot and a memory stick for the data and it worked - nuff sed.

Écrasez l'infâme,