Historical Radio, Mk. III

On display at the ITP winter show was the Mk. III version of the Historical Radio.

Overview

A conventional radio lets you travel through space: you can listen to stations from the local area, or with a shortwave or longwave radio, from broadcasters far away.  But the thing about a radio is that it’s stuck in the permanent present.  You hear what’s being broadcast in real time.  The Historical radio adds the dimension of time, providing for the ability to hear the past.

The time dimension is controlled by the tuning knob, moving longitudinally along the ‘tracks’ on the tuning dial.  The spatial dimension is radial, controlled by the band selector.  Each track represents a location/genre combination.  Ideally I wouldn’t have to combine those, see Mk. IV thoughts below.

The Time/Space switch, and associated indicator lights are for preprogrammed sequences, which march you along fixed in the dimension you select, either playing files related by being in the same time or same space.

The goal was to make something educational, more than just a “gee, isn’t it slick” project.  And the comments people had at the show were pretty much in line with what I was going for: “this belongs in a history museum!”

Behind the curtain

-it’s not a real radio.  [gasp]
inside is an Arduino Mega microcontroller, a Sparkfun / Robertsonics MP3 Trigger, an H-Bridge and a servo, and of course some LEDs.  Surprisingly it’s not as complicated as one might be led to believe.

The Arduino Mega was selected because I needed more digital I/O lines than the Duemilanove has available.  (Arduino development boards listing)

The H-Bridge was used to control the galvanometer.  See this post for a thorough discussion of how the H-Bridge works, including circuit diagram.

The MP3 Trigger was an adventure unto itself, see this post for a discussion of how to make that work.  I would recommend considering an Adafruit Waveshield or  other MP3 player.  I’ve heard good things about the Daisy: http://teuthis.com/daisy/index.html but haven’t seen it.  The main problem with the MP3 trigger is that the play and stop commands are both ‘O’ which requires some clever programming to get around.  See MP3 Trigger documentation for details.

Changes from Mk. II (previously named the Time-Travel Radio)

  1. More files, better alignment of events in Europe/America, and some RoW (rest of World) files, like Hirohito’s capitulation at the end of WWII, and some Che Guevara.
  2. debugged!
    – I found that I was not flushing the serial buffer as necessary, so it would occasionally lock up, waiting endlessly for the track-end signal.  Discussion of the necessary code for the MP3 trigger here
    I narrowed the ‘windows’ for the Q-Meter (the galvanometer tuning indicator) and the corresponding play window, to make more space.  if the switching is too fast (i.e. turning the tuning dial too fast/having the tuning windows too close together) makes it crash.  So that’s fixed.
  3. headphone jack (1/8” mini stereo) on front bezel
  4. hardware volume control – thanks to Eric Rosenthal for the circuit diagram.  Note: use a logarithmic potentiometer here, or you’ll get an exponential profile for the volume control (sound energy is logarithmic)
  5. ‘on station’ indicator on front panel, replacing power light.  This made it much easier for people to get the hang of using the radio, as few young people have used or seen a Q-meter.  One older man was ecstatic to see the Q-meter.  Hooray!

DSC_0510

 

Mk. IV

Nothing like this is ever done.  Things to do for Mk. IV

  1. 3D interface.  I would like to separate genre from geography, and perhaps do really zero in on the geographical dimension
  2. Maybe a full track of BBC, full track of CBC, Radio Moscow, etc.
  3. don’t wire together the Band selection LEDs, which makes for tough replacement when something burns out.
    DSC_0501
Advertisements

Plugs and power supplies

from LinkedIn discussion of power supplies:
 
The proliferation of wiring standards, plug-outlet combinations, and voltages/mains frequences is a major headache for designers, engineers,and users.  Unfortunately I doubt this will be dealt with any time soon, on a global scale.
A standardized system of low-voltage power supplies would be great, and could be implemented relatively easily.  While USB doesn’t have the capacity to transfer enough current for most devices, a set of power supply designs could be developed and standardized:
(1) a low-current supply for computer peripherals, mobile phones, etc.  USB could be used here, USB3.0 900mA power supply, and the battery charging specification could really be a good setup, allowing for lots of power transfer (up to 9W in power-only mode, 1.5A in low or full speed data mode)
(2) a medium current, low-voltage DC supply for things like laptops.  (20VDC, 5A powers my laptop).
(3) high voltage AC for standard household equipment like refrigerators, washing machines etc. Current 120VAC/220VAC mains supply
(4) high voltage AC for heavy equipment, like electric dryer, electric oven, electric car*
As much as I would like a new design for (3), the installed base is pretty much set, and for (4), a charging specification should be developed that is safer and easier to use than the current US 240V plug.  As electric vehicles proliferate, there needs to be some work done here.
for (1) and (2), standardization would be a great boon to society, as it would allow for interchange of power supplies among device users.  Most people where I work have Apple laptops of the same generation, and can share power supplies.  I’m the odd man out with the Dell.
I like the MagSafe connector, but it does have some drawbacks, like magnetic particles getting stuck to it, potentially shorting the terminals or interfering with the connection.  But in terms of usability it is pretty good, preventing your laptop from being swept off the table, or having the connector break on the cable or device.
A major benefit of standardization would be the ability to use one inverter/rectifier and transformer arrangement for all devices in a class (1) or (2), allowing for higher quality electronics to be used, and to have better switching, to reduce or eliminate standby power consumption.  Standby power consumption isn’t trivial, estimated to be hundreds or thousands of MW globally.  Standardizing the power supplies, and restricting standby power usage would go a long way towards combatting global warming, as well as reducing electronics production and e-waste.
Ideally in the future, there would be global standardization of mains voltage, frequency, and plug/socket pair.  I kind of like the IEC C13/C14 pair used on computers and other electronic equipment, and it’s pretty well standardized so far.  Unfortunately it doesn’t carry enough current.  Back to the old drawing board.

Historical Radio Mk. II

Behold the Historical Radio, Mk. II.  it will be in the ITP winter 2009 show, which means I have to upregulate this a bit.
 
 
 
tuning indicator:
 

The Innards:  I should put all this wiring on a perfboard for reliability, but it’s still a prototype
 
 
 

There were some interesting programming problems which came up in building this
  1. latching
    To get the MP3 Trigger to play, stop, and restart as intended, I had to set up a pair of ‘latches’ to (A) have it play then stop, and (B) reset when out of the tuning window.  The first latch (isPlaying) is set when the track is started.  The second latch (stopLatch) is set when the track is manually stopped, by moving out of the tuning window.  isPlaying is reset to false when the track end signal is received (the MP3 trigger transmits an ‘X’ when the track ends or ‘x’ when playing is cancelled by action (MP3 trigger receives ‘O’).

    see code samples below.

  2. C octal number declaration ‘feature’

    – as they say, "it’s not a bug, it’s an undocumented feature"  — note this is documented in the Arduino reference.

    In C, a leading 0 (zero) declares a number as an octal, and Arduino is a descendant of C, via Java, and has therefore preserved this convention.  So, when I tried sending track numbers such as Track 008, I started getting a strange error about octal constants.  What octal constants?  I’m not declaring anything as an octal … and why is it playing the wrong track? — because it’s considering it octally (base 8, 0..7) as opposed to decimally (0..9).
    A workaround will have to be figured out, and I’m sure it won’t be particularly difficult, but this was an unpleasant surprise.

Hardware issues, and words of the wise:

Wiring everything together ‘elegantly’ often ends up with a problem.  I thought I was being so slick soldering the grounds for the LED band indicators together.  Of course one of them burned out.  And now it’s a problem to replace it.  Mercifully I can just clip it out and run a separate ground for that one, but it’s a good lesson: design for disassembly, especially with prototypes.  "If something can go wrong, it will"- human factors researcher Edward A. Murphy (bet you didn’t know he was in the HF field, working with Stapp on the famous Rocket Sled!)

code samples:

void playTrack(int track)
{
  if (isPlaying == false) // check to see if a track is playing (would be true if playing)
  {  
     isPlaying = true; // set isPlaying interlock
     stopLatch = false; // open StopLatch interlock
     Serial1.print(‘t’, BYTE); // track signal
     Serial1.print(track, BYTE);
     Serial.println("playing");
  }
}

void stopTrack()
{
  if (isPlaying == true && stopLatch == false) 
  {
    do   // do-while loop tests condition at the end. 
    {
        Serial1.print(‘O’, BYTE);  // send play/stop signal to the MP3 trigger (in this case, stop signal)
        delay (20);
      Serial.print("stop signal");
      stopLatch = true; // set interlock
    }
    while (Serial1.available() > 0); // check state of serial buffer
    if (stopLatch = true)
   {
    Serial.println("stopLatch"); // print latch state to debugger
   }
 }
}

void recycle()
{
    inByte = Serial1.read();  //Serial1 for Arduino Mega
    if (inByte == ‘X’ or inByte == ‘x’)
    {
      isPlaying = false;// sets isPlaying latch open
      Serial.print("ACK ");  // for debugging purposes
      Serial.flush();
      digitalWrite(playLight, LOW); // debugging light
      delay(20); // wait state 20ms for recycle
    }
}

MP3 Trigger Documentation

The Robertsonics MP3 Trigger from SparkFun is a nice device, I think a better design than the Adafruit WaveShield.


(from SparkFun.com)

The MP3 Trigger plays MP3 encoded sounds, up to 255 of them, and has software volume control … and doesn’t cover up your Arduino (and therefore should work with a Mega or other non-standard size board).  An added bonus is the simple wire up mode: the seven pin pairs on the left can be either shorted or have 5VDC applied across them to trigger tracks 1..7, or serial control up to 255 tracks+volume control.  As a drawback, it doesn’t have much of an amplifier–(the Waveshield looks like it can drive more current, but that may not be the case in actuality.

I had a problem with my first board, which Sparkfun kindly exchanged for a brand new one.  Thanks!

MP3 Trigger control blocks

use as you like!

void playTrack(int track)
{
  if (isPlaying == 0) // check to see if a track is playing (would be 1 if playing)
  {  
     isPlaying = true; // set isPlaying to 1 (true)
     stopLatch = false; // open interlock
     Serial1.print(‘t’, BYTE); // track signal
     Serial1.print(track, BYTE);
     Serial.println("playing");
  }
}

void stopTrack()
{
  if (isPlaying == true && stopLatch == false) // if
  {
    do
    {
        Serial1.print(‘O’, BYTE);
        delay (10);
      Serial.print("stop signal");
      stopLatch = true;
    }
    while (Serial1.available() > 0);
    if (stopLatch = true)
   {
    Serial.println("stopLatch");
   }
 }
}

—- in your main loop you need to include the code below to call the recycle() block below—-

 inByte = Serial1.read();
 if (inByte == ‘X’ or inByte == ‘x’)
 {
  recycle();
}

void recycle()  // recycle isPlaying when track ends
{
    {
      isPlaying = false;  // set isPlaying interlock
      Serial.print("ACK ");  // print ackgnowledgement for debugging purposes
      Serial1.flush();  // Note Serial1 for Arduino Mega
      digitalWrite(playLight, LOW); // turn off playing light
      delay(20);
    }
}

Arduino code sample:

 

// MP3 Trigger test program.

//int volume;
char inByte=0; // initialize storage variable for serial read (receives X [ASCII 88] or x [ASCII 120] decimal)
boolean playBit; // flip bit for not playing/playing
boolean stopLatch;  // flip bit for stop interlock

int track = 0;

int volumePot = 2; // pot for volume control
int volume = 250; // volume control, default to most of the way up (0..255)

void setup()
{
  pinMode(40, INPUT);
  Serial.begin(38400);  // MP3 trigger communicates at 38400 b/s
  playBit = 0; // bit to flip while playing :: 0 for not playing, 1 for playing
}

void loop()
{

 //volume control
  volume = analogRead(volumePot);  // read potentiometer for volume control
  volume = map(volume, 0, 1023, 0 ,255);
  Serial.print(‘v’, BYTE);
  Serial.print(volume, BYTE);

 

//play track 2 if switch closed — NB: the documentation where it says to send messages like "002" will result in an error message!
  if (digitalRead(40) == HIGH)
  {
    playTrack (2);
  }
 }
else
{
 stopTrack();
}

 

 

void playTrack(int track)
{
  if (isPlaying == 0) // check to see if a track is playing (would be 1 if playing)
  {  
     isPlaying = true; // set isPlaying to 1 (true)
     stopLatch = false; // open interlock
     Serial1.print(‘t’, BYTE); // track signal
     Serial1.print(track, BYTE);
     Serial.println("playing");
  }
}

void stopTrack()
{
  if (isPlaying == true && stopLatch == false) // if
  {
    do    // do-while loop tests condition at the end, this way it does it at least once
    {
        Serial1.print(‘O’, BYTE); // send start-stop signal to MP3 trigger
        delay (10);
      Serial.print("stop signal");
      stopLatch = true;  // set interlock bit
    }
    while (Serial1.available() > 0);  // check fo see if it ackgnowledged the signal
    if (stopLatch = true)
   {
    Serial.println("stopLatch");    // for debugging purposes
   }
 }
}

Anti-Addiction Platform widgets

Anti-Addiction SMS widgets from www.Textmarks.com for Mobile Tech for Social Activism

Try out these widgets for advice on breaking addictive behavior patterns–good general advice or intervention when you have the urge to give in to the craving (be it for nicotine, or anything else that’s not moving you in the direction you want to move in.

you can also access these by sending an SMS (text message) to 41411 with the keywords breakaddiction1, breakaddiction2, or breakaddiction3.  This is a non-subscription service, you will only receive messages in response to your message in.

Special thanks to Kevin Seaman for quotes used.

http://flash.textmarks.com/flash/widgets-01/desc-sub-01.swf?v=2.61c-BETA

 
 
 

http://flash.textmarks.com/flash/widgets-01/desc-sub-01.swf?v=2.61c-BETA

USA All the Way – NYTimes Design Section

 
America has always had plenty of iconic design going on.  The chic StarTac, the swoopy Stingray ‘Vette, the coke bottle itself, … there’s plenty to see here in America.

We need a design policy to keep things going strong and on the right track


Dori Tunstall discussing design policy: http://www.designers421.org/archives/215
 
As part of my master’s degree, I think I’m going to be going more in this direction (from a persuasive technology and ecodesign standpoint) – but it’s exam week and discussion will wait until later.
 
As an aside, I do like the design of this retro-cool MP3 player from S. Korea: http://www.engadget.com/2009/12/05/mintpass-cube-mp3-player-features-plenty-of-style-few-capabilit/  but it fails on usability (portability unfriendly shape and poor interaction design).  Sorry, close doesn’t quite cut it.
 

H-Bridge galvanometer control

IMG_0500

A galvanometer is a very sensitive meter, which can be configured as an ammeter or a voltmeter, depending on how it is wired.  Here I’m using it as a voltmeter, which requires a high resistance in series with the voltage input, so it doesn’t just peg out.  An ideal voltmeter has an infinite resistance, an ideal ammeter has zero resistance … and as something that could be theoretically used for either, there’s a very low resistance across an ammeter.

The one I got requires a 54k-Ohm resistance in series to bring down the voltage from the Arduino 5V output to achieve a full-range reading.  To switch the direction I’m using an H-Bridge, which can be switched in direction based on which direction current is applied: +5V on (7) makes the meter swing to the left, +5V on (8) makes the needle swing to the right.  Pretty simple.

Because I’m using this as a tuning indicator, it’s set up to swing full left or right when it reaches the edge of a ‘window’, and center when the potentiometer value is at the target

IMG_0497

Notes:
(2), (7), (8), (3) refer to Arduino I/O pins

IMG_0494 

 

 

//Galvanometer testing program.  Use with potentiometer on analog pin 0 (zero)

// Pin Assignments
int enablePin = 2; // provides power to enable the H-Bridge
int galvNegPin = 7; // negative galvanometer power – H-Bridge leg 1 (pin 2, 1A)
int galvPosPin = 8; // positive galvanometer power – H-Bridge leg 2 (pin 7, 2A)
int galvFeedPin = 3; //galvanometer feed, PWM

//analog input pins for potentiometer
int tuningPin = 0;

//initial settings

int galvanometer = 0;  //NOTE: use 54k Ohm resistance string for full scale galvanometer reading (on Simpson alvanometer)

int target = 300;  //set tuning value (potentiometer value)
int tuning = 0;    //initial tuning value for the sake of initialization
int window = 50;   //
int track = 0;    //

void setup()
{
  Serial.begin(9600); // enable serial comm for debug panel
  //set other pin assignments
  pinMode(galvNegPin, OUTPUT);
  pinMode(galvPosPin, OUTPUT);
  pinMode(galvFeedPin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  digitalWrite(enablePin, LOW); //set enablePin low to disable H-Bridge, zero galvanometer
}

void loop()
{
  tuning = analogRead(tuningPin); // read tuning potentiometer value
  if (tuning < 500-window/2 or tuning < 500 + window/2)
  {
  target = 500; //0..1023 equivalent for target
  tune(tuning, target);  // call tune sub, pass tuning pot value
  }
}

void tune(int tuning, int target) // tune sub, passes tuning and target values
{
  Serial.println(tuning); //print value to debugger
  if (tuning >= target-window/2 and tuning < target) // tuning below target, within window/2  needle to left
  {
    galvanometer = ((target+tuning)/ (window/2));
    galvanometer = map(tuning, target-window/2, target, 255, 0); // map (var, low in, high in, low out, high out) NOTE: reversed to move galvanometer needle the right way from below towards zero
    digitalWrite(enablePin, HIGH); // enable H-Bridge
    digitalWrite(galvNegPin, HIGH); //power H bridge negative circuit;
    digitalWrite(galvPosPin, LOW); // unpower H bridge positive circuit;
    analogWrite(galvFeedPin, galvanometer); //send voltage to the galvanometer feed pin (3)
  }

  else if (target < tuning and tuning <= target + window/2) // tuning above target, within window/2  needle to right
  {
    galvanometer = ((target+tuning)/ (window/2));
    galvanometer = map(tuning, target-window/2, target, 0, 255); // map (var, low in, high in, low out, high out)
    digitalWrite(enablePin, HIGH);
    digitalWrite(galvNegPin, LOW); //power H bridge negative circuit;
    digitalWrite(galvPosPin, HIGH); // unpower H bridge positive circuit;
    analogWrite(galvFeedPin, galvanometer);
  }
  else // out of tuning window
  {
    digitalWrite(enablePin, LOW);  // disable H-bridge
    galvanometer = 0; // set galvanometer read to zero
    analogWrite(galvFeedPin, galvanometer);
  }
}