Arduino UNO R3
Some LEDs
A Proto board
Some wires
Some resistors
10 NXP 74HC595N Shift Registers (They were in an Arduino book I got from the library, so I got some)
10 Lite-On LTV-814H Opto isolators (for possibly measuring 24V thermostat signals)
Total Cost: $62.48 (I already had a USB cable.)
I started with a fairly simple project. I wanted to exercise the serial communication and try out the shift register, so I hooked up four LEDs to the shift register, and had the Arduino accept a value over serial and display it on the LEDs in binary. Simultaneously writing it back to the serial.
The circuit is easy. Just a simplification of this one, though I changed some pinning to make the wires fit better, and I only put in 4 LEDs. Here's a picture with the thing displaying a number 5. Yes. It's upside down. The extra LED monitors the clock pin and was only there so I could diagnose problems.
I put the following code in the Arduino and wrote a little LabView program to talk to it.
// Get a number 0-16 from the serial line. Display it on four LEDs using a shift register.
#define LATCH_PIN 10#define CLOCK_PIN 11#define DATA_PIN 8
int numberToDisplay = 0;
void setup(){//set pins to output so you can control the shift registerpinMode(LATCH_PIN, OUTPUT);pinMode(CLOCK_PIN, OUTPUT);pinMode(DATA_PIN, OUTPUT);pinMode(13, OUTPUT);Serial.begin(9600);Serial.println("I have reset");digitalWrite(13,LOW);}
void loop(){if(numberToDisplay >= 0 && numberToDisplay < 16){digitalWrite(13,LOW);digitalWrite(LATCH_PIN, LOW);shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, numberToDisplay);digitalWrite(LATCH_PIN, HIGH);} else { // If the number is invalid, light 13digitalWrite(LATCH_PIN, LOW);shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, 0);digitalWrite(LATCH_PIN, HIGH);digitalWrite(13,HIGH);}Serial.println(numberToDisplay);}
void serialEvent() {while (Serial.available()) {// get the new byte:numberToDisplay = (int)Serial.read();}}
NOTE: You will see I'm not good about commenting code. If someone actually reads this blog, I will get better. How's that for a social contract?
So a couple of notes about this first experience with Arduino.
First, the IDE does weird things with casting. For instance, I wanted to pass the serial data back and forth in binary format. This works with the Arduino reading the byte that's sent, but when it sends it back, it converts it to an ASCII character and then sends it. I guess that's just how println works. I supposed if I used one of the other commands, it might work.
Second, I am not sure why I don't need to look for a '/n' at the end of the transfers from the computer. The LabView VISA is set up to write a termination character. Is the Arduino just ignoring them?
Third, and weirdest: Check this out:
Ok, what happened there? The Arduino is sitting there, displaying a 7, passing that allong the Tx line, then poof. Tx and clock lines go out, Pin 13 blinks, and the display goes back to 0! This will happen every 30 seconds if I let it.
This had me really worried until I figured it out. I thought it was a major design flaw or I had a bad arduino or something. It turns out none of these is the case. Here is the evidence.
1. Arduino doesn't reset if it's not plugged into a computer. I plugged it into wife's iphone charger and it worked indefinitely.
2. Arduino doesn't reset if there is an actual serial connection open to it on the computer, such as in my LabView program or the Arduino IDE's serial monitor.
3. Arduino resets every time a serial connection is established to it, such as when I start my LabView program.
Here is my hypothesis:
The Arduinites recently added a feature to the Uno that makes it so it will automatically reset when you download your code to it. It does this by pulsing the DTR line to the micro. It is well documented online that this makes the Arduino reset each time a serial line is opened to it over the USB. Evidently, my computer is also doing something on the USB port every 30 seconds that also makes the thing reset. Maybe it is a Win7 "feature," or maybe it is just lonely and looking for someone to talk to.
Anyway, this is not a big deal for me just playing around with the thing as long as I am aware of it. It only becomes a serious problem when you want Arduino to go do something on its own, collect data in memory, then dump it to a computer, because as soon as the computer starts to talk to Arduino, it will reset and lose its memory.
There are three solutions:
1. Use EEProm instead of volatile memory. EEProm is like a tiny (1k) HardDrive in the Arduino, but it can only be written 100,000 times.
2. Cut some traces on the Arduino, as advised by half the people out there.
3. Add a low pass filter to the Arduino (resistor, capacitor) so it doesn't pick up the DTR pulse, as advised by the other half of people out there.
I don't care for right now, so we'll cross that bridge when we come to it.
Qualified Schmalified,
TRW