{"id":1722,"date":"2019-06-09T16:04:14","date_gmt":"2019-06-09T23:04:14","guid":{"rendered":"https:\/\/partofthething.com\/thoughts\/?p=1722"},"modified":"2021-07-31T07:31:33","modified_gmt":"2021-07-31T14:31:33","slug":"making-my-analog-doorbell-smart-by-simply-attaching-a-7-sensor-to-it","status":"publish","type":"post","link":"https:\/\/partofthething.com\/thoughts\/making-my-analog-doorbell-smart-by-simply-attaching-a-7-sensor-to-it\/","title":{"rendered":"Making my analog doorbell smart by simply attaching a $7 sensor to it"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"alignright is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145041-576x1024.jpg\" alt=\"\" class=\"wp-image-1752\" width=\"121\" height=\"215\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145041-576x1024.jpg 576w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145041-169x300.jpg 169w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145041-768x1365.jpg 768w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145041.jpg 1152w\" sizes=\"auto, (max-width: 121px) 100vw, 121px\" \/><figcaption>My doorbell, which I want to make smarter<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"has-drop-cap\">I live in tall and skinny house with a  loft on the upper floor. I can&#8217;t hear the doorbell going off when I&#8217;m up there, especially if I have music playing. This post is about how I extended the range of my doorbell by hooking a sensor up to it that communicates over Wifi to my smart-home, which then plays a doorbell tone over my speakers throughout the house. <\/p>\n\n\n\n<p>I <a href=\"https:\/\/partofthething.com\/thoughts\/home-automation-with-z-wave-home-assistant-aeon-multisensor-hue-lights-and-a-raspberry-pi-2\/\">already have a reasonably capable smart home<\/a> based on <a href=\"https:\/\/www.home-assistant.io\/\">Home Assistant<\/a>, so I challenged myself to do this in the cheapest, least intrusive way possible. In the end, I did this with a $7 part and without changing any of the wiring in my existing doorbell (I just had to connect 2 extra wires to the existing transformer).<\/p>\n\n\n\n<p>Here&#8217;s a preview of it working:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Demo of my doorbell attachment that makes it smart and wifi\" width=\"660\" height=\"371\" src=\"https:\/\/www.youtube.com\/embed\/sWDRt7TsB4I?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption>Here&#8217;s the demo of it working. The 2nd ring is through the stereo.<\/figcaption><\/figure>\n\n\n\n<!--more-->\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-09-13-01-43.png\" alt=\"\" class=\"wp-image-1750\" width=\"320\" height=\"237\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-09-13-01-43.png 746w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-09-13-01-43-300x222.png 300w\" sizes=\"auto, (max-width: 320px) 100vw, 320px\" \/><figcaption>My existing doorbell chime. I didn&#8217;t need to touch it. I just recorded it to play over the stereo.<\/figcaption><\/figure><\/div>\n\n\n\n<p>I used my favorite chip for this, the <a href=\"https:\/\/en.wikipedia.org\/wiki\/ESP8266\">ESP8266<\/a> WiFi microcontroller. When it senses that the button was pressed, the ESP sends a signal to my smart home (via a <a href=\"https:\/\/en.wikipedia.org\/wiki\/MQTT\">MQTT<\/a> message over the WiFi). Then, Home Assistant senses this and plays a recording of the doorbell noise. It can also e-mail me or something if I&#8217;m not home. <\/p>\n\n\n\n<p>Doorbells are usually <a href=\"https:\/\/diyhousehelp.com\/doorbell-wiring-diagrams\">wired like this<\/a>. The transformer is usually kicking out a good 16-24 VAC when nothing is happening. When the doorbell is pressed, electromagnets slap some metal to cause a chime. At this time, the voltage drops at the transformer because the circuit is temporarily interrupted. That&#8217;s a good place to put the ESP8266 to watch for action. <\/p>\n\n\n\n<p class=\"has-yellow-background-color has-background\"><strong>UPDATE July 2021:<\/strong> After using the &#8220;voltage sniffing&#8221; technique described below for a few years, I got frustrated with the false positives that happened a) during storms and b) during heatwaves. The system was too sensitive to instabilities in the grid. Thus, I switched over to the <a href=\"https:\/\/hackaday.com\/2020\/03\/01\/never-miss-a-doorbell-with-this-notifier\/\">&#8220;put a reed switch in the chime right next to the solenoid&#8221; method<\/a> and that is now way more reliable since it&#8217;s current-sensing rather than voltage-sensing. It&#8217;s also more electrically decoupled from the A\/C. <\/p>\n\n\n\n<p>My transformer reads 18.75 VAC on my voltmeter under normal conditions. To experiment before installation, I&#8217;ll be using a 6 VAC test transformer, which reads 7.23 VAC on my meter, and which corresponds nicely with the 20.6 Vpp I see measured on the oscilloscope. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_110957_sm-1024x576.jpg\" alt=\"\" class=\"wp-image-1745\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_110957_sm-1024x576.jpg 1024w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_110957_sm-300x169.jpg 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_110957_sm-768x432.jpg 768w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_110957_sm.jpg 2000w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Test setup with voltage divider, diode, and test transformer<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145133-576x1024.jpg\" alt=\"\" class=\"wp-image-1753\" width=\"177\" height=\"315\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145133-576x1024.jpg 576w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145133-169x300.jpg 169w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145133-768x1365.jpg 768w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_145133.jpg 1152w\" sizes=\"auto, (max-width: 177px) 100vw, 177px\" \/><figcaption>Testing on the production transformer. I wired these in with the screws for production. Careful: AC can kill you, even though on this side of the transformer it&#8217;s lower voltage. Turn off the mains. <\/figcaption><\/figure><\/div>\n\n\n\n<p>The ESP8266 chip has a 10-bit analog-to-digital (ADC) converter on it that functions between 0-1 V, returning digital values between 0-1024. Many development boards, like my <a href=\"https:\/\/wiki.wemos.cc\/products:d1:d1_mini\">Wemos D1<\/a>, have a voltage divider already in place that takes the max input up to 3.3 V. So I needed to convert my doorbell signal down to 3.3 Vpp. This is the job of a simple <a href=\"https:\/\/en.wikipedia.org\/wiki\/Voltage_divider\">voltage divider<\/a>, plus a diode to chop off the negative side of the AC wave. <\/p>\n\n\n\n<p>We solve: \n\\( \nV_{peak} = V_{RMS} \\cdot  \\sqrt{2} \\cdot x = 3.3V\n\\) for x<\/p>\n\n\n\n<p>For fun, we can try simulating the circuit with <a href=\"http:\/\/qucs.sourceforge.net\/\">Qucs<\/a>. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"864\" height=\"543\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-01-12-16-13.png\" alt=\"\" class=\"wp-image-1729\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-01-12-16-13.png 864w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-01-12-16-13-300x189.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-01-12-16-13-768x483.png 768w\" sizes=\"auto, (max-width: 864px) 100vw, 864px\" \/><figcaption>A first simulation of my voltage divider in the Qucs circuit simulator<\/figcaption><\/figure>\n\n\n\n<p>On my test transformer, I tried cutting the voltage by a factor of 10. A voltage divider with a top resistor 9x the bottom one will work. So 1 k\u03a9 and 10 k\u03a9 would be close. Measuring reality with the oscilloscope agrees:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/scope_voltage_divider_doorbell.png\" alt=\"\" class=\"wp-image-1726\" width=\"662\" height=\"323\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/scope_voltage_divider_doorbell.png 480w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/scope_voltage_divider_doorbell-300x146.png 300w\" sizes=\"auto, (max-width: 662px) 100vw, 662px\" \/><figcaption>The oscilloscope measurement shows that the output signal is 10x less than the input signal, and totally positive. Looks perfect for the ESP&#8217;s ADC<br><\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_125711_sm-1024x576.jpg\" alt=\"\" class=\"wp-image-1749\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_125711_sm-1024x576.jpg 1024w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_125711_sm-300x169.jpg 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_125711_sm-768x432.jpg 768w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/IMG_20190609_125711_sm.jpg 2000w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>The voltage divider soldered up. <\/figcaption><\/figure>\n\n\n\n<p>On the production system, I need to drop 18.7 Vrms down to 3.3 V peak, so my voltage divider must cut voltage down to 0.124 the peak, so a ratio close to 1:8 is needed. Honestly, 1 k\u03a9 and 10 k\u03a9, with a 1:11 ratio should work fine. Let&#8217;s simulate it. Theory says it should give 2.4 V. Simulation agrees. Reality will also. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"932\" height=\"587\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-15.png\" alt=\"\" class=\"wp-image-1731\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-15.png 932w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-15-300x189.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-15-768x484.png 768w\" sizes=\"auto, (max-width: 932px) 100vw, 932px\" \/><figcaption>Simulation of the production setup in Qucs<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"882\" height=\"562\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-19.png\" alt=\"\" class=\"wp-image-1732\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-19.png 882w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-19-300x191.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/Screenshot-from-2019-06-02-15-14-19-768x489.png 768w\" sizes=\"auto, (max-width: 882px) 100vw, 882px\" \/><figcaption>Unsurprisingly, the simulation results agree with theory, 2.4V peak<\/figcaption><\/figure>\n\n\n\n<p>2.4V on a 10-bit 3.3 ADC will be \\(1024 \\cdot \\frac{2.4}{3.3} = 744\\). So let&#8217;s set the ESP ADC to consider anything above 720 to indicate BUTTON NOT PRESSED, and anything below 720 to be BUTTON PRESSED. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Signal Processing and Software<\/h2>\n\n\n\n<p>Originally I thought it&#8217;d be really easy to read the peaks and detect the drop in voltage. I got it going and hooked into MQTT and Home Assistant really quickly with some simple software. <\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Expanding my doorbell range with a stereo, an ESP8266, and Home Assistant\" width=\"660\" height=\"371\" src=\"https:\/\/www.youtube.com\/embed\/QhbSbNmrc-o?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption>Here I am playing around with the test setup<\/figcaption><\/figure>\n\n\n\n<p>However, seeing the break in the circuit is not so easy. With some test runs on the real doorbell, I wasn&#8217;t able to reliably detect a quick\/normal doorbell press. If I really held down on the doorbell button I could detect it, but it wasn&#8217;t good enough. So I had to fiddle around in software to find a good read of the ADC with these kinds of pulses. <\/p>\n\n\n\n<p class=\"has-dark-brown-color has-yellow-background-color has-text-color has-background\"><strong>Sidenote<\/strong>: If you were using MQTT over TLS before and now you have connection troubles, it&#8217;s probably because ESP switched to a more robust TLS library and you either need to explicitly allow insecure connections over TLS or load a certificate chain. This took me a while to figure out. More <a href=\"https:\/\/arduino-esp8266.readthedocs.io\/en\/latest\/esp8266wifi\/readme.html\">here<\/a>.<\/p>\n\n\n\n<p>The ESP8266&#8217;s ADC isn&#8217;t all that fast. In the <a href=\"https:\/\/www.espressif.com\/sites\/default\/files\/2c-esp8266_non_os_sdk_api_guide_en_v1.5.4.pdf\">ESP&#8217;s API guide<\/a>, you can find a really nice sample program around the description of <code>system_adc_read_fast<\/code>. This is also <a href=\"https:\/\/arduino.stackexchange.com\/questions\/48640\/esp8266-system-adc-read-fast-always-give-1024-as-output\">discussed here<\/a> with a very similar waveform to what I&#8217;m dealing with. I did some tests in the Appendix below.<\/p>\n\n\n\n<p>In the USA, a 60 Hz sine wave will cycle once every 16.6 milliseconds. If I sample enough to capture at least 1 full cycle and save the max value from that window, I can watch for a reduction in max values and trigger off of that. From the appendix, one cycle looks like it will require about 2300 samples with clk_div = 16 to capture. Then, we&#8217;ll want to keep the past 20 cycles or so to check\/respond in about a 5th of a second. That ought to be fast enough. <\/p>\n\n\n\n<p>I set up two interrupts with two timers: A fast one to read nearly every peak from every AC cycle and a slower one to take a look at the past 20 peaks and see if any of those have dipped below the trigger threshold. <\/p>\n\n\n\n<p>Here&#8217;s the fast interrupt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ICACHE_FLASH_ATTR read_adc(void *p)\n{\n  \n  uint16 cycle_max = 0;\n  ets_intr_lock();\n  system_adc_read_fast(adc_vals, NUM_SAMPLES, CLK_DIV);\n  ets_intr_unlock();  \n  \n  \/\/ Find peak\n  for(int i=0; i&lt;NUM_SAMPLES; i++)\n  {\n    if (adc_vals&#091;i]&gt;cycle_max)\n      cycle_max = adc_vals&#091;i];\n  }\n  \n  \/\/ Store peak\n  cycle_maxes&#091;cycle_idx] = cycle_max;\n  cycle_idx++;\n  \n  if (cycle_idx == NUM_WINDOWS)\n    cycle_idx=0;\n  \n  os_timer_disarm(&amp;timer);\n  if(recently_pressed==false){\n    os_timer_setfn(&amp;timer, read_adc, NULL);\n    os_timer_arm(&amp;timer,MEASURE_INTERVAL,1);\n  }\n  \n}<\/code><\/pre>\n\n\n\n<p>And here&#8217;s the sentinel one looking for button-presses in the data:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void ICACHE_FLASH_ATTR respond_to_adc_val(void *p)\n{\n  os_timer_disarm(&amp;printtimer);\n\n  \/\/ find lowest peak in previous N cycles\n  uint16 min_val=1024;\n  for (int i=0;i&lt;NUM_WINDOWS;i++) {\n     if (cycle_maxes&#091;i] &lt; min_val)\n        min_val=cycle_maxes&#091;i];\n  }\n  \n  if (min_val &lt; THRESHOLD and recently_pressed == false) {\n     recently_pressed = true;\n  }\n  else {\n    os_timer_setfn(&amp;printtimer, respond_to_adc_val, NULL);\n    os_timer_arm(&amp;printtimer,MONITOR_INTERVAL,1);\n  }\n}<\/code><\/pre>\n\n\n\n<p>Both interrupts re-schedule themselves with their respective timers unless a button-press has been detected, at which point they suspend themselves until something else turns them back on. That something lives in my loop function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void loop() {\n  if (recently_pressed==true)\n  {\n      ontime = millis();\n      \/\/ Hard part: We need to turn the WiFi back on, \n      \/\/ hook back into MQTT, and send the message. \n      \/\/ It's been off because of the ADC reading. \n\n      delay(50); \/\/ wait for adc timer to disable itself\n      clear_results();\n      wifi_set_opmode(STATION_MODE);\n      client.loop();\n      if (!client.connected()) {\n          reconnect();\n      }\n      client.publish(topic, \"ON\", true);\n      Serial.println(\"DING!\");\n      delay(3000);\n      client.publish(topic, \"OFF\", true);\n      Serial.println(\"DONG!\");\n      recently_pressed=false;\n      \n      \/\/ Turn ADC back on\n      os_timer_setfn(&amp;timer, read_adc, NULL);\n      os_timer_arm(&amp;timer,MEASURE_INTERVAL,1);\n\n      \/\/ Turn monitor back on\n      os_timer_setfn(&amp;printtimer, respond_to_adc_val, NULL);\n      os_timer_arm(&amp;printtimer,MONITOR_INTERVAL,1);\n  }\n  delay(10);\n}<\/code><\/pre>\n\n\n\n<p>That&#8217;s pretty much it. The WiFi and MQTT setups are all pretty traditional. I reset ADC results to HIGH on the ADC 1024 to avoid echo-triggers after one gets sensed. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void setup() {\n  Serial.begin(115200);\n  \n  clear_results();\n  \n  setup_wifi();\n  setup_mqtt();\n\n  os_timer_setfn(&amp;timer, read_adc, NULL);\n  os_timer_arm(&amp;timer,MEASURE_INTERVAL,1);\n\n  os_timer_setfn(&amp;printtimer, respond_to_adc_val, NULL);\n  os_timer_arm(&amp;printtimer,MONITOR_INTERVAL,1);\n}\n\nvoid clear_results(void) {\n   cycle_idx=0;\n   for (int i=0;i&lt;NUM_WINDOWS;i++) {\n     cycle_maxes&#091;i]=1024;\n  }\n}<\/code><\/pre>\n\n\n\n<p>This arrangement of the dual timers and windows and stuff is the result of a bit of trial and error. I&#8217;m pretty happy with its ability to sense short variations in the peak AC signal. I cannot press it fast enough to make it miss the read. Yay. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Automation setup in Home Assistant<\/h2>\n\n\n\n<p>Now that the doorbell status is just a MQTT topic that we will monitor, the configuration in Home Assistant is pretty straightforward. First we need a binary sensor based on the MQTT topic:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">binary_sensor:\n  - platform: mqtt\n    state_topic: \"home\/doorbell\"\n    name: \"Doorbell\"\n    device_class: opening<\/pre>\n\n\n\n<p>And of course the automation:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">- alias: Actual doorbell\n  initial_state: on\n  trigger:\n    - platform: state\n      entity_id: binary_sensor.doorbell\n      from: 'off'\n      to: 'on'\n  action:\n    - service: shell_command.dingdong<\/pre>\n\n\n\n<p>That&#8217;s it! It works great and plays throughout the house thanks to my <a href=\"https:\/\/partofthething.com\/thoughts\/multi-room-audio-over-wi-fi-with-pulseaudio-and-raspberry-pis\/\">Snapcast setup<\/a>. Total incremental parts cost for a smart doorbell: $7. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Appendix A: How fast is the ESP8266 ADC?<\/h2>\n\n\n\n<p>I figured I&#8217;d just do some experiments with the ADC to help me understand how fast it really is. In summary, I was able to read 16384 samples that captured 8 peaks of a 60 Hz signal, so the fastest sample rate is roughly 123,000 samples\/second. Not great, not terrible. Totally sufficient for this kind of work though, for sure. <\/p>\n\n\n\n<figure class=\"wp-block-gallery columns-2 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk16.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"700\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk16.png\" alt=\"\" data-id=\"1736\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1736\" class=\"wp-image-1736\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk16.png 900w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk16-300x233.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk16-768x597.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">Clock division =16. This is as slow as we can go<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"700\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8.png\" alt=\"\" data-id=\"1737\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1737\" class=\"wp-image-1737\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8.png 900w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8-300x233.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8-768x597.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">Clock division =8. This is as fast as we can go<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk32.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"700\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk32.png\" alt=\"\" data-id=\"1738\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1738\" class=\"wp-image-1738\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk32.png 900w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk32-300x233.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk32-768x597.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">With Clock div=32, it malfunctions and just returns 1024 for everything.<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk24.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"700\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk24.png\" alt=\"\" data-id=\"1739\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1739\" class=\"wp-image-1739\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk24.png 900w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk24-300x233.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk24-768x597.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">Just for fun I tried clock division = 24. That was messed up.<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8_zoom.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"700\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8_zoom.png\" alt=\"\" data-id=\"1740\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1740\" class=\"wp-image-1740\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8_zoom.png 900w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8_zoom-300x233.png 300w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/clk8_zoom-768x597.png 768w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">Zooming in on some of the data in a peak to see the noise<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00009.png\"><img loading=\"lazy\" decoding=\"async\" width=\"480\" height=\"234\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00009.png\" alt=\"\" data-id=\"1741\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1741\" class=\"wp-image-1741\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00009.png 480w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00009-300x146.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">Here&#8217;s what the real peak looks like on my oscilloscope<\/figcaption><\/figure><\/li><li class=\"blocks-gallery-item\"><figure><a href=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00007.png\"><img loading=\"lazy\" decoding=\"async\" width=\"480\" height=\"234\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00007.png\" alt=\"\" data-id=\"1742\" data-link=\"https:\/\/partofthething.com\/thoughts\/?attachment_id=1742\" class=\"wp-image-1742\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00007.png 480w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/SDS00007-300x146.png 300w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/a><figcaption class=\"blocks-gallery-item__caption\">Zoomed in more on the scope<\/figcaption><\/figure><\/li><\/ul><\/figure>\n\n\n\n<p>The code used to do these demos is below. I just copy\/pasted the data from the serial monitor into a text file and wrote a quick plotter in Python to graph the data. (Interestingly I couldn&#8217;t copy\/paste all from the console output b\/c one of the garbage characters halted the paste, so I shift-clicked to copy the large block quickly). <\/p>\n\n\n\n<p>The code uses a timer to call the <code>system_adc_read_fast<\/code> function once and then prints it out and then just sits forever. I triggered the software watchdog a few times so I put that <code>wdtFeed<\/code> call in there to prevent it from resetting me all the time. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;ESP8266WiFi.h&gt;\n\n#define NUM_SAMPLES 16384\n#define CLK_DIV 16\n\nextern void system_adc_read_fast(uint16 *adc_addr, uint16 adc_num, uint8 adc_clk_div);\n\n\/\/ globals\nos_timer_t timer;\nuint16 adc_vals&#091;NUM_SAMPLES];\nbool printed_once = false;\n\nvoid ICACHE_FLASH_ATTR ADC_TEST(void *p)\n{\n  \/\/Serial.printf(\"Reading ADC...\\n\");\n  wifi_set_opmode(NULL_MODE);\n  ets_intr_lock( );\n  system_adc_read_fast(adc_vals, NUM_SAMPLES, CLK_DIV);\n  ets_intr_unlock();\n  os_timer_disarm(&amp;timer);\n}\n\nvoid print_results(void) {\n  \/\/Serial.printf(\"Reporting ADC...\\n\");\n  for (int i=0;i&lt;NUM_SAMPLES;i++) {\n    Serial.printf(\"%d\\n\", adc_vals&#091;i]);\n    ESP.wdtFeed();\n  }\n}\n\nvoid setup() {\n  Serial.begin(115200);\n  \n  os_timer_setfn(&amp;timer, ADC_TEST, NULL);\n  os_timer_arm(&amp;timer,2000,1);\n}\n\nvoid loop() {\n  delay(3000);\n  if(!printed_once) {\n    print_results();\n    printed_once=true;\n  }\n  \/\/Serial.printf(\"Heartbeat...\\n\");\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I live in tall and skinny house with a loft on the upper floor. I can&#8217;t hear the doorbell going off when I&#8217;m up there, especially if I have music playing. This post is about how I extended the range of my doorbell by hooking a sensor up to it that communicates over Wifi to &hellip; <a href=\"https:\/\/partofthething.com\/thoughts\/making-my-analog-doorbell-smart-by-simply-attaching-a-7-sensor-to-it\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Making my analog doorbell smart by simply attaching a $7 sensor to it<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[69,75],"tags":[],"class_list":["post-1722","post","type-post","status-publish","format-standard","hentry","category-electronics-and-physics","category-home-automation"],"_links":{"self":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/1722","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/comments?post=1722"}],"version-history":[{"count":18,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/1722\/revisions"}],"predecessor-version":[{"id":2112,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/1722\/revisions\/2112"}],"wp:attachment":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media?parent=1722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/categories?post=1722"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/tags?post=1722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}