Wednesday, March 17, 2010

Read LDR after Button Press (Task 38,39)

This code waits for a button to be pressed, then reads a value from an LDR and out puts it over serial.
Code:
int reading;
int push;

void setup() {
Serial.begin(9600);
pinMode(2,INPUT);
count = 0;
}

void loop() {
push = digitalRead(2);
if(push == HIGH){
delay(500); //This avoids multiple values being read per push
reading = analogRead(0);
Serial.println(reading);
}
}
Layout:


You can customize the output to make it look better and provide a count to track readings:
int reading;
int push;
int count;

void setup() {
Serial.begin(9600);
pinMode(2,INPUT);
count = 0;
}

void loop() {
push = digitalRead(2);
if(push == HIGH){
count ++;
delay(500);
reading = analogRead(0);
Serial.print("Reading ");
Serial.print(count);
Serial.print(" is ");
Serial.println(reading);
}
}

Random Number Generators (Tasks 34,35,36)

The following program writes a list of 100 random numbers on serial output
Code:
int value;
int count;
void setup(){
Serial.begin(9600);
delay(3000); //This delay allows for the serial monitor to be opened before the first number is generated
for (count = 0; count < 100; count++){
value = random(0,10);
Serial.println(value);
}
}
void loop(){
}

To give a more readable output we can alter the for loop:
for (count = 1; count < 101; count++){
value = random(0,11);
Serial.print(count);
Serial.print(". ");
Serial.println(value);
}

To generate averages from the above code it need to be altered slightly. On each cycle of the for loop it adds the randomized number to a total and then divides the total by 100. Code:
int value;
int count;
int total;

void setup(){
Serial.begin(9600);
randomSeed(analogRead(0));
delay(3000);
for (count = 1; count < 101; count++){
value = random(0,11);
total = total + value;
Serial.print(count);
Serial.print(". ");
Serial.println(value);
}
total = total / 100;
Serial.print("The average is ");
Serial.println(total);
}

void loop(){
}

Push Button, Digital Read (Tasks 30,31,32)

The below code uses digitalread() to check the state of a button and turn an LED on pin 13 on when pressed and off when not pressed.

int state = 0;
void setup(){
pinMode(13,OUTPUT);
pinMode(2,INPUT);
}
void loop(){
state = digitalRead(2); //Writes either HIGH or LOW to the state variable
if (state == HIGH){
digitalWrite(13,HIGH);
}
else{
digitalWrite(13,0);
}
}

Schematic:


To cause the program to do the opposite (have the LED on and turn off when the button is pressed) simply alter the if statement. Two alternatives are:
if (state != HIGH) or if (state == LOW)

Too add serial output referring to the LED and button state this is the new code:

int state = 0;
boolean change = HIGH;
void setup(){
pinMode(13,OUTPUT);
pinMode(2,INPUT);
Serial.begin(9600);
}
void loop(){
state = digitalRead(2);
if (state != HIGH){
digitalWrite(13,1);
if (change == HIGH){
Serial.println("LED On, Button Not Pressed");
change = !change;
}
}
else{
digitalWrite(13,0);
if (change == LOW){
Serial.println("LED Off, Button Pressed");
change = !change;
}
}
}

Friday, March 12, 2010

LED Project

This project takes a serial input of a single hex digit and displays it on a 7 segment display. The display is driven by only 2 data pins by the use of a shift register.

Fritzing Diagram:


Code:
int clock = 13;
int data = 12;
int input;

byte value[] = {B01111110,B00010010,B10111100,B10110110,B11010010,B11100110,B11101110,B00110010,B11111110,B11110110,B11111010,B11001110,B10001100,B10011110,B11101100,B11101000,B00000000}; //This is the byte patterns for the shift register stored in an array.

void setup()
{
pinMode(clock, OUTPUT);
pinMode(data , OUTPUT);
Serial.begin(9600);
}

void loop()
{
int i = Serial.read();
switch (i){ //This case statement takes the ASCII value read from serial and translates it to its corresponding index value in the array
case 48:{ input = 0;}
break;
case 49:{ input = 1;}
break;
case 50:{ input = 2;}
break;
case 51:{ input = 3;}
break;
case 52:{ input = 4;}
break;
case 53:{ input = 5;}
break;
case 54:{ input = 6;}
break;
case 55:{ input = 7;}
break;
case 56:{ input = 8;}
break;
case 57:{ input = 9;}
break;
case 65:{ input = 10;} //Values beyond 9 are letters A-F (65-70) and a-f(97-102)
break;
case 66:{ input = 11;}
break;
case 67:{ input = 12;}
break;
case 68:{ input = 13;}
break;
case 69:{ input = 14;}
break;
case 70:{ input = 15;}
break;
case 97:{ input = 10;}
break;
case 98:{ input = 11;}
break;
case 99:{ input = 12;}
break;
case 100:{ input = 13;}
break;
case 101:{ input = 14;}
break;
case 102:{ input = 15;}
break;
default: {input = 16;} //If no value is input this value will be chosen
}
if (input == 16){ //this loop flashes the centre bar of the display when no value has been read
shiftOut(data, clock, LSBFIRST, B10000000);
delay(1000);
shiftOut(data, clock, LSBFIRST, value[input]);
delay(1000);
}
else
{ //if a value has been read, it will display it on the display for 2 seconds then clear the display for 1
shiftOut(data, clock, LSBFIRST, value[input]);
delay(2000); //with no delay all segments stay on
shiftOut(data, clock, LSBFIRST, value[16]);
delay(1000);
}
}

Sunday, March 7, 2010

LED Project (Due Friday 12 March)

My project will consist of a 7 segment display run from a 74HC164 shift register. The 7 segment display will be able to display any hex character (0-9,a-f) input via serial from a computer. Code updates and pictures/videos to follow.

Thursday, March 4, 2010

Shift Registers

Lots of projects on sites like Make and Instructables make use of shift registers but what are they exactly? The most basic way to explain what they do is to say that they expand the number of digital pins available to use (with some downsides). A more complex way to explain them is to call them a cascade of flip-flops. What this means is that with only 2 data pins, you can control 8 (or more with different chips) digital outputs (but not inputs). A common chip used with Arduinos are 74HC164 (I got mine from Jaycar for $3.50 74HC164 8-bit Serial in/out Shift Register IC) and here is a project that gives a basic run down of the chip and some simple projects to use them in http://www.instructables.com/id/The-74HC164-Shift-Register-and-your-Arduino/. The below code is adapted from project two from the instructables link to emulate a program I wrote earlier ("snake" around a 7 segment display):

#define data 2
#define clock 3

byte zero = B11100000;
byte one = B01110000;
byte two = B10110000;
byte three = B10011000;
byte four = B10001100;
byte five = B00001110;
byte six = B10000110;
byte seven = B11000010;//these are variables that specify which pins should be turned on

void setup()
{
pinMode(clock, OUTPUT);
pinMode(data , OUTPUT);

void loop()
{
shiftOut(data, clock, LSBFIRST, zero);
delay(100);
shiftOut(data, clock, LSBFIRST, one);
delay(100);
shiftOut(data, clock, LSBFIRST, two);
delay(100);
shiftOut(data, clock, LSBFIRST, three);
delay(100);
shiftOut(data, clock, LSBFIRST, four);
delay(100);
shiftOut(data, clock, LSBFIRST, five);
delay(100);
shiftOut(data, clock, LSBFIRST, six);
delay(100);
shiftOut(data, clock, LSBFIRST, seven);
delay(100);
}

shiftOut is a specialised command for shift registers. the first two values specify the data pin (the pin which sends a high/low pattern) and the clock pin (this breaks up the individual values in one variable by cycling high/low to specify the end of a value). LSBFIRST is short for Last Significant Bit First and is used to specify in which order the byte pattern is loaded and then the byte pattern for the shift register to use (B11110000 for example will turn pins 1,2,3 and 4 on high from the shift register and 5,6,7 and 8 on low).

Analog Input (LDR) with Digital Output (7 Segment Display) (Task 27)

Addition to the program we wrote that read a value of an LDR and the output it to serial. This program takes that reading, divides it by 10 then outputs the value onto a 7 segment display. The board layout is that same as in the post titled "Combining Some New Concepts" :

int reading;
void setup() {
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
Serial.begin(9600);
}

void loop() {
reading = analogRead(0);
reading = reading/100;
digitalWrite(13,0);
digitalWrite(12,0);
digitalWrite(11,0);
digitalWrite(10,0);
digitalWrite(9,0);
digitalWrite(8,0);
digitalWrite(7,0); //resets all LEDs on segment
Serial.println(reading); //output value to serial for debugging and checking values
switch (reading) {
case 1:{
digitalWrite(10,1);
digitalWrite(7,1);}
break;
case 2:{
digitalWrite(13,1);
digitalWrite(11,1);
digitalWrite(10,1);
digitalWrite(9,1);
digitalWrite(8,1);}
break;
case 3:{
digitalWrite(13,1);
digitalWrite(11,1);
digitalWrite(10,1);
digitalWrite(8,1);
digitalWrite(7,1);}
break;
case 4:{
digitalWrite(13,1);
digitalWrite(12,1);
digitalWrite(10,1);
digitalWrite(7,1);}
break;
case 5:{
digitalWrite(13,1);
digitalWrite(12,1);
digitalWrite(11,1);
digitalWrite(8,1);
digitalWrite(7,1);}
break;
case 6:{
digitalWrite(13,1);
digitalWrite(12,1);
digitalWrite(11,1);
digitalWrite(9,1);
digitalWrite(8,1);
digitalWrite(7,1);}
break;
case 7:{
digitalWrite(11,1);
digitalWrite(10,1);
digitalWrite(7,1);}
break;
case 8:{
digitalWrite(13,1);
digitalWrite(12,1);
digitalWrite(11,1);
digitalWrite(10,1);
digitalWrite(9,1);
digitalWrite(8,1);
digitalWrite(7,1);}
break;
case 9:{
digitalWrite(13,1);
digitalWrite(12,1);
digitalWrite(11,1);
digitalWrite(10,1);
digitalWrite(8,1);
digitalWrite(7,1);}
break;
case 0:{
digitalWrite(12,1);
digitalWrite(11,1);
digitalWrite(10,1);
digitalWrite(9,1);
digitalWrite(8,1);
digitalWrite(7,1);} // if a value is above 999 or below 99 then the display will show 0
}
delay(500);
}

Tuesday, March 2, 2010

PWM RGB LED Part 2

This code is built of code from the previous post but works slightly different (namely it uses arrays and for loops rather than explicitly defining pins and value changes) and has a new feature: fading of each colour to both extremes and then back again:

boolean go = HIGH;
int pins [3] = {11,10,9};
int colours [3] = {0,0,0};
boolean dir [3] = {HIGH,HIGH,HIGH};

void setup() {
randomSeed(analogRead(5));
Serial.begin(9600);
}

void loop() {
if (go == HIGH){
go = !go;
for (int i = 0; i < 3; i ++){
colours[i] = random(1,255);
} //sets up initial values for cycling
}

for (int i = 0; i < 3; i ++){
if (dir[i] == HIGH){
colours[i] += 5;
if (colours[i] >= 250){ //if this value exceeds 255 then that colour will turn off resulting in a flash when it drops below 255 again
dir[i] = LOW;
}
}
else
{
colours[i] -= 5;
if (colours[i] <= 5){
dir[i] = HIGH;
}
}
analogWrite(pins[i],colours[i]);
}
delay(30);
}

EDIT

Did some playing around with the above code and now in the beginning loop when first assigning values it will also randomize the beginning direction of the colour value as well as randomizing the incrementing value.

First Attempt at Using Pulse Width Modulation

Bored (again) and wanted to play around with the RGB LED from the kit. After a bit of research and reading up on PWM with the Arduino I wrote this little program:

boolean go = HIGH;
int red;
int green;
int blue;

void setup() {
randomSeed(analogRead(5));
Serial.begin(9600);
}

void loop() {
if (go == HIGH){
go = !go;
red = random(1,255);
blue = random(1,255);
green = random(1,255);
analogWrite(11,blue);
analogWrite(10,green);
analogWrite(9,red);
Serial.print("red =");
Serial.println(red);
Serial.print("blue =");
Serial.println(blue);
Serial.print("green =");
Serial.println(green);
}
}

Basically the Arduino will generate three random numbers and use those values on the PWM pins to display a random colour with the RGB LED. These values are also sent via serial back to the PC to view. I wrote the program to only run once so to generate a new colour the reset button must be used. I was happy with how the program ran but disappointed with the physical output as the colours do not "blend" well enough.

Monday, March 1, 2010

Dark LDR, Turn on LED (Task 28)

Sinple program that reads the light levels from the LDR and will turn an LED if it is dark and off if it is light:

int reading;

void setup() {
pinMode(13,OUTPUT);
Serial.begin(9600);
}

void loop() {
reading = analogRead(0);
if (reading < 200) {digitalWrite(13,1);}
else
{digitalWrite(13,0);}
}

Catch Up on Missed Tasks (Tasks 4, 5)

I've been treating this as a sort of code dump so I'm going to catch up on some of my "wordy" tasks in this post.

4)Check out all the sites related to the list in the embedded notices blog.
Write a sentence about what each one does. You don't have to be very familiar with each one.

Arduino Environment: This is the compiler used for writing and uploading code to Arduinos. It also has a built in serial monitor for receiving feedback from the Arduinos.

Processing environment: This is an open source programming language that uses visual aids to teach people how to program.

GNU gcc: The GCC is the GNU Compiler Colelction. It is a set of compilers for C, C++, Fortran, Pascal, Java and Ada as well as others. Since these come under the GNU license they are all free and open source.

WikiEducator: A wiki specially for teachers and students that can be used for sharing resources.

Moodle: A free open source e-learning platform that is similar to BlackBoard.

Chip8: This is a specialized programming language and virtual machine for running old school 8 bit games.

Fritzing: A program that is similar to Crocodile Clips. It is used to document breadboard circuits and design PCB layouts. This software is free and open source.

Open Office: More free and open source software. The open office suite is a Microsoft Office replacement.

PeerWise: A website that can be used as a revision tool. Students can ask questions and receive answers as well as view other questions and answers asked by other students.

5) Find 4 more Arduino LED related videos in Youtube, BlipTV etc. Put a link and a two-sentence review about each one in your blog. Be prepared to talk about one or more of them.

Team Fortress 2 Kill Counter

The arduino is constantly monitoring for serial communication to display output from a separate program running on the computer. Once it receives the value via serial it displays it in binary on the LEDs.

LED matrix for an Umbrella

The umbrella has 80 LEDs that are all individually addressable. Its not running purely off an arduino but has a secondary microcontroller to allow the use of so many LEDs

POV Ceiling Fan

From the site instructables (http://www.instructables.com/id/Ceiling-Fan-LED-Display/). Each blade of the fan had a row of LEDs on them that flash on or off depending on what image is being displayed. The LEDs are controlled via shift registers.

Overclocked, Liquid Cooled Arduino

Still technically an LED project as the sketch flashes a single LED on and off.

Combining some new concepts

Working with some ideas i had yesterday with the 7 segment display and the LDRs. I wrote this small program this morning that runs a pattern across the display (this pattern is stored in an array) and the speed at which the pattern is run through is decided by an LDR:

int pattern[8] = {10,11,12,13,7,8,9,13};
int pri;
int sec;
int tri;
int rate;

void setup(){
pinMode(13,OUTPUT);
pinMode(12,OUTPUT);
pinMode(11,OUTPUT);
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
pinMode(8,OUTPUT);
pinMode(7,OUTPUT);
Serial.begin(9600);
}

void loop(){
for (int i = 0; i < 8; i++){
digitalWrite(pattern[pri],0);
digitalWrite(pattern[sec],0);
digitalWrite(pattern[tri],0);
tri = sec;
sec = pri;
pri = i;
digitalWrite(pattern[pri],1);
digitalWrite(pattern[sec],1);
digitalWrite(pattern[tri],1);
rate = analogRead(0);
delay(rate);
}
}

The bread board is set out identical to dice part 2 except the button is replaced with an LDR.