Wednesday, April 16, 2014

Disc Foam, Limit Switches, Hopper Side-Skirts, Compass Mount, Front Channel - Matt Mannino

With 1 week left, we finally started to put together most of the vital pieces to the robot.  We ran into the issue where spacing on the discs was very critical, and the slightest adjustment would either make them grip the balls too much, or not enough.  So the addition of foam on the inside of one disc would help compensate for the variation in spacing.  
Green foam on inner disc
Another vital part of the ball collection mechanism is the hopper.  We cut and mounted the hopper ramp, but there still needed to be some sort of walls to keep the balls from falling out.  So we cut and mounted some 1/16 inch aluminum sheet metal for the side-skirts. They are also notched at the electronics box hinges to still allow access.

Side-skirts for hopper
The other mechanism we added was a front channel to help channel the various balls into the collection mechanism.  It is comprised of Vex c-channel about 12 inches long each.  They are mounted with a piano hinge on the inside of the chassis and with a slotted L-bracket on the outside.

Front channel (far right)

 The additions to allow the robot to realize it has backed in to the home station are two limit switches at the very back of the robot.  These will allow the robot to perfectly line up with the home station.  Another limit switch we added was for the trapdoor so the robot will be able to open and close the door accordingly.

Limit switch on back for home station

Limit switch on top bracket of trap door mechanism
While coding, I realized that any metal in the immediate vicinity of the compass module would cause erratic readings.  To address this, we had to come up with a mount that was void of metal for the most part.  We cut a piece of 1 inch diameter pvc to about 7 inches for the main mount. To hold the compass module in place, we used a piece of fairly rigid foam and inserted the connectors for the compass.  I also fished the wires through the pvc.

Side view of compass mount

Top view of compass mount

Sunday, April 13, 2014

Trap Door and Electronics Box Work - Matt Mannino

With more items on our to-do-list left, we are finally finishing them one at a time.  We assembled a "trap door" for the hopper on the back of the robot.  This allows the balls to be dumped out from the hopper into the home station once its path is completed.
Trap Door closed

Trap Door opened
We also added some smaller features to the electronics box that protects and houses the electronics components.  There are two metal clasps, one on each side, that hold the box shut.  There is also a hinge that locks the box in place while it is open.

Metal clasp to hold protective box shut

Hinge on left to keep box open for working on electronics

Final Robot so far

Drive Motor Configuration, Wiring, and Disc motor - Andrew Baden

Over the past few days, we have completed many of our remaining tasks to get the project completed by April 25th.  For starters, we finally have the correct motors in place for our drive train, and have the chains correctly laid out to the point that we shouldn't need to reconfigure them again.
The correct drive train motors mounted and wired
We have also completed most of the major wiring to for devices such as the motors, motor controllers, battery, switches, indicator light, and the Arduino motor controller.

All the major components wired and placed

Emergency and main power switches, and emergency light mounted and wired

Indicator light operational
Now that we have the discs cut and hubs put on them, we can now finalize the mounting solution for them. The mount we used before was too flimsy, and was difficult to mount the motor to.  The mount we have now houses a compound gearbox because the motor we chose that would have enough power, runs too fast. This compound gearbox puts the discs spinning at an effective speed. The mount we have now also uses angle aluminum from the Gears Ed. kit to allow for a more stable platform, and reduce the flimsiness the previous mount had.
Compound Gearbox
Over the next few days, I would like to finalize the hopper's position, and create the channeling plows on the front for the ball collector.

Saturday, April 5, 2014

Disc Machining and Mounting - Andrew Baden

Yesterday I finally got the plastic discs cut out on the CNC machine, with the help of Dr. B.  Each disc has a bolt pattern to mount a hub to, so we can mount the discs themselves to a shaft.

The discs being ready to cut in the CNC machine
More perorations for the discs
Discs being cut
Discs cut with hub attached
Discs attached to chassis
Our next step is to figure out a way to power these discs, and to put an abrasive or rubber like material on the discs to better pick up the balls from the ground.

Sunday, March 30, 2014

Compass Sensor mount - Andrew Baden

For our compass sensor, we need a mount that is a material that will not interfere with sensor itself.  So, I created this mount that we can print on the 3D printer with plastic material.  This mount also places the sensor itself above anything else that could possibly interfere with it such as magnetic fields from motors, or the metal chassis itself.

CADD Model of Compass Mount

Saturday, March 22, 2014

Dog Collar Work - Andrew Baden

Over spring break, I worked on getting the dog collar to interface with the Arduino micro controller.  When I had it connected before, it was having issues reading stable values while the dog collar was not detecting the outer boundary of the dog fence.  I found a simple issue with it, and fixed the problem.  The polarity was backwards! So now I have this working with an analog input on the micro controller itself.  To make this more simple when it comes to programming, I put the output to a 7414 inverting hex Schmitt trigger.   I used the 7414 to clean up the output of the dog collar because it was not always giving a nice stable value.  This will also allow us to use a digital input on the micro controller, and detect if it is at the boundary or not with boolean values rather than a range of values with the analog input.  

Schmitt Trigger on breadboard

Schmitt Trigger schematic
Basically when the Schmitt trigger sees an input (I am currently using pin 1) that is above 1.7V it will trigger a low output on pin 2, and when the trigger sees an input lower than  0.8V, it sends out a high output on pin 2. Now when the dog collar is near the dog fence, the input on the micro controller will read a LOW, and when the dog collar is away from the fence, a HIGH will be read.  I could potentially put the output of the inverter into the input of another inverter and the output of the second inverer to the micro controller to allow a HIGH to indicate the collar being next to the boundary, and a LOW to indicate the collar being away from the boundary.

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;
}

Prototype Video - Nick Alioto

The main reason on why we built the prototype was to see if the collection mechanism can work. This video is proof that the concept does work. 


Arduino programming- Nick Alioto

Andrew has been working on the programming of the arduino mega. He has manage to get motors running and the ultra sonic sensor to sense. Matt has been helping with the electrical setup to the arduino.

Prototyping Vex- Nick Alioto

For the past week we have been working on a prototype for our robot. We choose to make it out of vex because we can build easily and fast. Andrew worked on the prototype chassis. Matt worked on the collection mechanism mount. I (Nick) worked on the collection mechanism discs and hopper. 

Thursday, January 30, 2014

Proposal- Nick Alioto

The Team started brainstorming on 1/21/14 for "Project Palmer" a robot that is used for ball collection. Our objective is to make sure that it can collect golf balls, baseballs, and tennis balls.
Andrew worked on Typing the proposal. Matt worked on visuals like a Gantt chart and robot sketches for the proposal. I (Nick) worked on creating the blog and created a block diagram for the proposal. - Nick