/ / Knightrider
The following exercises are about sequential programming and good programming techniques for the I/O board.
- Wire your board so that pins 2-9 are outputs with LEDs attached to them.
- Each LED needs a 220 resistor.
- Place a pull-down resistor switch on pin 10.
- Write code to make the LEDs blink in a sequence, one by one using only digitalWrite(pinNum,HIGH/LOW)
and delay(time).
The lights should turn on and off after the button is pressed and stop when the button is pressed again. - Write code to make the LEDs blink in a sequence, one by one using two for loops—One loop to turn on the lights and another to turn them off.
This is the syntax for a for loopinit is where you set a variable, like int led=2;for(init;condition;next){ }
condition is how long the loop will continue, like led<=9;
next is where you increment or decrement the variable, like led++;
/ /Arrays

© Chris Collins/CORBIS
An array is another type of variable that keeps track of multiple pieces of information at once.
Where a variable can only hold one piece of information, an array can hold a whole bunch of information and it holds them in a given order.
Where a variable can only hold one piece of information, an array can hold a whole bunch of information and it holds them in a given order.
Basically, an array is like giving a single name to a whole list of variables, where each variable can be affected separately by the programmer without having to give it a separate name. Each separate variable within the array is referred to as a cell or element of the array.
Think of an array as a sequence of mailboxes in an apartment building. Each box may or may not have content within it. Each mailbox corresponds to an element of the array. Each mailbox is labeled with a number. In array speak, that number is called the index. The first index of a array in most programming languages is 0.
Remember: An array with five elements has the indices 0, 1, 2, 3, and 4.
|
To access an array element at a given index, write:
myArray[index]
To assign a value to an array element at a given index, write:
myArray[index]=value;
Used in this way the square brackets are pronounced “sub”. myArray[1] is pronounced myArray sub 1.
If you wanted to assign the value 8 to every element in an array, use a loop:
int arrayLen=8;
for(i=0;i<arrayLen;i++){
myArray[i]=8;
}Using a loop to access the values of an array is called looping over or looping through the array.
Exercise 2—Back to Arduino
Rewrite the last program using an array:
int pinArray[] = {2, 3, 4, 5, 6, 7, 8, 9};
int timer = 100;
Look at your solution to the bike light (you'll have to remove the interval code and add a timer variable)
- Use a loop to set the pinMode: setup():
for(int i=0;i<8;i++){ pinMode(i,OUTPUT); } - When your lightOn variable is true turn the lights on, then off. Between the 2 loops add a slight delay.
While this works with the delay, it's not great, you'll have to hold the button down until the delay is complete and the chip can poll the button again.
/ /Just 1 at a Time
By lighting the next led shortly after the current led is turned off, you will create a different effect.
Using the last program, modify the loops(). Here is the modification for the first loop:
digitalWrite(pinArray[your_var], HIGH); delay(timer); digitalWrite(pinArray[your_var], LOW); delay(timer*2);
/ /Shooting Star
Connect 11 LEDs to 11 arduino digital pins through a 220 Ohm resistance.
The program should light up LEDs until it reaches the number of LEDs equal to the size you have established for the tail. Then it will continue lighting LEDs towards the left to make the line keep moving, and will start erasing from the right, to make sure you see the tail (otherwise you would just light up the whole line of leds, this will happen also if the tail size is equal or bigger than 11).
The tail size should be relatively small in comparison with the number of LEDs in order to see it.
Copy, paste and complete the following:
// Variable declaration
int pinArray [] = ___________; // Array of LED pins
int timer = 100; // delay
int tailLength = 4; // Num of LEDs that stay lit before you start turning them off
int lineSize = 11; // Number of LEDs connected
void setup(){
//turn all your leds to OUTPUTS
______________________
______________________
______________________
}
// Main loop
void loop(){
int tailCounter = tailLength; // set up the tail length in a counter
for (int i=0; i<length_of_array; i++){
// light up the LEDs consecutively
__________________________
// Add a delay. This time variable controls how fast you light them up
______________
if (tailCounter == 0){
// turn off the LEDs depending on tailLength
digitalWrite(pinArray[i-tailLength],___);
}else if (tailCounter > 0)
tailCounter--;
}
for (int i=0; i<length_of_array; i++){
// turn off the LEDs
digitalWrite(________);
//pause
_____________
}
}Combine the code above with your toggle switch.
/ /Shift Register
In digital circuits, a shift register is an integrated circuit or IC chip. This particular chip, the 74hc595, will give you eight additional outputs while using only three arduino pins.You can also link Shift Registers together to get many extr outputs.
To use a Shift Register you clock in the data and then lock latch it in. To do this you set the data pin to either HIGH or LOW, pulse the clock, then set the data pin again and pulse the clock repeating until you have shifted out 8 bits of data. Then you pulse the latch and the eight bits are transferred to the shift register pins.
Here is the schematic:

Wire up your board, then complete the program and upload it to your microcontroller
//Pin Definitions
//The 74HC595 using a protocol called SPI
//Which has three pins
int data = 2;
int clock = 3;
int latch = 4;
int delayTime = 100; //the number of milliseconds to delay between LED updates
//Used for single LED manipulation
int ledState = 0;
const int ON = HIGH;
const int OFF = LOW;
void setup(){
//set your three pins connected to the shift register as OUTPUTS
}
void loop(){
//create a loop between 0 and 255
_____________________
/*call the function updateLEDs and pass it the var holding the current iteration of your loop*/
________________
//call delay and pass it your delay var
____________
//close the loop
_____________
}
/*
* define updateLEDs() -
* this function sends the LED states set in ledStates to the 74HC595
* sequence
*/
void updateLEDs(int value){
//Pull the chips latch low by setting the pin to LOW
__________________
//Shifts out the 8 bits to the shift register
shiftOut(data, clock, MSBFIRST, value);
//Pull the chips latch high which will display the data
___________________
}
An Arduino can make complex actions simple.
Replace your function updateLEDs with this:
*
* updateLEDsLong() - sends the LED states set in ledStates to the 74HC595
* sequence. Same as updateLEDs except the shifting out is done in software
* so you can see what is happening.
*/
void updateLEDsLong(int value){
//Pull the chips latch low by setting the pin to LOW
__________________
/* create a for loop between 0 and 8
* you want the loop to repeat 8 times (once for each bit)
*/
________________________
int bit = value & B10000000; //Use a "bitmask" to select only the eighth
//bit in your number (the one you are addressing this time through
value = value << 1; //move your number up one bit value so next time bit 7 will be
//bit 8 and you'll do some math on it
//test if bit 8 is set
if(bit == 128){
//if it is then set your data pin high
__________________
//if it is not set, set the data pin LOW
_________________________
//the next three lines pulse the clock pin
digitalWrite(clock, HIGH);
delay(1);
digitalWrite(clock, LOW);
}
//pull the latch high shifting your data into being displayed
__________________
}As the eight LED states are stored in a byte (8 bits) you can use bitwise math to manipulate the bits.
Replace your current loop() code with this:
for (int i=0;i<8;i++){
changeLED(i,ON);
delay(delayTime);
}
//toggle the bit
for (_______________){
changeLED(i,___);
________________
}
int bits[] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000};
int masks[] = {B11111110, B11111101, B11111011, B11110111, B11101111, B11011111, B10111111, B01111111};
/*
* changeLED(int led, int state) - changes an individual LED
* LEDs are 0 to 7 and state is either 0 - OFF or 1 - ON
*/
void changeLED(int led, int state){
ledState = ledState & masks[led]; //clears ledState of the bit you are addressing
if(state == ON){
ledState = ledState | bits[led];
} //if the bit is on we will add it to ledState
updateLEDs(ledState); //send the new LED state to the shift register
} Some Math
Masking is the technique used to determine the value of certain bits of a binary value. Here are some bitwise operations:| ~ | ones complement | Converts the bits within an operand to 1 if they are 0 and 0 if they are 1 |
| << | Left Shift | Will shift the left operand to the left, in binary fashion, the number of times specified by the right operand. In a left shift operation, 0 is always shifted in replacing the lower bit positions that would have been empty. Each shift left effectively multiplies the operand by 2. |
| >> | Right Shift | Will shift the bits of the left operand to the right, in binary fashion, the number of times specified by the right operand. Each shift effectively performs a division by 2. When a right shift is performed, signed and unsigned variables are treated differently. The sign bit (the left most significant bit) in a signed integer will be replicated. This sign extension allows a positive or negative number to be shifted right while maintaining the sign. When an unsigned variable is shifted right, zeros will always be shifted in from the left. |
| & | AND | Will result in a 1 at each position where both operands are 1 |
| ^ | EXCLUSIVE OR | Will result in a 1 at each position where the operands are different |
| | | INCLUSIVE OR | Will result in a 1 at each position where at least one of the operands contains a 1 |
0xC9=11001001
| x=~y | 00110110 or 0x36 |
| x=y<<3 | 01001000 or 0x48 |
| x=y>>4 | 00001100 or 0x0C |
| x=y&0x3F | 00001001 or 0x09 |
| x=y^1 | 11001000 or 0xC8 |
| x=y|0x10 | 11011001 or 0xD9 |
LED as input
You can also use an LED to detect light. For best results, use a colored LED (such as red) and a normal white flashlight (the brighter the better).
Connect the anode into the 0 Analog In pin and connect the cathode to Ground.
Here is code to show you that the LED is detecting light:
/* LED Light Sensor
* by Duane O'Brien
* for IBM Developer Works
*/
int recvPin = 0;
int wait = 1000;
int val = 0;
void setup() {
// Initialize the Serial Interface
Serial.begin(9600);
}
void loop() {
// Take a reading from the Analog Pin
val = analogRead(recvPin);
// Output the detected value
Serial.print("DETECT : ");
Serial.println(val);
// Wait to take the next reading.
delay(wait);
}
Now you are going to modify the code to learn a little bit about frequency.
Infrared is everywhere, so sensors need to filter out anything not being transmitted at a specific frequency. The code below will show you, in a rudimentary way, how transmitting frequency works. This isn't intended to be a comprehensive scientific experiment, but it may help illustrate the concept.
You are going to change the code so that when the light reading jumps by more than 5 percent of the baseline, a cycle is started that looks at the next two readings, outputting a specific code based on the codes detected. You'll need some additional variables:
- a variable to determine how many readings should be taken to establish the baseline number for ambient light
- a variable to hold the minimum reading jump you are expecting
- an iterator
- an array to hold the different codes
- and a tracking int to tell where you are in a cycle.
int recvPin = 0;
int wait = 1000;
int val = 0;
int readings = 5;
int jump = 0;
int i = 0;
int code[2];
int incycle = 0;
void setup() {
/*Next, you need to take a set of readings during setup, average them, and determine
what 5 percent means. Generally, the first reading is always abnormally high,
so throw that one out right away. */
// Initialize the Serial Interface
Serial.begin(9600);
Serial.print("establishing baseline... ");
val = analogRead(recvPin); // throw out the first one, it's usually high.
delay(wait);
for (i = 0; i < readings;i++) {
jump += analogRead(recvPin);
delay(wait);
}
jump = (jump / readings)*1.05;
Serial.println(jump);
// Output the detected value
delay(wait);
}
void loop() {
/*you read the pin. If you're in a cycle, you need to save the
code, and if you have received all the code, output a result. If you're not in a cycle,
and the reading is 5 percent above the baseline, you start a cycle. Listing 10 could
be more compact, but it's spelled out a little more clearly so you can see what's
going on. */
// Take a reading from the Analog Pin
val = analogRead(recvPin);
switch (incycle) {
case 0:
if (val > jump) {
Serial.println("In Cycle");
incycle = 1;
} else {
Serial.println("Out Of Cycle");
}
break;
case 1:
if (val > jump) {
code[0] = 1;
} else {
code[0] = 0;
}
incycle = 2;
Serial.println("Read One");
break;
case 2:
if (val > jump) {
code[1] = 1;
} else {
code[1] = 0;
}
incycle = 3;
Serial.println("Read Two");
break;
case 3:
if (code[0] == 0 && code[1] == 0) {
Serial.println("Reset");
} else if (code[0] == 1 && code[1] == 0) {
Serial.println("Turn On");
} else if (code[0] == 0 && code[1] == 1) {
Serial.println("Turn Off");
} else if (code[0] == 1 && code[1] == 1) {
Serial.println("Explode");
}
code[0] = 0;
code[1] = 0;
incycle = 0;
break;
}
delay(wait);
}
What you're doing here is signaling a binary message at a very low frequency.
/* ---------------------------------------------------------
* | Arduino Experimentation Kit Example Code |
* | CIRC-05 .: 8 More LEDs :. (74HC595 Shift Register) |
* ---------------------------------------------------------
*
* We have already controlled 8 LEDs however this does it in a slightly
* different manner. Rather than using 8 pins we will use just three
* and an additional chip.
*
*
*/
//Pin Definitions
//The 74HC595 using a protocol called SPI (for more details http://www.arduino.cc/en/Tutorial/ShiftOut)
//Which has three pins
int data = 2;
int clock = 3;
int latch = 4;
//Used for single LED manipulation
int ledState = 0;
const int ON = HIGH;
const int OFF = LOW;
/*
* setup() - this function runs once when you turn your Arduino on
* We set the three control pins to outputs
*/
void setup()
{
pinMode(data, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(latch, OUTPUT);
}
/*
* loop() - this function will start after setup finishes and then repeat
* we set which LEDs we want on then call a routine which sends the states to the 74HC595
*/
void loop() // run over and over again
{
int delayTime = 100; //the number of milliseconds to delay between LED updates
for(int i = 0; i < 256; i++){
updateLEDs(i);
delay(delayTime);
}
}
/*
* updateLEDs() - sends the LED states set in ledStates to the 74HC595
* sequence
*/
void updateLEDs(int value){
digitalWrite(latch, LOW); //Pulls the chips latch low
shiftOut(data, clock, MSBFIRST, value); //Shifts out the 8 bits to the shift register
digitalWrite(latch, HIGH); //Pulls the latch high displaying the data
}
/*
* updateLEDsLong() - sends the LED states set in ledStates to the 74HC595
* sequence. Same as updateLEDs except the shifting out is done in software
* so you can see what is happening.
*/
void updateLEDsLong(int value){
digitalWrite(latch, LOW); //Pulls the chips latch low
for(int i = 0; i < 8; i++){ //Will repeat 8 times (once for each bit)
int bit = value & B10000000; //We use a "bitmask" to select only the eighth
//bit in our number (the one we are addressing this time through
value = value << 1; //we move our number up one bit value so next time bit 7 will be
//bit 8 and we will do our math on it
if(bit == 128){digitalWrite(data, HIGH);} //if bit 8 is set then set our data pin high
else{digitalWrite(data, LOW);} //if bit 8 is unset then set the data pin low
digitalWrite(clock, HIGH); //the next three lines pulse the clock pin
delay(1);
digitalWrite(clock, LOW);
}
digitalWrite(latch, HIGH); //pulls the latch high shifting our data into being displayed
}
//These are used in the bitwise math that we use to change individual LEDs
int bits[] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000};
int masks[] = {B11111110, B11111101, B11111011, B11110111, B11101111, B11011111, B10111111, B01111111};
/*
* changeLED(int led, int state) - changes an individual LED
* LEDs are 0 to 7 and state is either 0 - OFF or 1 - ON
*/
void changeLED(int led, int state){
ledState = ledState & masks[led]; //clears ledState of the bit we are addressing
if(state == ON){ledState = ledState | bits[led];} //if the bit is on we will add it to ledState
updateLEDs(ledState); //send the new LED state to the shift register
} http://aterribleidea.com/2009/02/25/building-an-arduino-based-laser-tag-game/