Monthly Archives: February 2013

2N2222 transistor from Radio Shack links Arduino UNO and Teensy 2.0

This screen shot may not seem like much, but it marks the first time I have ever used a transistor:

Reading Transistor SwitchMy Tandy joystick project has two goals. The first is to allow an analog Tandy joystick be used as a USB device for a modern computer. This part is easy, since the variable resistors in the joysticks can be easily read from the Arduino/Teensy’s analog inputs, and the joystick buttons can be read on a digital pin.

The second part is a bit trickier. The idea is to use a modern input device on an old Tandy 1000 or Color Computer. To do this, the USB device’s analog position (if it is an analog stick or a mouse) has to be turned in to a resistance value that the old computer can read through it’s joystick ports. I found a tutorial on the Arduino site that shows doing this with an AD5206 digital potentiometer chip:

http://arduino.cc/en/Tutorial/SPIDigitalPot

That seems easy enough, but I wasn’t sure how to make a digital output pin from the Teensy turn in to a dry contact switch. A bit of research led me to a few useful tutorials dealing with transistors and optoisolators:

http://teachmetomake.wordpress.com/how-to-use-a-transistor-as-a-switch/

http://quarkstream.wordpress.com/2012/05/31/arduino-12-transistors/

…and I found various projects where they were using these devices to simulate a button press on a camera, to automate it:

http://www.zipfelmaus.com/blog/hack-a-canon-camera-and-controll-it-with-an-arduino/

The above project is precisely the type of thing I want to do, so I wired up an Arduino like his layout, and then instead of running wires to the switch of a Canon camera, I ran them to a digital input of my Teensy 2.0 and its ground. Using the Fritzing program, here is a diagram of what I did:

Hooking digital outputs to digital inputs.

Hooking digital outputs to digital inputs. (Diagram done with Fritzing)

I hacked a bit of code on the Arduino side that just toggles that digital pin HIGH and LOW (basically, I hacked the LED blink example to also do pin 12):

int led = 13;
int transistor = 12;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT); 
  pinMode(transistor, OUTPUT);  
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(transistor, HIGH);
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(transistor, LOW);
  delay(1000);               // wait for a second
}

Then, on the Teensy, I wired up to the transistor similar to the Input Pullup example (which reads a button) and reports if the status of the pin had changed. Here’s some quick and dirty code:

void setup()
{
  // Initialize the serial port.
  Serial.begin(9600);

  pinMode(3, INPUT_PULLUP);

  pinMode(LED_PIN, OUTPUT);

  Serial.println("Ready.");
}

int oldStatus;
int status;

void loop()
{

  status = digitalRead(3);
  if (status!=oldStatus)
  {
    Serial.print("Pin 3: ");
    Serial.println(digitalRead(3));
    oldStatus = status;
    digitalWrite(LED_PIN, status);
  } 
}

Now, with both devices running, on the Arduino, every time the LED turns on, it is also turning on the pin connected to the transistor. On the Teensy, that pin connects to digital input 3. (I started at 3 since that is just passed the three pins used by SPI, which I will be needing for my real project.)

When the light on the Arduino goes on, the light on the Teensy goes off. I would need to change how I wired them (active high versus active low) to make them sync. But, it works.

I have much learning to do on all this, but this proof-of-concept gets me one step closer to what I am trying to do. I will be next be trying the same thing using optoisolator chips, though I am not sure there really needs to be any isolation between the joystick buttons and the Teensy.

More to come…

Fritzing circuit designer…

I was looking at an Arduino tutorial and noticed they had a rather nice computer diagram of an Arduino, showing how to connect all the wires up for the project

I decided to check out the link for the Fritzing program that was used to make the diagram. This freely downloadable software for PC, Mac and Linux is pretty neat. You can diagram out an Arduino breadboard layout, and then turn that in to a real schematic and even PCB layout. The layout can then be exported and sent off to have boards made. I have never done anything like this before, but I am having fun experimenting…

The following picture shows something I was playing with. It doesn’t work — it was just me experimenting with some objects. But, I think this program might end up being pretty fun to play with. Check it out.

Playing with Fritzing...(Above was some initial concept work done on “yet another” joystick converter. This one will be designed to hook a modern USB joystick or mouse up to an old Tandy 1000 or Color Computer. I also plan to allow it to do the same thing with a PC keyboard to the CoCo. For emulation fans, the reverse is also planned, allowing an analog TRS-80 joystick to be hooked up to a modern computer via USB, and the same thing with a CoCo keyboard. This is going to take a bit more work than what I have done so far, but it seems pretty straight forward, once I figure out how to use switching transistors…)

 

X-Arcade Tankstick

20130225-171025.jpg

(photo from xgaming.com)

There is a popular set of arcade style joysticks made by a company called X-Arcade. A friend of mine owns one, and he was kind enough to send me a few links with information about these joysticks, and I thought I would share them here.

First, there is an online (Java-based) test program that shows the Tankstick buttons working:

http://www.xgaming.com/support/questions/4/Test+Your+X-Arcade%E2%84%A2+First%21+-+Online+Test+Utility+Program

And this page shows what the various buttons map to:

http://www.xgaming.com/service/images/Layouts/PC-MAC.htm

Of particular interest to me is the realization that Tankstick doesn’t appear as a USB joystick at all. Instead, it appears as a keyboard, and sends key presses for the joystick directions, buttons, etc. For models with a trackball (Tankstick+, for instance), I am guessing the trackball appears as a mouse. So, Tankstick is a keyboard/mouse, as opposed to an analog or (as I previously expected) digital joystick.

This means a third layer of support will be needed to create a conversion between Tankstick keyboard presses and the iCade sequences. This would be a very simple Arduino script since it removes any need for reading digital input pins or USB status bits. It does complicate things for me, however, since now I have to learn what it takes to expect data from either a keyboard or joystick (hopefully without requiring the user to switch). My ultimate goal is to have my code “just work” whether the user is wiring up their own controls to the digital inputs, or using a USB host shield and plugging up an analog or digital joystick, or keyboard device like the Tankstick.

Incidentally, the Tankstick still supports the “ancient” (by computer standards) PS/2 style keyboards as well, and those could be read on an Ardunio (or Teensy) using very little add-on hardware and digital pins. It seems a Tankstick-to-iCade converter could be done very easily, so maybe I can spin one of those off as well.

More updates when I have time to get back to this…

iCade button numbering.

A few notes from my research on the iCade. There is a developer document currently linked from this page:

http://www.ionaudio.com/products/details/icade

Here is the direct link to the current version (1.5) in PDF format:

http://www.ionaudio.com/downloads/ION%20Arcade%20Dev%20Resource%20v1.5.pdf

This document covers the button layout of the original iCade/iCade Core (same layout) used by the iPad, and the iCade Jr./iCade Mobile used by the iPhone/iPod Touch models. Only with the addition of photos showing the buttons for the iCade Mobile did I begin to understand I have been wrong about how the iCade organizes its buttons. Without one to test and play with, I have just been guessing based on available documentation.

(photo from http://www.ionaudio.com/products/details/icadecore)

(photo from http://www.ionaudio.com/products/details/icadecore)

All models provide either a joystick or a 4-way touch pad. For the original iCade (and the cost reduced iCade Core, which is the same unit but without the arcade-looking enclosure), there are eight buttons, organized as two rows of four buttons each. The buttons go red, black, black and white on each row, as if to indicate the group of 2×2 black buttons in the center are different than the red and white ones on the ends. I had been assuming that the main control buttons would be the black ones in the center, similar to the USB joystick I have been experimenting with, which labels the four buttons in the center with the Playstation symbols (square, circle, triangle, smiley face, cute kitty, whatever they are).

With the additional descriptions of the iCade Mobile button layout, I see now this is not the case. I had guessed that the buttons were numbered across, as in the first row being button 1-4 and the second row being button 5-8. This is not the case. Instead, the numbering looks more like this:

1 3 5 7
2 4 6 8

I realized this when I noticed the iCade Mobile was using the four buttons on the left (1-4) for it’s buttons, with 5-8 going to the front index finger buttons. The same was true for the iCade Jr., except buttons 5-8 were located on the back of that unit.

So, the four “primary” buttons for the iCade were 1-4, with two being red and two being black, and the other four (two red, two white) were the extra buttons. This was not what I expected, and it has led me to reorganize my button mapping for the iCade converter project.

There is only one diagram in the iCade documentation that numbers the buttons. Here it is, for the iCade Mobile:

(from http://www.ionaudio.com/products/details/icade)

(from http://www.ionaudio.com/products/details/icade)

Here it seems they number the directional buttons as 1-4, then the primary buttons as 5-8 and the final four as 9, 0, E1 (enter 1) and E2 (enter 2). With that in mind, I have changed my button definitions.

My arcade joystick has the primary buttons in the center, with the extras as grey buttons to the left and right:

Playtech Pro arcade fighting stick

So my arcade joystick thinks it is like a Playstation game pad, with the center color buttons being the right hand buttons, and the grey ones on the left and the right being the four buttons under the fingertips on the front of the gamepad.

If I wanted my joystick to use the same layout as the original iCade, I would have to map my buttons differently. With the joystick now being known as buttons 1-4, the iCade numbering layout looks like this:

  1  (5) (7) (9) (E1)
 3+4
  2  (6) (8) (0) (E2)

I build my iCade array in the order of the 12 buttons:

// This is just used for printing out debug info to the console.
char iCadeDesc[][USB_BTN_COUNT] =
 {"Up", "Down", "Left", "Right",
 "Btn5", "Btn6", "Btn7", "Btn8",
 "Btn9", "Btn0", "BtnE1", "BtnE2"};

So in order to map my joystick over, I created alternate defines for my buttons so they would be easier to figure out:

// We will be treating joystick as a 16-bit value.
// Extra Buttons:
#define SELECT_USB  (1< &lt;8)  // Z1:0x0100 - Select
#define L3_USB      (1<&lt;9)  // Z1:0x0200 - L3
#define R3_USB      (1<&lt;10) // Z1:0x0400 - R3
#define START_USB   (1<&lt;11) // Z1:0x0800 - Start
// Joystick:
#define UP_USB      (1<&lt;12) // Z1:0x1000 - Up
#define RIGHT_USB   (1<&lt;13) // Z1:0x2000 - Right
#define DOWN_USB    (1<&lt;14) // Z1:0x4000 - Down
#define LEFT_USB    (1<&lt;15) // Z1:0x8000 - Left
// Grey/Front Buttons:
#define BTN1_USB    (1<&lt;0)  // Z2:0x0001 - L2
#define BTN2_USB    (1<&lt;1)  // Z2:0x0002 - R2
#define BTN3_USB    (1<&lt;2)  // Z2:0x0004 - L1
#define BTN4_USB    (1<&lt;3)  // Z2:0x0008 - R1
// Primary Buttons:
#define BTN5_USB    (1<&lt;4)  // Z2:0x0010 - "Triangle"
#define BTN6_USB    (1<&lt;5)  // Z2:0x0020 - "Circle"
#define BTN7_USB    (1<&lt;6)  // Z2:0x0040 - "X"
#define BTN8_USB    (1<&lt;7)  // Z2:0x0080 - "Square"

// Redefine some buttons for Playstation type layout:
#define TRI_BTN     BTN5_USB 
#define CIR_BTN     BTN6_USB
#define X_BTN       BTN7_USB
#define SQR_BTN     BTN8_USB
#define L1_BTN      BTN3_USB
#define R1_BTN      BTN4_USB
#define L2_BTN      BTN1_USB
#define R2_BTN      BTN2_USB

The group at the end just gives me Playstation-style labels for the buttons I will be using. So, for a gamepad style controller, my mappings would be like this:

unsigned int myPins[USB_BTN_COUNT] =
  {UP_USB, DOWN_USB, LEFT_USB, RIGHT_USB,
  /*5*/SQR_BTN,   /*6*/X_BTN,    /*7*/TRI_BTN,   /*8*/CIR_BTN,
  /*9*/BTN5_USB,  /*0*/BTN6_USB, /*E1*/BTN7_USB, /*E2*/BTN8_USB};

…but for my arcade stick, where the Playstation buttons are in the center, I would map it like this:

unsigned int myPins[USB_BTN_COUNT] =
  {UP_USB, DOWN_USB, LEFT_USB, RIGHT_USB,
   /*5*/L1_BTN,  /*6*/L2_BTN,  /*7*/SQR_BTN, /*8*/X_BTN,
   /*9*/TRI_BTN, /*0*/CIR_BTN, /*E1*/R1_BTN, /*E2*/R2_BTN};

Here you can see I assign my L1 button (top left grey) to be button 5 to the iCade, L2 for button 6, and so on. This will map my layout to match the original iCade.

It looks like I am going to need a way to switch the type of joystick being used, since clearly things are different. I will work on this next.

Oh, and I plugged up my Legacy Engineering Atari 2600 USB joystick and found it did not work at all with my converter. (Original company seems to be gone, but here is another recreation.) Instead of stuffing bits in Z1 and Z2, the Atari joystick puts them in the X and Y locations. 0 meaning left, 128 meaning center, and 255 meaning right. They are basically taking a digital joystick and faking out analog positions. The single button is mapped in to Z1 as a bit. (Inside this joystick you can hack on additional buttons, and I bet they fill out other bits in Z1.)

So, I now need to deal with two types of digital layouts (gamepad style, and fighting stick style) and an analog type stick (even one being faked, like the Atari).

To be continued…

Arduino USB joystick to iCade converter

  • 2014/03/16 Update: The source code to this is now on GitHub. Check the Arduino link at the top of each page of this site.
  • 2013/02/22 Update: WordPress seems to love to chew up source code, so the sources pasted in are not working properly. I will try to find a solution. Sometimes it works great, other times not at all.
IMG_0649

Arduino Leonardo and USB Host shield acting as USB Joystick to iCade converter.

Today, I picked up my Circuits@Home USB Host adapter from the post office. Now I could finally try to put together a converter that would read from a standard USB joystick and send out iCade formatted keyboard characters to my iPad. Since I had never worked with USB before, I was amazed it only took about 30 minutes to figure out. This is a testament to the work done by the folks responsible for the USB Host library code. The inclusion of functioning sample code allowed me to make quick modifications to do what I wanted.

I will post full details soon, but right now, here are some highlights.

For this project, I am using an Arduino Leonardo. Unlike the UNO and most other Arduinos, the Leonardo is capable of acting as a USB HID (human interface device) so it can appear to be a mouse or keyboard to the computer it is plugged in to. In my case, the computer would be an iPad via Apple’s Camera Connector Kit USB port adapter, and the Leonardo would be acting like a keyboard to send iCade keys,

I had previously downloaded the Arduino USB library from GitHub and extracted it in to my Arduino IDE library folder. I discussed my first experience with Arduino libraries in an earlier article when I was trying to get the iTead Studios USB shield to work.

I was able to test the USB by running various example programs that came with the library, specifically USBHidJoystick. Here is an example of that program’s output as I moved the joystick and pressed some buttons:

This example program shows values coming back from the USB joystick. The joystick and buttons seem to be contained in the Z bytes (Z1 and Z2).

This example program shows values coming back from the USB joystick. The joystick and buttons seem to be contained in the Z bytes (Z1 and Z2).

The joystick I am using is a “Playtech Pro Arcade Fighting Stick” sold on Amazon.com. (As of this posting, the price is $32, but it was about $26 back in December.) Moving the joystick around seemed to change bits in the Z1 value. The four arcade buttons changed bits in Z2. This joystick has a row of seven small control buttons on the top, and four of those buttons (marked Select, Start, L3 and R3) toggled the remaining four bits in Z1.

I do not know how standard USB joysticks are, but I would hope at least the joystick directions and primary buttons would be standardized. The four buttons that were different colors and labeled like Playstation controllers (triangle, circle, X, square) were the high bits of Z2, and the grey surrounding buttons (L1, L2, R1 and R2) were the lower four bits. Perhaps these grey buttons map to the front edge buttons found on console gamepads?

The iCade has a joystick and eight buttons, so I would need to figure out which of the USB buttons I would need to use.

This sample program would be the basis of my experiment. It was made of an Arduino sketch called USBHIDJoystick.pde, and two C++ files — hidjoystickrptparser.cpp and hidjoystickrptparser.h. It seemed the sketch would initialize the USB library, and specify the name of a custom function which would parse the USB data and pull out the joystick related bits. Inside the main loop() was just a call to a task handler function in the library, which I assume is the code responsible for polling and processing incoming USB data.

Inside the hidjoystickrptparser.cpp file, there was a function called OnGamePadChanged() which would print out various values. I planned to comment the print lines out, and just have it call my own button processing code which would parse the set bits rather than read digital input pins. I would just stick the Z1 and Z2 bytes together as a 16-bit integer:

void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
  // Call our joystick handler...
  // We are going to combine the two Z1 and Z2 bytes in to a 16-bit value
  // for easier parsing...
  handleJoystick( (unsigned int)(evt->Z1< <8)|(evt->Z2) );

The GamePadEventData structure, defined in the .h file, contains five byte variables:

uint8_t X, Y, Z1, Z2, Rz;

I would just take the Z1, shift it to the left 8 bits, and OR in the Z2 value, creating a new 16-bit value that held both. In hex, it would look like this: 0xAABB, where AA is Z1 and BB is Z1. Now, inside my new handleJoystick() routine, I could look for those bits rather than scan digital I/O pins.

Instead of using the example sketch, I planned to just merge the USB specific items in to my existing teensy_icade sketch. This would be including some header files, and declaring some variables. The following code was lifted directly from the sample sketch:

// Header files, taken from USBHIDJoystick example.
#include

#include
#include
#include
#include <usb_ch9 .h>
#include
#include
#include
#include</pre>
<address>#include
#include

#include "hidjoystickrptparser.h"

#include #include
#include
#include
// Define some C++ stuff.
USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);</address>
<pre>

Inside my setup(), I would need to include the USB specific items. Since I have not found any documentation on the USB library, I can only assume what these functions do. Usb.Init() seems clear enough (though this code still attempts to run even if it fails, which is bad), and the Hid.SetReportParser() seems to be where the calling program passes in a structure containing the handling functions that the USB code will call when it gets a joystick packet. Or something.

  // USB initialization stuff.
  if (Usb.Init() == -1)
      Serial.println("OSC did not start.");

  delay( 200 );

  if (!Hid.SetReportParser(0, &Joy))
      ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  );

After this, the only other bit of code I would be borrowing was to put a call to the USB task handler inside my loop():

  // Handle USB
  Usb.Task();

Now all I needed to do was pull out my pin reading code from the loop, and make it a separate function which would now be called, not by my loop, but when the USB handler had data to process.

Since my original code used an array of bytes, each representing what pin should be read to indicate the specific direction/button was active, I decided to use the same approach with this. I would use the same button mappings, but alter the defines so that instead of containing a byte value representing a pin number, each one would be a 16-bit value representing which bit was the one for the button. It looks like this:

// We will be treating joystick as a 16-bit value.
// Extra Buttons:
#define SELECT_USB  (1< <8)  // Z1:0x0100 - Select
#define L3_USB      (1<<9)  // Z1:0x0200 - L3
#define R3_USB      (1<<10) // Z1:0x0400 - R3
#define START_USB   (1<<11) // Z1:0x0800 - Start
// Joystick:
#define UP_USB      (1<<12) // Z1:0x1000 - Up
#define RIGHT_USB   (1<<13) // Z1:0x2000 - Right
#define DOWN_USB    (1<<14) // Z1:0x4000 - Down
#define LEFT_USB    (1<<15) // Z1:0x8000 - Left
// Grey/Front Buttons:
#define BTN1_USB    (1<<0)  // Z2:0x0001 - L2
#define BTN2_USB    (1<<1)  // Z2:0x0002 - R2
#define BTN3_USB    (1<<2)  // Z2:0x0004 - L1
#define BTN4_USB    (1<<3)  // Z2:0x0008 - R1
// Primary Buttons:
#define BTN5_USB    (1<<4)  // Z2:0x0010 - "Triangle"
#define BTN6_USB    (1<<5)  // Z2:0x0020 - "Circle"
#define BTN7_USB    (1<<6)  // Z2:0x0040 - "X"
#define BTN8_USB    (1<<7)  // Z2:0x0080 - "Square"

In my original code, I called them “BTN1_PIN” or “RIGHT_PIN”, but I wanted to change the names to be more clear, and also so a future version might mix both capabilities in the same source code. My array of these items would be updated to hold 16-bit values (instead of bytes), and use the renamed defines:
[/code]

// Each of these items is a 16-bit value, where the bits represent the 12
// iCade buttons.
unsigned int myPins[USB_BTN_COUNT] =
  {UP_USB, DOWN_USB, LEFT_USB, RIGHT_USB,
  BTN1_USB, BTN2_USB, BTN3_USB, BTN4_USB,
  BTN5_USB, BTN6_USB, BTN7_USB, BTN8_USB};

You can see that I also renamed a count #define to be “USB_BTN_COUNT” instead of “DI_PIN_COUNT”. The other defines I used in the original were removed, since they were just used to error check the user in case they tried to build a version using pins outside of the allowed range.

My iCade array remains the same, though it will need to be customized to map the eight USB buttons to the proper iCade buttons once I figure out what they should be.

Now the real work could begin. I ripped out the entire loop that went through the myPins[] array and made only a few changes. Instead of reading the status of a digital pin in the array, I already knew the status since I was being passed in the bit value. I would just set status to that specific bit:

void handleJoystick(unsigned int buttonMask)
{
  /*-------------------------------------------------------------------------*/
  // Loop through each Digital Input pin.
  for (int thisPin=0; thisPin < USB_BTN_COUNT; thisPin++ )
  {
    // Read the pin's current status.
    unsigned int status = (buttonMask & myPins[thisPin]);

For digital pins, you read each pin and got a LOW or HIGH value. For this, I assume multiple bits could be set at the same time (?), so I wanted to take the buttonMask passed in from the USB code and just test the specific bit pattern for the button in question. I was still looping through all 12 buttons, but now I would be checking the status of a bit pattern to a bit mask in an array, rather than reading a digital pin and storing the status of that pin.

Now status would no longer be LOW or HIGH (0 or 1), but instead would either be 0x0000 or have a specific bit set like 0x0200 or 0x8000. Instead of comparing “status==LOW” I needed to simply check against it being 0. (My Teensy wiring used “active low” so LOW meant the button was pressed, and here the bit pattern being HIGH mean it was pressed.) That change looked like this:
[/code]

            // If pin is Active LOW,
            if (status!=0)
            {

(I still need to clean up the comments.)

I believe those were the only changes I needed to make, but my first test did not work. It seems my debounce code was causing some kind of issue. Since I assumed the joystick should already be doing denounce before sending out a USB packet with the button status, I tried just commenting out my debounce check and that got everything working. Almost.

The Teensy 2.0 had to be told what kind of USB device it was at compile time. A menu setting would toggle it between USB Serial, or USB Keyboard. With the Leonardo, that option did not appear in the IDE. A quick search revealed I needed to turn on the USB keyboard support in setup():

   Keyboard.begin();

Once done, I could open up a text editor (so the “typing” from the Arduino had a place to show up) and move the joystick around and see the results on the screen:

iCade keys generated by the USB joystick.

iCade keys generated by the USB joystick.

“lv” represents BTN8 pressed then released. “hr” is BTN5. “we” is UP. It worked!

Testing on the iPad was next. Unlike the Teensy 2.0, which could run from the tiny 20mah of power the iPad USB port provided, the Leonardo and USB Host shield would be more demanding. I was not sure what the rules were with using an external power supply on an Arduino — didn’t I read somewhere that you had to change something to prevent problems if it was also connected to a computer’s USB port at the same time?

To be safe, I decided to use a powered USB hub. For testing, my setup looked like this:

JOYSTICK -> Leonardo -> USB Hub -> Mac

I figured all I would have to do is unplug the hub cable from the Mac, and plug it in to the iPad using the Apple Camera Connector kit.

It worked just fine, and I soon found myself testing it on Atari’s Greatest Hits (the first official app to support the iCade) as well as Gridlee (a free arcade game which runs on the MAME emulator).

The buttons were not where they needed to be, so I will need to fix that next.

But for now, I wanted to share my initial progress. I will clean up the code and post it soon.

Part 2: From pressure mats to serial output.

In Part 1: How I got started with Arduino, I discussed a bit of my background and how I came to experiment with an Arduino to solve a particular problem in a haunted house attraction. We were needing something that was capable of reading a switch (like a push button), and sending out a serial message to the COM: port of a PC. Since the $200 Wal-Mart netbooks we were using were modern and had no RS232 ports, the device needed to speak USB or else we would have to use a USB to RS232 adapter, like the FTDI one I used for programming BASIC Stamps.

After a quick experiment with a coworkers Arduino, I discovered it was capable of sending out serial data via the USB port. The device appeared to the host PC as if it was a COM: port, and all one had to do was write a message out in the Arduino code:

Serial.println("Hello, world!");

My initial research about reading switches/buttons on an Arduino led me to a button tutorial on the official Arduino website. It showed that all I needed was a switch (like the pressure mats folks would step on inside the haunted house) and a 10K resistor. I was able to borrow such a resistor from our hardware lab.

Using the diagram on the tutorial site, I stuck one end of the resistor in to the GND header pin socket on the Arduino, then wrapped a wire around the other end and connected it to Pin 2. I wrapped a second wire on the same end, and then, to simulate a switch, I would plug and unplug the end of that wire in to the 5V header pin socket. Their sample code was able to read it as a switch!

During this research, I discovered that the Arduino didn’t actually need the resistor to do this. It had “pull up” resistors built in, and they could be enabled in software. A tutorial on the Digital Pins would explain this to me. Basically, you chose a pin and set it to input, then used a digitalWrite() call to enable the pullup resistor:

pinMode(pin, INPUT);     // set pin to input
digitalWrite(pin, HIGH); // turn on pullup resistor

With this, I could simple put a switch between GND and the PIN and it would work with no extra resistors needed. In fact, it looked as if we could just wire all the mat switches up to various Digital Input pins and be set.

Unfortunately, the early experimental code (see Part 1) had some issues. I will dissect it and explain:

First, I defined the range of Digital Input pins I would be using. Pins 0 and 1 were reserved for talking to the serial port (TX, transmit, and RX, receive), leaving pins 2 through 14 available. I used #define macros so I could change these pin numbers in one place without having to touch the code. I also needed the number of how many pins were in use, so I made a second macro that just subtracted the END from START to get that number:

#define DI_PIN_START 2
#define DI_PIN_END   14
#define DI_PIN_COUNT (DI_PIN_END - DI_PIN_START)

Next, I needed to know the status of each pin so I could tell if it changed. I created an array of integers to hold the status values:

int pinStatus[DI_PIN_COUNT];

For the setup routine, I would initialize each pin for input, then read the status of each pin and store it in the array. I would also initialize the serial port, based on examples from the Arduino site:

void setup()
{
// Initialize the pins and pinStatus array.
for (int thisPin=0; thisPin < DI_PIN_COUNT; thisPin++ ) { pinMode(thisPin+DI_PIN_START, INPUT_PULLUP); pinStatus[thisPin] = digitalRead(thisPin); } // Initialize the serial port. Serial.begin(9600); while(!Serial) { ; } } [/code] The main loop of the program would be very simple. I would loop through each pin and read its current status. If the status was different from the saved status, I knew it changed (button pressed, or button released). Since I wanted to send out serial data to represent the pins, I chose a simple single character, with UPPERCASE meaning "button pressed" and lowercase meaning "button released". Since I had learned that the pin status was either a 0 or 1, I used that to determine if I should print UPPERCASE or lowercase. As I looped through the pins (0 through Max), I would print the character "A" (char 65) plus the pin number (thus, 0 would be A, 1 would be B, etc.). To tell if it was upper or lower, I took the status and multiplied it by 32. In the ASCII character set, 65 is where the uppercase alphabet starts, and 97 (32 higher) is where the lowercase alphabet starts. If status was 1, I would be adding 32 to the number (status*32). If status was 0, I would be adding 0 to the number (0*32) leaving it uppercase.

It was a quick and dirty way to do it, and it looked like this:

void loop()
{
int status = -1;

for (int thisPin=0; thisPin < DI_PIN_COUNT; thisPin++ ) { status = digitalRead(thisPin+DI_PIN_START); // Is pin status different from last time we read it? if (pinStatus[thisPin]!=status) { pinStatus[thisPin] = status; Serial.println(char((97+thisPin)-(status*32))); } } } [/code] This would indeed print out a series of characters based on which pin was connected. Going through all of them might produce:

AaBbCcDdEe


But, it seemed the action of  making the connection would sometimes cause many characters to emit:

AaAaAaAaBbBbCcCcCc

Only if I was very quick with the connection could I prevent that. I was familiar with this problem, thanks to getting started with home computers in the early 1980s. The keyboard of my TRS-80 Color Computer was a matrix of switches, and it contained code in the BASIC ROM to do “denouncing”. Basically, it wouldn’t report that a switch was connected until it had been connected for some small amount of time. Thus, these jitters as the connection was being made would be smoothed out, and not detected.

I would need to add debounce code to my DItoSerial routine.

Until the next part, here is the Arduino tutorial on Debouncing switches. I will discuss how I did it in an upcoming posting.

Until then…

Arduino, iTead Studio USB Host shield, and libraries…

Thanks to my day job, I got my first exposure to Arduino (as well as other similar devices, like the $4.30 TI 430 Launchpad). From time to time, I will post little tidbits of things I have learned.

This is one of those times. (I post this mostly so it will end up in Google search results and maybe save someone the time I wasted trying to figure this out on my own ;-)

There is a USB Host Shield sold by iTead Studio in China. Their product retails for $24.00 (currently $21.60) and it allows the Arduino to act as a “host” and read from other USB devices such as mice, keyboards, etc.

For those unfamiliar with how USB works, there are two types of USB things… USB “device” mode is for something you would plug to a computer so the computer could use it. A printer or thumb drive supports USB device mode. The computer acts as the host, so it has a USB host port. In the 90s, when I was working for Microware, we were bringing USB support to our OS-9 embedded operating system, but initially were only doing device mode. This would let a gadget running OS-9 hook up to a PC so it could talk to it. It did not let you hook up USB devices to OS-9 (though later, this support was added for flash drives and such).

But I digress.

Why would one want a USB host shield when the Arduino already has a USB port? The USB Host shield’s USB port is a “host” port, and is different than the USB “device” port found on the Arduino. The USB port on most Arduinos is just a serial device for loading programs and input/output. It makes the Arduino appear as a serial “device” to the “host” PC. There are some boards, like the Teensy 2.0 and Arduino Leonardo, that do have USB ports than can switch between device and host mode to act be seen as a USB HID (human interface device) such as a keyboard, mouse or joystick.

As part of my expansion of the iCade joystick experiment, I wanted to get a USB Host shield that would let the Arduino read a standard USB joystick (like the $14 arcade controllers found on Amazon) and then convert that in to iCade USB keyboard messages which would be sent out a the Arduino’s built-in port, configured to appear as a USB HID keyboard. This would require an Arduino that can act as a USB HID device (Leonardo), The joystick would plug in to the USB Host shield, then the USB port of the Arduino would go to the iPad.

As mentioned, the Arduino Leonardo provides USB HID support, similar to the Teensy 2.0 I previously experimented with. Unfortunately, the iTead USB Host shield will not work with the Leonardo due to some pins being moved around. The iTead Host Shield communicates over SPI, which is a communication protocol standard. The Arduino UNO has the SPI pins mixed in with the normal digital pins, but the Leonardo moves the SPI pins to a separate small header block (2×3, if I recall) located at the center edge of the board. Thus, the Leonardo does not connect those pins to the iTead Shield.

There is a Circuits at Home USB Host shield that does have this connection, so it should work with the Leonardo. This will be discussed at a later time. For now, my Arduino UNO can hook up to the iTead shield for testing and creating the program that would ultimately need to run on a Leonardo. (Or, for a few dollars and some time, there seems to be a project that lets you hook a USB port to the Arduino and use a special library that allows it to send keyboard commands.)

For now, I will just share a few things I wondered and learned…

Arduino programs are called “sketches” and they are very C-like. The ones I see have are files that use the extension .ino.

There are also Libraries that appear to be written as C or C++ files, ending with typical .c, .h, and .cpp extensions. The iTead Studio USB Host shield came with a .zip file of a USB implementation like this, but absolutely no documentation on what to do with it.

I was not sure how to compile C code, and casual searches didn’t prove helpful. The IDE refused to open a .c file, but would let you drag-and-drop one in to the editor. Building it didn’t work.

I was able to find a more current version of the USB Host library on github.com, but still didn’t know what to do with it.

Last night, after reading a reference on how to add a Library to the Arduino, I apparently figured it out. It seems all I had to do was drag the USB Host source directory in to the “library” folder of the Arduino IDE. (On a Mac, it was in ~/Documents/Arduino/library). Once I did this, I could open the included USB example sketches (.pde extension, for some reason) and build them… There were some minor problems along the way, like having to remove any spaces or special characters from the library folder name (how quaint), and then some conflicts with having the iTead library files installed (I ended up removing them), but the end result was building the test USB code and getting to try it out on an Arduino UNO using the iTead shield.

Wow. That was easy.

To be continued…

Part 1b: A few more notes…

In an earlier post, I shared some source code for a Teensy 2.0 that would use digital input pins to read an Atari 2600 joystick and output USB keyboard characters in iCade format. You may notice that this source code is vastly different than the simple “first thing I ever wrote on an Arduino” I just posted. The current source code incorporates debouncing, statistics, and is easily configurable from some defines and arrays.

Over the next few posts on this subject, I will share the two versions of source that connect my first trial to the current Teensy iCade source code. I have installed a code formatting plug in to this blog which should make the code display a bit nicer. I have even gone back and hand edited the previous posts to clean up the existing source, and fix some HTML nastiness that the software I am using wasn’t smart enough to prevent.

I should also note that, while I am new with Arduino, I am not new with programming embedded devices. I used to work for a company called Microware that made an embedded, multi-user, real-time operating system called OS-9. Before I began work there in 1995, I spent my youth programming 8-bit home computers like the Tandy/Radio Shack TRS-80 Color Computer. After all these years of feeling like technology has passed me by, I suddenly find myself back in a world where a tiny micro like the Arduino (or the TI MSP430s I program on at my day job) feels right at home.

Maybe one day I will learn how to program Android and iOS apps, but until then, there are still plenty of unused bits in these tiny computers to exploit.

More to come…

Part 1: How I got started with Arduino.

I remember hearing about some open-source hardware platform with a weird name a few years ago, but at the time I had little interest. I thought my hardware days were behind me, and even when they weren’t, I was never really in to hardware that much beyond soldering cables and making simple circuits. This is the story of how all this changed.

But first, allow me to regress…

In September 2012, I was helping out at a local haunted house at Sleepy Hollow Sports Park in Des Moines, Iowa. My association with them began in 2004 when they were starting to work with Festivals International to build the permanent home of the Des Moines Renaissance Faire. When they found out I was a “computer guy,” I was asked if I knew much about electronics and automation. This led me to building prop controller boxes (based on the EFX-TEK Basic Stamp Prop-1 boards) for their haunted houses.

My little boxes, built using as much off-the-shelf RadioShack stuff as possible (to allow for quick local repairs if needed), would trigger 12V solenoids that controlled pneumatic pistons to move various props or figures. We built a motion-activated gas chamber prop (complete with gas, lights, and several animations including standing up), and several other pop-up type figures. The first test-run of the gas chamber prop can be found on YouTube:

It was a great learning experience, and I wrote a BasicStamp program that allowed multitasking two (or more) prop sequences in the same box. I later found out this was written about by Jon Williams in an article found in Nuts and Volts magazine (available here as a PDF file, though he misspells my name). If there is ever any interest in BasicStamp programming, I would be happy to share more on those projects as well.

Anyway, I didn’t really do anything again with hardware until last year, instead focusing more on audio and video effects. In 2011, Sleepy Hollow brought on a local hauntrepenuer named Nathaniel who had been doing very elaborate backyard haunts in Urbandale, Iowa for years. Nathaniel introduced us to PC-based show control systems. We tested out his system by converting the “Torture Chamber” museum at the Renaissance Faire in to a computer controlled light and sound tour… And suddenly had lines never seen before at the attraction. A pre-opening test video can be found on YouTube:

The wiring of lights and speakers in the torture chamber was just the beginning. We continued to wire up the entire haunted castle (which was not open during the Renaissance Faire) and had our own Haunted Mansion style experience that October, complete with a ghostly narrator that followed guests from room to room. A duplicate computer system was used to run a pre show and some lighting effects at a new laser tag zombie shootout attraction. It was a ton of work, but a great learning experience.

And that’s where the Arduino came in. Or would, a year later.

In 2012, we did further upgrades to the torture chamber, haunted castle, and zombie shootout, and even added an all-new haunted house. The hobbyist-grade software we were using was already having difficulties keeping up. We had encountered several issues with it the past season, so we began to explore various other options. We even evaluated some high end professional products like Venue Magic. Unfortunately, there wasn’t a budget for something like that so we had to make due with cheap netbooks and whatever we could cobble together.

However, during our evaluation of Venue Magic (initially in a trial “runs forever, but cannot save” mode), I started exploring how it handled inputs. It did not support any of the input hardware we already had, so we looked in to some other solutions (in the $150 price range). They all seemed expensively complex for our needs. The cheap interfaces we had acted like simple USB serial devices, sending serial data when a switch was triggered… which gave me an idea.

At work, someone had an old Arduino Duemilanove. I borrowed it over lunch and found that it could easily act as a USB serial device, and quickly had something hacked together that would read the status of the digital input pins and emit a letter for each pin triggered. My original code looked something like this:

#define DI_PIN_START  2
#define DI_PIN_END    14
#define DI_PIN_COUNT  (DI_PIN_END-DI_PIN_START)

int pinStatus[DI_PIN_COUNT];

void setup()
{
  // Initialize the pins and pinStatus array.
  for (int thisPin=0; thisPin < DI_PIN_COUNT; thisPin++ )
  {
    pinMode(thisPin+DI_PIN_START, INPUT_PULLUP);
    pinStatus[thisPin] = digitalRead(thisPin);
  }

  // Initialize the serial port.
  Serial.begin(9600);

  while(!Serial) {
    ;
  }
}

void loop()
{
  int status = -1;

  for (int thisPin=0; thisPin < DI_PIN_COUNT; thisPin++ )
  {
    status = digitalRead(thisPin+DI_PIN_START);
    // Is pin status different from last time we read it?
    if (pinStatus[thisPin]!=status)
    {
      pinStatus[thisPin] = status;
      Serial.println(char((97+thisPin)-(status*32)));
    }
  }
}

On startup, it would read and store the current state of each pin, then in a loop, if a pin changed, it would print either an UPPPERCASE or lowercase letter, based on the pin. Pressing and releasing the first pin would send “A” then “a”, for example. This proof-of-concept showed it would work, and I went down to Radio Shack and purchased my own Arduino Duo to begin experimenting.

I will share more code in future posts, and explain how that simple bit of code turned into something much more elegant.

To be continued…