Modified Sonar code with the addition of the Modern Devices LCD117
April 3, 2011 Leave a comment
Here’s the new sonar code with temp compensation and the addition of the Modern Devices LCD117. All of the references to the LCD library (#include <LiquidCrystal.h>) are gone and the “SoftwareSerial” header file is referenced instead (#include <SoftwareSerial.h>).
Additionally, notice I had to add a function to display floating point numbers. I visited Peter H. Anderson’s site for directions to display floating point numbers on the LCD117. (Peter is the designer of the LCD117).
http://phanderson.com/arduino/arduino_display.html
Note: I’ll likely take temperature compensation out to save memory when we move the code to the rover. I don’t think it’s really necessary for object avoidance in a fast moving robot. However, it was beneficial for the grandson to learn how temperature affects the speed of sound in air.
——————————————————————————-
// Sonar with temp compensated ping and addtiion of LCD117
// Jim Winburn > http://www.apphipania.com
#include <SoftwareSerial.h>
//constants
#define rxPin 4 // rxPin is immaterial – not used
#define txPin 14 // pin 14 is analog pin 0, use a 3 wire servo cable
, see Reference pinMode
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);
const float sensor_gap =0.2;
const int pingPin = 7; //ping sensor
const int tempPin = 1; //TMP36 temperature sensor
const float supplyv = 5.0; //suply voltage
const float ts_offset = 3.86515625; //TM136 calibration offset
const int ts_multi = 30; // TM136 temp multi (calibration)
const float cm_to_in = 0.3937008; //convert cm to inches
//variables
float current_temp;
float duration, inches, cm, temp_f, comp_duration, comp_inches;
//——————————————————–
void setup()
{
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
pinMode(txPin, OUTPUT);
mySerial.begin(9600); // 9600 baud is chip comm speed
mySerial.print(“?G420″); // set display geometry, 4 x 20 characters in this case
delay(500); // pause to allow LCD EEPROM to program
mySerial.print(“?Bff”); // set backlight to ff hex, maximum brightness
delay(1000); // pause to allow LCD EEPROM to program
mySerial.print(“?s6″); // set tabs to six spaces
delay(1000); // pause to allow LCD EEPROM to program
mySerial.print(“?f”); // clear the LCD
delay(10);
mySerial.print(“?x00?y0″); // cursor to first character of line 0
delay(10);
mySerial.print(“Distance to object:”);
}
//————————————————————-
void loop()
{
// get current temp
current_temp = get_temp();
// measure distance
float duration = measure_distance();
// convert the time into a distance in inches
inches = microsecondsToInches(duration);
// adjust speed of sound by temp
//mpcm = microseconds_per_cm();
// adjust duration in cm by temp and sensor offset
comp_duration = microseconds_to_cm(duration);
// convert the time into an adjusted distance in inches
comp_inches = (comp_duration * cm_to_in); // cm to inches
//—————————————
mySerial.print(“?x00?y1″); // cursor to first character of line 1
mySerial.print(” “);
mySerial.print(“?x00?y1″); // cursor to first character of line 1
print_float(inches,2); // print var in floating point with # decimal points
mySerial.print(“?x07?y1″); // cursor to first character of line 1
mySerial.print(” Inches”);
//—————————————-
mySerial.print(“?x00?y2″); // cursor to first character of line 2
mySerial.print(” “);
mySerial.print(“?x00?y2″); // cursor to first character of line 2
temp_f = current_temp * 9/5 + 32; //convert temp in c to f
print_float(temp_f,2); // print var in floating point with # decimal points
mySerial.print(“?x07?y2″); // cursor to first character of line 2
mySerial.print(” Deg F”);
//——————————————-
mySerial.print(“?x00?y3″); // cursor to first character of line 3
mySerial.print(” “);
mySerial.print(“?x00?y3″); // cursor to first character of line 3
print_float(comp_inches,2); // print var in floating point with # decimal points
mySerial.print(“?x07?y3″); // cursor to first character of line 3
mySerial.print(” Comp Inches”);
delay(500);
}
//———-functions—————–
float microsecondsToInches(float 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 / 73.746 / 2;
}
//———————————————–
float get_temp() //return filtered temp in c
{
// apply smoothing filter
const int numReadings = 10;
int readings[numReadings]; // number of samples from temp sensor
int index = 0; // index of the current reading
int total = 0; // running total
int average = 0; // average
// initialize all the temp readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++)
{
readings[thisReading] = 0;
// apply filter and get current temp
total= total – readings[index];
// read from the sensor:
readings[index] = analogRead(tempPin);
// 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;
}
}
return average * supplyv * ts_multi /1024 + ts_offset; //tempc ;
}
//————————————————————–
const float microseconds_per_cm()
{
return 1/ ((331.5 +(0.6 * current_temp)) /10000);
}
//—————————————————————
const float sensor_offset()
{
return sensor_gap * microseconds_per_cm() * 2;
}
//—————————————————————
const float microseconds_to_cm(const unsigned long microseconds)
{
const float net_distance = microseconds-sensor_offset();
return net_distance/ microseconds_per_cm()/2;
}
//—————————————————————-
const unsigned long measure_distance()
{
// 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);
// get return time duration
return pulseIn(pingPin, HIGH);
}
//—————————————————————————-
void print_float(float f, int num_digits)
{
int f_int;
int pows_of_ten[4] = {1, 10, 100, 1000};
int multiplier, whole, fract, d, n;
multiplier = pows_of_ten[num_digits];
if (f < 0.0)
{
f = -f;
mySerial.print(“-”);
}
whole = (int) f;
fract = (int) (multiplier * (f – (float)whole));
mySerial.print(whole);
mySerial.print(“.”);
for (n=num_digits-1; n>=0; n–) // print each digit with no leading zero suppression
{
d = fract / pows_of_ten[n];
mySerial.print(d);
fract = fract % pows_of_ten[n];
}
}







