Digital for Arduino

From LVL1
Jump to navigation Jump to search

This Page documents a series of workshops taught in 2012. Feel free to use the items for reference.

Digital.png

Digital electronics for Arduino Workshop. Taught and designed by Brian Wagner.

SIGN UP HERE http://digitalarduino.eventbrite.com

We will build and program an electronic game and in the process learn LED's, tri-color LED's, pushbutton switches, speakers and Arduino programming.


You must bring your own Arduino or clone!


You will need to have an Arduino or an Arduino clone to participate in this workshop. They can be purchased online (but be aware of shipping times) or at a local Radio shack http://www.radioshack.com/product/index.jsp?productId=12268262 You will need to have a USB cable to connect to your computer.


Other Arduino retailers

Adafruit http://www.adafruit.com/products/50

Sparkfun http://www.sparkfun.com/products/9950

Solarbotics (Canada - can have slower shipping) http://www.solarbotics.com/products/28920/

Seeed studios http://www.seeedstudio.com/depot/seeeduino-v30-atmega-328p-p-669.html?cPath=132_133 Cheapest around, but they come from HK so they take a while to get.

Again, do not forget the USB cable

You can also use a serial based Arduino such as the Diavolina ($13!!!), but you need a $20 cable! http://evilmadscience.com/productsmenu/tinykitlist/180


You will also need to bring a laptop computer for programming your Arduino. We will show you how!


All other supplies are included in the cost of the workshop (wire, leds, switch, solderless breadboard, speaker, etc)


LVL1 has snacks and sodas available for purchase, but you can bring your own if you want.


Here is the Poster so you can print and hang in your favorite coffee shop. File:Digital.pdf


The Class

As we work through the parts below, do not remove the parts as you go. I have set this up so that by the end, the whole circuit game is built! I have taken parts of a couple of other classes to create this class. For the most part, the code is the same, but sometimes I had to rewire the circuit so the code has changed. I have posted the changes.

Part 1

Install the Arduino software and get your development system going. Be sure to run power and ground to the Arduino.

http://wiki.lvl1.org/1st_Inning


Part 2

Blinky Light - Get one LED blinking. This Blinkey light is hooked up to pin 13, but this is not the last light in the cylon lights, so please give room on your breadboard for one more LED to the left.

You can run the code in the Arduino development File->Examples->Basics->Blink. This blinking code is a very useful way to see if your Arduino is working. Some Arduino boards have a LED already installed to Pin D13 just for testing purposes.

http://wiki.lvl1.org/2nd_Inning

Part 3

2012-01-28 0001.jpg

Cylon lights - Battlestar Galactica or KITT from Knight Rider - take your pick. In this part we will use pin A0 instead of digital pin 6. I need the PWM capabilities of digital pin 6 for the tri-color LED. Pin A0 (as well as all the analog pins) can be used as digital pins. A0 can be thought of as D14.

Go ahead and build the circuit on the breadboard. You will want to keep the LEDS close to each other. I spaced them two columns apart from each other on the breadboard.

http://wiki.lvl1.org/Cylon_LEDs

And the code specific to having A0 used instead of D6:

//Code for Cylon - I am sure this could be more elegant!
//bpw 2/11/22
//modified for Pin A0 bpw 1/28/12

int pinled1 = 7; 
int pinled2 = 8; 
int pinled3 = 9;
int pinled4 = 10;
int pinled5 = 11;
int pinled6 = 12;
int pinled7 = 13;
int pinled8 = 14;  //Pin 14 is the same as A0.  You can use A0 as a digital pin!
int t = 50; 
void setup() 
{
pinMode(pinled1, OUTPUT);
pinMode(pinled2, OUTPUT);
pinMode(pinled3, OUTPUT);
pinMode(pinled4, OUTPUT);
pinMode(pinled5, OUTPUT);
pinMode(pinled6, OUTPUT);
pinMode(pinled7, OUTPUT);
pinMode(pinled8, OUTPUT);
}

void loop() 
{
digitalWrite(pinled1, HIGH); 
delay(t); 
digitalWrite(pinled2, HIGH);
delay(t);
digitalWrite(pinled1, LOW);
delay(t);
digitalWrite(pinled3, HIGH);
delay(t);
digitalWrite(pinled2, LOW);
delay(t);
digitalWrite(pinled4, HIGH);
delay(t);
digitalWrite(pinled3, LOW);
delay(t);
digitalWrite(pinled5, HIGH);
delay(t);
digitalWrite(pinled4, LOW);
delay(t);
digitalWrite(pinled6, HIGH);
delay(t);
digitalWrite(pinled5, LOW);
delay(t);
digitalWrite(pinled7, HIGH);
delay(t);
digitalWrite(pinled6, LOW);
delay(t);
digitalWrite(pinled8, HIGH);
delay(t);
digitalWrite(pinled7, LOW);
delay(t);
digitalWrite(pinled7, HIGH);
delay(t);
digitalWrite(pinled8, LOW);
delay(t);
digitalWrite(pinled6, HIGH);
delay(t);
digitalWrite(pinled7, LOW);
delay(t);
digitalWrite(pinled5, HIGH);
delay(t);
digitalWrite(pinled6, LOW);
delay(t);
digitalWrite(pinled4, HIGH);
delay(t);
digitalWrite(pinled5, LOW);
delay(t);
digitalWrite(pinled3, HIGH);
delay(t); 
digitalWrite(pinled4, LOW);
delay(t);
digitalWrite(pinled2, HIGH);
delay(t);
digitalWrite(pinled3, LOW);
delay(t);
digitalWrite(pinled1, HIGH);
delay(t);
digitalWrite(pinled2, LOW);
delay(t);

}

Part 4

Tri-Color LED. The Tricolor LED is set to use pins D6, D5, and D3. Those are Pulse Width Modulation pins. The Common Cathode is the longer pin and it is connected to Ground. I accidentally gave you all 100K ohm resistors, so I need to swap those out with 1K resistors during the class.

http://wiki.lvl1.org/3rd_Inning

Here is the code to check your tricolor LED

//This code comes from...
//http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207331496
//modified to just go through a pretty color loop!
//use tools->serial monitor to watch the values
//bpw 5/10/10


int rpin = 3;    // RED pin of the LED to PWM pin 3 
int gpin = 5;  // GREEN pin of the LED to PWM pin 5
int bpin = 6;   // BLUE pin of the LED to PWM pin 6

int r=0, g=0, b=0;
float h;


void h2rgb(float h, int &R, int &G, int &B);

void setup()                    // run once, when the sketch starts
{
   Serial.begin(9600);    
}


void loop()                     // run over and over again
{
  
  for (int val = 0; val <1024; val++) {
    h = ((float)val)/1024;

    h2rgb(h,r,g,b);
    Serial.println (val) ;
    Serial.println (h) ;
    Serial.println (r) ;
    Serial.println (g) ;
    Serial.println (b) ;
    Serial.println ("  ") ;

    analogWrite(rpin, r);
    analogWrite(gpin, g);
    analogWrite(bpin, b);
    //delay(50);
  }
}

void h2rgb(float H, int& R, int& G, int& B) {

  int var_i;
  float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  if ( S == 0 )                       //HSV values = 0 ÷ 1
  {
    R = V * 255;
    G = V * 255;
    B = V * 255;
  }
  else
  {
    var_h = H * 6;
    if ( var_h == 6 ) var_h = 0;      //H must be < 1
    var_i = int( var_h ) ;            //Or ... var_i = floor( var_h )
    var_1 = V * ( 1 - S );
    var_2 = V * ( 1 - S * ( var_h - var_i ) );
    var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

    if      ( var_i == 0 ) {
      var_r = V     ;
      var_g = var_3 ;
      var_b = var_1 ;
    }
    else if ( var_i == 1 ) {
      var_r = var_2 ;
      var_g = V     ;
      var_b = var_1 ;
    }
    else if ( var_i == 2 ) {
      var_r = var_1 ;
      var_g = V     ;
      var_b = var_3 ;
    }
    else if ( var_i == 3 ) {
      var_r = var_1 ;
      var_g = var_2 ;
      var_b = V     ;
    }
    else if ( var_i == 4 ) {
      var_r = var_3 ;
      var_g = var_1 ;
      var_b = V     ;
    }
    else                   {
      var_r = V     ;
      var_g = var_1 ;
      var_b = var_2 ;
    }

    R = (1-var_r) * 255;                  //RGB results = 0 ÷ 255
    G = (1-var_g) * 255;
    B = (1-var_b) * 255;
  }
}
 


Part 5

Push Button Switch - You will have to solder some leads onto your switch. Use longer wires, they are easier to work with. Run the code below to test your switch.

http://wiki.lvl1.org/5th_Inning

/* Basic Digital Read
 * ------------------ 
 *
 * turns on and off a light emitting diode(LED) connected to digital  
 * pin 13, when pressing a pushbutton attached to pin 2. It illustrates the
 * concept of Active-Low, which consists in connecting buttons using a
 * 1K to 10K pull-up resistor.
 *
 * Created 1 December 2005
 * copyleft 2005 DojoDave <http://www.0j0.org>
 * http://arduino.berlios.de
 *
 */

int ledPin = 13; // choose the pin for the LED
int inPin = 2;   // choose the input pin (for a pushbutton)
int val = 0;     // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);  // declare LED as output
  pinMode(inPin, INPUT);    // declare pushbutton as input
  digitalWrite(inPin,HIGH);  //engages internal pullup resistor
}

void loop(){
  val = digitalRead(inPin);  // read input value
  if (val == HIGH) {         // check if the input is HIGH (button released)
    digitalWrite(ledPin, LOW);  // turn LED OFF
  } else {
    digitalWrite(ledPin, HIGH);  // turn LED ON
  }
}

Part 6

Speaker - Lets make some noise. Follow the instructions on 9th Inning. You should be able to get some sound out of your Arduino. You will have to solder a couple of leads to the speaker to hook it up. The speaker has 8 ohms resistance, so be sure to use the 1K resistor in series. It really does not matter if you put the resistor between the speaker and D4 or the speaker and ground.

http://wiki.lvl1.org/9th_Inning

Part 7

Put it all together and make a game. With all the components in place, I made a game that uses a pushbutton switch to stop the cylon lights at the precise moment the tri-color LED is lit. I had to use interrupts, which is an advanced Arduino topic. You can read about that here: http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/

The program plays a song and makes pretty lights if you win. If you do not win, it tells you how far away you are. Programming this game was only a matter of putting the pieces together. If you need help learning C, I would suggest just using a lot of cut and paste code to piece things together. Also, here is a good website tutorial: http://www.cprogramming.com/tutorial/c-tutorial.html

Thanks for letting me show you digital electronics for the Arduino Brian (brian (at) lvl1.org)

Here is the game code:

//Stop the LED game.
//see http://wiki.lvl1.org/Digital_for_Arduino for details
// bpw 1/28/12

//musical constancts
 #define NOTE_B0  31
 #define NOTE_C1  33
 #define NOTE_CS1 35
 #define NOTE_D1  37
 #define NOTE_DS1 39
 #define NOTE_E1  41
 #define NOTE_F1  44
 #define NOTE_FS1 46
 #define NOTE_G1  49
 #define NOTE_GS1 52
 #define NOTE_A1  55
 #define NOTE_AS1 58
 #define NOTE_B1  62
 #define NOTE_C2  65
 #define NOTE_CS2 69
 #define NOTE_D2  73
 #define NOTE_DS2 78
 #define NOTE_E2  82
 #define NOTE_F2  87
 #define NOTE_FS2 93
 #define NOTE_G2  98
 #define NOTE_GS2 104
 #define NOTE_A2  110
 #define NOTE_AS2 117
 #define NOTE_B2  123
 #define NOTE_C3  131
 #define NOTE_CS3 139
 #define NOTE_D3  147
 #define NOTE_DS3 156
 #define NOTE_E3  165
 #define NOTE_F3  175
 #define NOTE_FS3 185
 #define NOTE_G3  196
 #define NOTE_GS3 208
 #define NOTE_A3  220
 #define NOTE_AS3 233
 #define NOTE_B3  247
 #define NOTE_C4  262
 #define NOTE_CS4 277
 #define NOTE_D4  294
 #define NOTE_DS4 311
 #define NOTE_E4  330
 #define NOTE_F4  349
 #define NOTE_FS4 370
 #define NOTE_G4  392
 #define NOTE_GS4 415
 #define NOTE_A4  440
 #define NOTE_AS4 466
 #define NOTE_B4  494
 #define NOTE_C5  523
 #define NOTE_CS5 554
 #define NOTE_D5  587
 #define NOTE_DS5 622
 #define NOTE_E5  659
 #define NOTE_F5  698
 #define NOTE_FS5 740
 #define NOTE_G5  784
 #define NOTE_GS5 831
 #define NOTE_A5  880
 #define NOTE_AS5 932
 #define NOTE_B5  988
 #define NOTE_C6  1047
 #define NOTE_CS6 1109
 #define NOTE_D6  1175
 #define NOTE_DS6 1245
 #define NOTE_E6  1319
 #define NOTE_F6  1397
 #define NOTE_FS6 1480
 #define NOTE_G6  1568
 #define NOTE_GS6 1661
 #define NOTE_A6  1760
 #define NOTE_AS6 1865
 #define NOTE_B6  1976
 #define NOTE_C7  2093
 #define NOTE_CS7 2217
 #define NOTE_D7  2349
 #define NOTE_DS7 2489
 #define NOTE_E7  2637
 #define NOTE_F7  2794
 #define NOTE_FS7 2960
 #define NOTE_G7  3136
 #define NOTE_GS7 3322
 #define NOTE_A7  3520
 #define NOTE_AS7 3729
 #define NOTE_B7  3951
 #define NOTE_C8  4186
 #define NOTE_CS8 4435
 #define NOTE_D8  4699
 #define NOTE_DS8 4978

//This program uses interrupts - read here http://www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/
#include <avr/interrupt.h>


int pinled1 = 7; 
int pinled2 = 8; 
int pinled3 = 9;
int pinled4 = 10;
int pinled5 = 11;
int pinled6 = 12;
int pinled7 = 13;
int pinled8 = 14;  //Pin 14 is the same as A0.  You can use A0 as a digital pin!
int t = 50; 

int rpin = 3;    // RED pin of the LED to PWM pin 3 
int gpin = 5;  // GREEN pin of the LED to PWM pin 5
int bpin = 6;   // BLUE pin of the LED to PWM pin 6

int beeptone = 200;

volatile int GameOver;
volatile int CurrLoc;
volatile int Score;

int r=0, g=0, b=0;
float h;

void h2rgb(float h, int &R, int &G, int &B);
void pin2ISR();

 // notes in the melody:
 int melody[] = {
   NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
 // note durations: 4 = quarter note, 8 = eighth note, etc.:
 int noteDurations[] = {
   4, 8, 8, 4,4,4,4,4 };
int thisNote;
int noteDuration;
int pauseBetweenNotes ;
int i;


void setup() 
{
pinMode(pinled1, OUTPUT);
pinMode(pinled2, OUTPUT);
pinMode(pinled3, OUTPUT);
pinMode(pinled4, OUTPUT);
pinMode(pinled5, OUTPUT);
pinMode(pinled6, OUTPUT);
pinMode(pinled7, OUTPUT);
pinMode(pinled8, OUTPUT);

//set up the interrupt for the switch on pin2
pinMode(2, INPUT);
digitalWrite(2, HIGH);    // Enable pullup resistor
attachInterrupt(0, pin2ISR, FALLING);
GameOver = 0;
CurrLoc = 10;
Score = 10;
}


void loop() 
{

do  {

    digitalWrite(pinled1, HIGH); 
    delay(t); 
    digitalWrite(pinled2, HIGH);
    CurrLoc = 2;
    delay(t);
    digitalWrite(pinled1, LOW);
    delay(t);
    digitalWrite(pinled3, HIGH);
    CurrLoc = 3;
    delay(t);
    digitalWrite(pinled2, LOW);
    delay(t);
    digitalWrite(pinled4, HIGH);
    CurrLoc = 4;
    delay(t);
    digitalWrite(pinled3, LOW);
    delay(t);
    digitalWrite(pinled5, HIGH);
    CurrLoc = 5;
    delay(t);
    digitalWrite(pinled4, LOW);
    delay(t);
    digitalWrite(pinled6, HIGH);
    CurrLoc = 6;
    delay(t);
    digitalWrite(pinled5, LOW);
    delay(t);
    digitalWrite(pinled7, HIGH);
    CurrLoc = 7;
    delay(t);
    digitalWrite(pinled6, LOW);
    delay(t);
    digitalWrite(pinled8, HIGH);
    CurrLoc = 8;
    delay(t);
    digitalWrite(pinled7, LOW);
    delay(t);
    digitalWrite(pinled7, HIGH);
    CurrLoc = 7;
    delay(t);
    digitalWrite(pinled8, LOW);
    delay(t);
    digitalWrite(pinled6, HIGH);
    CurrLoc = 6;
    delay(t);
    digitalWrite(pinled7, LOW);
    delay(t);
    digitalWrite(pinled5, HIGH);
    CurrLoc = 5;
    delay(t);
    digitalWrite(pinled6, LOW);
    delay(t);
    digitalWrite(pinled4, HIGH);
    CurrLoc = 4;
    delay(t);
    digitalWrite(pinled5, LOW);
    delay(t);
    digitalWrite(pinled3, HIGH);
    CurrLoc = 3;
    delay(t); 
    digitalWrite(pinled4, LOW);
    delay(t);
    digitalWrite(pinled2, HIGH);
    CurrLoc = 2;
    delay(t);
    digitalWrite(pinled3, LOW);
    delay(t);
    digitalWrite(pinled1, HIGH);
    delay(t);
    digitalWrite(pinled2, LOW);
    delay(t);
    digitalWrite(pinled1, LOW);
    delay(t);
    CurrLoc = 1; //only here do we win
    digitalWrite(bpin, HIGH);  //pull the blue high
    digitalWrite(rpin, HIGH);  //pull the red high - to make a nice purple
    delay(t);
    tone(4, beeptone += 50, 100);  //incrementing beeps as the game goes further
    if (beeptone > 800) { beeptone = 200; }
    digitalWrite(bpin, LOW);
    digitalWrite(rpin, LOW);
    delay(t);
} while (GameOver < 1 );

if (Score == 1) {
  
   for (i=1;i<10;i++){
   for (int val = 0; val <1024; val++) {
    h = ((float)val)/1024;

    h2rgb(h,r,g,b);
    analogWrite(rpin, r);
    analogWrite(gpin, g);
    analogWrite(bpin, b);
    //delay(10);
    }}
    
    //Play the song
    for ( thisNote = 0; thisNote < 8; thisNote++) {
       noteDuration = 1000/noteDurations[thisNote];
       tone(4, melody[thisNote],noteDuration);
       pauseBetweenNotes = noteDuration * 1.30;
       delay(pauseBetweenNotes);
    }
    //Turn off the LEDs
    digitalWrite(bpin, LOW);  
    digitalWrite(rpin, LOW);  
    digitalWrite(gpin, LOW);  
}
else {
    for (i=1; i<Score; i++) {
      tone(4, 800, 200);
      delay(500);
    }
}


//we timed out - game over - reset to start again
beeptone = 200;
GameOver = 0;
Score = 10;
CurrLoc = 10;
digitalWrite(14, HIGH); 

}



// Interrupt Service Routine attached to INT0 vector
void pin2ISR()
{
    digitalWrite(14, HIGH);    // Make Pin 14 high to indicate switch is engaged
    GameOver = 1;
    Score = CurrLoc;

}


void h2rgb(float H, int& R, int& G, int& B) {

  int var_i;
  float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  if ( S == 0 )                       //HSV values = 0 ÷ 1
  {
    R = V * 255;
    G = V * 255;
    B = V * 255;
  }
  else
  {
    var_h = H * 6;
    if ( var_h == 6 ) var_h = 0;      //H must be < 1
    var_i = int( var_h ) ;            //Or ... var_i = floor( var_h )
    var_1 = V * ( 1 - S );
    var_2 = V * ( 1 - S * ( var_h - var_i ) );
    var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

    if      ( var_i == 0 ) {
      var_r = V     ;
      var_g = var_3 ;
      var_b = var_1 ;
    }
    else if ( var_i == 1 ) {
      var_r = var_2 ;
      var_g = V     ;
      var_b = var_1 ;
    }
    else if ( var_i == 2 ) {
      var_r = var_1 ;
      var_g = V     ;
      var_b = var_3 ;
    }
    else if ( var_i == 3 ) {
      var_r = var_1 ;
      var_g = var_2 ;
      var_b = V     ;
    }
    else if ( var_i == 4 ) {
      var_r = var_3 ;
      var_g = var_1 ;
      var_b = V     ;
    }
    else                   {
      var_r = V     ;
      var_g = var_1 ;
      var_b = var_2 ;
    }

    R = (1-var_r) * 255;                  //RGB results = 0 ÷ 255
    G = (1-var_g) * 255;
    B = (1-var_b) * 255;
  }
}