Introduction: DriveAlert

Picture of DriveAlert

The deaf and those with a hearing impairment often have a difficult time detecting an approaching emergency vehicle. DriveAlert is a product that will revolutionize driving for the deaf and those with hearing impairments. Emergency vehicles’ sirens fall into the frequency range of 0.5-3 kHz. If an emergency vehicle is approaching, DriveAlert will first detect the presence of this vehicle and will then give a visual indicator to the driver via an LED. Detection wise, an Arduino chipset will be connected to an array of microphone modules and will search for the specific sound of a siren. When the Arduino detects the sound of an emergency vehicle, it will send an electric signal to an LED array, which would be placed near the dashboard. The location of the LED array ensures that it is easily visible to the driver. The driver would be able to know that an emergency vehicle is approaching and would be able to promptly move out of the way.

Step 1: Purpose

To create a device that would warn deaf drivers of approaching emergency vehicles, in order for them to promptly move out of the way.

Step 2: Procedure

  • Develop a plan to design and implement all required components of the project
  • Design preliminary ideas and develop a prototype
  • Start construction of the device
  • Run tests on both the device capabilities and the code
  • Troubleshoot and fix bugs in the code

Step 3: Device Logic

  • Detect frequency of sound detected by microphone
    • If frequency is consistent with that of a siren, send signal to LED array to light up and alert driver
      • Turn LED array off after 300-800 milliseconds
  • If frequency is not consistent with that of a siren, wait 100 milliseconds and redetect frequency of sound

Step 4: Power System

Picture of Power System

  • The device uses 0.75 Watts to power the Arduino Micro, the Microphone, the LCD display, and the LED array.
  • The power is sent directly to the Arduino and is then relayed to the individual components.

Step 5: Parts List

Picture of Parts List

  • Arduino chipset
  • Arduino case
  • Arduino wiring
  • Arduino LCD display
  • Arduino microphone
  • LED strip with backpack
  • Soldering iron
  • Solder
  • Computer
  • Computer to Arduino connection wire

Step 6: Assembly

Picture of Assembly
  • Construct box to intended specifications
  • Wire LED to Arduino power
  • Wire LED array, microphone, and display to analog and digital pins (keep track of which pins you are using)
  • If you would like, create a housing for the microphone (as shown in the photo).
  • After wiring is complete, connect Arduino to computer and open up the Arduino program

Step 7: Programming

  • Program the device to detect incoming frequencies and see if they are within the range for sirens
  • I utilized a library called FreqPeriod to determine the frequency
  • Make sure the pin numbers that you used while wiring are the ones you send signals to from the code

The code I used is below (be sure to modify the pin numbers if you are using this; the code below is a modification of the code that was found with the library):

//clipping indicator variables

boolean clipping = 0;

//data storage variables

byte newData = 0;

byte prevData = 0;

unsigned int time = 0;//keeps time and sends vales to store in timer[] occasionally

int timer[10];//sstorage for timing of events

int slope[10];//storage for slope of events

unsigned int totalTimer;//used to calculate period

unsigned int period;//storage for period of wave

byte index = 0;//current storage index

float frequency;//storage for frequency calculations

int maxSlope = 0;//used to calculate max slope as trigger point

int newSlope;//storage for incoming slope data

//variables for decided whether you have a match

byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long

byte slopeTol = 3;//slope tolerance- adjust this if you need

int timerTol = 10;//timer tolerance- adjust this if you need

//variables for amp detection

unsigned int ampTimer = 0;

byte maxAmp = 0;

byte checkMaxAmp;

byte ampThreshold = 10;//raise if you have a very noisy signal

const int ledPin = 13;

int ledState = LOW;

unsigned long previousMillis = 0;

const long interval = 1000;

void setup(){

Serial.begin(9600);

Serial.println("Program Initiated");

pinMode(ledPin, OUTPUT);//led indicator pin

pinMode(12,OUTPUT);//output pin

pinMode(9,OUTPUT);

cli();//diable interrupts

//set up continuous sampling of analog pin 0 at 38.5kHz

//clear ADCSRA and ADCSRB registers

ADCSRA = 0;

ADCSRB = 0;

ADMUX |= (1 << REFS0); //set reference voltage

ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only

ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz

ADCSRA |= (1 << ADATE); //enabble auto trigger

ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete

ADCSRA |= (1 << ADEN); //enable ADC

ADCSRA |= (1 << ADSC); //start ADC measurements

sei();//enable interrupts

}

ISR(ADC_vect) {//when new ADC value ready

PORTB &= B11101111;//set pin 12 low

prevData = newData;//store previous value

newData = ADCH;//get value from A0

if (prevData < 127 && newData >=127){//if increasing and crossing midpoint

newSlope = newData - prevData;//calculate slope

if (abs(newSlope-maxSlope)

//record new data and reset time

slope[index] = newSlope;

timer[index] = time;

time = 0;

if (index == 0){//new max slope just reset

PORTB |= B00010000;//set pin 12 high

noMatch = 0;

index++;//increment index

}

else if (abs(timer[0]-timer[index])

//sum timer values

totalTimer = 0;

for (byte i=0;i

totalTimer+=timer[i];

}

period = totalTimer;//set period

//reset new zero index values to compare with

timer[0] = timer[index];

slope[0] = slope[index];

index = 1;//set index to 1

PORTB |= B00010000;//set pin 12 high

noMatch = 0;

}

else{//crossing midpoint but not match

index++;//increment index

if (index > 9){

reset();

}

}

}

else if (newSlope>maxSlope){//if new slope is much larger than max slope

maxSlope = newSlope;

time = 0;//reset clock

noMatch = 0;

index = 0;//reset index

}

else{//slope not steep enough

noMatch++;//increment no match counter

if (noMatch>9){

reset();

}

}

}

if (newData == 0 || newData == 1023){//if clipping

PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led

clipping = 1;//currently clipping

}

time++;//increment timer at rate of 38.5kHz

ampTimer++;//increment amplitude timer

if (abs(127-ADCH)>maxAmp){

maxAmp = abs(127-ADCH);

}

if (ampTimer==1000){

ampTimer = 0;

checkMaxAmp = maxAmp;

maxAmp = 0;

}

delay(50000);

digitalWrite(9, HIGH);

}

void reset(){//clea out some variables

index = 0;//reset index

noMatch = 0;//reset match couner

maxSlope = 0;//reset slope

}

void checkClipping(){//manage clipping indicator LED

if (clipping){//if currently clipping

PORTB &= B11011111;//turn off clipping indicator led

clipping = 0;

}

}

void loop(){

checkClipping();

if (checkMaxAmp>ampThreshold){

frequency = 38462/float(period);//calculate frequency timer rate/period

//print results

Serial.print(frequency);

Serial.println(" hz");

if (frequency>1166 && frequency<1201.93){

ledState = HIGH;

digitalWrite(ledPin, ledState);

delay(1000);

ledState = LOW;

digitalWrite(ledPin, ledState);

Serial.println("Detected");

}

else if (frequency>1131 && frequency<1164){

ledState = HIGH;

digitalWrite(ledPin, ledState);

delay(500);

ledState = LOW;

digitalWrite(ledPin, ledState);

Serial.println("Detected");

}

else if (frequency>1201.95 && frequency<1241){

ledState = HIGH;

digitalWrite(ledPin, ledState);

delay(500);

ledState = LOW;

digitalWrite(ledPin, ledState);

Serial.println("Detected");

}

else if (frequency>2960 && frequency<3200){

ledState = HIGH;

digitalWrite(ledPin, ledState);

delay(500);

ledState = LOW;

digitalWrite(ledPin, ledState);

Serial.println("Detected");

}

else if (frequency>895 && frequency<910){

ledState = HIGH;

digitalWrite(ledPin, ledState);

delay(500);

ledState = LOW;

digitalWrite(ledPin, ledState);

Serial.println("Detected");

}

}

delay(100);//delete this if you want

}

Step 8: Conclusion

Picture of Conclusion
  • The device was able to accurately detect a siren over 70% of the time
  • This product will hopefully change the lives of many for the better

DriveAlert

Comments

About This Instructable

1,379views

8favorites

Bio: The BCAMRL is a Mechatronics Research Lab, found on the campus of Bergen County Academies a magnet high school within the Bergen County Technical School ... More »
More by bcamrl:IR Communication in Swarming Robotics for Search and RescueElderly Sleep Safe (E.S.S.)Sudden Infant Death Syndrome Crib
Add instructable to: