APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

USB I/O on Wiring.org board


2007/11/16

I'm continuing to play around with the Wiring.org 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 Wiring.org board measure typing speed. Here's what it looks like when it is running:


Ready
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 
==================================
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
==================================
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 Wirin.org 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 ?
  Serial.println("");
  Serial.println("Ready");
  
  now=millis();
  lastBlink=now;
  lastCharRead=lastBlink;


}




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) {
     lastBlink=now;
     blink();
  
   }
      

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

    waiting=0;
    numChars++;
  
    val = Serial.read(); 
    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.println("==================================");
      Serial.print("Chars: ");Serial.println(numChars);
      Serial.print(" elapsed ");myprint(elapsedTime,3);
      Serial.print("CPS: "); myprint(cps,3);
      Serial.println("==================================");
   
      
      numChars=0;
      elapsedTime=0;
      waiting=1;      // waiting for tying to start again
      
   }
   now=millis(); 
 
}

void blink() {
     if (ledState == HIGH) {
       ledState=LOW;
       digitalWrite(ledPin, LOW);
     } else {
       ledState=HIGH;
       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;
  Serial.print(long(rounded));
  Serial.print(".");
  
  while (scale--) {

      float toPrint=floor(remainder * 10);
      Serial.print(int(toPrint));
      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 Wiring.org 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?

Unix/Linux/Mac OS X support by phone, email or on-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





Computers make it easier to do a lot of things, but most of the things they make it easier to do don't need to be done. (Andy Rooney)

The easy confidence with which I know another man's religion is folly teaches me to suspect that my own is also. (Mark Twain)












This post tagged: