Friday, March 7, 2014

Compass Programming with Vex Prototype- Matt Mannino

I have mounted the Arduino and the sensors onto the Vex prototype to start working on a main program.  I interfaced the Vex motors to the Arduino and added a 7.2V NiMH battery for power to the Arduino and the Vex Motors.  We started on a program that will face the robot in the correct heading based on what values it is given.  It works fine for headings up to 359 degrees.  It has trouble pointing North because it is on the threshold of 359 to 0 degrees and cannot compensate for that.  I have been trying to work on it so that it can work with that threshold of values.


Compass Program

#include <Wire.h>
#include <LSM303.h>
#include <Servo.h>

LSM303 compass;
Servo LeftMotor;
Servo RightMotor;
Servo BallMotor;

int stopp = 100;
int forward = 70;
int backward = 130;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  compass.init();
  compass.enableDefault();
  LeftMotor.attach(3);
  RightMotor.attach(2);
  BallMotor.attach(4);
 
  compass.m_min = (LSM303::vector<int16_t>){-32767, -32767, -32767};
  compass.m_max = (LSM303::vector<int16_t>){+32767, +32767, +32767};
}

void loop()
{
  int dir = compass.heading();
  Serial.println(dir);
 
  face(180);
}

void face (int val)
{
  int dir = 0;
 
  while(true)
  {
    compass.read();
    dir = compass.heading();
   
    Serial.println(dir);
   
     if(dir > (val+5))
     {
       turnleft();
     }
     else if(dir < (val-5))
     {
       turnright();
     }
     else
     {
       nospeed();
       delay(50);
       break;
     }
   }
 }

//motor movement functions
void goforward()
{
  RightMotor.write(backward);
  LeftMotor.write(forward);
  delay(1);
}

void gobackward()
{
  RightMotor.write(forward);
  LeftMotor.write(backward);
  delay (1);
}

void nospeed()
{
  RightMotor.write(stopp);
  LeftMotor.write(stopp);
  delay (1);
 
}

void turnleft()
{
  RightMotor.write(backward);
  LeftMotor.write(backward);
  delay (1);
}

void turnright()
{
  RightMotor.write(forward);
  LeftMotor.write(forward);
  delay(1);
}

void ballmotor()
{
  BallMotor.write(forward);
  delay(1);

}

Chassis Rail Machining - Andrew Baden

Today I worked with Dr. Bronakowski on machining the side chassis rails using the CNC machine to allow the motor mounts to be adjustable.  We would like these motor mounts to be adjustable so that we can minimize the amount of slack in the chains used for the drive system.

Slot in chassis rail for motor mounts
Here are pictures of the motor mount attached to one of the chassis rails:

Top view

Front view
The motor mount is not fully attached in these pictures because I just wanted to do a test fit with the motor mounts to see if they fit correctly with the fasteners that we are using.  Later I will need to machine a similar but larger slot for the motor's shaft to go through.

Sunday, March 2, 2014

Parts arriving, Sprocket Modification, Chassis Rail Modification - Andrew Baden

The parts ordered from VEX Robotics including wheels, sprockets, bearings, and collars were received today.  When the parts were being confirmed, some parts were not correct. 

New Parts from VEX Robotics
The sprockets we ordered were not the size we needed.  We will have to adjust sprockets on hand and modify them for our cause.  To get these sprockets to work with what we need, all we have to do is drill three holes into the existing sprockets to attach them to our wheel/chain assembly.  In the picture below, the sprocket on the right is the sprocket being modified, and the series of sprockets on the left are secured to the other sprocket to allow us to drill out the proper holes for attaching the existing sprockets to the wheel assembly.

Sprocket Assembly to Drill in Drill Press
To allow the motor chains from falling off their sprockets, we are creating a slot in the chassis rails to allow the motors on each side to be adjustable, so they can eliminate any slack present in the assembly.

Chassis Rail with Slotted Drawing






Compass and Line Sensor Programming- Matt Mannino

The orders came in finally and I was able to start working on programming the Pololu LSM303 Compass Sensor.  I used an example program from Pololu using their specific library for the LSM303.  I was getting stable values for the heading.  I also started on the line sensing programming using the QRD1114 light sensors.  The light sensor is for predetermined boundaries where the robot is going to operate in using tape.

QRD1114 Wiring for Arduino


Value Readings from QRD1114 Light Sensor

Heading Value Readings from LSM303 Compass Sensor



LSM303 Pinouts


     5V  ->  VIN
    GND  ->  GND
    SDA  ->  SDA
    SCL  ->  SCL








QRD1114 Test
int sensorPin = 0; //A0

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int val = analogRead(sensorPin);
  Serial.println(val);

  delay(100);


}


LSM303 Compass Heading

#include <Wire.h>
#include <LSM303.h>

LSM303 compass;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  compass.init();
  compass.enableDefault();

  compass.m_min = (LSM303::vector<int16_t>){-32767, -32767, -32767};
  compass.m_max = (LSM303::vector<int16_t>){+32767, +32767, +32767};
}

void loop()
{
  compass.read();

  float heading = compass.heading();

  Serial.println(heading);
  delay(100);

}

Friday, February 21, 2014

Ultrasonic and Compass Programming- Matt Mannino

Today I worked more on the Ultrasonic sensor programming.  It works with sensing if the hopper is full now.  I removed the coding that shows that the hopper is filling on the LCD display since it was pretty unnecessary.  I also started to work on the programming for the compass, but I am temporarily using the  Hitachi HM55B Compass Module since we are ultimately using the Pololu LSM303D Compass Module.  I found example code to get data off of the Compass Module and display it.

Displays current reading and hopper status

Readings of the HM55B Compass Module

Ultrasonic Program
#include <SoftwareSerial.h>
#include <Timer.h>

const int TxPin = 18;
const int pingPin = 30;
int counter = 0;

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

void setup()
{
  Serial.begin(9600);    // initialize serial communication:
}

void loop()
{
  long duration, inches, cm;      // establish variables for duration of the ping,
                                  // and the distance result in inches and centimeters:
  pinMode(TxPin, OUTPUT);
  digitalWrite(TxPin, HIGH);

  mySerial.begin(9600);
  delay(50);
  mySerial.write(12);                 // Clear          
  mySerial.write(17);                 // Turn backlight on
  delay(5);                           // Required delay

  pinMode(pingPin, OUTPUT);             // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  digitalWrite(pingPin, LOW);           // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);




  pinMode(pingPin, INPUT);                // The same pin is used to read the signal from the PING))): a HIGH
  duration = pulseIn(pingPin, HIGH);      // pulse whose duration is the time (in microseconds) from the sending
                                          // of the ping to the reception of its echo off of an object.
                                       
  inches = microsecondsToInches(duration);      // convert the time into a distance
  cm = microsecondsToCentimeters(duration);

  mySerial.print(inches);
  mySerial.print("in, ");
  mySerial.print(cm);
  mySerial.print("cm");
  mySerial.println();

  delay(5);

  if(counter > 10)
  {
    mySerial.write(13);                 // Turn backlight on
    mySerial.write(12);                 // Clear screen
    mySerial.print("Hopper Full");
  }

  else
  {
    mySerial.write(13);                // Turn backlight on
    mySerial.print("Empty");
  }
  if(inches < 4)
  {
   counter++;
  }
  else
  {
  counter=0;
  }

}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}


Compass Program
#include <math.h>

//// VARS

byte CLK_pin = 8;
byte EN_pin = 9;
byte DIO_pin = 10;

int X_Data = 0;
int Y_Data = 0;
int angle;

//// FUNCTIONS

void ShiftOut(int Value, int BitsCount) {
  for(int i = BitsCount; i >= 0; i--) {
    digitalWrite(CLK_pin, LOW);
    if ((Value & 1 << i) == ( 1 << i)) {
      digitalWrite(DIO_pin, HIGH);
    }
    else {
      digitalWrite(DIO_pin, LOW);
    }
    digitalWrite(CLK_pin, HIGH);
    delayMicroseconds(1);
  }
}

int ShiftIn(int BitsCount) {
  int ShiftIn_result;
  ShiftIn_result = 0;
  pinMode(DIO_pin, INPUT);
  for(int i = BitsCount; i >= 0; i--) {
    digitalWrite(CLK_pin, HIGH);
    delayMicroseconds(1);
    if (digitalRead(DIO_pin) == HIGH) {
      ShiftIn_result = (ShiftIn_result << 1) + 1;
    }
    else {
      ShiftIn_result = (ShiftIn_result << 1) + 0;
    }
    digitalWrite(CLK_pin, LOW);
    delayMicroseconds(1);
  }

  // below is difficult to understand:
  // if bit 11 is Set the value is negative
  // the representation of negative values you
  // have to add B11111000 in the upper Byte of
  // the integer.
  if ((ShiftIn_result & 1 << 11) == 1 << 11) {
    ShiftIn_result = (B11111000 << 8) | ShiftIn_result;
  }

  return ShiftIn_result;
}

void HM55B_Reset() {
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(EN_pin, LOW);
  ShiftOut(B0000, 3);
  digitalWrite(EN_pin, HIGH);
}

void HM55B_StartMeasurementCommand() {
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(EN_pin, LOW);
  ShiftOut(B1000, 3);
  digitalWrite(EN_pin, HIGH);
}

int HM55B_ReadCommand() {
  int result = 0;
  pinMode(DIO_pin, OUTPUT);
  digitalWrite(EN_pin, LOW);
  ShiftOut(B1100, 3);
  result = ShiftIn(3);
  return result;
}


void setup() {
  Serial.begin(9600);
  pinMode(EN_pin, OUTPUT);
  pinMode(CLK_pin, OUTPUT);
  pinMode(DIO_pin, INPUT);

  HM55B_Reset();
}

void loop() {

  HM55B_StartMeasurementCommand(); // necessary!!
  delay(40); // the data is 40ms later ready
  Serial.print(HM55B_ReadCommand()); // read data and print Status
  Serial.print(" ");

  X_Data = ShiftIn(11); // Field strength in X
  Y_Data = ShiftIn(11); // and Y direction

  //Serial.print(X_Data); // print X strength
  //Serial.print(" ");
  //Serial.print(Y_Data); // print Y strength
  //Serial.print(" ");
  digitalWrite(EN_pin, HIGH); // ok deselect chip
  angle = 180 * (atan2(-1 * Y_Data , X_Data) / M_PI); // angle is atan( -y/x) !!!
  Serial.print("angle = ");
  Serial.print(angle); // print angle
  Serial.println();
  //Serial.println("");

}

Tuesday, February 18, 2014

Early Development of drive chassis - Nick Alioto

I helped Andrew work on an early version of the robot drive chassis. It is mainly used to be an idea of what the size could be for the final robot with the supplies that we could find in our lab. There is a possibility that we might need to modify and machine some of the parts to get the chassis to a point of satisfaction.

Ultrasonic Programming- Matt Mannino

While we are in the process of waiting for parts to come in, we started working on some of the programming.  Since we already have the Ultrasonic sensor, I started working on a program for the "hopper".  This program uses the Parallax 2x16 Serial LCD backlit display, the Parallax Ultrasonic Ping sensor, and the Arduino Mega.  The current version displays current readings from the Ultrasonic Sensor on the LCD display.  It is in the process of being able to detect if the hopper is full or not.

The setup with the Ping sensor and LCD display

LCD display showing current status



#include <SoftwareSerial.h>

const int TxPin = 18;
const int pingPin = 30;

SoftwareSerial mySerial = SoftwareSerial(255, TxPin);

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
}

void loop()
{
  // establish variables for duration of the ping,
  // and the distance result in inches and centimeters:
  long duration, inches, cm;
  int timer = 0;

  pinMode(TxPin, OUTPUT);
  digitalWrite(TxPin, HIGH);

  mySerial.begin(9600);
  delay(100);
  mySerial.write(12);                 // Clear          
  mySerial.write(17);                 // Turn backlight on
  delay(5);                           // Required delay

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);

  mySerial.print(inches);
  mySerial.print("in, ");
  mySerial.print(cm);
  mySerial.print("cm");
  mySerial.println();

  delay(5);

  if(inches < 3)
  {
    mySerial.write(13);
    mySerial.print("Filling");

  if(timer > 10)
  {
    mySerial.write(13);
    mySerial.write(12);                 // Clear
    mySerial.print("Hopper Full");
  }
    timer ++;
  }
  else
  {
    mySerial.write(13);
    mySerial.print("Empty");
  }
}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}