I am working on a similar project but it's for my robot. Right now I've got the scan and display the map on a Nokia LCD using a Ping ultrasonic sensor. Why Ping? Because it has the fastest response. I got it scan left to right and right to left and display the objects on the display. It's so fast, I wish this could be done with Sharp sensors for greater accuracy. But the Sharp sensors take several measurements and average them internally and output the result over a 39ms period. And that is not good enough, we also need to average a few scans to get the proper distance. This slows down the scanning greatly. My next step is to use 2 long distance Sharp sensors mounted at 45 degrees on each side of the Ping sensor and scan only 90 degrees taking measurements with both sensors at once. I will also scan with the Ping sensor and display the results on the same map using different colors. Perhaps I'll use the Ping when I need to fast scan and the Sharps for a greater accuracy scan.
Edit: forgot to add that my robot has encoders and an I2C compass that I intend to use for map following after I get the scanning stuff completed.
Here is a video:
Here is the code I have so far:
/*
Scan and display map on Nokia LCD (Epson).
Ping sensor on a pan servo.
Created by Gabriel Petrut, Oct 27th, 2009.
Released into the public domain.
*/
#include <NokiaLCD.h>
#include <SoftwareServo.h>
#define PanPin 16
#define PingPin 15
// Nokia LCD Setup settings
// Basic Colors
#define WHITE 0xFFF
#define BLACK 0x000
#define RED 0xF00
#define GREEN 0x0F0
#define BLUE 0x00F
#define CYAN 0x0FF
#define MAGENTA 0xF0F
#define YELLOW 0xFF0
#define BROWN 0xB22
#define ORANGE 0xFA0
#define PINK 0xF6A
// Nokia LCD pins:
#define CSE 4
#define RST 5
#define SDA 11
#define SCK 13
#define MapXcenter 65
#define MapYcenter 35
SoftwareServo Pan;
NokiaLCD nokiaLcd;
byte PingDistance = 0;
byte USValue[181];
byte x=0;
byte y=0;
byte a=0;
char text [50];
char byteString[4];
void setup()
{
pinMode(CSE, OUTPUT);
digitalWrite(CSE, HIGH);
pinMode(SCK, OUTPUT);
digitalWrite(SCK, HIGH);
pinMode(SDA, OUTPUT);
digitalWrite(SDA, HIGH);
pinMode(RST, OUTPUT);
digitalWrite(RST, HIGH);
pinMode(PingPin, OUTPUT);
digitalWrite(PingPin, LOW);
Pan.attach(PanPin);
Pan.write(80);
SoftwareServo::refresh();
nokiaLcd.lcd_init();
delay(500);
}
void loop()
{
ScanMap();
}
void ScanMap()
{
nokiaLcd.lcd_clear(BLUE, 0, 0, 131, 131);
strcpy(text,"o");
nokiaLcd.lcd_draw_text(PINK, BLACK, (131-MapXcenter-3), (131-MapYcenter), text);
for (a=0; a<181; ++a)
{
ScanAndDisplay();
}
delay(1000);
nokiaLcd.lcd_clear(BLUE, 0, 0, 131, 131);
strcpy(text,"o");
nokiaLcd.lcd_draw_text(PINK, BLACK, (131-MapXcenter-3), (131-MapYcenter), text);
for (a=180; a>0; --a)
{
ScanAndDisplay();
}
delay(1000);
}
void ScanAndDisplay()
{
Pan.write(a);
SoftwareServo::refresh();
USValue[a] = Read_Ping_Sensor();
if (USValue[a]<200)
{
byte pos=57;
if (USValue[a]<100)
{
strcpy(text," ");
nokiaLcd.lcd_draw_text(CYAN, BLACK, pos, 115, text);
pos=63;
}
itoa(USValue[a], byteString, 10);
strcpy(text, byteString);
nokiaLcd.lcd_draw_text(CYAN, BLACK, pos, 115, text);
// multiply the angle° of the servo by 0.01745 etc to convert to radians - a is the angle of the servo ( 90° is to twist result sideways for display)
x=131-(MapXcenter+USValue[a]*(sin((a-90)*0.0174532925)));
y=131-(MapYcenter+USValue[a]*(cos((a-90)*0.0174532925)));
nokiaLcd.LCD_put_pixel(CYAN, x, y);
}
}
// Read Sensors
int Read_Ping_Sensor() {
//trigger the sensor
int Ping = 0;
pinMode(PingPin, OUTPUT);
digitalWrite(PingPin, LOW);
delayMicroseconds(2);
digitalWrite(PingPin, HIGH);
delayMicroseconds(5);
digitalWrite(PingPin, LOW);
//receive the echo
pinMode(PingPin, INPUT);
digitalWrite(PingPin, HIGH); // turn on pull up resistor
Ping = pulseIn(PingPin, HIGH);
return Ping/29/2;
}