Wednesday, June 24, 2009

"My" first Arduino program

Ray invited me to post on his blog to share in learning experiences and to collaborate on different projects. We both seem to be interested in learning the Arduino at the moment, so here's a bit on that, "my" first Arduino program. Not too interesting to many, but to anyone learning microcontrollers (specifically the Arduino) there might be a lesson or two to be gleaned.

I'll admit that it's not 100% mine, infact it's nearly all not mine (thus the quotes around "my"), BUT it didn't come verbatim from a tutorial (I hacked a couple tutorials to come up with it, mainly to force me not to just follow the bouncing tutorial-dot). It's a script that has chasing LEDs (Knight Rider style), and the speed which the LEDs chase is controlled directly with a potatometer (less resistance = faster chase. From 0 millisec up to 1023 millisec, just over 1 full sec in between flashes for max resistance).

The code is posted below. I would have posted pictures but my camera seems to have a crappy USB port, and won't upload pics. A moving picture would be better, but to my knowledge man has yet to invent moving pictures (or "movies" as I would like to call them).


The Schematic shown here is, if nothing else, pretty ugly. The jagged scribbles between the Arduino and the LEDs are resistors (I used 220 Ohm, for no other reason than that's about what all the tutorials use for LEDs - no idea why that specific value though). There's also an error in it, the digital pins 1-5 should be 2-6.

The first thing I realized was that pin 14 is also analog pin 0. They're one in the same, the only difference is when using it as an analog pin with "analogWrite" (or read) it's pin 0, when using it as a digital pin with "digitalWrite" (or read) it's pin 14. The second interesting thing I learned was kind of the opposite of PWM control, though it was inadvertent. I accidentially hooked up the potatometer's ground to the LED ground. When I ran the program, the potatometer controlled the brightness of the LED's rather than their speed. I was using an analog signal to control the digital outputs (in PWM, you use pulsed digital to control analog). Another interesting thing was that the Arduino was still reading the analog 0 pin (which was hooked up to nothing) so it read some random value, which just happened to give me about a half-second delay. Luckily I saw that I was hooked up incorrectly and rewired. The program ran exactly as intended. Turning the pot slowed or sped the chasing lights accordingly.

This excercise also drove home the operation of the "for" function. When the lights are chasing quickly, you don't notice, but when they're chasing slowly and you turn the pot, the way this program is structured, the lights will complete their chase before reading the new pot value to speed things up.

I was also able to notice how the "delay(x)" function delays everything - could be bad to use in certian situations when you need an immediate change or read, etc... if the sketch is in the middle of a "delay" it doesn't seem to respond to anything until it's good and ready.

Thanks for reading, hope I didn't bore you too much and maybe you learned from some of my errors.

Here's the code:


/* Variable Chasing LEDs
This adjusts the rate at which a chasing LED array operates
Circut: Potatometer is attached to analog input 0 (digital pin 14), 5 LEDs are attached to digital outputs 2 through 6 (to ground through 220 Ohm resistors).
*/

int sensorPin = 0; //initalize which pin is potentometer input
int ledPin[] = {2,3,4,5,6}; // initalize LED pin outputs
int numleds = 5; // number of LED outputs in circut
int potVal = 0; // potentometer's value (initalized @ zero)

void setup(){
//loop to initalize LED pins as outputs:
for(i=0; i
pinMode(ledPin[i], OUTPUT);}
}

void loop(){
potVal = analogRead(sensorPin); //read potentometer value

// forward chasing, delayed according to value of potentometer:
for(int i=0; i
digitalWrite(ledPin[i], HIGH);
delay(potVal);
digitalWrite(ledPin[i], LOW);
}
// now back chasing:
for(int i=numleds-1; i>=0; i--){
digitalWrite(ledPin[i], HIGH);
delay(potVal);
digitalWrite(ledPin[i], LOW);
}
}

3 comments:

  1. this is excellent =) i like that you included the mistake so we can learn from the mistake as well.

    what will be your next arduino project? extending on this one? a new one entirely?

    ReplyDelete
  2. I dunno, any ideas?
    I was thinking of taking a thermocouple to read water temp from a faucet and then vary the brightness of a blue and red LED to indicate if it's hot, cold or warm.

    ReplyDelete
  3. I encapsulated your code with:

    < pre class="prettyprint">
    ....code....
    < /pre>

    so it comes out looking like nice code =P

    ReplyDelete