This article will guide you and me about building a very smart, talking camping security system disguised as an owl. This is not your typical Arduino ultrasonic sensor project. In this article, we will learn how to redesign very inexpensive, but much more advanced parking sensors (which are installed in the bumper of a car). These sensors have a much wider beam than classic ultrasonic sensors such as HC-SR04.
Also from the article we will learn how to assemble a small audio amplifier.
The master has developed this system taking into account the following requirements:
-Early notification (no need to wait until the door or window is kicked out to trigger the alarm)
-Voice notification (the system automatically talks to the intruder, threatening to call the police)
-Wide coverage (beam) of territory monitoring – -Sending a notification to a mobile phone when an intrusion is detected
Tools and materials: -An owl figure; -Parktronic or analogs;
-Arduino MKR Zero; -Amplifier Adafruit Mono 2.5 W (optional);
For self-assembly of the amplifier (optional):
-Audio amplifier LM386;
-Speaker 8 Ohm 1/2 W;
-Resistor 10 Ohm; -Two resistors 4.7 kOhm;
-Capacitors 10 uF;
-Capacitor 0.1 uF; -Capacitor 220 uF; -Logic analyzer; -Digital multimeter; -Code and 3D file;
Step one: features of Arduino MKR Zero
For this assembly, the master chose Arduino MKR Zero. Features of the board are as follows:
-Price – $ 25
-Allows you to play sound files without additional hardware
-Slot for an SD card
-Allows you to load dozens of sounds < -22 digital pins, SPI and I2C
-Allows to connect to the parking sensor board
-Built-in battery charging control
The only thing missing in this board is Wi-Fi.
Step two: about parking sensors
Car parking sensors use ultrasound, which is an acoustic wave with a very high frequency. Frequencies above 20 kHz are inaccessible to human hearing. What's amazing about it is how “loud” it is. It emits an inaudible sound of more than 100 dB – “louder” than a motorcycle, but does not damage the human ear.
With such a short wavelength, it has a good beam shape that allows reliable measurements for sensing objects. In addition, since sound travels through the air, it nominally travels at a speed of 340 m/s.
Step three: protocol of data exchange with the sensor
If you bought exactly the same set of parking sensors, which is indicated in the “materials”, then you can skip this step. If the parking sensor is different, then in this step the wizard will teach us how to hack the equipment.
To hack the parking sensors, you just need to figure out how the “brains” of the parking sensors interact with their LED monitor. Since different manufacturers make them with their own protocols, you need to find communication protocol cables as well as ground and voltage cables. Approximately the following steps should be taken:
1) Use a breadboard to test the circuit:
There are four wires leading from the parking sensor board to the display. Using jumpers, you need to add a breadboard between the parking sensors board and the display to the circuit.
2) Find the ground that goes to the monitor:
Since this is an automotive technology, a 12V nominal voltage source is used to power the parking sensors board. Most likely the display is powered from voltage no more than 5 V.
First you need to set the multimeter to search for an open circuit. Then, having installed one probe to ground on the board, with the second probe, one by one we ring out the wires suitable for the display. An audible buzzer will indicate that we have found a pair of ground wires.
3) Find a 5V wire:
This wire will be used to power the Arduino. Connect the 9 V battery to power the module and ground it. We measure the remaining three wires. On two of them, the voltage will fluctuate, on the third, it will be 5 V. This is the power wire.
4) Find the buzzer wire:
There is a built-in buzzer on the displays of the parking sensors, which warns of approaching an obstacle. It is very easy to identify the buzzer wire. You just need to remove the jumpers from one wire. If the sound stops, then we have found the required wire. If the sound continues, then the wire remains bridged.
5) Signal wire:
As you probably already guessed, the remaining fourth wire is a signal wire.
6) Hacking the communication protocol:
Leaving just one wire eliminates the I2C and SPI communication protocols. They need a different signal.
It could be serial communication, or some custom pulse width modulation (PWM) protocol developed by the manufacturer.
For further work you need an oscilloscope or, better yet, a cheap logic analyzer.
Often a serial link has a long pulse signal. After the long pulse, there are 8 segments that can be high or low. The width between each segment is fixed. By measuring the shortest high pulse, it can be assumed that this is the period and, in turn, the corresponding transmission rate.
In this case, 9600 baud seems to be acceptable for serial communication. But the number of segments is more than 8. In fact, after a long pulse, the number of beats is not evenly divisible by eight. This suggests that the manufacturer has created their own messaging system using 5V PWM.
Then we connect one ultrasonic sensor to one port at a time. It looks like the data is being segmented after a very long pulse. (Long means “compared to other pulses”.) Here you can see that there are 4 bytes of pulses (a byte representing each sensor). The short pulses are zero and the long ones are 1. When the sensor is connected, the start of the byte becomes 000 instead of 111. The code is cracked.
The communication protocol is as follows:
1 very long start pulse (the code will wait for a pulse for some time before calling the parse routine)
1 short start pulse
Short pulses mean zero in each period, long pulses mean one
4 bytes, each of which represents sensor data in the following order: Sensor A, D, C, B
If the first 3 bits are zero in a byte, the sensor is recognized
The last 5 bytes are binary for decimetres of distance from this sensor
Step four: sound alarm system
If you bought an amplifier from Adafruit listed in the Materials section, then you can skip this step and just connect the amplifier, parktronic board and ESP8266 to the Arduino.
For those who want to build their own amplifier, follow the next steps.
Get a datasheet for the LM386 amplifier IC.
View the diagram in the images below.
Make a breadboard circuit and test it with a 3.5mm music player. < br> Note. The music player ground is connected to pin 2 of the LM386. This pin is not connected to the circuit ground, otherwise there will be only noise.
If you want to change the circuit, you can download the files here.
Step five: software
If you have purchased a parking sensor, which is listed in the consumables section, then you can use this code without changes. Otherwise, you will need to customize the code.
This tutorial is based on the knowledge that the user is familiar with uploading code to Arduino. Follow the normal download procedure.
For sound files, simply record the sound and save the file to an SD card named alarm.wav and owlHello.wav.
You can also get this code on the wizard's GitHub.
Arduino MKR Zero code:
< code>#include & lt; SD.h & gt; #include & lt; SPI.h & gt; #include & lt; AudioZero.h & gt; int sense_pin = 0; int alarm_pin = 1; unsigned long pulse_length; unsigned long first_pulse; int sensorValue & # 91; 32 & # 93 ;; unsigned long lengths & # 91; 32 & # 93 ;; int pulse_value; float A, B, C, D; float averageDistance, lastAverage; int first_few_counter = 0; void setup () & # 123; 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)) & # 123; Serial.println (& # 34; failed! & # 34;); while (true); } Serial.println (& # 34; Starting ... & # 34;); delay (1000); PlaySound (& # 34; owlHello.wav & # 34;); } void loop () & # 123; Sense (); delay (2000); } void Sense () & # 123; Serial.println (& # 34; Sensing ... & # 34;); 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 & lt; 1900) & # 123; 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 & lt; 32; i ++) & # 123; pulse_length = pulseIn (sense_pin, HIGH); if (pulse_length & lt; 180) & # 123; pulse_value = 0; } else & # 123; if (pulse_length & gt; 1000) & # 123; Serial.println (& # 34; Overran! & # 34;); delay (1000); return; //just exit out of the routine if it fails to sense correctly this time through. } pulse_value = 1; } sensorValue & # 91; i & # 93; = pulse_value; lengths & # 91; i & # 93; = pulse_length; } //Sensor A if (sensorValue & # 91; 0 & # 93; == 0) & # 123; //String sensorA = String (sensorValue & # 91; 3 & # 93;) + String (sensorValue & # 91; 4 & # 93;) + String (sensorValue & # 91; 5 & # 93;) + String (sensorValue & # 91; 6 & # 93 ;) + String (sensorValue & # 91; 7 & # 93;); //Serial.println(sensorA); A = 16 * sensorValue & # 91; 3 & # 93; + 8 * sensorValue & # 91; 4 & # 93; + 4 * sensorValue & # 91; 5 & # 93; + 2 * sensorValue & # 91; 6 & # 93; + sensorValue & # 91; 7 & # 93 ;; A = A/(10 * .3048); //convert decimeters to feet Serial.println (A); } //Sensor D if (sensorValue & # 91; 8 & # 93; == 0) & # 123; D = 16 * sensorValue & # 91; 11 & # 93; + 8 * sensorValue & # 91; 12 & # 93; + 4 * sensorValue & # 91; 13 & # 93; + 2 * sensorValue & # 91; 14 & # 93; + sensorValue & # 91; 15 & # 93 ;; D = D/(10 * .3048); //convert decimeters to feet Serial.println (D); } //Sensor C if (sensorValue & # 91; 16 & # 93; == 0) & # 123; C = 16 * sensorValue & # 91; 19 & # 93; + 8 * sensorValue & # 91; 20 & # 93; + 4 * sensorValue & # 91; 21 & # 93; + 2 * sensorValue & # 91; 22 & # 93; + sensorValue & # 91; 23 & # 93 ;; C = C/(10 * .3048); //convert decimeters to feet Serial.println (C); } //Sensor B if (sensorValue & # 91; 24 & # 93; == 0) & # 123; B = 16 * sensorValue & # 91; 27 & # 93; + 8 * sensorValue & # 91; 28 & # 93; + 4 * sensorValue & # 91; 29 & # 93; + 2 * sensorValue & # 91; 30 & # 93; + sensorValue & # 91; 31 & # 93 ;; B = B/(10 * .3048); //convert decimeters to feet Serial.println (B); } averageDistance = (A + B + C + D)/4; if (((abs (lastAverage-averageDistance))/lastAverage) & gt; .1) alarm (); lastAverage = averageDistance; } void alarm () & # 123; if (first_few_counter ++ & lt; 3) return; //this keeps it from triggering when you first set it down and turn it on. digitalWrite (alarm_pin, LOW); PlaySound (& # 34; alarm.wav & # 34;); delay (5000); digitalWrite (alarm_pin, HIGH); } void PlaySound (String the_sound) & # 123; 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; }
The wizard uses the Pushbullet messaging program to communicate with the phone. You will need to install the key and replace it with “YOURPUSHBULLETKEY”.
#include & lt; ESP8266WiFi.h & gt; #include & lt; WiFiClientSecure.h & gt; const char * ssid = & # 34; YOURSSID & # 34 ;; const char * password = & # 34; YOURPASSWORD & # 34 ;; const char * host = & # 34; api.pushbullet.com & # 34 ;; const int httpsPort = 443; const char * PushBulletAPIKEY = & # 34; YOURPUSHBULLETKEY & # 34 ;; //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 & lt; a href = & # 34; https & # 58; //www.grc.com/fingerprints.htm"> & lt; a href = & # 34; https & # 58; //www.grc.com/fingerprints.htm" rel = & # 34; nofollow & # 34; & gt; https & # 58; //www.grc.com/fingerprints.htm & lt;/a & gt; & lt;/a & gt; and enter api.pushbullet.com const char * fingerprint = & # 34; BB FC 9F 1B C1 3C D9 96 F2 68 A2 E3 41 29 D1 47 8F B9 33 BE & # 34 ;; void setup () & # 123; Serial.begin (115200); Serial.println (); Serial.print (& # 34; connecting to & # 34;); Serial.println (ssid); WiFi.mode (WIFI_STA); WiFi.begin (ssid, password); while (WiFi.status ()! = WL_CONNECTED) & # 123; delay (500); Serial.print (& # 34;. & # 34;); } Serial.println (& # 34; & # 34;); Serial.println (& # 34; WiFi connected & # 34;); Serial.println (& # 34; IP address & # 58; & # 34;); Serial.println (WiFi.localIP ()); pushBullet (& # 34; The Owl Orb of Protection Has Started! & # 34;); pinMode (2, INPUT_PULLUP); } void pushBullet (String the_msg) & # 123; //Use WiFiClientSecure class to create TLS connection WiFiClientSecure client; Serial.print (& # 34; connecting to & # 34;); Serial.println (host); if (! client.connect (host, httpsPort)) & # 123; Serial.println (& # 34; connection failed & # 34;); return; } if (client.verify (fingerprint, host)) & # 123; Serial.println (& # 34; certificate matches & # 34;); } else & # 123; Serial.println (& # 34; certificate doesn & # 39; t match & # 34;); } String url = & # 34;/v2/pushes & # 34 ;; String messagebody = & # 34; & # 123; & # 34; type & # 34; & # 58; & # 34; note & # 34 ;, & # 34; title & # 34; & # 58; & # 34; ESP8266 & # 34 ;, & # 34; body & # 34; & # 58; & # 34; & # 34; + the_msg + & # 34; & # 34;} r n & # 34 ;; Serial.print (& # 34; requesting URL & # 58; & # 34;); Serial.println (url); client.print (String (& # 34; POST & # 34;) + url + & # 34; HTTP/1.1 r n & # 34; + & # 34; Host & # 58; & # 34; + host + & # 34; r n & # 34; + & # 34; Authorization & # 58; Bearer & # 34; + PushBulletAPIKEY + & # 34; r n & # 34; + & # 34; Content-Type & # 58; application/json r n & # 34; + & # 34; Content-Length & # 58; & # 34; + String (messagebody.length ()) + & # 34; r n r n & # 34;) ; client.print (messagebody); Serial.println (& # 34; request sent & # 34;); //print the response while (client.available () == 0); while (client.available ()) & # 123; String line = client.readStringUntil (& # 39; n & # 39;); Serial.println (line); }} void loop () & # 123; delay (200); if (digitalRead (2) == LOW) & # 123; //Wait for pin 2 to go to ground to trigger. pushBullet (& # 34; The Owl has detected something! & # 34;); delay (5000); }
Step six: body
For the base, you can take any waterproof box. The master has printed the body on a 3D printer.
Files for printing can be downloaded here.
Step Seven: Owl
Now for the fun part – the assembly.
Squeeze out the owl's eyeballs.
Using the hole saw included with the sensor, expand the holes for the diameter of the sensors.
Pass the two sensor wires through the holes.
Connect the wires to the base.
All you need to do next is to place the owl in the right place and connect the power supply. In the event of intruders appearing, the owl will hear sounds warning about the police call (or others that the user will record), and an alert will be sent to the user's phone.