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("");

}