/*
Parking Assistant Using Range Sensor
Created by Mark Slemko - October 5, 2013
Parts taken from: http://arduino.cc/en/Tutorial/AnalogInput
refined 2015-10-17
- adjusted to accomodate shorter distance
refined 2021-01-31
- adjusted to clarify code, clean up, and to work on arduino pro mini
*/
#include <math.h>
#include <SoftwareSerial.h>
SoftwareSerial Serial7Segment(8, 9); //RX pin, TX pin
int pingPin = 2; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
int colorR = 7;
int colorGnd = 6;
int colorG = 4;
int colorB = 5;
int settleTime = 5000; // when same value is reached for this time, stop checking as often
int recheckTime = 0;
int timer = 0;
double settleDistance = 0.0;
double variance = 2.0;
#define STOP_DISTANCE 70.0
#define STOP_BRACKET 6.0
#define MAX_RECHECK_TIME 2000
#define NORMAL_RECHECK_TIME 100
#define SENSOR_ACTIVE 250.0
#define SENSOR_TOO_CLOSE 20.0
#define LED_ACTIVE_PING_INDICATOR_TIME 10
void setColor( int r, int g, int b) {
digitalWrite(colorGnd, LOW);
digitalWrite(colorR, r);
digitalWrite(colorG, g);
digitalWrite(colorB, b);
}
void setup() {
// declare the ledPin as an OUTPUT:
pinMode(ledPin, OUTPUT);
pinMode(colorR, OUTPUT);
pinMode(colorGnd, OUTPUT);
pinMode(colorG, OUTPUT);
pinMode(colorB, OUTPUT);
setColor(LOW, LOW, LOW);
Serial.begin(9600);
Serial7Segment.begin(9600); //Talk to the Serial7Segment at 9600 bps
Serial7Segment.write('v'); //Reset the display - this forces the cursor to return to the beginning of the display
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 343 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.
double cm = (double)microseconds / 58.32; // 29.16 * 2 us
return (long)cm;
}
long sonicPing() {
long duration, cm;
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(10);
digitalWrite(pingPin, LOW);
delayMicroseconds(20);
// 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) - 350;
Serial.print(duration);
Serial.print("us ");
cm = microsecondsToCentimeters(duration);
return cm;
}
void loop() {
// read the value from the sensor:
double distance = sonicPing();
Serial.print(distance);
Serial.print("cm ");
// display the distance
char tempString[10]; //Used for sprintf
sprintf(tempString, "%4d", (int)distance); //Convert deciSecond into a string that is right adjusted
Serial7Segment.print(tempString);
// give visual indication that a ping occurs
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(LED_ACTIVE_PING_INDICATOR_TIME); // stop the program for a few milliseconds to show a ping just occurred
digitalWrite(ledPin, LOW); // turn the ledPin off:
Serial.print(" wait ");
bool settledTimeReached = checkSettleTimeReached(distance);
timer += NORMAL_RECHECK_TIME; // increment timer
// check if settle time reached to turn off LED
if (settledTimeReached) {
// turn off LED
setColor( LOW, LOW, LOW);
recheckTime = timer;
if (recheckTime < settleTime) {
if (recheckTime > MAX_RECHECK_TIME) {
recheckTime = MAX_RECHECK_TIME;
}
} else {
timer = recheckTime = settleTime;
}
// turn off RGBLED
setColor( LOW, LOW, LOW);
} else {
recheckTime = NORMAL_RECHECK_TIME;
setColor( LOW, LOW, LOW);
if (shouldShowStopLED(distance)) {
if (distance < (STOP_DISTANCE - STOP_BRACKET)) {
// too close - blue on
setColor( HIGH, HIGH, HIGH);
Serial.print(" too close ");
} else if (distance > (STOP_DISTANCE + STOP_BRACKET)) {
// too far - green on
setColor( LOW, HIGH, LOW);
Serial.print(" too far ");
} else {
// perfect - red on
setColor( HIGH, LOW, LOW);
Serial.print(" stop ");
}
}
}
Serial.print(" delay recheck ");
Serial.print(timer);
delay(recheckTime); // wait for next check
Serial.println("");
}
boolean shouldShowStopLED(double distance) {
//abs(distance - STOP_DISTANCE) < (variance * (1.0 + distance / 50.0)) + (STOP_BRACKET * 2)) {
if ( abs(distance) < SENSOR_ACTIVE && abs(distance) > SENSOR_TOO_CLOSE) {
return true;
}
return false;
}
boolean checkSettleTimeReached(double distance) {
boolean delta = abs(settleDistance - distance) > (variance * (1.0 + distance / 100.0));
// if the delta is too big, reset the timer
if (delta) {
timer = 0;
}
if (timer < settleTime) {
settleDistance = distance;
return false;
} else {
return true;
}
}
These are baically notes for me, but it might help someone else.
Needless to say, you can’t connect an iphone to Linux yet without jail-breaking your phone, or buying another computer with a ‘supported’ OS like mac or windows.
Bah!
Update: using Fedora 15 or later, the iPhone does connect under Linux and you can browse it! Wooh!
Nevertheless, the tools on Linux are fantastic to edit sound and do gobs of other stuff…
1) ring tones have to be less than 30 seconds in length… so use Audacity to edit your favourite audio file to a nice <30 second clip.
2) Save that selection as a .wav (16 bit stereo PCM) file.
3) in a command prompt type something like this:
faac -b 128 -c 44100 -w --title TITLE mysound.wav
and it will produce something like mysound.m4a
4) rename it to be mysound.m4r (because ringtones are aac with the .m4r extension — whatever)
5) transfer that on your iTunes 'supported' OS (bah – ridiculous) that you can connect your iPhone to and transfer the file into the ringtones folder.
6) sync the iphone.
done.