USB I/O on board


I'm continuing to play around with the I/O Board and wanted to see how to use its built-in USB port for input and output. It turns out that's not hard to do, but I did run into a number of data conversion problems along the way, so the project became a little challenging.

What I created is a little thing that lets the board measure typing speed. Here's what it looks like when it is running:

I can't type very fast 
Chars: 22
 elapsed 5.155 
CPS: 4.260 
I could just hold down a key: 
Chars: 29
 elapsed 7.514 
CPS: 3.850 
Chars: 45
 elapsed 4.056 
CPS: 11.090 
Or paste in some text:
Chars: 23
 elapsed 5.862 
CPS: 3.920 
This was pasted in! 
Chars: 19
 elapsed 0.019 
CPS: 1000.000 
But that would be cheating 
Chars: 26
 elapsed 5.521 
CPS: 4.700 

To do this, you need to be able to connect to the USB port from your computer. I used "screen" on my Mac:

screen /dev/tty.usbserial-0000103D 9600

I had to download USB VCP drivers to give me that serial port; you'd need to do the same for Windows or Linux.

On a PC you could use any good terminal program like Putty; on Linux you's probably use screen also. Remember to disconnect (CTRL-A, CTRL-\ for screen) before trying to upload programs to the board.

The program itself is not terribly complex:

// example of reading and writing I/O board
// through USB port
// Anthony Lawrence November 2007

// Globals

int ledPin = 48;                  // LED connected to the Wiring I/O board pin 48 

unsigned long now=0;              // milliseconds since boot
unsigned long lastBlink=0;        // LED last blinked then
unsigned long lastCharRead=0;     // read last typed character then
boolean ledState=HIGH;                

char val;                         // character typed
int numChars;                     // count of characters typed
long elapsedTime=0;               // time spent typing
boolean waiting=1;                // waiting to begin typing

void setup()
  pinMode(ledPin, OUTPUT);       // sets the digital pin as output
  digitalWrite(ledPin, HIGH);    // set the LED on
  Serial.begin(9600);            //sets baud rate for port
  delay(5000);                   // takes a little bit to be ready ?


void loop()
   // blink every few seconds no matter what
   // this should be 5 seconds, but it's less than 3 for me
   if ((now - lastBlink) > 5000) {

  // check for serial characters and accumulate elapsed time
  if  (Serial.available() > 0) { 
    if (waiting == 1) {
       lastCharRead=now;    // first read
    elapsedTime += (now - lastCharRead);

    val =; 
    Serial.print(val);     // echo back to screen
    blink();              // and blink LED

 // if nothing has been typed for a bit, output results
 // again, should be 2 seconds but is less for me
 if ((now - lastCharRead) > 2000 and waiting == 0) {
      unsigned long ucps=numChars * 100000;
      ucps = ucps / elapsedTime;
      ucps *= 10;
      long cps=long(ucps);
      // a lot of extra work in here because of rounding and overflows
      Serial.println(" ");
      Serial.print("Chars: ");Serial.println(numChars);
      Serial.print(" elapsed ");myprint(elapsedTime,3);
      Serial.print("CPS: "); myprint(cps,3);
      waiting=1;      // waiting for tying to start again

void blink() {
     if (ledState == HIGH) {
       digitalWrite(ledPin, LOW);
     } else {
       digitalWrite(ledPin, HIGH);

void myprint(long number, int scale) {
    // again, a lot of extra work in here because of rounding and overflows
  float mult=pow(10,scale);
  float rounded= floor(number /mult);
  float biground=rounded * mult;
  float remainder=(number - biground); 
  remainder = remainder / mult;
  while (scale--) {

      float toPrint=floor(remainder * 10);
      remainder -= (toPrint/10);
      remainder *=10;

  Serial.println(" ");

The Wiring language is a work in progress, and as most uses aren't talking to anything but other hardware, not much attention is given to such matters. There is no printf(), for example, and the Serial.println function can't output floats, so I had to write a little routine to do that. But that's part of what makes playing with this fun; the challenge of getting around language limitations takes me back to when I was playing with assembly language on a Z-80: you invent your own routines when you need them.

I also had quite a bit of trouble with data conversion. Look at the section that calculates CPS - I just could not get this to work without that extra unsigned long "ucps". Again, you might consider that annoying, but for me it's just part of the fun.

This might be a good "challenge" project for someone new to programming - show them this running, then have them duplicate the functionality. There are a lot of "learning opportunities" there.

Got something to add? Send me email.

(OLDER) <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> USB I/O on board

Increase ad revenue 50-250% with Ezoic

More Articles by

Find me on Google+

© Anthony Lawrence

Kerio Samepage

Have you tried Searching this site?

Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us

privacy policy