Friday, June 29, 2012

A redesign of the lego car for Arduino


Very exciting... I tried uploading all of the code over the weekend and the car works much better.
I also did a redesign of the variable speed and it is so much better.  I still need to add smoothing to the ping sensors.  I think it will help more.  These things will hopefully happen on Tuesday this week.
----------------------------------------

On Wednesday, I finished the lego car and uploaded the code, which is posted below.  It was moderatly okay, after I fixed many issues with speed and power.  But it was not good enough so I had to ponder the power issues I was having.  The main problem was that variable speed equation ran the power from 0 to 255 as from the arduino outputs.  This however also meant that the voltage to the motor was from 0 to 12 volts.  And so, it did not work so well.

After pondering the issue for a while, I realized that I needed to set my equation so that the voltage would be between about 10 and 12 volts.  That might translate into 200 to 255 on the arduino.  I have not done this yet but will put it into the next round.

The other issue was that I was spinning my gear ratio from the motor to the wheels was a 1:1.  This is not how electric motors are meant to work.  They need high spinning speeds to low spinning wheels.   So I also put this mechanical change into the next model.

The final issue was that when having a rear wheel turning, the back end actually pushes out to one side or the other which, when close to a side wall, was enough to steer the back end into the wall.  You will see this in the video.


This is a video of the first Lego Car.  It drives with only the input from two Ping Sensors pointing right and left and one IR Sensor pointing front.

This is the new design of the Lego Car.  It has the same sensors but is now front wheel drive.  The front wheels can still turn 360 degrees as in the previous model.

-------------------------
This code is updated and better then previous versions.
Note::  You need to have the NewPing.h library which is avail from the Arduino Libraries.


// for the IR Sensor
int IRpin = 0;                                    // analog pin for reading the IR sensor
float volts = 0;   // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
float forward_distance = 0;          // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk

// for both ping sensors
  #include <NewPing.h>

  #define trig_right  8  // Arduino pin tied to trigger pin on ping sensor.
  #define echo_right  9  // Arduino pin tied to echo pin on ping sensor.
  #define max_distance_right 200 // Maximum distanceance we want to ping for (in centimeters). Maximum sensor distanceance is rated at 400-500cm.
  NewPing sonar_right(trig_right, echo_right, max_distance_right); // NewPing setup of pins and maximum distanceance.
  unsigned int pingSpeed_right = 50;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
  unsigned long pingTimer_right = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
  int cm_right = 50;

  #define trig_left  12  // Arduino pin tied to trigger pin on ping sensor.
  #define echo_left  13  // Arduino pin tied to echo pin on ping sensor.
  #define max_distance_left 200 // Maximum distanceance we want to ping for (in centimeters). Maximum sensor distanceance is rated at 400-500cm.
  NewPing sonar_left(trig_left, echo_left, max_distance_left); // NewPing setup of pins and maximum distanceance.
  unsigned int pingSpeed_left = 50;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
  unsigned long pingTimer_left = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
  int cm_left = 50;
  
// for the stearing servo
  #include <Servo.h>
  Servo myservo;
  int center = 75;                //the center position for the servo is 90 degrees

// for the dirve 
  int motor = 11;                 //When doing analog, you must use int and not define.
  int motor_speed = 0;
  
void IR_1(){
  volts = analogRead(IRpin)*0.0048828125;   // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
  forward_distance = 65*pow(volts, -1.10);          // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk
  if(forward_distance <= 30)                           //this is the domain of the sensor, 30 to 140 cm.
    forward_distance = 30;
  if(forward_distance >= 140)
    forward_distance = 140;
  motor_speed = 155*forward_distance/110-30*155/110+150;    //this is the equation for variable motor speed.
  if(forward_distance == 30){                              //  this 155 corrisponds to 30 cm.  I want the motor turned off!
    motor_speed = 0;
  }
//  motor_speed = (255/110)*(forward_distance-30);       //this is used for when there is an LED Test Light in Place
  Serial.print(forward_distance);                       // print the distance
  Serial.print("cm Forward Distance     ");
  Serial.print(motor_speed);
  Serial.println("mph domain is 155 to 255");
}

void Ping_Right(){
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distanceance pings.
  if (millis() >= pingTimer_right) {       // pingSpeed_1 milliseconds since last ping, do another ping.
    pingTimer_right += pingSpeed_right;    // Set the next ping time.
    cm_right = sonar_right.ping_cm();      // Send out the ping, get the results in centimeters.
  if(cm_right <= 15)                       //this is the domain of the sensor.  15 to 60 cm.
    cm_right = 15;
  if(cm_right >= 60)
    cm_right = 60;
    Serial.print(cm_right);          // Print the result (0 = outside the set distanceance range, no ping echo)
    Serial.println(" cm Ping Sensor RIGHT");
    delay(10);
  }
}

void Ping_Left(){
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distanceance pings.
  if (millis() >= pingTimer_left) {       // pingSpeed_1 milliseconds since last ping, do another ping.
    pingTimer_left += pingSpeed_left;     // Set the next ping time.
    cm_left = sonar_left.ping_cm();       // Send out the ping, get the results in centimeters.
  if(cm_left <= 15)                       //this is the domain of the sensor.  15 to 60 cm.
    cm_left = 15;
  if(cm_left >= 60)
    cm_left = 60;
    Serial.print(cm_left);          // Print the result (0 = outside the set distanceance range, no ping echo)
    Serial.println(" cm Ping Sensor LEFT");
  }
}

void setup() {
  Serial.begin(9600);                             // start the serial port
  myservo.attach(7);
  myservo.write(center);

}

void loop() {
  IR_1();
  while (forward_distance >= 70 && forward_distance <= 140){           //Variable speed, No Turns
    analogWrite(motor, motor_speed);
    myservo.write(center);
    IR_1();
    Serial.println("---#1  Variable speed, No Turns");
  }
  while (forward_distance >= 50 && forward_distance < 70){              //Variable speed, Little Turns
    analogWrite(motor, motor_speed);
    Ping_Right();
    Ping_Left();
    if (cm_right > cm_left){
      myservo.write(center - 25);
    Serial.println("---#3 Turn a Little Left");
    }
    else {
      myservo.write(center + 25);
    Serial.println("---#4 Turn a Little Right");
    }
    IR_1();
  }  
  while (forward_distance >= 30 && forward_distance < 50){              //Variable speed, big Turns
    analogWrite(motor, motor_speed);
    Ping_Right();
    Ping_Left();
    if (cm_right > cm_left){
      myservo.write(center - 45);
    Serial.println("---#6 Turn a lot Left");
    }
    else {
      myservo.write(center + 45);
    Serial.println("---#7 Turn a lot Right");
    }
    IR_1();
  }  
}

Monday, June 25, 2012

Two ping and 1 IR sensor

This is a rough working bit of code for two ping sensors I intend on pointing to the sides of the car while the IR sensor points forward.

I have set up each sensor as a seperate function so I can only call the part of the code that I need.  It runs pretty fast but is a little jumpy.  I want to still figure out a way to get a more variable turn on the servo.  I think that will be by smoothing those sensors and then getting an avg. difference.  Somehow using that number to add or subtract the degree of the turn from center position

The speed of the motor is based on the distance from an object.  Still need to work out the situation where it will go very slow and just how slow the actual motor can spin while attached to a lego car. Not sure about that either at the moment.

The sharp IR sensor and Arduino Board


The code is below.  Such fun pondering this stuff.
---------------------------------------



// for the IR Sensor
int IRpin = 0;                                    // analog pin for reading the IR sensor
float volts = 0;   // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
float forward_distance = 0;          // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk

// for both ping sensors
  #include <NewPing.h>
  int p_d = 0;               //the value for the difference between ping sensors

  #define trig_right  2  // Arduino pin tied to trigger pin on ping sensor.
  #define echo_right  3  // Arduino pin tied to echo pin on ping sensor.
  #define max_distance_right 200 // Maximum distanceance we want to ping for (in centimeters). Maximum sensor distanceance is rated at 400-500cm.
  NewPing sonar_right(trig_right, echo_right, max_distance_right); // NewPing setup of pins and maximum distanceance.
  unsigned int pingSpeed_right = 50;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
  unsigned long pingTimer_right = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
  int cm_right = 50;

  #define trig_left  12  // Arduino pin tied to trigger pin on ping sensor.
  #define echo_left  13  // Arduino pin tied to echo pin on ping sensor.
  #define max_distance_left 200 // Maximum distanceance we want to ping for (in centimeters). Maximum sensor distanceance is rated at 400-500cm.
  NewPing sonar_left(trig_left, echo_left, max_distance_left); // NewPing setup of pins and maximum distanceance.
  unsigned int pingSpeed_left = 50;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
  unsigned long pingTimer_left = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
  int cm_left = 50;

// for the stearing servo
  #include <Servo.h>
  Servo myservo;
  int center = 90;                //the center position for the servo is 90 degrees

// for the dirve
  int motor = 11;                 //When doing analog, you must use int and not define.
  int motor_speed = 0;

void IR_1(){
  volts = analogRead(IRpin)*0.0048828125;   // value from sensor * (5/1024) - if running 3.3.volts then change 5 to 3.3
  forward_distance = 65*pow(volts, -1.10);          // worked out from graph 65 = theretical distance / (1/Volts)S - luckylarry.co.uk
  if(forward_distance <= 30)                           //this is the domain of the sensor, 30 to 140 cm.
    forward_distance = 30;
  if(forward_distance >= 140)
    forward_distance = 140;
  motor_speed = (205/110)*(forward_distance-30)+50;    //this is the equation for variable motor speed.
//  motor_speed = (255/110)*(forward_distance-30);       //this is used for when there is an LED Test Light in Place
  Serial.print(forward_distance);                       // print the distance
  Serial.println(" cm Forward Distance");
}

void Ping_Right(){
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distanceance pings.
  if (millis() >= pingTimer_right) {       // pingSpeed_1 milliseconds since last ping, do another ping.
    pingTimer_right += pingSpeed_right;    // Set the next ping time.
    cm_right = sonar_right.ping_cm();      // Send out the ping, get the results in centimeters.
  if(cm_right <= 15)                       //this is the domain of the sensor.  15 to 60 cm.
    cm_right = 15;
  if(cm_right >= 60)
    cm_right = 60;
    Serial.print(cm_right);          // Print the result (0 = outside the set distanceance range, no ping echo)
    Serial.println(" cm Ping Sensor RIGHT");
    delay(10);
  }
}

void Ping_Left(){
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distanceance pings.
  if (millis() >= pingTimer_left) {       // pingSpeed_1 milliseconds since last ping, do another ping.
    pingTimer_left += pingSpeed_left;     // Set the next ping time.
    cm_left = sonar_left.ping_cm();       // Send out the ping, get the results in centimeters.
  if(cm_left <= 15)                       //this is the domain of the sensor.  15 to 60 cm.
    cm_left = 15;
  if(cm_left >= 60)
    cm_left = 60;
    Serial.print(cm_left);          // Print the result (0 = outside the set distanceance range, no ping echo)
    Serial.println(" cm Ping Sensor LEFT");
  }
}

void ping_difference(){
  p_d = cm_left - cm_right;
  Serial.print(p_d);
  Serial.println(" Ping Difference");
}

void setup() {
  Serial.begin(9600);                             // start the serial port
  myservo.attach(7);
  myservo.write(50);

}

void loop() {
  IR_1();
  while (forward_distance == 140){                                    //Full Speed, Lots of Room
    analogWrite(motor, 255);
    myservo.write(center);
    IR_1();
    Serial.println("---#1  Full Speed, No Turns");
  }
  while (forward_distance >= 50 && forward_distance < 140){           //Variable speed, No Turns
    analogWrite(motor, motor_speed);
    myservo.write(center);
    IR_1();
    Serial.println("---#2  Variable speed, No Turns");
  }
  while (forward_distance >= 40 && forward_distance < 50){              //Variable speed, Little Turns
    analogWrite(motor, motor_speed);
    Ping_Right();
    Ping_Left();
    ping_difference();
    if (p_d > 0){
      myservo.write(center - 35);
    Serial.println("---#3 Turn a Little Left");
    }
    else {
      myservo.write(center + 35);
    Serial.println("---#4 Turn a Little Right");
    }
    delay (700);
    IR_1();
  }
  while (forward_distance >= 30 && forward_distance < 40){              //Variable speed, Little Turns
    analogWrite(motor, motor_speed);
    Ping_Right();
    Ping_Left();
    ping_difference();
    if (p_d > 0){
      myservo.write(center - 65);
    Serial.println("---#6 Turn a lot Left");
    }
    else {
      myservo.write(center + 65);
    Serial.println("---#7 Turn a lot Right");
    }
    delay(700);
    IR_1();
  }
}

Friday, June 22, 2012

1st Lego Prototype for Arduino Robot

I finished making the first model for my Arduino robot.  It's features are a rear wheel drive, with differential, and 360 degree turning.  I will try to mount the electronics on Monday.



Much Better Ping Code

Wednesday was an exciting day for us.  Because of the simple question, "If we are struggling with this, don't you think that someone else has already figured this out??"  So we looked into the Ping Sensor Bad Data issue and found that on the Arduino.cc site, there was a new library and sketch for the ping sensor we were using.  This new code got rid of the delay that occurs when there was an error reading, and returns a 0 instead of a delay.  So we just wrote out the 0 by using an "if" statement and life is better.

The code is below.  I still need to tweak a bit and am thinking that I may want to use three sensors.  There is still the issue that the ping sensor can't detect very well at angles greater then 45 degrees.
I will also try the Infrared Distance Sensors as a remedy to this problem.

Code
---------------------------------

//Two Ping Sensors with one Motor and one Servo

//This code is for controling a single motor and a servo with a pair of ping sensors (4-pin, HC-SR04).
//Orginally used for a Lego Technics car that self drives around a room
//by Philip Leete

//Define information about ping sensors
#include <NewPing.h>

#define TRIGGER_PIN_R  2  // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN_R     3  // Arduino pin tied to echo pin on ping sensor.
#define TRIGGER_PIN_L  8  // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN_L     9  // Arduino pin tied to echo pin on ping sensor.
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
int distance_R = 0;
int distance_L = 0;

NewPing sonar_R(TRIGGER_PIN_R, ECHO_PIN_R, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
NewPing sonar_L(TRIGGER_PIN_L, ECHO_PIN_L, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

unsigned int pingSpeed_R = 50;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer_R = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.
unsigned int pingSpeed_L = 50;  // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer_L = 75; // Holds the next ping time, start at 75ms to give time for the Arduino pins to stabilize.

//This sections is required for the smoothing
const int numReadings = 2;
int readings_R[numReadings];
int readings_L[numReadings];                               // the readings from the analog input
int index_R = 0,             index_L = 0;                  // the index of the current reading
int total_R = 0,             total_L = 0;                  // the running total
int average_R = 0,           average_L = 0;                // the average of the light values
int difference = 0;
int counter = 0;                                           // this counter will be used to start/stop sensors

//Define information about motors
#define fwd_motor 6                    //fwd motor connected to digital pin 6
#define rev_motor 11                   //rev motor connected to digital pin 11
int rev_motor_speed = 0;               //a integer to be used to determine if the motor is on or off backwards

//Define information about steering servo
int center = 90;                       //the center position for driving straight with the servo
#include <Servo.h>
Servo stearing;

void setup() {
  Serial.begin (9600);                 //Turn on Serial Monitor
  //Define what will be inputs and what will be outputs
  pinMode(fwd_motor, OUTPUT);
  pinMode(rev_motor, OUTPUT);
  stearing.attach(5);                  //Where the steering servo will be put
  //These for statements are to initalize all of the smoothing settings to zero
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings_R[thisReading] = 0;                        
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings_L[thisReading] = 0;
}

//create a function called smooth_sensors so it can be called later in the void loop
void smooth_sensors(){
  while (counter < numReadings){
    counter = (counter + counter++);
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
  if (millis() >= pingTimer_R) { // pingSpeed milliseconds since last ping, do another ping.
    pingTimer_R += pingSpeed_R;    // Set the next ping time.
    distance_R = sonar_R.ping_cm();  // Send out the ping, get the results in centimeters.
  // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
  }
  if (millis() >= pingTimer_L) { // pingSpeed milliseconds since last ping, do another ping.
    pingTimer_L += pingSpeed_L;    // Set the next ping time.
    distance_L = sonar_L.ping_cm();  // Send out the ping, get the results in centimeters.
  }

//This section is for smoothing
  total_R= total_R - readings_R[index_R];           // subtract the last reading:  
  total_L= total_L - readings_L[index_L];      
  readings_R[index_R] = distance_R;                 // read from the sensor:
  readings_L[index_L] = distance_L;
  total_R= total_R + readings_R[index_R];           // add the reading to the total:
  total_L= total_L + readings_L[index_L];
  index_R = index_R + 1, index_L = index_R + 1;     // advance to the next position in the array:
  if (index_R >= numReadings)                       // if we're at the end of the array...
    index_R = 0;                                    // ...wrap around to the beginning
  if (index_L >= numReadings)                  
    index_L = 0;                                
  average_R = total_R / numReadings;                // calculate the average rt. distance
  average_L = total_L / numReadings;                // calculate the average lft. distance
  difference = average_R - average_L;               // calculate the difference beween sensors

//this sections prints out info to the serial monitor
    Serial.print(distance_L);          // Print the result (0 = outside the set distance range, no ping echo)
    Serial.println("cm Left");
    Serial.print(distance_R);          // Print the result (0 = outside the set distance range, no ping echo)
    Serial.println("cm Right");
  }
    Serial.print(average_L);
    Serial.println("  Left Sensor Avgerage");  
    Serial.print(average_R);
    Serial.println("  Right Sensor Avgerage");  
   delay (5000);
  counter = 0;
}

void loop() {
  smooth_sensors();

//Case #1 - No Time to Turn so Back Up
  if (average_R <= 3 && average_L <= 3){  
      analogWrite (fwd_motor, 0);
      rev_motor_speed = 0;
      stearing.write(center);
      Serial.println("STOP and Center stering c1");
      delay (3000);
    while(average_R <= 8 || average_L <= 8){
      analogWrite (rev_motor, 50);
      Serial.println("reverse slowly - Straight c1");
      rev_motor_speed = 50;
      smooth_sensors();
      delay(500);
    }
  }
//Case #2 - Need to Turn with in Turning Range and drive slow
  if (average_R <= 8 || average_L <= 8){
      if (rev_motor_speed > 0){
        analogWrite(rev_motor, 0);
        rev_motor_speed = 0;
        Serial.println("STOP, Turn off rev. motor c2");
        delay(2000);                      //if the Rev Motor is on, turn it OFF and wait 1 sec.
      }    
      if (difference < 0){            //indicates right sensor is closer so turn left
        stearing.write(center - 30);      //turn left
        analogWrite(fwd_motor, 50);        //drive fwd slowly
        Serial.println("   Turning Left and Drive Fwd Slow c2");
        delay(500);
      }
      if (difference > 0){      
        stearing.write(center + 30);      //turn right
        analogWrite(fwd_motor, 50);        //drive fwd slowly
        Serial.println("  Turn Right and driving fwd slowly c2");
        delay(500);
      }
      else {
        stearing.write(center);
        analogWrite(fwd_motor, 50);        //drive fwd slowly
        Serial.println("  Drive fwd slowly c2");
        delay(500);
      }
  }

//Case #3 - No obstacles so drive fwd at full speed.
  if (average_R > 8 && average_L > 8){
    if (rev_motor_speed > 0){
      analogWrite(rev_motor, 0);
      rev_motor_speed = 0;
      stearing.write(center);
      Serial.println("STOP, turn off Rev. Motor and center stearing c3");
      delay(2000);      //if the Rev Motor is on, turn it OFF and wait 1 sec.
    }
    while (average_R > 8 && average_L > 8){
        analogWrite(fwd_motor, 255);
        stearing.write(center);
        smooth_sensors();
        Serial.println("Drive Forward Full Speed c3");
        delay(500);
      }
  }
}

Monday, June 18, 2012

Buggy Code for Two Ping Sensors, One Motor and One Servo

Today was a successful day.  About as much as it could be.  Using the
Ultrasonic Module HC-SR04 Distance Sensor For Arduino, I was able to use the smoothing example in the Arduino Interface software, and something that I am calling threading to get the motor to turn on variable speeds based on distance, including reverse, and the servo to turn right or left depending on the difference of the two sensors.  The issue is that the sensors are still buggy.  With the smoothing, I am now getting better numbers because the errors are averaged out.  However, when an error happens on the sensor, it takes a second pause which given my written delay, it is taking as long as 4 seconds to get a measurement sometimes.  This causes the entire thing to slow down and become not reliable for a moving car that is trying to make decisions about going right or left or speeding up or slowing down.  I am hoping to have better luck with some IR Sensors.  I am hoping that it will give me more predictable results along with a faster response time.   The code for what I did is below.  It does work as is.  But is has issues.


--------------------------------------------

//Two Ping Sensors with one Motor and one Servo

//This code is for controling a single motor and a servo with a pair of ping sensors (4-pin, HC-SR04).
//Orginally used for a Lego Technics car that self drives around a room
//by Philip Leete

//Define information about ping sensors
int trigPin_R = 2, trigPin_L = 8;
int echoPin_R = 3, echoPin_L = 9;
int duration_R,    duration_L;
int distance_R,    distance_L;
int difference = 0;                                  //uses avg. distances to calculate

//This sections is required for the smoothing
const int numReadings = 10;
int readings_R[numReadings];
int readings_L[numReadings];                               // the readings from the analog input
int index_R = 0,             index_L = 0;                  // the index of the current reading
int total_R = 0,             total_L = 0;                  // the running total
int average_R = 0,           average_L = 0;                // the average of the light values
int counter = 0;                                           // this counter will be used to start/stop sensors

//Define information about motors
#define fwd_motor 6                    //fwd motor connected to digital pin 6
#define rev_motor 11                   //rev motor connected to digital pin 11
int rev_motor_speed = 0;               //a integer to be used to determine if the motor is on or off backwards

//Define information about steering servo
int center = 90;                       //the center position for driving straight with the servo
#include <Servo.h>
Servo stearing;

void setup() {
  Serial.begin (9600);                 //Turn on Serial Monitor
  //Define what will be inputs and what will be outputs
  pinMode(trigPin_R, OUTPUT);
  pinMode(echoPin_R, INPUT);
  pinMode(trigPin_L, OUTPUT);
  pinMode(echoPin_L, INPUT);
  pinMode(fwd_motor, OUTPUT);
  pinMode(rev_motor, OUTPUT);
  stearing.attach(5);                  //Where the steering servo will be put
  //These for statements are to initalize all of the smoothing settings to zero
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings_R[thisReading] = 0;                          
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings_L[thisReading] = 0;
}

//create a function called smooth_sensors so it can be called later in the void loop
void smooth_sensors(){
  while (counter < numReadings){
    counter = (counter + counter++);
//Activate the Left Ping Sensor
    digitalWrite(trigPin_L, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin_L, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin_L, LOW);
  duration_L = pulseIn(echoPin_L, HIGH);
  distance_L = (duration_L)/140;                  //conversion to inches
//Activate the Right Ping Sensor
    digitalWrite(trigPin_R, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin_R, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin_R, LOW);
  duration_R = pulseIn(echoPin_R, HIGH);
  distance_R = (duration_R)/140;                  //conversion to inches

//This section is for smoothing
  total_R= total_R - readings_R[index_R];           // subtract the last reading:    
  total_L= total_L - readings_L[index_L];        
  readings_R[index_R] = distance_R;                 // read from the sensor:
  readings_L[index_L] = distance_L;
  total_R= total_R + readings_R[index_R];           // add the reading to the total:
  total_L= total_L + readings_L[index_L];
  index_R = index_R + 1, index_L = index_R + 1;     // advance to the next position in the array:
  if (index_R >= numReadings)                       // if we're at the end of the array...
    index_R = 0;                                    // ...wrap around to the beginning
  if (index_L >= numReadings)                    
    index_L = 0;                                  
  average_R = total_R / numReadings;                // calculate the average rt. distance
  average_L = total_L / numReadings;                // calculate the average lft. distance
  difference = average_R - average_L;               // calculate the difference beween sensors
 
//this sections prints out info to the serial monitor
//  Serial.print(average_L);
//  Serial.println("  Left Sensor Avgerage");    
//  Serial.print(distance_L);                      
//  Serial.println("  Left Sensor Data");
//  Serial.print(average_R);
//  Serial.println("  Right Sensor Avgerage");    
//  Serial.print(distance_R);                      
//  Serial.println("  Right Sensor Data");
  delay(2);                                      // delay in between reads for stability          
  }
//  Serial.println("finished new average");
  counter = 0;
}

void loop() {
  smooth_sensors();

//Case #1 - No Time to Turn so Back Up
  if (average_R <= 5 && average_L <= 5){    
      analogWrite (fwd_motor, 0);
      rev_motor_speed = 0;
      stearing.write(center);
      Serial.println("stop and Center stering c1");
      delay (1000);
    while(average_R <= 10 || average_L <= 10){
      analogWrite (rev_motor, 50);
      Serial.println("reverse slowly - Straight c1");
      rev_motor_speed = 50;
      smooth_sensors();
      delay(1000);
    }
  }
//Case #2 - Need to Turn with in Turning Range and drive slow
  if (average_R <= 10 || average_L <= 10){
      if (rev_motor_speed > 0){
        analogWrite(rev_motor, 0);
        rev_motor_speed = 0;
        Serial.println("Turn off rev. motor c2");
        delay(1000);                      //if the Rev Motor is on, turn it OFF and wait 1 sec.
      }      
      if (difference < 0){            //indicates right sensor is closer so turn left
        stearing.write(center - 30);      //turn left
        analogWrite(fwd_motor, 50);        //drive fwd slowly
        Serial.println("   Turning Left and Drive Fwd Slow c2");
        delay(1000);
      }
      if (difference > 0){        
        stearing.write(center + 30);      //turn right
        analogWrite(fwd_motor, 50);        //drive fwd slowly
        Serial.println("  Turn Right and driving fwd slowly c2");
        delay(1000);
      }
      else {
        stearing.write(center);
        analogWrite(fwd_motor, 50);        //drive fwd slowly
        Serial.println("  Drive fwd slowly c2");
        delay(1000);
      }
  }

//Case #3 - No obstacles so drive fwd at full speed.
  if (average_R > 10 && average_L > 10){
    if (rev_motor_speed > 0){
      analogWrite(rev_motor, 0);
      rev_motor_speed = 0;
      stearing.write(center);
      Serial.println("turn off Rev. Motor and center stearing c3");
      delay(1000);      //if the Rev Motor is on, turn it OFF and wait 1 sec.
    }
    while (average_R > 10 && average_L > 10){
        analogWrite(fwd_motor, 255);
        stearing.write(center);
        smooth_sensors();
        Serial.println("Drive Forward Full Speed c3");
        delay(1000);
      }
  }
}

Thursday, June 14, 2012

Smoothing Two Ping Sensors

This is Cool!!

I was able to take the smoothing concept and run it on two ping sensors.  The result is much more fluid changes in values and even when error numbers roll across the screen, the data still only moves slowly.

The down side, given that I am pulling 100 number samples, the response time can be as much 5 seconds.
I will play with that and see if I can't get some better things going.  Or maybe I don't need that level of smooth.

The other thing that I did was to call the smoothing process a function so I can thread it easily into my void loop for when I need decisions to be made.

The code is below.
-------------------------------

// Two Ping Sensors with Smoothing
//by Philip Leete

//Define where the Ping Sensors are
int trigPin_R = 2, trigPin_L = 8;
int echoPin_R = 3, echoPin_L = 9;
int duration_R,    duration_L;
int distance_R,    distance_L;
 
//This sections is required for the smoothing
const int numReadings = 10;
int readings_R[numReadings];
int readings_L[numReadings];                               // the readings from the analog input
int index_R = 0,             index_L = 0;                  // the index of the current reading
int total_R = 0,             total_L = 0;                  // the running total
int average_R = 0,           average_L = 0;                // the average of the light values

void setup() {
  Serial.begin (9600);
  pinMode(trigPin_L, OUTPUT);
  pinMode(trigPin_R, OUTPUT);
  pinMode(echoPin_L, INPUT);
  pinMode(echoPin_R, INPUT);
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings_R[thisReading] = 0;                             // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings_L[thisReading] = 0;
  }

void smooth_sensors(){
    //Activate the Left Ping Sensor
    digitalWrite(trigPin_L, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin_L, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin_L, LOW);
  duration_L = pulseIn(echoPin_L, HIGH);
  distance_L = (duration_L)/140;                  //conversion to inches

//Activate the Right Ping Sensor
    digitalWrite(trigPin_R, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin_R, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin_R, LOW);
  duration_R = pulseIn(echoPin_R, HIGH);
  distance_R = (duration_R)/140;                  //conversion to inches

//This section is for smoothing
  total_R= total_R - readings_R[index_R];           // subtract the last reading:    
  total_L= total_L - readings_L[index_L];        
  readings_R[index_R] = distance_R;                 // read from the sensor:
  readings_L[index_L] = distance_L;
  total_R= total_R + readings_R[index_R];           // add the reading to the total:
  total_L= total_L + readings_L[index_L];
  index_R = index_R + 1, index_L = index_R + 1;     // advance to the next position in the array:
  if (index_R >= numReadings)                       // if we're at the end of the array...
    index_R = 0;                                    // ...wrap around to the beginning
  if (index_L >= numReadings)                    
    index_L = 0;                                  
  average_R = total_R / numReadings;                // calculate the average:
  average_L = total_L / numReadings;                // calculate the average:
 
//this sections prints out info to the serial monitor
  Serial.print(average_L);
  Serial.println("  Left Sensor Avgerage");    
//  Serial.print(distance_L);                      
//  Serial.println("  Left Sensor Data");
  Serial.print(average_R);
  Serial.println("  Right Sensor Avgerage");    
//  Serial.print(distance_R);                      
//  Serial.println("  Right Sensor Data");
  delay(1);                                      // delay in between reads for stability          
}

void loop() {
  smooth_sensors();
}

Smoothing

Today, I need to figure out how to smooth the code (Take the avg. of an analog input).
I hope that this will help to remove some of the bad data and get more consistent results.

The first thing I did was to use the code in the Arduino Exmples along with a light sensor.


/*How to smooth code from a light sensor
modified by Philip Leete from the Arduino Examples
tested with a light sensor wired to a 5v. circuit.
   
This code will show, with LED, how smoothing works by effecting the fade rates
of two LED lights.
*/

const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average of the light values
int LED_Avg = 5;                // the LED for Avg readings is on pin 5
int LED_Real = 9;               // the LED for Real readings is on pin 9
int Light_Sensor = A0;          // the light sensor is in pin A0
int Light_Value;                // a value used to store the real light value

void setup()
{
  // initialize serial communication with computer:
  Serial.begin(9600);                
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;        
  pinMode(LED_Avg, OUTPUT);
  pinMode(LED_Real, OUTPUT);
}

void loop() {
  // subtract the last reading:
  total= total - readings[index];      
  // read from the sensor:
  readings[index] = analogRead(Light_Sensor);
  // add the reading to the total:
  total= total + readings[index];    
  // advance to the next position in the array:
  index = index + 1;                  

  // if we're at the end of the array...
  if (index >= numReadings)            
    // ...wrap around to the beginning
    index = 0;                        

  // calculate the average:
  average = total / numReadings;      
  // send it to the computer as ASCII digits
  Light_Value = analogRead(A0);

  analogWrite(LED_Real, Light_Value);  //this controls the fading of the LED
  analogWrite(LED_Avg, average);   //this is the fading of each LED

  Serial.print(average);
  Serial.println("  Avgerage");         //you can see how the avg will match the real value
  Serial.print(Light_Value);            //after a few moments.
  Serial.println("  Light Value");
  delay(1);                             // delay in between reads for stability          
}

-----------------------------------------

Wiring the TI-SN75441

This is an important picture for wiring the TI-SN75441 which is used for controlling up to 4 motors or one stepper motor.


Wednesday, June 13, 2012

First Attempt at Code for 2 sensors, motor and servo


ARGH!!  Okay, so yesterday, it made sense in my head.  However, to talk about what you want to happen and what you can write are two different things.  How frustrating!

First, to refresh on what I am trying to do.  I want to build a car (out of legos first) that will avoid obstacles and navigate around a room without any input from a person.  I am trying to do this by using two ultrasonic ping sensors as the eyes, a servo for steering, and a motor to control forward and backward speed.

I ended up with three ideas (or logic circles) in the code.
First Idea:  No time to turn so stop moving and back up.
Second Idea: I am inside the turning range so turn.  Just pick the correct direction and slow down.
Third Idea:  The coast is clear so go forward as fast as you can

In the code below, I used global variables and writing functions that I can call later on in the script.  The biggest issue is that everything depends on the accuracy of the two ping sensors.  I am not having luck.  THIS IS NOT THE CASE.  I am getting some garbage data as things change and that will spin the code into one loop or another.  Yet when the sensor is doing what it should, it is within 2 inches.  Either way, the results are not nearly consistent enough.
So, I am going to explore some ideas for storing a group of sensor reading and taking averages of the sensor data.  I think it's called "Smoothing."  The other idea I need to try is something that I think might be called "Threading" but I am not sure.  The concept is that you take the important piece, (The avg. sensor data) and call for it to refresh when ever the robot needs to make a decision.

The idea of these two thoughts is that Smoothing will help to eliminate data by letting the sensors run faster and gather more data.  As for Threading, I think I can call for the Avg. Smooth Ping Data every time the code gets to a decision point.  It should speed up the process and fix the reliability issues.

Regardless, below is the code that does work but is Very Buggy!  It needs some serious help.
//-------------------------------------------------------
//Two Ping Sensors with one Motor and one Servo

//This code is for controling a single motor and a servo with a pair of ping sensors.
//Orginally used for a Lego Technics car that self drives around a room
//by Philip Leete

#define trigPinR 2
#define echoPinR 3
#define trigPinL 8
#define echoPinL 9
#define fwd_motor 6               //fwd motor connected to digital pin 6
#define rev_motor 11              //rev motor connected to digital pin 11
int rev_motor_speed = 0;           //a integer to be used to determine if the motor is on or off backwards
int center = 90;                   //the center position for driving straight with the servo
int distanceR = 0;                     //distance of the right sensor, inches
int distanceL = 0;                     //distance of the left sensor, inches
int difference = 0;                    //the difference between the Right and Left Sensor
#include <Servo.h>
Servo stearing;

void setup() {
  Serial.begin (9600);
  pinMode(trigPinR, OUTPUT);
  pinMode(echoPinR, INPUT);
  pinMode(trigPinL, OUTPUT);
  pinMode(echoPinL, INPUT);
  pinMode(fwd_motor, OUTPUT);
  pinMode(rev_motor, OUTPUT);
  stearing.attach(5);
  stearing.write(75);
  analogWrite(fwd_motor, 100);               //Test motor Fwd for 2 seconds
  delay (2000);
  analogWrite(fwd_motor, 0);
  delay (1000);
  analogWrite(rev_motor, 100);               //Test motor Rev for 2 seconds
  delay (2000);                            
  analogWrite(rev_motor, 0);
  delay (10000);
  }

//this is the distance_sensors function that I will call later
void distance_sensors() {
    digitalWrite(trigPinL, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPinL, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPinL, LOW);
  distanceL = pulseIn(echoPinL, HIGH)/140;   // the divide by 140 is a conversion to inches
    delayMicroseconds(150);
    Serial.print(distanceL);
    Serial.println(" in. left");
   
    digitalWrite(trigPinR, LOW);
    delayMicroseconds (2);
    digitalWrite(trigPinR, HIGH);
    delayMicroseconds(15);
    digitalWrite(trigPinR, LOW);
  distanceR = pulseIn(echoPinR, HIGH)/140;
    delayMicroseconds(150);
    Serial.print(distanceR);
    Serial.println(" in. right");
  difference = distanceR - distanceL;
}


void loop() {
  distance_sensors();

//Case #1 - No Time to Turn so Back Up
  if (distanceR <= 10 && distanceL <= 10){  
      analogWrite (fwd_motor, 0);
      Serial.println("stop");
      delay (2000);
      stearing.write(center);
      delay (500);
    while(distanceR <= 20 || distanceL <= 20){
      analogWrite (rev_motor, 50);
      rev_motor_speed = 50;
      distance_sensors();
      Serial.println("reverse slowly - Straight");
      delay(500);
    }
  }


//Case #2 - Need to Turn with in Turning Range and drive slow
  if (distanceR <=20 || distanceL <= 20){
      if (rev_motor_speed > 0){
        analogWrite(rev_motor, 0);
        rev_motor_speed = 0;
        Serial.println("Turn off rev. motor");
        delay(2000);                      //if the Rev Motor is on, turn it OFF and wait 2 sec.
      }      
      analogWrite(fwd_motor, 50);        //drive fwd slowly
      Serial.println("driving fwd slowly");
   
      if (difference < 0){            //indicates right sensor is closer so turn left
        stearing.write(center + 10);      //turn soft left
        Serial.print(center + 10);
        Serial.println("   Turning Soft Left");
        delay(500);
        distance_sensors();
      }
      else {        
        stearing.write(center - 10);      //turn soft right
        Serial.print(center - 10);
        Serial.println("   Turning Soft Right");
        delay(500);
        distance_sensors();
      }
}

//Case #3 - No obstacles so drive fwd at full speed.
  if (distanceR > 20 && distanceL > 20){
    if (rev_motor_speed > 0){
      analogWrite(rev_motor, 0);
      Serial.println("turn off Rev. Motor");
      delay(2000);      //if the Rev Motor is on, turn it OFF and wait 2 sec.
    }
    while (distanceR > 20 && distanceL > 20){
        analogWrite(fwd_motor, 255);
        distance_sensors();
        Serial.println("Drive Forward Full Speed");
        delay(250);
      }
  }
}

Tuesday, June 12, 2012

Servo Sweep Test

I did this so that I could test a servo and see how it runs.  It has both a sweep in the void loop and a specific angle set in the void setup.  It was run on an Arduio UNO Board


// Servo Sweep Test
// by Philip Leete

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos;            // variable to store the servo position
int Speed = 15;     // variable to set the speed of sweep
int step_size = 2;  //Step size for sweep

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object  

  myservo.write(170);  //Moves servo arm to 170 degrees
  delay (5000);        //Wait 5 sec. so you can see the movement
  myservo.write(90);   //Moves servo arm to 90 degrees
  delay (5000);        //Wait 5 sec. so you can see the movement
}


void loop()
{
  for(pos = 10; pos < 170; pos += step_size)  // goes from 10 degrees to 170 degrees
  {                                        //I noticed that there are some odd skips and hops that happen if
                                           //you run the servo to 180 and 0 degrees.
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(Speed);                  
  }
  for(pos = 170; pos>=10; pos -= step_size)     // goes from 170 degrees to 10 degrees
  {                              
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(Speed);                  
  }
}

Ping Sensor Test


I modified some ping sensor code to make this.  It is for a 4 pin ping sensor and used on the Arduino Board.


// Ping Sensor Test
//by Philip Leete

#define trigPin 2  //I am putting the sensor onpins 2 and 3
#define echoPin 3

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  int sensor_value;
    digitalWrite(trigPin, LOW)                
    delayMicroseconds (2)                      //This is to insure that the sensor is off
    digitalWrite(trigPin, HIGH);
    delayMicroseconds (5);                      //This is to insure that it gets a reading
    digitalWrite(trigPin, LOW);
  sensor_value = pulseIn(echoPin, HIGH);
    Serial.println(sensor_value);       //Will print out raw data.  Appears to be in range of 0 to 1700
   
 delay (1000);                            //This is so we can get a reading each second and see what is happening
  }


My Obstacle Avoiding Car Project, Part 1

Last night was fun.  I got my lego Technic kits and made three things in a few hours.

 I think all three will work very well when I custom make a motor and servo to fit.  The goal, to make it become an obstacle avoiding car. So that left me this morning to work on figuring out some code.
I did a bit with it.  Most of it is detailed in other blogs today to help keep organized.
But first, I needed to figure out how to get a servo working on the Arduino, so I modified a piece of code and turned it into a test code for servos.  It taught me a bit about how to write positions for servos.  That code is on the next blog.   After that, I worked on trying to discover why our ping sensor was not very reliable.  I wrote a test code for that also.  But am still wrestling with some issues.  I talk about that in the next blog also.

The last thing that I did was to try to sketch out the basic idea for how the code will actually run when I have the completed project.  Here are those thoughts.  I wrote this sketch down while waiting for the wind to blow so I could go kite boarding.

The first idea
define - stop_distance, slow_distance, med_distance, fast_distance
  (This was to help me later on tweak my ideas and important distances that would help govern the speed of the car)
Next was to break down three loops.
1. If both sensors are less then stop_distance
    Then Back UP  ( I am not sure if I should have a turn when I back up or not.  TBD)
2. If both sensors are between the slow_distance and fast_distance
    Then set the motor speed as a linear function of the distance.
3. Else
    Turn the motor on full.

So then I realized that this would not work at all because I was not addressing the need to turn and how that would be affected by the distances to sensors.  So came idea 2.
Still use three loops, (Or maybe if statements.  Not sure.  Will need to ask.)
1. "Back Up Range (0..10 inches approx.)
     If Both Sensors are in 0..10 range, then do...
     Set fwd_pin to LOW and delay for 4 seconds.
    Set rev_pin to HIGH but at 1/4 speed.  (The idea here is that I will need two 5v. loops so that I can run the electricity fwd or backwards through the motor to get it to move fwd or backwards)
2. "In the Turning Range" (0..30 inches approx.)
     If either sensor is in 0..30 range, then do set fwd_speed to function of distance...
    if Rsensor is less then Lsensor, then set servo to be an inverse function of difference.
   Visia versa  (But the issue was weather how to write this funtion so I could get a variable turning ability)
3. else motor fwd full speed.

And that got me to the third idea which is getting closer to something that actually looks like code.
1. "Back Up Range" (Both Sensors are 0..10 inches approx.)
   fwd_pin = 0
   Delay(4000)
   Servo (Center_position - 5)    (This is to turn while backing up.  I also am going to use a Center Position defination so I can make some calibration part in the beginning so that the car will drive straight)
  Delay(100)  (These delays are so that I don't bust my motors or gears and so the servo can get into position before the car starts going backwards)
   Rev_Pin = 50  (I assume this can be a value between 0 and 254. I want it to back up slowly)
  Check the back up range again.  If it is still in back up range, keep doing this.  If it is not in back up range any more, then move to next piece of code.
2. "Turn Range" (Either Sensor is 0..20 inches approx.)
    fwd_pin = (function of Avg. Distance s.t. when avg = 20, speed should be very slow.)
   If the Rsensor is less then Lsensor, then Servo(Center+(-mx+b))  S.T x is the difference between sensors
   If the Lsensor is less then Rsensor, then Servo(Center-(-mx+b))
   Check this loop again to see if it still applies.  Otherwise, move on.
3.  Full Speed ahead.  No Obstacles.


Monday, June 11, 2012

Going further with Blinking Lights

In this one, I am now trying to make lots of lights blink.
In the first example, I just put 6 lights in parallel all on the same pin 13 that was used before.  The code did not change at all.  Just the image changed.

In the next, I then tried playing with the code to get a sort of Night Rider effect with the lights going down a line and back.  I also wanted to speed up the delay between one LED off and the next On.  This helped to smooth out the effect.

--------------------------------------------------------------------


//6 LED Blink Sequence - Written by Philip Leete
#define LED1 1   //I used this naming policy just so I could keep track of where the lights were.
#define LED2 2   //Each led is assigned to the corrisponding pin
#define LED3 3
#define LED4 4
#define LED5 5
#define LED6 6

void setup()
{
pinMode(LED1, OUTPUT);   //This is naming each of the led as an output
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);
pinMode(LED6, OUTPUT);
}

void loop()   //This void loop will turn on all LED's and then turn on one at a time as it ripples down the line and back.
{
digitalWrite(LED1, LOW);    //Notice that the first time throught the loop will turn on all LEDs
delay(100);                 //After that, it will sequence each off and back on
digitalWrite(LED1, HIGH);   //And if I did my math correctly, each step should take 1/10th of a second.  There are 10 steps.  Total time - 1 second

digitalWrite(LED2, LOW);
delay(100);
digitalWrite(LED2, HIGH);

digitalWrite(LED3, LOW);
delay(100);
digitalWrite(LED3, HIGH);

digitalWrite(LED4, LOW);
delay(100);
digitalWrite(LED4, HIGH);

digitalWrite(LED5, LOW);
delay(100);
digitalWrite(LED5, HIGH);

digitalWrite(LED6, LOW);
delay(100);
digitalWrite(LED6, HIGH);

digitalWrite(LED5, LOW);
delay(100);
digitalWrite(LED5, HIGH);

digitalWrite(LED4, LOW);
delay(100);
digitalWrite(LED4, HIGH);

digitalWrite(LED3, LOW);
delay(100);
digitalWrite(LED3, HIGH);

digitalWrite(LED2, LOW);
delay(100);
digitalWrite(LED2, HIGH);
}


The effect was cool but still not real brilliant.  So I will do more later.  On to other things on this Morning.

Blinking an LED

So this is the most basic thing that I could find for the Arduino. It is actually a useful tool because as you go on to more complex things, the time will come when you are wondering, "Did I just burn out my board? How can I find out if it is evening working???" I have used this code to do just that. Trouble shoot an issue and figure out if the Arduino and Computer are even communicating. This first bit of codec came directly from the book.

// Example 01 : Blinking LED from the Arduino Book
#define LED 13 // LED connected to
// digital pin 13
void setup()
{
pinMode(LED, OUTPUT); // sets the digital
// pin as output
}
void loop()
{
digitalWrite(LED, HIGH); // turns the LED on
delay(1000); // waits for a second
digitalWrite(LED, LOW); // turns the LED off
delay(1000); // waits for a second
}
-----------------------------------------

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
  This code was found in the Arduino Software
  This example code is in the public domain.
 */

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {              
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);  
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}


What I find interesting is the differences. One uses int led = 13. The other uses define LED 13. I am still not sure what the difference is but I am sure that it will become more important later, and hopefully I will begin to get it.But what can you do with it. I can make it blink fast and slow and make it stay on or blink in uneven pattern. I can also put a few lights there and then alternate them. It is kind of fun.


So the code for making a two led blink pattern, I just used cut and paste to add another LED on pin 12.  Otherwise, the code is the same as above.


// 2 Blinking LED's  - Modified by Philip Leete
#define First_Led 12        //First_Led is connected to pin 12
#define Second_Led 13       //Second_LED is connected to pin 13

void setup()
{
pinMode(First_Led, OUTPUT);   //This sets both leds as outputs
pinMode(Second_Led, OUTPUT);
}
void loop()
{
digitalWrite(First_Led, HIGH); // turns the First LED on
delay(100); // waits for the given time, in miliseconds
digitalWrite(First_Led, LOW); // turns the First LED off
delay(100);

digitalWrite(Second_Led, HIGH); // turns the Second LED on
delay(100);
digitalWrite(Second_Led, LOW); // turns the Second LED off
delay(100);
}


Starting with Arduino

The book that I am using to get things rolling is "Getting Started with Arduino" by Massimo Banzi. I have found this book to be very helpful for those that have done none to very little with programming or electronics. It is a small book so I would recommend starting at the beginning and working through all of it. Even if it seems easy. Your ideas and basic understanding will grow by leaps and bounds. This includes reading the Preface and the Introduction! Read it all!