Acoustics

Enter Your Electronics & Design Project for a chance to win an $200 Shopping cart of product!

Back to The Project14 homepage

Project14 Home
Monthly Themes
Monthly Theme Poll

 

PREFACE:

This project is centered around acoustics and designed to protect our home.  I want a system that doesn't have to wait until a door is kicked in or a window is broken to trigger.  I also don't want a laser beam that they can maneuver around.  The goal is to make a sensor system that will provide an orb of protection around my back porch impossible to infiltrate without triggering the alarm.

 

Pressed for time?  Just view the pictures and read the bold captions!  You'll get it!  Have time to spare?  I'll wear you out with the details.

 

TABLE OF CONTENTS

 

Protecting our Home with the Ultrasonic Owl Orb of Protection

 

INTRODUCTION

To pull off the orb of protection, we'll leverage popular tech that has emerged in the last several years in the automotive industry - backup radar.  These weatherproof sensors provide a wide band of proximity detection and a unit can be purchased for just $10!

Parking Sensor Kit1 - Our Orb of Protection

$10 gets you 4 Weather Proof Sensors, a Hole Saw, A Display (won't need it), and a Brain box

Hacking the brain box will allow us to use this with our own code

for a Smart Home Monitoring System

 

The kicker of the project is to hack into the inexpensive kit to allow our own communication with the sensors.  In turn, we can add plenty of smarts to appropriately handle just about any scenario.

 

Since this blog is around acoustics, in addition to ultra sonics, we'll experiment with an amp circuit while we are at it.

PROJECT BILL OF MATERIALS

 

 

ULTRASONIC TECHNOLOGY

Car parking sensors use ultrasound, which is an acoustic wave with a very high frequency.  The frequency is beyond human hearing above 20kHz. What is amazing about it is how "loud" it is.  It sends out a inaudible scream at over 100dB - "louder" than a motorcycle, but does not cause human ear damage.

Ultrasonic Sensor Angle and Distance Image2

With that short wave length, it has a good shaped beam which allows for reliable measurements for sensing objects.  Also, since it is sound travelling through air, it travels nominally at 340m/s.  That's slow in the world of electrons, so, inexpensive devices can measure the time it takes to "bounce back" easily.

 

REVERSE ENGINEERING

To hack the parking sensor, we simply need to figure out how the brain box is communicating to the monitor.  Web searches showed a couple of blogs from over 7 years ago on the Arduino.  It appears different parking sensor kit manufacturers take different approaches for the communication protocol, so we have to do this from scratch.

 

With the bare eye, you can see that there are four (4) wires going to the sensor kit display monitor.  With jumpers, we'll add a breadboard in between the brain box and monitor so we can safely probe without accidentally shorting pins and frying the circuit boards.

 

Installing a breadboard between the brain box and monitor allows me to probe safely while trying to hack its communication protocol

 

Now with 4 wires, we know what two of them are for, right? You have to power that monitor, so they have to be a hot and ground.  I'm hoping for 5V so I can power my Arduino.  Since it's automobile tech, the brain box has a 12V nominal source.  Based on experience with displays for microcontrollers, it's more than likely the monitor is powered by no more than 5V, but we'll see.  To start, I'll look for continuity to ground.

 

I set the ohmmeter to beep if I have continuity as I expect zero resistance to ground from the monitor's ground pin.  Not knowing which it is, I touch each wire that connects to the monitor to the ground pin of the brain box until I get a beep.  Once I got that one, I have three more to figure out.  I find one that is a solid 5V.  That must power the monitor and it will power my Arduino.  The other two seem to be reading all over the place.

 

Probing for 5V and a Ground

 

Now, one thing that is going on is a bunch of beeping from the monitor.  The out-of-the-box system is designed to do this to alert the vehicle driver to things getting close.  So, I lift one jumper and then the other.  The beeping stopped.  That second wire is simply pulsing out 5V from the brain box to a piezo beeper in the display monitor case!

 

Last, we need to know what is going on with that final wire.  It's all that is left that could be our communication from the brain box to the monitor.  If I can tap that, I can do anything I want with proximity data versus just hear an annoying beep.

 

To determine the protocal, I first consider that I only have one wire left.  So, I'm ruling out I2C and SPI because they use a second wire that sets the beat to coordinate the "morse code" of their protocols.  Serial communication could be an option because it is a "fire and forget" protocal.  It's up to you to get the beat and decipher.  It also could be some custom pulse width modulation (PWM).  This is a good time for an oscilloscope.  So I hooked up my Keysight DSOX1102GKeysight DSOX1102G to see what I could find.

 

With the ground and power already found, an oscilloscope, allows me to study the signal of the final unknown wire

 

Often, serial communication has a long pulse, which we do have here, followed by 8 segments that may be high or low.  The width between each segment is fixed.  By measuring the shortest high pulse, I can assume that is the period - and in turn, the corresponding baud rate.  In this case it does correspond to 9600 baud, which seems plausible.  But, what doesn't seem plausible is that we have way more than 8 segments here.  In fact, after the long pulse, the count of the beat is not evenly divisible by eight (8).

 

This tells me they have made their own "morse code" messaging system using Pulse Width Modulation of 5Vs.  So, we'll have to experiment to figure it out.  This time, I'm going to hook up a logic analyzer so it will pretty up the signals with clean edges and allow me to quickly screen capture.  If you don't have an oscilloscope, but have a PC or laptop, this is a crazy inexpensive tool to allow you to reach your inner hacker.  They are under $15 US bucks.

My Logic Analyzer shows a discernible pattern as I switch sensor ports and move my hand in front of the sensor

Doing this, I can decipher the code!

 

To experiment, I plugged one sensor into one port at a time.  It appears the data is segmented after a very long pulse.  (By long, I mean compared to the other pulses.)  You can see there are 4 bytes of pulses here - a byte representing each sensor port.  Short pulses are zero and long pulses are a 1.  When the sensor is plugged in, the start of the byte turns to 000 instead of 111.

 

Eureka!  Reverse Engineered!  The communication protocol is as follows:

    • 1 very long start pulse (code will wait for a pulse this long before calling the parse routine)
    • 1 short start pulse (throw away bit)
    • short pulse mean zero in each period, long pulses mean one
    • 4 bytes worth pulsed out for each packet, each representing a sensors data in order of Sensor A, D, C, B
    • If first 3 bits are a zero in the byte, the sensor is recognized.  Last 5 bytes are binary for decimeters

 

With the code cracked, we now can build our porch!

 

BUILDING THE PORCH

Coincidentally, I was in the middle of a porch build anyway.  Also, coincidentally, someone on my side of town had their house broken into.  The theif simply forced open the back door.  The e14 challenge, my porch, and the theft gave me the idea for the Orb of Protection.  My porch railing layout could be designed to ensure an intrudor would have to enter the orb if they are attempting to get in the house.

 

Per my usual M.O., I spent way too long visualizing and designing with Autodesk Fusion 360.  However, it allowed me to get it exactly the way my wife liked it before I started building. 

 

To Roost the Owl, Autodesk Fusion 360 is a Great Tool to Design the Porch

A Double Beam and 4x4 Posts make the Porch Rock Solid

 

To Give It Even More Rock Solid Feel, I'll Go with a Faux Stone Exterior

 

Our original stairs were falling apart and not built with structural integrity in mind.  The previous owner used deck screws to pin a board under the doors and added on from there.  Not very informed was he.  He needed a book6.

 

Our new porch allows one to be able to step outside on a platform, shut the door, and then go to the patio.

Original Hazardous and Poorly Designed Porch

 

Installing a Ledger Board with Lab Screws - Strong Enough to Hold a Tank

 

Framing it Up - Note the Extra Support in the Traffic Zone

 

Sheathing it with a Nice Stone Look - Note the Double Beam Underneath

 

Laying the Composite Decking-  Shims are Great Spacers

 

 

 

Still More to Go, but Enough To Land Our Orb of Protection

Autodesk Fusion 360 Served us Well

 

 

 

That's far enough to direct traffic for now.  I'm hitting the pause button on finishing the porch so I can enable the Orb of Protection.  We'll finish the porch once the weather improves.

 

BUILDING THE ORB GENERATOR

My first thought was to design in the ultrasonic sensor directly into the porch.  This would be cool, but, since we will be moving in a few years, I elected not to perforate my porch and house header joist to pull this one off.  That's better left for my retirement house.  So, I elected to make the ORB generator from our owl decoy that sits on the back porch to keep birds away.

The Owl Brains

My Microcontroller of choice on this project is the Arduino MKRZero.  It has plenty of pins and an onboard DAC to allow me to send audio out to a custom built ampliefier.  The Arduino talk to the car parking sensor kit brain box to get the most current data from each of the four (4) sensors.  When something looks suspicious, it will play an audio file to let the stranger know that the owner's have been notified of their presence.  The Arduino will drop a pin from high to low to signal to an ESP8266 that it is in alarm mode.  The ESP8266 will handle the IoT function of notifying us via cell phone.

 

With the Sensor Kit Hacked, the Arduino MKR Zero will be the smarts!

Arduino MKR Zero - Plenty of pins and great for audio applications

 

 

The Circuits

For the amplifier and speaker circuit, we can use the LM386.  Below is the example 200 Gain circuit straight from its datasheet.  I just hook Vin to DAC0 (Digital to Analog 0 Output).  A good snip of code to start with is right on the Arduino Website3.

 

LM368 Datasheet Circuit4

This circuit will be a good start for experimenting with the amplifier circuit.

 

 

 

My Hybrid Amplifier Circuit from the Two (2) Data Sheet Examples

 

A little 8 Ohm 1/2W speaker ended up being plenty for what I'm looking to achieve.  I varied my QJE PS3005QJE PS3005 power source between 5V and 12V and found less distortion at12V.  Even after I shortened my jumpers on the breadboard, it would pick up radio waves, so I'm counting on a soldered protoboard not doing that.

 

 

Doing a little tinkering, I found the radio interference (an actual radio talk show) was loudest when the power lines from my bench power supplies were hooked up.  Changing to a 9V battery with small leads, the interference of the talk show was still there, but it made it quieter.  Adding capacitors on pin 6 greatly helped to kill the noise.  Once I got the board soldered up, it was definitely quiet to be of issue sitting on the porch.  In a future design, I'll add a transistor to cut power if nothing is going on, so it will sit there and not make any noise at all.

 

 

MY COMPLETE CIRCUIT WITH ARDUINO MKRZERO, ESP8266, AND LM386 AMP

 

CIRCUIT BOARD LAYOUT OF THE OWL ORB OF PROTECTION

We get 12V in.  The car parking brain box has a 5V out to feed

the Arduino MKRZero.  The MKRZero has a 3.3V to feed the ESP8266.  Nice!

 

 

I soldered on headers first - this allows me to easily check for continuity and shorts

 

 

I connected 5V with a test script and it hit Push Bullet - no shorts!

 

 

The Enclosure

The enclosure is pretty much just a box.  We designed it to be silicone'd in to prevent water intrusion.  We'll stick some bricks around it to dress it up.

 

3D Printed Enclosure to Hold the Brains

The Code

The code is very straight forward.  You wait for that long pulse and then start "If Then'ing" your way to logging the morse code pulsing by.  To auto calibrate against stationary objects around the orb, the program keeps track of recent distances of each sensor.  To detect something coming into its "orb", it looks for a shift from any sensor that would indicate an object just got closer.  It then goes through its alarm routine which will hit Push Bullet to alert my mobile phone of the activity.  It also then states to the intruder that they are about to be arrested.

 

First, I needed to tune my algorithm to the pulse timing.  So, I whipped up this little diddy:

 

int pin = 0;
unsigned long pulse_length;
unsigned long first_pulse;
byte sensorValue[32];
unsigned long lengths[32];
byte pulse_value;
void setup()
{
  pinMode(pin, INPUT);
  Serial.begin(115200);
  delay(1000);
  Serial.println("Starting...");
}
void loop()
{
  Serial.println("Loop Start!");
  delay(1000);
  int i;
  //look for starter pulse
  pulse_length = pulseIn(pin, HIGH);  
  
  // wait for the long pulse to signify the start
  while (pulse_length < 1900) {
    pulse_length = pulseIn(pin, HIGH);
  }
  first_pulse=pulse_length;
  
  // consume the throw away bit
  pulse_length = pulseIn(pin, HIGH);
  // Get the 32 bits to follow
  for (i = 0; i < 32; i = i + 1) {
    pulse_length = pulseIn(pin, HIGH);
    while (pulse_length<50) {
      pulse_length = pulseIn(pin, HIGH);
    }
    if (pulse_length < 150) {
      pulse_value = B1;
    }
    else {
      if (pulse_length > 1000) {
        Serial.println("Overran!");
        delay(1000);
        break;
      }
      pulse_value = B0;
    }
    sensorValue[i] = pulse_value;
    lengths[i]=pulse_length;
  }
  Serial.println(" ");
  Serial.print("First:");
  Serial.println(first_pulse);
  for (i = 0; i < 30; i = i + 1) {
    Serial.print(sensorValue[i], BIN);
  }
  Serial.println(" ");
  for (i = 0; i < 30; i = i + 1) {
    Serial.println(lengths[i]);
  }
}

 

 

Arduino MKRZero Tapped into the Sensor Module for Calibration of the Sensors
Kitchen tables are great for getting the entire family Involved.

 

With a little help from Tank the Cat and my e14 Presents breadboard, I was able to tap the signal line and tweak my code's if..then's until I got the expected results:

First:1938
111110110000000000000000000000 
101
93
101
101
101
202
101
101
202
202
200
194
202
202
194
202
202
200
202
202
200
202
202
200
194
202
202
192
202
202
Loop Start!

 

As you can see, the short pulses are consistently around 100 and the long pulses 200.  A pulse near 1900 is the trigger pulse to let you know the packet is about to start.  There is also a throw away pulse after the trigger that doesn't seem to signify anything.

 

We can now slap in some ArduinoZero.play() logic on the Arduino MKRZero and some IoT code on the ESP8266 to sound the alarm.  If you ever need to do some IoT code from Arduino or Linux based microcontrollers, I provided just about every spin on it in a 5 part blog series called Home Automation Mojo You Must Know.5

 

To sound the alarm, I use the MKRZero to pull a pin low to signal the ESP8266 to use its epic WiFi prowess to alarm.

 

Arduino MKRZero Code:

#include <SD.h>
#include <SPI.h>
#include <AudioZero.h>
int sense_pin = 0;
int alarm_pin = 1;
unsigned long pulse_length;
unsigned long first_pulse;
int sensorValue[32];
unsigned long lengths[32];
int pulse_value;
float A, B, C, D;
float averageDistance, lastAverage;
int first_few_counter=0;
void setup()
{
  Serial.begin(115200);
  delay(1000);  
  A=0;B=0;C=0;D=0;
  averageDistance=0;lastAverage;
  pinMode(sense_pin,INPUT);
  pinMode(alarm_pin,OUTPUT);
  digitalWrite(alarm_pin,HIGH); // Leave it high and pull it low to alarm.
  digitalWrite(A0,HIGH); //kills noise on the line;  
  if (!SD.begin(SDCARD_SS_PIN)) {
    Serial.println(" failed!");
    while(true);
  }  
  Serial.println("Starting...");
  delay(1000);
  PlaySound("owlHello.wav");
}
void loop() {
  Sense();
  delay(2000);
}
void Sense()
{  Serial.println("Sensing...");
  delay(1000);
  int i;
  //look for starter pulse
  pulse_length = pulseIn(sense_pin, HIGH);  
  
  // wait for the long pulse to signify the start
  while (pulse_length < 1900) {
    pulse_length = pulseIn(sense_pin, HIGH);
  }
  first_pulse=pulse_length;
  
  // consume the throw away bit
  pulse_length = pulseIn(sense_pin, HIGH);
  // Get the 32 bits to follow
  for (i = 0; i < 32; i ++) {
    pulse_length = pulseIn(sense_pin, HIGH);
    if (pulse_length < 180) {
      pulse_value = 0;
    }
    else {
      if (pulse_length > 1000) {
        Serial.println("Overran!");
        delay(1000);
        return; // just exit out of the routine if it fails to sense correctly this time through.
      }
      pulse_value = 1;
    }
    sensorValue[i] = pulse_value;
    lengths[i]=pulse_length;
  }
  // Sensor A
  if (sensorValue[0]==0) {
    //String sensorA=String(sensorValue[3])+String(sensorValue[4])+String(sensorValue[5])+String(sensorValue[6])+String(sensorValue[7]);
    //Serial.println(sensorA);
    A=16*sensorValue[3] + 8*sensorValue[4] + 4*sensorValue[5] + 2*sensorValue[6] + sensorValue[7];
    A=A/(10*.3048); // convert decimeters to feet
    Serial.println(A);
  }
 
  // Sensor D
  if (sensorValue[8]==0) {
    D=16*sensorValue[11] + 8*sensorValue[12] + 4*sensorValue[13] + 2*sensorValue[14] + sensorValue[15];
    D=D/(10*.3048); // convert decimeters to feet
    Serial.println(D);
  }
  
  // Sensor C
  if (sensorValue[16]==0) {
    C=16*sensorValue[19] + 8*sensorValue[20] + 4*sensorValue[21] + 2*sensorValue[22] + sensorValue[23];
    C=C/(10*.3048); // convert decimeters to feet
    Serial.println(C);
  }
  
  // Sensor B
  if (sensorValue[24]==0) {
    B=16*sensorValue[27] + 8*sensorValue[28] + 4*sensorValue[29] + 2*sensorValue[30] + sensorValue[31];
    B=B/(10*.3048); // convert decimeters to feet
    Serial.println(B);
  }
  averageDistance=(A+B+C+D)/4;
  if (((abs(lastAverage-averageDistance))/lastAverage)>.1) alarm();
  lastAverage=averageDistance;
}
void alarm(){
  if (first_few_counter++<3) return; // this keeps it from triggering when you first set it down and turn it on.
  digitalWrite(alarm_pin,LOW);
  PlaySound("alarm.wav");
  delay(5000);
  digitalWrite(alarm_pin,HIGH);
}
void PlaySound(String the_sound)
{
  File myFile;
  // open wave file from sdcard
  myFile = SD.open(the_sound);
  
  // until the file is not finished  
  AudioZero.begin(44100);
  AudioZero.play(myFile);
  myFile.close();
  AudioZero.end();
  digitalWrite(A0,HIGH); //kills noise on the line;
}

 

ESP8266 Code:

#include <ESP8266WiFi.h>  
#include <WiFiClientSecure.h>  
const char* ssid = "YOURSSID";  
const char* password = "YOURPASSWORD";  
const char* host = "api.pushbullet.com";  
const int httpsPort = 443;  
const char* PushBulletAPIKEY = "YOURPUSHBULLETKEY"; //get it from your pushbullet account  
// Use web browser to view and copy SHA1 fingerprint of the certificate.  Click the lock by the address in the browser and then click view certificate.  
// Alternately, go to https://www.grc.com/fingerprints.htm and enter api.pushbullet.com  
const char* fingerprint = "BB FC 9F 1B C1 3C D9 96 F2 68 A2 E3 41 29 D1 47 8F B9 33 BE";   
void setup() {  
  Serial.begin(115200);  
  Serial.println();  
  Serial.print("connecting to ");  
  Serial.println(ssid);  
  WiFi.mode(WIFI_STA);  
  WiFi.begin(ssid, password);  
  while (WiFi.status() != WL_CONNECTED) {  
    delay(500);  
    Serial.print(".");  
  }  
  Serial.println("");  
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");  
  Serial.println(WiFi.localIP());  
  pushBullet("The Owl Orb of Protection Has Started!");  
  pinMode(2,INPUT_PULLUP);  
}  
void pushBullet(String the_msg){  
      // Use WiFiClientSecure class to create TLS connection  
      WiFiClientSecure client;  
      Serial.print("connecting to ");  
      Serial.println(host);  
      if (!client.connect(host, httpsPort)) {  
        Serial.println("connection failed");  
        return;  
      }  
      
      if (client.verify(fingerprint, host)) {  
        Serial.println("certificate matches");  
      } else {  
        Serial.println("certificate doesn't match");  
      }  
      String url = "/v2/pushes";  
      String messagebody = "{\"type\": \"note\", \"title\": \"ESP8266\", \"body\": \""+the_msg+"\"}\r\n";  
      Serial.print("requesting URL: ");  
      Serial.println(url);  
      
      client.print(String("POST ") + url + " HTTP/1.1\r\n" +  
                   "Host: " + host + "\r\n" +  
                   "Authorization: Bearer " + PushBulletAPIKEY + "\r\n" +  
                   "Content-Type: application/json\r\n" +  
                   "Content-Length: " +  
                   String(messagebody.length()) + "\r\n\r\n");  
      client.print(messagebody);  
      
      Serial.println("request sent");  
      
      //print the response  
      
      while (client.available() == 0);  
      
      while (client.available()) {  
        String line = client.readStringUntil('\n');  
        Serial.println(line);  
      }      
}  
void loop() {  
  delay(200);  
  if (digitalRead(2)==LOW) {//Wait for pin 2 to go to ground to trigger.  
    pushBullet("The back porch alarm has been sounded!");  
    delay(5000);  
  }  

 

Before poking the owl's eyes out, I thought I'd run it through a desktop test first.  This was shot with a "speaker bomb" as I had yet to make the custom circuit board:

Table Test of the Code and Sensors

The Build

Now that we have working sensors, brains, and audio, we are ready to outfit our decoy owl with the gear.  We first had to pluck out his eyeballs:

 

Connor Removed His Eyeballs with a Prybar Synonym

This made way for two sensors

 

He drilled out the eye socket with the hole saw from the Car Radar Kit

 

He then fished the sensor cable through.

 

The Bird Has a Bunghole for Filling with Sand

Sounds like a personal problem.

That is where we will tie in our brain box.

We'll do a little 3D Printing magic and siliconing to keep it water tight and wind resistant.

 

 

Since the Hole is Perfectly Sized, We Get the Confirmational Click

Now we just have to shove everyting else in a box and sit him on it.

 

 

This project will make you bug eyed!

 

 

 

 

SENSOR WIRES PASSING FROM THE EYES TO THE BRAINS

 

 

READY TO GUARD

 

Evil looking little guy, but he'll do the trick.

 

PROJECT SUMMARY

This project was fun - mostly because I never have hacked a protocol like this before.  Way back in the day, I hacked a save file for the game Alone in the Dark by comparing hexadecimal values before and after firing a shotgun.  That's as close as I ever got.  With this project, I learned how to use a logic analyzer and have a better understanding of PWM.  Also, I finally built my first custom amp circuit with the LM386 datasheet.  I learned the importance to taking out the ripple in a switching power supply as it relates to noise.  I'll be further experimenting with the voltage divider at pin 3 of the LM386 and capacitors on the power to pin 6.

 

Since the car backup radar kits are so cheap, I can see me expanding the orb of protection to the front and in the garage to help with parking my '99 Jeep in the perfect garage location.  That will be for another cold, rainy day.

 

See ya,

Sean

 

REFERENCES

1) Parking Sensor Kit

2) ITP Sensor Workshop-https://itp.nyu.edu/archive/physcomp-spring2014/sensors/Main/HomePage.html

3) LM386 Amplifier Datasheet - https://www.echelleinconnue.net/outils/mobio/composants/LM386.pdf

4) Arduino MKRZero Basic Audio Project - https://www.arduino.cc/en/Tutorial/SimpleAudioPlayerZero

5) Home Automation Mojo You Must Know by Sean J. Miller - https://www.element14.com/community/community/project14/homeautomation/blog/2019/01/26/home-automation-mojo-you-must-know

6) The Complete Guide to Decks: Plan & Build Your Dream Deck Includes Complete Deck Plans (Black & Decker Complete Guide)