├── README.md ├── doorbell-no-fona.ino ├── doorbell.ino └── schematic.png /README.md: -------------------------------------------------------------------------------- 1 | # [Digital Ding Dong Ditch](http://samy.pl/dingdong) 2 | 3 | **Digital Ding Dong Ditch** is a device to hack into and ring my best friend's wireless doorbell whenever I send a text message to the device. The best part of the device is that it causes my friend, without fail, to come outside, find no one, and go back in. 4 | 5 | In this project, we'll learn not only how to create this device, but how to reverse engineer radio frequencies we know nothing about using RTL-SDR (a ~$14 software defined radio), as well as creating hardware and software using Arduino, the Adafruit FONA (GSM/SMS/2G board), an RF (radio frequency) transmitter to transmit custom signals, and even how to reverse engineer a proprietary radio signal we know nothing about! 6 | 7 | by [@SamyKamkar](https://twitter.com/samykamkar) // code@samy.pl // [http://samy.pl](http://samy.pl) // Dec 11, 2014 8 | 9 | 10 | Watch the detailed video (and demo;) 11 | Digital Ding Dong Ditch 12 | 13 | ------ 14 | 15 | # Overview 16 | 17 | My best friend [Matt](http://m-austin.com/) (we call him "donr") mentioned to me the other day that his doorbell was wireless. Incredible! 18 | 19 | While he was away from his house, I decided to drive to his house and: 20 | 21 | * ring his doorbell a bunch of times, while discovering the radio frequency and modulation used by it 22 | * reverse engineer the signal in order to interpret it 23 | * build a device capable of replaying the doorbell signal (ringing his doorbell), and have it work from long distances by allowing it to receive a special text message to trigger the doorbell 24 | 25 | Amazing. Hopefully we'll still be friends after this. I can now ring his doorbell no matter how far away I am from his house, and he will never see my device as it's hidden across the street wirelessly manipulating his home. 26 | 27 | Through this project, I'm going to explain from start to finish how I determined, hacked, reverse engineered, and built each piece and joined them together into this fun project, as well as provide schematics, source code, and explanation from start to finish. 28 | 29 | ![http://samy.pl/dingdong/dddd.png](http://samy.pl/dingdong/dddd.png) 30 | 31 | 32 | ------ 33 | 34 | # Software 35 | 36 | ### Digital Dong Ding Ditch 37 | You can acquire the Digital Ding Dong Ditch source code from my github: 38 | 39 | This is an Arduino sketch which uses the hardware mentioned below. 40 | 41 | ### Samy's Adafruit FONA library 42 | You should use [my version of the Adafruit FONA library](https://github.com/samyk/Adafruit_FONA_Library) as I include an additional option that allows the FONA to let us know when there's a new text message. In the original library, you must constantly poll to see if there are more text messages than you expect, however with my version you can enable an option `fona.setSMSInterrupt(1)` which causes the RI (Ring Interrupt) pin to pull low for a moment upon new SMS messages. 43 | 44 | ### GQRX / SDRSharp 45 | For Linux or Mac, you can use [GQRX](http://gqrx.dk/), or for Windows, [SDRSharp](http://sdrsharp.com/#download). These allow you to have GUI interfaces to visualize and listen to signals through your RTL-SDR device. Any program that interfaces with RTL-SDR to see an FFT or waterfall view of the spectrum will suffice. 46 | 47 | ### RTL-SDR 48 | We use the [RTL-SDR](http://sdr.osmocom.org/trac/wiki/rtl-sdr) codebase to listen and save the signal (via `rtl_fm`), however you can simply use GQRX or SDRSharp mentioned above to save the signal if you prefer. 49 | 50 | ### Audacity 51 | [Audacity](http://audacity.sourceforge.net/) is a free application for audio file modification. We use it to look at and interpret the radio signal. 52 | 53 | 54 | ----- 55 | 56 | # Hardware 57 | 58 | ### RTL-SDR 59 | **$14**: [RTL-SDR](http://www.amazon.com/KEEDOX%C2%AE-RTL-SDR-DVB-T-RTL2832U-R820T/dp/B00D3GRU24/ref=sr_1_3?s=electronics&ie=UTF8&qid=1417979999&sr=1-3&keywords=rtl-sdr) is an extremely inexpensive software defined radio (SDR) using a chip from Realtek (RTL). If you have any idea why all Realtek devices are labeled RTL, rather than RLT, please [email me](mailto:rtl@samy.pl) as it really bothers me. 60 | 61 | Anyway, you can get these dongles new around $14-20. These great chips allow you to receive full I/Q samples of radio frequencies down to potentially 22MHz up to around 2.2GHz, which includes all sorts of interesting radio frequencies! Cars! Garages! Doorbells! Glucometers! Medical devices! Pagers! Cell phones! Wireless phones! Broadcast TV! Airplanes! Power meters! Two way radios! Did I mentiong pagers? Don't page me, bro. Any RTL-SDR device with decent reviews on Amazon should suffice. 62 | 63 | ### Arduino 64 | **$6**: [Arduino](http://arduino.cc/en/Main/arduinoBoardUno) is an awesome platform for software and hardware development and allows rapid creation of hardware. We'll be using an [Arduino Nano](http://arduino.cc/en/Main/arduinoBoardNano) clone specifically, however almost any Arduino microcontroller should work. Other microcontrollers or other devices capable of serial communication such as the Raspberry Pi, BeagleBone Black, raw Atmel chip or any other reasonable microcontroller should be able to do what we're doing here. 65 | 66 | ### 434MHz ASK RF Transmitter 67 | **$4**: I use an inexpensive ($4) [434MHz ASK RF transmitter](https://www.sparkfun.com/products/10534) from SparkFun for this project. Note that this device entirely depends on the frequency and modulation of the device you're attempting to transmit to. I knew to get this transmitter only after I determined Matt's doorbell was using the radio frequency of ~434MHz (see how we determine this below or [watch the video](http://www.youtube.com/watch?feature=player_embedded&v=BnwBdeQB7vQ)) and that the digital modulation was ASK, which is a type of digital amplitude modulation (AM). You can see the [datasheet here](http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Wireless/General/TWS-BS-3_433.92MHz_ASK_RF_Transmitter_Module_Data_Sheet.pdf). 68 | 69 | ### Adafruit FONA 70 | **OPTIONAL ($45)**: Adafruit created an awesome board called the [FONA](https://www.adafruit.com/products/1963) which allows you to drop in a 2G SIM card and send/receive SMS's, phone calls, and even use the Internet directly from this little device and a microcontroller. Look ma', I'm on the information super highway! 71 | 72 | If you obtain this, you'll be able to send a text message to your Arduino to send the signal, however if you're not looking to to have this sort of setup, no problem, I include a version without any GSM board where the Arduino simply annoyingly rings the doorbell every 30 seconds without any text message or FONA board required! 73 | 74 | ### SIM Card 75 | **OPTIONAL ($3, only if using FONA)**: The FONA requires a mini-SIM card (NOT micro-SIM). I use a T-Mobile prepaid SIM card which is $3 and I believe only costs on outbound messages/calls which we won't be doing. I specifically use T-Moile because they support 2G, where most other carriers have or are deprecating their 2G network, and the FONA only supports 2G for Internet. Make sure you get the right size of SIM card -- more details on [FONA SIM requirements here](https://learn.adafruit.com/adafruit-fona-mini-gsm-gprs-cellular-phone-module/obtaining-a-sim). 76 | 77 | ### 3.7V Lithium-Ion (LiOn or LiPo) Battery 78 | **OPTIONAL ($5 and up, only if using FONA)**: This is annoying, but as cool as the FONA is, it requires *three* power sources, and only one can be directly from the Arduino board. You can't spell cool without loco. One should be a rechargable battery such as [this 3.v 1200mAh LiOn battery](https://www.adafruit.com/products/258). 79 | 80 | 81 | ----- 82 | 83 | # Locating the Signal 84 | 85 | At first, I had no idea what frequency the signal was on, so while normally I would use a spectrum analyzer, I wanted to use only RTL-SDR (to keep the project very low cost) and some educated guessing based off of common frequencies. 86 | 87 | Typically if you're dealing with a device that transmits and are in the US or Canada, you can look on the back and find an FCC ID or IC ID (for Canada). You can then [look that FCC ID up](http://transition.fcc.gov/oet/fccid/) to find the frequencies associated with it. Since the doorbell I was ringing itself didn't have an FCC ID and I wasn't inside the house to inspect the rest of it, I had no information on what frequency, FCC id, or even brand or model it was. 88 | 89 | However, there happen to be a number of common [ISM radio bands](http://en.wikipedia.org/wiki/ISM_band) (industrial, scientific and medical radio bands) that are used for many, many devices. In the US, we'll typically see simple devices transmitting around 315MHz, 433MHz or 900MHz, especially if there's low throughput and not much data to send. We also have some other bands such as 2.4GHz (used by wifi, bluetooth, and more) and a few others. 90 | 91 | Using GQRX with the RTL-SDR plugged in, I simply started at 300MHz, and it would show me 3MHz at a time. I'd repeatedly hit the doorbell, and if I see no signal, I simply move up. You can skip around from 320 to about 430 usually as if it's not 300-320, it will more likely be in the 400+ or 900 range. 92 | 93 | Once I saw a correlation between pressing the button and a signal in GQRX, I knew I had the right frequency, which was around **433.8MHz**. 94 | ![http://samy.pl/dingdong/gqrx.png](http://samy.pl/dingdong/gqrx.png) 95 | 96 | 97 | ----- 98 | 99 | # Capturing and Demodulating the Signal 100 | Now that we know the frequency, we must determine the type of modulation used. Modulation is what allows data to be transmitted via radio frequency. I knew based off watching the waterfall view in GQRX that this was Amplitude Modulation (AM), and will explain how below. 101 | 102 | We can determine whether the signal is amplitude modulation easily here because it happens to be using something called [On-Off Keying](http://en.wikipedia.org/wiki/On-off_keying), or OOK, which is a type of [Amplitude Shift Keying](http://en.wikipedia.org/wiki/Amplitude-shift_keying) (ASK). 103 | 104 | Okay, we're getting into a lot of acronyms, so let's break down the types of modulation we'll see on the first level/layer. First we want to determine the generic modulation (which was Amplitude Modulation in this case): 105 | 106 | * AM - [Amplitude Modulation](http://en.wikipedia.org/wiki/Amplitude_modulation) (eg, AM radio) 107 | * FM - [Frequency Modulation](http://en.wikipedia.org/wiki/Frequency_modulation) (eg, FM radio) 108 | * PM - [Phase Modulation](http://en.wikipedia.org/wiki/Phase_modulation) 109 | 110 | 111 | There are a number of others, but these are the common/most basic modulation schemes we'll see in radio. 112 | 113 | Amplitude modulation simply modulates the amplitude of the signal to send data (so you'll see a high signal sometimes, and a lower or no signal other times). 114 | 115 | Frequency modulation actually changes the *frequency* the signal comes on, so if you're listening to 105.9 FM radio (105.9MHz), the station will actually send audio between 105.895MHz and 105.905MHz depending on the pitch of the sound or the data meant to be revealed. The audio or information is sent by the *change* in the frequency, aka the modulation of the frequency. 116 | 117 | ![http://upload.wikimedia.org/wikipedia/commons/a/a4/Amfm3-en-de.gif](http://upload.wikimedia.org/wikipedia/commons/a/a4/Amfm3-en-de.gif) 118 | 119 | 120 | However, since we're dealing with digital information, rather than analog (such as sound), then the modulation will be more discrete (1s and 0s) and use modulation schemes such as: 121 | 122 | * ASK - [Amplitude Shift Keying](http://en.wikipedia.org/wiki/Amplitude-shift_keying) (digital data using AM) 123 | * FSK - [Frequency Shift Keying](http://en.wikipedia.org/wiki/Frequency-shift_keying) (digital data using FM) 124 | * PSK - [Phase Shift Keying](http://en.wikipedia.org/wiki/Phase-shift_keying) (digital data using PM) 125 | 126 | ![http://samy.pl/dingdong/amfm.png](http://samy.pl/dingdong/amfm.png) 127 | 128 | In this case, if we are using ASK, a type of AM, the signal is likely to only contain 0s and 1s, where no amplitude/signal is sent for 0, and amplitude is high for 1. This makes it easy to interpret the data, and when dealing with Amplitude Shift Keying with no signal or full signal, we have yet another acronym, OOK or [On-Off Keying](http://en.wikipedia.org/wiki/On-off_keying), to describe this modulation. OOK simply means the signal is on (high/1) or off (0/low). You will find this for most common ASK signals. 129 | 130 | In many cases, there are additional coding schemes which go on top of this data, such as [Manchester coding](http://en.wikipedia.org/wiki/Manchester_code) or [NRZ](http://en.wikipedia.org/wiki/Non-return-to-zero), which produce a switch between high/low signals much more often, however we don't see that in this signal. 131 | 132 | Now since we know it's amplitude modulation (AM / ASK / OOK) by the looks of it, we'll use `rtl_fm` to save the data as AM into a wav file: 133 | 134 | `rtl_fm -M am -f 434000000 -s 2000000 - | sox -t raw -r 2000000 -e signed-integer -b 16 -c 1 -V1 - doorbell.wav` 135 | 136 | ----- 137 | 138 | # Interpreting the Signal 139 | It appears the signal (when looking in Audacity) always sends the same width of the "1"/high signal at 750us (us = microseconds -- 1,000 microseconds in 1 millisecond, and 1,000 milliseconds in 1 second, so 1,000,000 microseconds/us in 1 second)). 140 | 141 | The "0"s/lows/no signal also appear to be in blocks of 750us but can be back to back, so you may run into 750us or no signal, or 750 \* 2us (1500us), or 750 \* 3 (2250us), or many more. 142 | 143 | Normally I would take a signal like this and convert it to 1s and 0s. Since 750us seems to be the [greatest common divisor](http://en.wikipedia.org/wiki/Greatest_common_divisor), we could just take every 750us of a 1high and call it "1", and every 750us of a low/no signal and call it 0. There's a number of ways to do this with software, likely with something like [GNU Radio](http://gnuradio.org/redmine/projects/gnuradio/wiki) or possibly [rtl_433](https://github.com/merbanan/rtl_433/commits/master), but we're going to do everything by hand today. 144 | 145 | In this case because I'm lazy and it doesn't really matter if we have a sequence of 1s/0s, since we just need to retransmit a similar signal, no matter how we interpret it, I opt to instead simply send a "1" for 750us, followed by a "0" up until the next "1". This makes it much simpler for me to just locate where all the 1s are, put the time the "1" started in an array, and have code loop through the array to determine how long it should sends all the 0s for (0 will always be for the `next location of the "1" - this location of the "1" - 750us`). I explain this further in the video above. 146 | 147 | 148 | ### Partial signal (beginning) 149 | ![http://samy.pl/dingdong/aud.png](http://samy.pl/dingdong/aud.png) 150 | 151 | ### Full signal: 152 | ![http://samy.pl/dingdong/aud2.png](http://samy.pl/dingdong/aud2.png) 153 | 154 | ----- 155 | 156 | # Writing the Code 157 | 158 | Creating the code to trigger this is pretty simple once we've created an array with all the times the "1" (or high) signal begins. 159 | 160 | You may be tempted to use a library like VirtualWire or [RadioHead](http://www.airspayce.com/mikem/arduino/RadioHead/) to send the RF signal, but don't! These libraries are great when you're creating your own RX and TX devices, but we're only transmitting and we want to be very specific about what we send. These libraries do all sorts of convenient and nice things for you such as adding preambles and CRC checks which help in transmissions where you control the receiver, but will entirely screw up our signal in this case, unless you disable all of those features. The amount of work to disable the features is more work than just bit-banging the signal as we do below I believe. 161 | 162 | All of the code is on , but here is the relevant part for transmission: 163 | 164 | ``` 165 | #define TX_PIN 9 166 | #define BIT_PERIOD 700 167 | #define TIMES 22 168 | 169 | // here's an array (in seconds) where each "1" begins in the signal 170 | float times[TIMES] = { 171 | 0, .0015, .003, .0045, .0092, .0122, .0161, .0214, .0268, .0298, .0352, .0413, .0436, .0505, .0535, .0574, .062, .0673, .0719, .0757, .0803 }; 172 | 173 | /// ... some code 174 | 175 | // go through each "1" bit 176 | for (int i = 0; i < TIMES-1; i++) 177 | { 178 | // calculate microseconds (us) from the second 179 | int us = times[i] * 1000000; 180 | 181 | // don't delay before the first "1" 182 | // (this would be a negative amount for the first iteration anwyay) 183 | // this essentially produces a "0"/low all the way from our last "1" to our current "1" 184 | if (i != 0) 185 | delayMicroseconds(us - last - BIT_PERIOD); 186 | 187 | // send a "1" for our BIT_PERIOD which is around 700-800us 188 | digitalWrite(TX_PIN, HIGH); 189 | delayMicroseconds(BIT_PERIOD); 190 | digitalWrite(TX_PIN, LOW); 191 | 192 | last = us; 193 | } 194 | 195 | /// more awesome code 196 | ``` 197 | 198 | 199 | ------ 200 | 201 | # Creating the Arduino 202 | 203 | I go into the Arduino a little bit in the video, however I've created a Fritzing sketch below so you can see how everything is wired up. 204 | 205 | Now that we know the signal is 434MHz and ASK, we can get a simple ASK transmitter on 434MHz for just a few dollars and use it to "bit bang" our signal. If you're not using the FONA/GSM board, simply ignore the FONA and its connections. 206 | 207 | The software you need to load on the Arduino is on github here: 208 | 209 | ![http://samy.pl/dingdong/fritz.png](http://samy.pl/dingdong/fritz.png) 210 | 211 | ----- 212 | 213 | # Ringing the Doorbell 214 | You do need to power the Arduino (easy by connecting USB to it), as well as connecting USB to the FONA and a 3.7v Lion/LiPo battery to the FONA and leave it outside the location of the doorbell. Don't worry as the FONA USB connection simply charges the battery. It's silly, I know, but it's necessary. If just running temporary, USB batteries work great too. 215 | 216 | I actually left it across the street and it worked great! 217 | 218 | Then, you simply send an SMS message with the word "doorbell" to the device (case sensitive), and it will cause the Arduino to transmit the signal we created and ring the doorbell! Awesome! 219 | 220 | ----- 221 | 222 | # Ditch 223 | Run. Seriously, run!!! 224 | 225 | 226 | ------ 227 | 228 | 229 | # Questions? 230 | 231 | Feel free to contact me with any questions! 232 | 233 | Follow [@SamyKamkar](https://twitter.com/samykamkar) on Twitter! 234 | 235 | You can see more of my projects at or contact me at . 236 | 237 | 238 | ------ 239 | 240 | -------------------------------------------------------------------------------- /doorbell-no-fona.ino: -------------------------------------------------------------------------------- 1 | // digital ding dong ditch 2 | // by samy kamkar 3 | // dec 7, 2014 4 | // 5 | // this arduino sketch connects to an RF transmitter (pin 9) and sends a signal every 30 seconds to trigger a wireless doorbell based off a transmission we sniffed previously with RTL-SDR 6 | // 7 | // more details at http://samy.pl/dingdong 8 | 9 | #define TX_PIN 9 10 | #define BIT_PERIOD 700 11 | 12 | long times[] = { 13 | 0, 1500, 3000, 4500, 9200, 12200, 16100, 21400, 14 | 26800, 29800, 35200, 41300, 43600, 50500, 53500, 15 | 57400, 62000, 67300, 71900, 75700, 80300 16 | }; 17 | 18 | void setup() 19 | { 20 | pinMode(TX_PIN, OUTPUT); 21 | 22 | 23 | Serial.begin(115200); 24 | Serial.println(""); 25 | Serial.println(F("Digital Ding Dong Ditch")); 26 | Serial.println(F("by Samy Kamkar - https://twitter.com/samykamkar")); 27 | } 28 | 29 | void ring_bell() 30 | { 31 | Serial.println("Ringing!\n"); 32 | 33 | // the actual doorbell sends our signal 12 times, so we'll emulate it 34 | for (int j = 0; j < 12; j++) 35 | { 36 | single_ring(); 37 | } 38 | } 39 | 40 | 41 | void single_ring() 42 | { 43 | // go through each "1" bit 44 | for (int i = 1; i < sizeof(times) / sizeof(long); i++) 45 | { 46 | // send a "1" for our BIT_PERIOD which is around 700-800us 47 | digitalWrite(TX_PIN, HIGH); 48 | delayMicroseconds(BIT_PERIOD); 49 | digitalWrite(TX_PIN, LOW); 50 | // calculate microseconds (us) 51 | delayMicroseconds(times[i] - times[i - 1] - BIT_PERIOD); 52 | } 53 | delay(20); 54 | } 55 | 56 | 57 | void loop() 58 | { 59 | ring_bell(); 60 | delay(30000); 61 | } 62 | -------------------------------------------------------------------------------- /doorbell.ino: -------------------------------------------------------------------------------- 1 | // digital ding dong ditch 2 | // by samy kamkar 3 | // dec 7, 2014 4 | // 5 | // this arduino sketch connects to an Adafruit FONA (for GSM) and an RF transmitter (pin 9) -- when we receive a text message with the word "doorbell", we send an RF signal out to ring a doorbell based off a transmission we sniffed previously with RTL-SDR 6 | // 7 | // more details at http://samy.pl/dingdong 8 | 9 | #define TX_PIN 9 10 | #define BIT_PERIOD 700 11 | 12 | long times[] = { 13 | 0, 1500, 3000, 4500, 9200, 12200, 16100, 21400, 14 | 26800, 29800, 35200, 41300, 43600, 50500, 53500, 15 | 57400, 62000, 67300, 71900, 75700, 80300 16 | }; 17 | 18 | #include 19 | 20 | // You'll need to use my modified FONA library here: 21 | // https://github.com/samyk/Adafruit_FONA_Library 22 | #include "Adafruit_FONA.h" 23 | 24 | #define FONA_RX 5 // was 2, but we're going to use that for an interrupt (RI) 25 | #define FONA_TX 3 26 | #define FONA_RST 4 27 | 28 | // this is a large buffer for replies 29 | char replybuffer[255]; 30 | 31 | SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX); 32 | Adafruit_FONA fona = Adafruit_FONA(&fonaSS, FONA_RST); 33 | 34 | int8_t last_sms; 35 | int8_t sms_interrupt = 0; 36 | 37 | void got_sms() 38 | { 39 | sms_interrupt = 1; 40 | } 41 | 42 | void handle_sms() 43 | { 44 | sms_interrupt = 0; 45 | 46 | // we got an interrupt, so check for new SMS 47 | // it's possible we got nothing as a phone call will also call this function 48 | // 49 | // don't call me bro 50 | 51 | // now let's compare with the number of SMS' we have 52 | int8_t smsnum = fona.getNumSMS(); 53 | 54 | if (smsnum < 0) { 55 | Serial.println(F("G Could not read # SMS")); 56 | } 57 | else { 58 | Serial.print(smsnum); 59 | Serial.println(F(" SMS's on SIM card!")); 60 | } 61 | 62 | // we got at least one new SMS!!!! 63 | if (last_sms < smsnum) 64 | { 65 | 66 | // go through each sms 67 | while (last_sms++ != smsnum) 68 | { 69 | // read this SMS and check for the word "doorbell" 70 | Serial.print(F("\n\rReading SMS #")); 71 | Serial.println(last_sms); 72 | 73 | // Retrieve SMS sender address/phone number. 74 | if (! fona.getSMSSender(last_sms, replybuffer, 250)) { 75 | Serial.println("Failed!"); 76 | break; 77 | } 78 | Serial.print(F("FROM: ")); 79 | Serial.println(replybuffer); 80 | 81 | // Retrieve SMS value. 82 | uint16_t smslen; 83 | if (! fona.readSMS(last_sms, replybuffer, 250, &smslen)) { // pass in buffer and max len! 84 | Serial.println("Failed!"); 85 | break; 86 | } 87 | Serial.print(F("***** SMS #")); 88 | Serial.print(last_sms); 89 | Serial.print(" ("); 90 | Serial.print(smslen); 91 | Serial.println(F(") bytes *****")); 92 | Serial.println(replybuffer); 93 | Serial.println(F("*****")); 94 | 95 | // now, should this SMS ring the doorbell?? 96 | // we use the C function `strstr` because we're dealing with a character array, 97 | // not the typical arduino "string" object 98 | if (strstr(replybuffer, "doorbell\0") != NULL) 99 | { 100 | ring_bell(); 101 | } 102 | } 103 | 104 | // save our sms number 105 | last_sms = smsnum; 106 | } 107 | } 108 | 109 | void setup() 110 | { 111 | pinMode(TX_PIN, OUTPUT); 112 | 113 | // attach interrupt to pin 2 (interrupt 0) for ring interrupt (when we recv SMS) 114 | attachInterrupt(0, got_sms, LOW); 115 | 116 | Serial.begin(115200); 117 | Serial.println(""); 118 | Serial.println(F("Digital Ding Dong Ditch")); 119 | Serial.println(F("by Samy Kamkar - https://twitter.com/samykamkar")); 120 | Serial.println(F("Initializing....(May take a few seconds)")); 121 | 122 | 123 | // See if the FONA is responding 124 | while (! fona.begin(4800)) { // make it slow so its easy to read! 125 | Serial.println(F("Couldn't find FONA")); 126 | delay(1000); 127 | } 128 | Serial.println(F("FONA is OK")); 129 | 130 | // call our RI (ring interrrupt) upon new SMS messages! 131 | fona.setSMSInterrupt(1); 132 | 133 | // Print SIM card IMEI number. 134 | char imei[15] = { 0 }; // MUST use a 16 character buffer for IMEI! 135 | uint8_t imeiLen = fona.getIMEI(imei); 136 | if (imeiLen > 0) { 137 | Serial.print("SIM card IMEI: "); 138 | Serial.println(imei); 139 | } 140 | 141 | // set the number of SMS's we currently have in EEPROM 142 | int8_t smsnum = fona.getNumSMS(); 143 | 144 | if (smsnum < 0) { 145 | Serial.println(F("Could not read # SMS")); 146 | } 147 | else { 148 | Serial.print(smsnum); 149 | Serial.println(F(" SMS's on SIM card!")); 150 | // save our sms number in EEPROM 151 | last_sms = smsnum; 152 | } 153 | 154 | } 155 | 156 | void ring_bell() 157 | { 158 | Serial.println("Ringing!\n"); 159 | 160 | // the actual doorbell sends our signal 12 times, so we'll emulate it 161 | for (int j = 0; j < 12; j++) 162 | { 163 | single_ring(); 164 | } 165 | } 166 | 167 | void single_ring() 168 | { 169 | // go through each "1" bit 170 | for (int i = 1; i < sizeof(times) / sizeof(long); i++) 171 | { 172 | // send a "1" for our BIT_PERIOD which is around 700-800us 173 | digitalWrite(TX_PIN, HIGH); 174 | delayMicroseconds(BIT_PERIOD); 175 | digitalWrite(TX_PIN, LOW); 176 | // calculate microseconds (us) 177 | delayMicroseconds(times[i] - times[i - 1] - BIT_PERIOD); 178 | } 179 | delay(20); 180 | } 181 | 182 | 183 | void loop() 184 | { 185 | // you'd think we'd just call handle_sms() from the interrupt, but the FONA will not behave properly if you access it from an interrupt, so we simply set a flag instead 186 | if (sms_interrupt) 187 | handle_sms(); 188 | delay(1000); 189 | } 190 | -------------------------------------------------------------------------------- /schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samyk/dingdong/ad09e66d12470efe463518f3c7910bfbe2f4fcc6/schematic.png --------------------------------------------------------------------------------