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.

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. We appreciate comments and article submissions.
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.
Click here to add your comments
Don't miss responses! Subscribe to Comments by RSS or by Email
Click here to add your comments
If you want a picture to show with your comment, go get a Gravatar