Jon Thysell

Xbox engineer. Fiction writer. Returned Peace Corps Volunteer. Ukulele nut. Nerd.

Aloha ‘Oe on baritone ukulele (slack key style)

Took some time this weekend to record this. It went a lot smoother than I anticipated, though it still needs some work.

Recording some slack key ukulele videos

For a while now I’ve wanted to record some videos of myself playing ukulele, both to keep tabs on my progress and to introduce some more slack key uke videos online. Now it’s true I’ve recorded some videos in the past, but I was never impressed with the video quality of my regular webcams. So this past week I finally found a HD camcorder I liked (the awesomely cheap Zoom Q2HD) and on Saturday I sat down to record.

These were all recorded on my Black Bear baritone ukulele, which I talk about in the first video. Enjoy!

/jon

Sega Genesis controllers and Arduino revisited

Version 1.0

A couple of months ago I detailed the process by which I used an Arduino Uno to read the button presses of a pair of Sega Genesis controllers. It was my first bit of micro-controller programming, and it has exposed me to a whole new world of possibilities for hardware hacking. So it is with some certain future projects in mind that I’ve revisited and updated that initial code.

Version 1.1

Other than some minor code cleanup, the only major feature-add to the core of the sketch is to support reading the “Mode” button on six-button controllers (thanks to a comment from soe for that). The other change, now that I’ve acquired an Arduino Leonardo, is to create a fork of the sketch which reports the button presses as keyboard key presses via the ATmega32u4 chip’s ability appear as a USB keyboard.

Anyway, here’s the updated code (for reporting over the Serial connection):

/*
 * Sega Controller Reader
 * Author: Jon Thysell <thysell@gmail.com>
 * Version: 1.1
 * Date: 9/29/2014
 *
 * Reads buttons presses from Sega Genesis 3/6 button controllers
 * and reports their state via the Serial connection. Handles hot
 * swapping of controllers and auto-switches between 3 and 6 button
 * polling patterns.
 *
 */

const int PLAYERS = 2;

// Controller Button Flags
const int ON = 1;
const int UP = 2;
const int DOWN = 4;
const int LEFT = 8;
const int RIGHT = 16;
const int START = 32;
const int A = 64;
const int B = 128;
const int C = 256;
const int X = 512;
const int Y = 1024;
const int Z = 2048;
const int MODE = 4096;

// Controller DB9 Pin 7 Mappings
const int SELECT[] = { 8, 9 };

typedef struct
{
  int player;
  int pin;
  int lowFlag;
  int highFlag;
  int pulse3Flag;
} input;

// Controller DB9 Pin to Button Flag Mappings
// First column is the controller index, second column
// is the Arduino pin that the controller's DB9 pin is
// attached to, remaing columns are the button flags
input inputMap[] = {
  { 0,  2,  UP,    UP,     Z    }, // P0 DB9 Pin 1
  { 0,  3,  DOWN,  DOWN,   Y    }, // P0 DB9 Pin 2
  { 0,  4,  ON,    LEFT,   X    }, // P0 DB9 Pin 3
  { 0,  5,  ON,    RIGHT,  MODE }, // P0 DB9 Pin 4
  { 0,  6,  A,     B,      0    }, // P0 DB9 Pin 6
  { 0,  7,  START, C,      0    }, // P0 DB9 Pin 9
  { 1,  A0, UP,    UP,     Z    }, // P1 DB9 Pin 1
  { 1,  A1, DOWN,  DOWN,   Y    }, // P1 DB9 Pin 2
  { 1,  A2, ON,    LEFT,   X    }, // P1 DB9 Pin 3
  { 1,  A3, ON,    RIGHT,  MODE }, // P1 DB9 Pin 4
  { 1,  A4, A,     B,      0    }, // P1 DB9 Pin 6
  { 1,  A5, START, C,      0    }  // P1 DB9 Pin 9
};

// Controller State
int currentState[] = { 0, 0 };
int lastState[] = { -1, -1 };

// Default to three-button mode until six-button connects
boolean sixButtonMode[] = { false, false };

void setup()
{
  // Setup input pins
  for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    pinMode(inputMap[i].pin, INPUT);
    digitalWrite(inputMap[i].pin, HIGH);
  }
 
  // Setup select pins
  for (int i = 0; i < PLAYERS; i++)
  {
    pinMode(SELECT[i], OUTPUT);
    digitalWrite(SELECT[i], HIGH);
  }
 
  Serial.begin(9600);
}

void loop()
{
  readButtons();
  sendStates();
}

void readButtons()
{
  for (int i = 0; i < PLAYERS; i++)
  {
    resetState(i);
    if (sixButtonMode[i])
    {
      read6buttons(i);
    }
    else
    {
      read3buttons(i);
    }
  }
}

void resetState(int player)
{
  currentState[player] = 0;
}

void read3buttons(int player)
{
  // Set SELECT LOW and read lowFlag
  digitalWrite(SELECT[player], LOW);
    
  delayMicroseconds(20);
    
  for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW)
    {
      currentState[player] |= inputMap[i].lowFlag;
    }
  }

  // Set SELECT HIGH and read highFlag
  digitalWrite(SELECT[player], HIGH);
    
  delayMicroseconds(20);
    
  for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW)
    {
      currentState[player] |= inputMap[i].highFlag;
    }
  }
   
  // When a six-button first connects, it'll spam UP and DOWN,
  // which signals the game to switch to 6-button polling
  if (currentState[player] == (ON | UP | DOWN))
  {
    sixButtonMode[player] = true;
  }
  // When a controller disconnects, revert to three-button polling
  else if ((currentState[player] & ON) == 0)
  {
    sixButtonMode[player] = false;
  }
 
  delayMicroseconds(20);
}

void read6buttons(int player)
{
  // Poll for three-button states twice
  read3buttons(player);
  read3buttons(player);
 
  // After two three-button polls, pulse the SELECT line
  // so the six-button reports the higher button states
  digitalWrite(SELECT[player], LOW);
  delayMicroseconds(20);
  digitalWrite(SELECT[player], HIGH);
 
  for(int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW)
    {
      currentState[player] |= inputMap[i].pulse3Flag;
    }
  }
 
  delayMicroseconds(1000);
}

void sendStates()
{
  // Only report controller states if at least one has changed
  boolean hasChanged = false;
 
  for (int i = 0; i < PLAYERS; i++)
  {
    if (currentState[i] != lastState[i])
    {
      hasChanged = true;
    }
  }
 
  if (hasChanged)
  {
    for (int i = 0; i < PLAYERS; i++)
    {
      Serial.print((currentState[i] & ON) == ON ? "+" : "-");
      Serial.print((currentState[i] & UP) == UP ? "U" : "0");
      Serial.print((currentState[i] & DOWN) == DOWN ? "D" : "0");
      Serial.print((currentState[i] & LEFT) == LEFT ? "L" : "0");
      Serial.print((currentState[i] & RIGHT) == RIGHT ? "R" : "0");
      Serial.print((currentState[i] & START) == START ? "S" : "0");
      Serial.print((currentState[i] & A) == A ? "A" : "0");
      Serial.print((currentState[i] & B) == B ? "B" : "0");
      Serial.print((currentState[i] & C) == C ? "C" : "0");
      Serial.print((currentState[i] & X) == X ? "X" : "0");
      Serial.print((currentState[i] & Y) == Y ? "Y" : "0");
      Serial.print((currentState[i] & Z) == Z ? "Z" : "0");
      Serial.print((currentState[i] & MODE) == MODE ? "M" : "0");
        
      Serial.print((i == 0) ? "," : "\n");
      lastState[i] = currentState[i];
    }
  }
}

As with the previous version, all you have to do is upload the sketch and connect the controller’s DB9 pins to the Arduino following the mapping in inputMap in the code.

Now, if you have an Arduino Leonardo (or compatible board), and want the controller button presses to map to keyboard keys instead, you can upload the following sketch:

/*
 * Sega Controller Reader (Keyboard)
 * Author: Jon Thysell <thysell@gmail.com>
 * Version: 1.1
 * Date: 9/29/2014
 *
 * Reads buttons presses from Sega Genesis 3/6 button controllers
 * and reports their state via keyboard button presses. Handles hot
 * swapping of controllers and auto-switches between 3 and 6 button
 * polling patterns.
 *
 */

const int PLAYERS = 2;

// Controller Button Flags
const int ON = 1;
const int UP = 2;
const int DOWN = 4;
const int LEFT = 8;
const int RIGHT = 16;
const int START = 32;
const int A = 64;
const int B = 128;
const int C = 256;
const int X = 512;
const int Y = 1024;
const int Z = 2048;
const int MODE = 4096;

// Controller DB9 Pin 7 Mappings
const int SELECT[] = { 8, 9 };

typedef struct
{
  int player;
  int pin;
  int lowFlag;
  int highFlag;
  int pulse3Flag;
} input;

// Controller DB9 Pin to Button Flag Mappings
// First column is the controller index, second column
// is the Arduino pin that the controller's DB9 pin is
// attached to
input inputMap[] = {
  { 0,  2,  UP,    UP,     Z    }, // P0 DB9 Pin 1
  { 0,  3,  DOWN,  DOWN,   Y    }, // P0 DB9 Pin 2
  { 0,  4,  ON,    LEFT,   X    }, // P0 DB9 Pin 3
  { 0,  5,  ON,    RIGHT,  MODE }, // P0 DB9 Pin 4
  { 0,  6,  A,     B,      0    }, // P0 DB9 Pin 6
  { 0,  7,  START, C,      0    }, // P0 DB9 Pin 9
  { 1,  A0, UP,    UP,     Z    }, // P1 DB9 Pin 1
  { 1,  A1, DOWN,  DOWN,   Y    }, // P1 DB9 Pin 2
  { 1,  A2, ON,    LEFT,   X    }, // P1 DB9 Pin 3
  { 1,  A3, ON,    RIGHT,  MODE }, // P1 DB9 Pin 4
  { 1,  A4, A,     B,      0    }, // P1 DB9 Pin 6
  { 1,  A5, START, C,      0    }  // P1 DB9 Pin 9
};

typedef struct
{
  int player;
  int flag;
  char key;
} output;

// Controller Button Flag to Keyboard Mappings
// First column is the controller index, second column
// is the button flag, third is keyboard key
output outputMap[] = {
  { 0, UP,    KEY_UP_ARROW },
  { 0, DOWN,  KEY_DOWN_ARROW },
  { 0, LEFT,  KEY_LEFT_ARROW },
  { 0, RIGHT, KEY_RIGHT_ARROW },
  { 0, START, KEY_RETURN },
  { 0, A,     'z' },
  { 0, B,     'x' },
  { 0, C,     'c' },
  { 0, X,     'a' },
  { 0, Y,     's' },
  { 0, Z,     'd' },
  { 0, MODE,  'q' },
  { 1, UP,    'i' },
  { 1, DOWN,  'k' },
  { 1, LEFT,  'j' },
  { 1, RIGHT, 'l' },
  { 1, START, 't' },
  { 1, A,     'v' },
  { 1, B,     'b' },
  { 1, C,     'n' },
  { 1, X,     'f' },
  { 1, Y,     'g' },
  { 1, Z,     'h' },
  { 1, MODE,  'r' }
};

// Controller State
int currentState[] = { 0, 0 };
int lastState[] = { -1, -1 };

// Default to three-button mode until six-button connects
boolean sixButtonMode[] = { false, false };

void setup()
{
  // Setup input pins
  for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    pinMode(inputMap[i].pin, INPUT);
    digitalWrite(inputMap[i].pin, HIGH);
  }
 
  // Setup select pins
  for (int i = 0; i < PLAYERS; i++)
  {
    pinMode(SELECT[i], OUTPUT);
    digitalWrite(SELECT[i], HIGH);
  }
 
  Keyboard.begin();
}

void loop()
{
  readButtons();
  sendStates();
}

void readButtons()
{
  for (int i = 0; i < PLAYERS; i++)
  {
    resetState(i);
    if (sixButtonMode[i])
    {
      read6buttons(i);
    }
    else
    {
      read3buttons(i);
    }
  }
}

void resetState(int player)
{
  currentState[player] = 0;
}

void read3buttons(int player)
{
  // Set SELECT LOW and read lowFlag
  digitalWrite(SELECT[player], LOW);
    
  delayMicroseconds(20);
    
  for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW)
    {
      currentState[player] |= inputMap[i].lowFlag;
    }
  }

  // Set SELECT HIGH and read highFlag
  digitalWrite(SELECT[player], HIGH);
    
  delayMicroseconds(20);
    
  for (int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW)
    {
      currentState[player] |= inputMap[i].highFlag;
    }
  }
   
  // When a six-button first connects, it'll spam UP and DOWN,
  // which signals the game to switch to 6-button polling
  if (currentState[player] == (ON | UP | DOWN))
  {
    sixButtonMode[player] = true;
  }
  // When a controller disconnects, revert to three-button polling
  else if ((currentState[player] & ON) == 0)
  {
    sixButtonMode[player] = false;
  }
 
  delayMicroseconds(20);
}

void read6buttons(int player)
{
  // Poll for three-button states twice
  read3buttons(player);
  read3buttons(player);
 
  // After two three-button polls, pulse the SELECT line
  // so the six-button reports the higher button states
  digitalWrite(SELECT[player], LOW);
  delayMicroseconds(20);
  digitalWrite(SELECT[player], HIGH);
 
  for(int i = 0; i < sizeof(inputMap) / sizeof(input); i++)
  {
    if (inputMap[i].player == player && digitalRead(inputMap[i].pin) == LOW)
    {
      currentState[player] |= inputMap[i].pulse3Flag;
    }
  }
 
  delayMicroseconds(1000);
}

void sendStates()
{
  for (int i = 0; i < sizeof(outputMap) / sizeof(output); i++)
  {
    int last = (lastState[outputMap[i].player] & outputMap[i].flag);
    int current = (currentState[outputMap[i].player] & outputMap[i].flag);
    
    if (last != current)
    {
      if (current == outputMap[i].flag)
      {
        Keyboard.press(outputMap[i].key);
      }
      else
      {
        Keyboard.release(outputMap[i].key);
      }
    }
  }
 
  for (int i = 0; i < PLAYERS; i++)
  {
    lastState[i] = currentState[i];
  }
}

If you want to change the button to key mapping, simply update outputMap in the code. You can use any key on the keyboard, including special keys and modifiers.

I hope this is a worthy updated to the sketch – it was a great delight to test it by playing emulated games on my laptop with real Genesis controllers. It worked wonderfully, and I can’t wait to get this integrated into a bigger project.

So happy hacking and stay tuned for more!

/jon

Chordious 1.0.0 now available at chordious.com!

Chordious Image

It’s here! Over a year since my first code check-in, and I’m finally ready to release Chordious 1.0.0 into the world. Need chord charts for your favorite stringed instruments? Want to make your own? Chordious helps you find chords and make customized chord diagrams for free.

It’s my first major cross-platform application, and is available now for Windows, Mac OS X, and Linux, with fancy-pants installers to boot.

Find out more at the new official Chordious website.

/jon

 

The Port Townsend Ukulele Festival 2014

Class photo after the first session of the Baritone Ukulele Support Group

The first session of the Baritone Ukulele Support Group

Last year I attended the first annual Port Townsend Ukulele Festival, and had so much fun that I jumped at the opportunity to preregister for this year. Yesterday marked the end of this year’s festival, and I thought I’d take a moment to review some of the wonderful things I’ve learned in the past few days.

The festival consisted of four sessions of ukulele workshops a day for three days, along with ad-hoc non-ukulele classes, daily open-mics, jam sessions, and two live concerts featuring the instructors. The classes were held in the various buildings at Fort Worden, and included one-day drop-in sessions for shorter topics, along with three-day classes let you really dig into particular subjects.

Besides all of the wonderful opportunities to just sit down and jam with other ukulele players (there were some 160 participants this year), I also came away with a bunch of new techniques to practice, songs to learn, and a greater appreciation for all of the music that these little instruments can make.

Of particular note this year was the acceptance and accommodation of baritone ukuleles. In fact, one of the biggest highlights for me was the positive reception to my playing of Hawaiian slack-key on my baritone uke by both the staff and other participants. (I really need to make some videos, at the very least so I can get on Humble Baritonics again.)

The other highlight was showing off Chordious, which also elicited a positive response from some of the instructors, especially those with upcoming books.

It would be impossible to list everything that happened this weekend, but here are some of my notes (grouped by class and not in any particular order):

Baritone Ukulele Support Group (Aaron Keim)

  • Embrace the wound string. Enjoy the color it adds to the music. Only you will hear the squeaks.
  • There are only so many string factories, so pick the material and gauges you like and feel free to make your own sets. For baritones (tuned dgbe’), Mya-Moe uses D’Addario silver-wound classical guitar strings (0.033w and 0.028w) for the basses, and Worth clear fluorocarbons (0.0319 and 0.0260) for the trebles. (Mya-Moe sells their strings here if you’re not interested in making your own).
  • Keeping your thumb behind wherever your 2nd (middle) finger is will make chording easier.
  • Barre with the bony side of your finger, not the fleshy part, for a cleaner sound.
  • Hang your hand at your side, then raise your elbow – that loose grip, straight wrist, is how your hand should be shaped when fretting.
  • If you play smaller ukes too, use your knowledge of those chord shapes by jumping down and barring at the fifth fret on your bari to play them.
  • When you’re the only bari player in a  group, look at chord names, not grids, and not other people’s hands.
  • Play around with chord fingerings to try to get the root note on your bass string, ie. the 2130 E7 with the root note on the bass sounds better than the 0100 E7 with the 7th note on the bass.
  • Don’t worry about transposing or being in the same key as the paper when you’re playing by yourself.
  • Swapping out that low-d for a high-d will give you a nice, more “ukulele” sound, and isn’t a new idea – jazz ukulele master Lyle Ritz has been playing that tuning on the tenor uke for decades.
  • There is no “official strumming pattern” for songs. Some strums just sound better than others, depending on the feel you want the song to have.
  • It’s not hard to make up your own strumming patterns – just think of it as reductive rather than additive – start with your basic down-up, down-up, down-up, down-up and then remove strokes, replace one with maybe a thumb on the bass, change which fingers you use, etc.
  • In a 4/4 strum, put emphasis on the back-beats (2 and 4). Say chat-ta-noo-ga chat-ta-noo-ga as you strum.
  • If you want to capo, do it. Arron uses Kyser banjo/mandolin capos on his bari.
  • For that dreaded key of F, capo at the first fret and play the shapes for the key of E.
  • For picking like Maybelle Carter, almost everything is lead and played with the thumb.
  • Start by learning the melody, then the chords, then play just melody, using chord strums to fill gaps in the melody

Baritone Chord Magic 3 (Ginger Johnson)

  • When you see scary jazz chords (9ths, 13ths, etc) you can substitute a 7th. Note it doesn’t always work the other way, using a 9th for a 7th might sound good, but might clash with a non-jazzy song.
  • Baritone ukulele can sound deep, sexy, and sultry – don’t get caught up trying to play it like a smaller uke, use its strengths.

Fretboard Roadmaps (Fred Sokolow)

  • Learn your minor pentatonic scale to solo over bluesy songs by just playing in the key of the song (no need to worry about chord changes, just key changes).
  • If the song isn’t bluesy, slide down (toward the head) 3 frets and play the minor pentatonic there.
  • Learning your chord shapes mean playing those I, IV, V chords anywhere on the neck, wherever it’s convenient for the chord changes or melody notes.
  • Learn that circle of fifths. There’s no substitute for just sitting down and committing it to memory.
  • Learn the common progressions in multiple keys so that they become second nature.
  • Learn where major scales are relative to the chord shapes so you can stay in the shape and solo easily

My Three Strums (Casey MacGill)

  • Swing strum is alternating between using your thumb and finger at the same volume, which gives a off-beat natural accent when the nail hits the strings.
  • Keep your hand near the uke, you don’t want to waste energy.
  • You’re pulling your wrist out perpendicular away from the strings and “pinching” it with your thumb like you’re picking apart a cotton-ball.
  • Then flick down with your finger and mute with your palm for the 2nd beat, leading with your wrist.
  • Shuffle strum is using the fleshy part of your finger, again keeping your hand near (or even on the uke) the whole time, and muting between strokes.
  • Rumba strum is down, roll, down-up, down-down-up. Ups are hit with your thumb nail, and there’s no muting.

Hawaiian and Hapa-Haole Songs (Francis Doo)

  • Hawaiian music doesn’t have to be fast, fancy and complicated – simple chord progressions with simple strums give you room to express yourself in the song.
  • The Hawaiian vamp is II7, V7, I, I, then repeated.

Unobtrusive Percussion (JoJo Mascorella)

  • If he could only have one thing, it would be wire brushes. Wire brushes on a sheet of paper on a chair and you have enough sounds to have a good time.
  • Play thinking as if you’re whipping down from your shoulder, to get the right attack, but don’t actually do it as you’ll get tired too fast.
  • Lots of warmups go a long way.
  • Practice slower and speed will come naturally
  • Practice with a metronome to test (and humble) yourself

The biggest refrain was about practice. It’s a dirty word to some, but it really is the only way you get better. Period.

I could fill up post after post with highlights from the festival, but writing about it just isn’t the same as having been there. This year there were some 160 participants with another 180 or so on the waiting-list, so rumor is that next year they’re going to try and meet the demand with two separate festivals back-to-back.

I can’t wait to register.

Happy strumming,

/jon

Follow

Get every new post delivered to your Inbox.

Join 502 other followers