twitter
Search

Entries in arduino (11)

Sunday
Mar252012

Arduino, BOE Shield, PING, and a servo

The video above is in two parts: first with a crawler kit and then with wheels. Switching back to wheels required a code modification to change the time it takes to turn. 
All the parts in the video were released for the original STAMP/Propeller chips, but the code below will get you off and running on the Arduino shield. Only digital pins 10, 11, 12, and 13 are used, so any shield that does not require those pins is available for use. 
// BOE Shield code from "Robotics with the BOE Bot"
// Roaming With Whiskers source, modified to use a PING)))
// sensor on the PING))) servo bracket.
// Using code from the Ping))) example sketch.
#include <Servo.h>                           // Include servo library
Servo servoLeft;                             // Declare left, right and Ping))) servos
Servo servoRight;
Servo PingServo;
int minSafeDist = 11 ;                        // Minimum distance in inches
int pingPin = 10;                             // PING input on 10 so the last servo port is used.
int centerDist, leftDist, rightDist;          // Define distance variables
long duration, inches, cm;                    // Define variables for Ping)))
void setup()                                 // Built-in initialization block
  tone(4, 3000, 1000);                       // Play tone for 1 second
  delay(1000);                               // Delay to finish tone
  servoLeft.attach(13);                      // Attach left signal to pin 13 
  servoRight.attach(12);                     // Attach right signal to pin 12
  PingServo.attach(11);
}  
void loop(){
  LookAhead();
  if(inches >= minSafeDist) /* If the inches in front of an object is greater than or equal to the minimum safe distance (11 inches), react*/
  {
    forward (121); //Go Forward
    delay(110); // Wait 0.11 seconds
  }
  else // If not:
  {
    servoLeft.writeMicroseconds(1500);
    servoRight.writeMicroseconds(1500);
    LookAround(); // Check your surroundings for best route
    if(rightDist > leftDist) // If the right distance is greater than the left distance , turn right
    {
      turnRight (250); // Turn Right      
    }
    else if (leftDist > rightDist) // If the left distance is greater than the right distance , turn left
    {
      turnLeft (250); // Turn Left
    }
    else
    {
      backward (250); // Go Backward
    }
    delay (250);
  }
}
void forward(int time)                       // Forward function
{
  servoLeft.writeMicroseconds(1700);         // Left wheel counterclockwise
  servoRight.writeMicroseconds(1300);        // Right wheel clockwise
  delay(time);                               // Maneuver for time ms
}
void turnLeft(int time)                      // Left turn function
{
  servoLeft.writeMicroseconds(1300);         // Left wheel clockwise
  servoRight.writeMicroseconds(1300);        // Right wheel clockwise
  delay(time);                               // Maneuver for time ms
}
void turnRight(int time)                     // Right turn function
{
  servoLeft.writeMicroseconds(1700);         // Left wheel counterclockwise
  servoRight.writeMicroseconds(1700);        // Right wheel counterclockwise
  delay(time);                               // Maneuver for time ms
}
void backward(int time)                      // Backward function
{
  servoLeft.writeMicroseconds(1300);         // Left wheel clockwise
  servoRight.writeMicroseconds(1700);        // Right wheel counterclockwise
  delay(time);                               // Maneuver for time ms
}
unsigned long ping() {
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW); //Send a low pulse
  delayMicroseconds(2); // wait for two microseconds
  digitalWrite(pingPin, HIGH); // Send a high pulse
  delayMicroseconds(5); // wait for 5 micro seconds
  digitalWrite(pingPin, LOW); // send a low pulse
  pinMode(pingPin,INPUT); // switch the Pingpin to input
  duration = pulseIn(pingPin, HIGH); //listen for echo
  /*Convert micro seconds to Inches
   -------------------------------------*/
  cm = microsecondsToCentimeters(duration);
  inches = microsecondsToInches(duration);
}
long microsecondsToInches(long microseconds) // converts time to a distance
{
  return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) // converts time to a distance
{
  return microseconds / 29 / 2;
}
void LookAhead() {
  PingServo.write(90);// angle to look forward
  delay(175); // wait 0.175 seconds
  ping();
}
void LookAround(){
  PingServo.write(20); // 20° angle
  delay(320); // wait 0.32 seconds
  ping();
  rightDist = inches; //get the right distance
  PingServo.write(160); // look to the other side
  delay(620); // wait 0.62 seconds
  ping(); 
  leftDist = inches; // get the left distance
  PingServo.write(90); // 90° angle
  delay(275); // wait 0.275 seconds
}

 

Wednesday
Mar212012

Parallax BOE Shield for Arduino: First Look

I'm a big fan of Parallax and adafruit industries, so was glad to learn that they are now stocking the Parallax BOE Shield for Arduino. I already owned this kit but have yet to have time to play with it. The video above is an unboxing of the BOE Shield, PING))) sensor mounting bracket, and crawler kit. 
The original Parallax BOE-Bot uses Propeller controller and is very good for learning robotics in that environment. The lessons, documentation, and examples are quite detailed. With a focus on education, Parallax wisely decided to expand this platform into Arduino territory. The only "required" pins for the shield are two of 10, 11, 12, and 13. You can choose which two in your Arduino code. The rest can be used with your normal stackable Arduino shields.
To get a general idea of the BOE Shield and completed robot in action, take a look at adafruit's new product announcement.
Here's a photo of the crawler kit sitting on an original BOE bot (borrowed from Parallax's site) that I intend to use with the BOE Shield.
I'll be posting all my source code and a bunch of pictures or videos, but it will all pale in comparison to the online book from Parallax.
Stay tuned for more!

 

Monday
Mar192012

R2-D2 Laser Robot for Cats

This is an expanded modification for the Laser ToyBot for Cats to fit into an R2-D2 toy. The entire project can be built with significantly less work without using the R2-D2, but the astromech droid had a lot more flair. First: How to make it work from scratch:

The first revision was just an Ardweeny on a proto board with some hot-glue attaching the continuous rotation servo horn to a project box. It spins in horizontal circles, randomly changing directions while also randomly changing vertical angle. The vertical servo must be "tuned" so it is consistently pointing toward the ground unless you enjoy having your cats climb the walls. 

Simple parts:

  1. Ardweeny (Maker Shed)
  2. Adafruit 1/2 Size Perma-Proto Board (adafruit)
  3. Micro Servo and perhaps some 10uF capacitors to clean up the noise (adafruit)
  4. Sparkfun TTL Laser and 10k resistor (Sparkfun) 
  5. Continuous Rotation Servo (adafruit)
  6. 3xAAA battery holder (adafruit)

Advanced/Optional parts:

  1. RobotShop pan kit for either Futaba or Hitec servos. I went with the Hitec version and modified a Hitec HS-422 servo for continuous rotation. Futaba continuous rotation servos are more widely available without modification, but the Futaba pan kit is more expensive. The servo I linked above is a Futaba servo.
  2. R2-D2 model. I used a Diamond Select bank I found on Amazon but can't find it anymore.
  3. Shape Lock molding plastic. (Maker Shed)
  4. On-Off button and LED. This beauty from adafruit does both

Simple assembly:

In my non-Droid version, I simply sandwiched the servos between the proto board and the battery holder then used hot glue to affix the continuous rotation servo to a project enclosure. It worked fine, but was not sturdy. The switch to the Perma-Proto board was ideal as shown here:

Pin assignment:

  • Vertical (standard) servo: 10
  • Horizontal (continuous rotation) servo: 9
  • Laser diode: 8  (The diode is TTL controlled and uses a 10k resistor to ground)
  • Power LED: 7

That's all that is needed to get a basic laser toy running. Fitting it into the R2-D2 robot was a bit more challenging. I needed to find a way to allow the entire R2-D2 head to spin freely without tangling wires and I didn't have a slip ring (but adafruit does now) so I decided to make the entire electronic device rotate. Finding the DDP155 Pan System from RobotShop and mounting it upside down solved that for me. I screwed in a few risers to the rotating plate to lift it higher into the droid model. 

 

When working with ShapeLock, be aware that the hot plastic will bond to other plastics. To get a very close form, insulate other plastic areas with aluminum foil until the cooling completes. ShapeLock can be cut with a Dremel rotary tool with a plastic or wood cutting bit at 5-8k RPM. Going over 10k causes the plastic to melt. USE SAFETY GLASSES when using a rotary tool. Little bits of white plastic in the eye are not fun.

The most difficult part of the R2-D2 enclosure was the centering and balancing of the head on the RobotShop pan kit. This took several tries. Thankfully ShapeLock can simply be melted down and re-molded. 

That's it for the construction. The rest is just source code. Enjoy!

 

/* Arduino laser cat toy
 
 2012 Daniel Gentleman
 thoughtfix.com
 Creative Commons Attribution license
 
 Laser diode attached to a standard servo for vertical movement
 Continuous rotation servo for horizontal spinning
 Power LED (optional) 
 
 */
#include <Servo.h> 
Servo myservoh;  // Horizontal servo - continuous rotation
Servo myservov; // Vertical servo - standard 
unsigned int duration = 0;
int lasttime1 = 0;
int lasttime2 = 0;
int randstart = 0;
int randend = 0;
int pos = 0;
int laser = 8; // TTL laser diode on pin 8
int vpos = 80; 
int powerLed = 7; // Power LED on pin 7
void setup()
{
  myservoh.attach(9); // Continuous rotation servo on pin 9
  myservov.attach(10); // Standard servo on pin 8
  pinMode(laser, OUTPUT);
  pinMode(powerLed, OUTPUT);
  digitalWrite(laser, LOW);  // Turn ON the laser 
  digitalWrite(powerLed, HIGH); // Turn ON the power LED
}
void loop()
{
  int vaxis = random(50,120); // Range of vertical movement (50-120 here)
  myservov.write(vaxis);
  lasttime1 = millis();
  randstart =  random(200, 19990); // Tune these for your preferred random behavior
  randend =  random(2000, 2400);
  while(pos <= randend) // Random horizontal spinning 
  {
    pos += 1;
    myservoh.writeMicroseconds(pos); 
    delay(1);
  }
  vaxis = random(70,100);
  myservov.write(vaxis); // Random vertical movement
  duration = millis() - lasttime1;
  lasttime2 = millis();
  while(pos >= randstart)
  {
    pos-=1;
    myservoh.write(pos);
    delay(1);
  }
  vaxis = random(70,100);
  delay(500);
  duration = millis() - lasttime2;
  duration = millis() - lasttime1;
}  

 

Sunday
Feb192012

Sparkfun RGB LED and RGB Light Sensor

I can't quite figure this one out: it's VERY delicate and I can't get consistant color results with the built-on LED on or off. I know if it gets a UV light, it shows a lot of purple and if it gets hit with a red laser it maxes out the red LED. Anyhow... Video and code! 

 

 

/*
Expanded to use the Sparkfun RGB LED on pins 3, 5, and 6, sending
PWM signals as 1/10 of the result. YouTube video of this in action at
Use of the RGB LED changes added by thoughtfix 2/2012
Inherited OSHW license.
Original comments below.
*/
/*
An Arduino code example for interfacing with the 
HDJD-S822-QR999 Color Sensor.  Put an object in front of the
sensor and look at the serial monitor to see the values the sensor
is reading.  Scaling factors and gains may have to be adjusted
for your application.
by: Jordan McConnell
 SparkFun Electronics
 created on: 1/24/12
 license: OSHW 1.0, http://freedomdefined.org/OSHW
 
Connect the gain pins of the sensor to digital pins 7 - 12 (or ground).
Connect the led pin to digital 13.
Connect Vr to analog 0, Vg to analog 1, and Vb to analog 2.
*/
// Define pins
const int ledpin = 13;
const int GSR1 = 12;
const int GSR0 = 11;
const int GSG1 = 10;
const int GSG0 = 9;
const int GSB1 = 8;
const int GSB0 = 7;
const int redLed = 3;
const int greenLed = 5;
const int blueLed = 6;
int redpin = A0;
int greenpin = A1;
int bluepin = A2;
// Sensor read values
int red = 0;
int green = 0;
int blue = 0;
int redBright = 0;
int greenBright = 0;
int blueBright = 0;
void setup() 
{
  Serial.begin(9600);
  pinMode(ledpin, OUTPUT);
  pinMode(GSR1, OUTPUT);
  pinMode(GSR0, OUTPUT);
  pinMode(GSG1, OUTPUT);
  pinMode(GSG0, OUTPUT);
  pinMode(GSB1, OUTPUT);
  pinMode(GSB0, OUTPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  // Turn on the LED
  digitalWrite(ledpin, LOW);
  
  // Set the gain of each sensor
  digitalWrite(GSR1, LOW);
  digitalWrite(GSR0, LOW);
  digitalWrite(GSG1, LOW);
  digitalWrite(GSG0, LOW);
  digitalWrite(GSB1, LOW);
  digitalWrite(GSB0, LOW);
}
void loop() 
{
  
  // Read sensors
  // On page 7 of the datasheet, there is a graph of the 
  // spectral responsivity of the chip.  Scaling factors were
  // selected based on this graph so that the gain of each 
  // color is closer to being equal
  red = analogRead(redpin) * 10;
  green = analogRead(greenpin) * 14;
  blue = analogRead(bluepin) * 17;
  redBright = red/10;
  greenBright = green/10;
  blueBright = blue/10;
  // Print values to the serial monitor
  Serial.print("Red: ");
  Serial.print(red, DEC);
  analogWrite(redLed, redBright);
  Serial.print("\t\tGreen: ");
  Serial.print(green, DEC);
  analogWrite(greenLed, greenBright);
  Serial.print("\tBlue: ");
  Serial.println(blue, DEC);
  analogWrite(blueLed, blueBright);
  delay(20);
}
/*Expanded to use the Sparkfun RGB LED on pins 3, 5, and 6, sendingPWM signals as 1/10 of the result. YouTube video of this in action at
Use of the RGB LED changes added by thoughtfix 2/2012Inherited OSHW license.Original comments below.*/
/*An Arduino code example for interfacing with the HDJD-S822-QR999 Color Sensor.  Put an object in front of thesensor and look at the serial monitor to see the values the sensoris reading.  Scaling factors and gains may have to be adjustedfor your application.
by: Jordan McConnell SparkFun Electronics created on: 1/24/12 license: OSHW 1.0, http://freedomdefined.org/OSHW Connect the gain pins of the sensor to digital pins 7 - 12 (or ground).Connect the led pin to digital 13.Connect Vr to analog 0, Vg to analog 1, and Vb to analog 2.*/

// Define pinsconst int ledpin = 13;const int GSR1 = 12;const int GSR0 = 11;const int GSG1 = 10;const int GSG0 = 9;const int GSB1 = 8;const int GSB0 = 7;const int redLed = 3;const int greenLed = 5;const int blueLed = 6;
int redpin = A0;int greenpin = A1;int bluepin = A2;
// Sensor read valuesint red = 0;int green = 0;int blue = 0;int redBright = 0;int greenBright = 0;int blueBright = 0;
void setup() {  Serial.begin(9600);
  pinMode(ledpin, OUTPUT);  pinMode(GSR1, OUTPUT);  pinMode(GSR0, OUTPUT);  pinMode(GSG1, OUTPUT);  pinMode(GSG0, OUTPUT);  pinMode(GSB1, OUTPUT);  pinMode(GSB0, OUTPUT);  pinMode(redLed, OUTPUT);  pinMode(greenLed, OUTPUT);  pinMode(blueLed, OUTPUT);
  // Turn on the LED  digitalWrite(ledpin, LOW);    // Set the gain of each sensor  digitalWrite(GSR1, LOW);  digitalWrite(GSR0, LOW);  digitalWrite(GSG1, LOW);  digitalWrite(GSG0, LOW);  digitalWrite(GSB1, LOW);  digitalWrite(GSB0, LOW);}
void loop() {    // Read sensors  // On page 7 of the datasheet, there is a graph of the   // spectral responsivity of the chip.  Scaling factors were  // selected based on this graph so that the gain of each   // color is closer to being equal  red = analogRead(redpin) * 10;  green = analogRead(greenpin) * 14;  blue = analogRead(bluepin) * 17;  redBright = red/10;  greenBright = green/10;  blueBright = blue/10;
  // Print values to the serial monitor  Serial.print("Red: ");  Serial.print(red, DEC);  analogWrite(redLed, redBright);  Serial.print("\t\tGreen: ");  Serial.print(green, DEC);  analogWrite(greenLed, greenBright);  Serial.print("\tBlue: ");  Serial.println(blue, DEC);  analogWrite(blueLed, blueBright);  delay(20);}

 

Wednesday
Feb012012

Laser ToyBot for Cats

This is a simple bot that really belongs installed in an R2-D2 toy. It's simply an Ardweeny on a breadboard, a set of AA batteries, a continuous rotation servo, a standard servo, and a laser. If there's a desire for source code, I'll post it here. However, it's simply a matter of random writes to both servos (after calibrating the vertical servo so it doesn't move more than 15 degrees.)