tag:blogger.com,1999:blog-16663564137182596782024-03-05T02:48:27.424-05:00jpuderer.netThings we need. Things that make us go.Unknownnoreply@blogger.comBlogger10125tag:blogger.com,1999:blog-1666356413718259678.post-55344141954076154512018-02-12T10:42:00.002-05:002018-02-15T15:40:13.636-05:00Pixel Debug Cable<span style="font-family: "helveticaneue"; font-size: 12px;">Hacking around with building your own Android / AOSP system images can lead to difficult to debug problems during early boot. </span><br />
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<div>
<br /></div>
<div>
Fortunately, the Pixel XL (and several other Nexus and Pixel devices) includes a serial debug port that uses the pins on the headphone jack. It’s possible to get early debug output (from the boot loader and kernel) by issuing a special fastboot command, and connecting a simple serial adapter.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsG2a_Chy7HfrFX4k4HmJGu1-J-DdYCbwfxIh2-gXepp7bwKI1Dc4J_j57MSJUo1seOawIShR0QX2T8nIJhas2xBd7BXwKVyxlsL7KckRfeTALfWtgxKeGp9Mo8urX-COrOcL7j8QjBh8/s1600/IMG_20180212_085526.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsG2a_Chy7HfrFX4k4HmJGu1-J-DdYCbwfxIh2-gXepp7bwKI1Dc4J_j57MSJUo1seOawIShR0QX2T8nIJhas2xBd7BXwKVyxlsL7KckRfeTALfWtgxKeGp9Mo8urX-COrOcL7j8QjBh8/s320/IMG_20180212_085526.jpg" width="240" /></a></div>
<div>
<br /></div>
<div>
<a name='more'></a><br /></div>
<div>
To build one, you’ll need to following components:</div>
<div>
<div>
<ul>
<li><a href="https://www.sparkfun.com/products/9873" target="_blank">SparkFun FTDI Basic Breakout - 3.3V </a></li>
<li><a href="https://www.sparkfun.com/products/9353" target="_blank">Heat Shrink Kit</a></li>
<li><a href="https://www.sparkfun.com/products/11580" target="_blank">Audio Cable TRRS - 18" (pigtail) </a></li>
<li><a href="https://www.sparkfun.com/products/8431" target="_blank">Jumper Wires Premium 6" M/M Pack of 10</a></li>
</ul>
</div>
</div>
</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
At a minimum, you’ll need a 3.3V FTDI board and TRRS jack, but I included the jumper wires and shrink wrap for tidiness sake.</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
Below is a simple Fritzing diagram that should make everything abundantly clear.</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs48RbKis87Tld18Epv711ds7fVkE5wT3YX759O3nh4tOVmpXX8J82Ancqf4r2NMQMmNPOCqlVR78OTn0uLjMvZ-6QjtKY_ZpHlcwekF-Jxq7in-FWhKAYNwubr4zI6GEpcwYC9HZDUDc/s1600/Pixel+Debug+Cable_bb.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="615" data-original-width="777" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs48RbKis87Tld18Epv711ds7fVkE5wT3YX759O3nh4tOVmpXX8J82Ancqf4r2NMQMmNPOCqlVR78OTn0uLjMvZ-6QjtKY_ZpHlcwekF-Jxq7in-FWhKAYNwubr4zI6GEpcwYC9HZDUDc/s400/Pixel+Debug+Cable_bb.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div class="info-box alert">
<div class="msg">
Note that the colors of the wires in the TRRS cable do not necessarily match the colors on the digram above (ie. black is most likely not ground). You should check the wires with a multimeter before connecting them to the serial board.</div>
</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
To enable the serial console, you’ll need to have unlocked the bootloader, have the device in fastboot mode, and issue the following fastboot command:</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-size: 12px; text-size-adjust: auto;">
<span style="font-family: "courier new" , "courier" , monospace;">fastboot oem uart enable</span></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
You can then connect to the serial console at 115200, 8N1 (with no flow control), though this may depend on the device.</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
Enjoy!</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div class="info-box alert">
<div class="msg">
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
Notes:</div>
<ul>
<li><span style="color: #eeeeee;">This worked for me on a Pixel XL running bootloader version 8996-012001-1709121620 </span></li>
<li><span style="color: #eeeeee;">Credit to jmcnicol for his original post: <a href="http://people.redhat.com/jmcnicol/nexus_debug/" target="_blank"> http://people.redhat.com/jmcnicol/nexus_debug/</a></span></li>
<li><span style="color: #eeeeee;">I’ve heard a rumour that most Nexus and Pixel devices support a serial console on the headphone jack</span></li>
<li><span style="color: #eeeeee;">I have not been able to enable the serial console on the N5X itself, the boot loader version may have changed</span></li>
<li><span style="color: #eeeeee;">The fastboot OEM commands are boot loader dependant and may change without warning. The commands seem to vary between devices</span></li>
<li><span style="color: #eeeeee;">Please comment below if you managed to get this working on other devices</span></li>
</ul>
</div>
</div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
<div style="font-family: HelveticaNeue; font-size: 12px; text-size-adjust: auto;">
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1666356413718259678.post-84479591372827619272017-11-18T11:13:00.001-05:002017-11-18T11:13:10.142-05:00Distributed Air Quality Monitoring (Using Taxis!)<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU8CwBog4Fjhx4bMXOqQW6Vz98kbXg0hK7wsRJ-V2H-ZaPsaQ7qJHelaIwzC7maeGJavcflzGj882HhwXacVSvC9nRAp9-ef7a0tAKBu2VyAX6KNTJlD8cTGuWwEP-WbnL8j_oz4i6bKg/s1600/Screen+Shot+2017-10-26+at+10.00.26+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="417" data-original-width="596" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU8CwBog4Fjhx4bMXOqQW6Vz98kbXg0hK7wsRJ-V2H-ZaPsaQ7qJHelaIwzC7maeGJavcflzGj882HhwXacVSvC9nRAp9-ef7a0tAKBu2VyAX6KNTJlD8cTGuWwEP-WbnL8j_oz4i6bKg/s320/Screen+Shot+2017-10-26+at+10.00.26+PM.png" width="320" /></a></div>
<br />
Last month I put together a project on <a href="http://www.hackster.io/" target="_blank">Hackster.io</a> as part of an <a href="https://developer.android.com/things/hardware/index.html" target="_blank">Android Things</a> contest that Google was sponsoring. Amazingly, I won!<br />
<br />
<br />
<a name='more'></a><br />
<br />
I got some pretty good coverage here:<br />
<br />
<ul>
<li><a href="https://android-developers.googleblog.com/2017/11/android-things-contest-winners.html">https://android-developers.googleblog.com/2017/11/android-things-contest-winners.html</a></li>
<li><a href="https://www.raspberrypi.org/blog/air-quality-peru/">https://www.raspberrypi.org/blog/air-quality-peru/</a></li>
<li><a href="https://blog.hackster.io/announcing-the-winners-of-hacksters-android-things-contest-bab6a3dfaee4">https://blog.hackster.io/announcing-the-winners-of-hacksters-android-things-contest-bab6a3dfaee4</a></li>
</ul>
<br />
This has been a fantastic experience. Also, a lot of work... 😏<br />
<br />
I'm going to have to think carefully about what to do with this next.<br />
<br />Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-1666356413718259678.post-2409156306477839302017-09-30T18:25:00.000-05:002017-09-30T18:25:09.572-05:00Making my TV dumb again!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSVOz06kZDMAx3ImnjhGo8Xu0kPdPfRd0vujfb6H-HpfPgXnM7W6NQhLrC1itwllRIwyoiVTpNpgrpiqk0g1uA6oLhEna4SKWYY2DPevrT2-Ny53K1FiVvg_rOSmfXbwg7fvGXJzsRGK4/s1600/tv.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="640" data-original-width="594" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSVOz06kZDMAx3ImnjhGo8Xu0kPdPfRd0vujfb6H-HpfPgXnM7W6NQhLrC1itwllRIwyoiVTpNpgrpiqk0g1uA6oLhEna4SKWYY2DPevrT2-Ny53K1FiVvg_rOSmfXbwg7fvGXJzsRGK4/s320/tv.png" width="297" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I don't like my TVs smart. I like them dumb....</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
...and when I'm using my 4k LG Smart TV as a glorified computer monitor for work, I *really* want nothing to do with pressing buttons on a remote control, chatty on-screen display messages, and displaying stupid pictures of a golden retriever.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Android Things to the rescue!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<a name='more'></a><br />
<br />
<div class="separator" style="clear: both;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju-8F9S7Z6f4bpG8PC0mYq7LWh9FibDSPLfXeLQfMuzAsaWp6mOXgIqfNw_jpVMmtyfqTLW0r7r7jJb-2j2gquzFObOoC9f3_oFCcBnkgHdth5noEXYZcVsN7_lbvYcMaxFCNLLDpozYQ/s1600/IMG_20161104_105549.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="856" data-original-width="640" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju-8F9S7Z6f4bpG8PC0mYq7LWh9FibDSPLfXeLQfMuzAsaWp6mOXgIqfNw_jpVMmtyfqTLW0r7r7jJb-2j2gquzFObOoC9f3_oFCcBnkgHdth5noEXYZcVsN7_lbvYcMaxFCNLLDpozYQ/s400/IMG_20161104_105549.jpg" width="298" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><div class="separator" style="clear: both; font-size: medium; text-align: center;">
<span style="font-size: 12.8px;">💖 </span> I LOVE my computer setup! <span style="font-size: 12.8px;">💖</span></div>
<div>
<br /></div>
</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
What's not to love? My 4k monitor has enough real-estate to display everything I might need to reference (Slack, browser windows, notes, etc.), and the smaller (but crisper and easier to read) Macbook Pro Retina display is used for what I'm actually concentrating on.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Well... the only thing not to love, is that this *awesome* monitor is sold and marketed as a Smart TV, which is marketer's parlance for loading it with features that make it as intrusive and as annoying as Microsoft's Clippy.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs3rsInwECD5LPCU7O3fGs0V3xuWzsE1YhNUrq4KknEt0UjeZtWGsaum47PvqRAKOIcF5o6E0VWkAsQnDovhBz3KRCyVCagitwznL8EpBs_dAY3b2TSyGTtyHLceKNkh7a1mdVw6HV7Cg/s1600/Clippy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="416" data-original-width="576" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs3rsInwECD5LPCU7O3fGs0V3xuWzsE1YhNUrq4KknEt0UjeZtWGsaum47PvqRAKOIcF5o6E0VWkAsQnDovhBz3KRCyVCagitwznL8EpBs_dAY3b2TSyGTtyHLceKNkh7a1mdVw6HV7Cg/s320/Clippy.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Actually, you know what? I'll do one better. Every time I unplug my computer, I get this silly picture of a dog smiling at me, so really it's more like that dog in Duck Hunt for the original Nintendo. You know, the one you can never shoot even though it constantly laughs at you when you miss the birds? (I guess you can all guess at how old I am now) </div>
<div class="separator" style="clear: both; text-align: left;">
<span style="background-color: yellow;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEIIO4X0wYTXFIXfzUXHpHMi-uu5MwDcqzxYGXVzA-23o9YO2psDoWGqO5I2v_uuvV6K9ayRy2In_C7FZyJBtOkisOer8RBDwX6UgJ2dO6pq2njPhF3iAoux7d0Km6KN6kfzBzcQtqc30/s1600/IMG_20170906_110453.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEIIO4X0wYTXFIXfzUXHpHMi-uu5MwDcqzxYGXVzA-23o9YO2psDoWGqO5I2v_uuvV6K9ayRy2In_C7FZyJBtOkisOer8RBDwX6UgJ2dO6pq2njPhF3iAoux7d0Km6KN6kfzBzcQtqc30/s1600/IMG_20170906_110453.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="853" data-original-width="1600" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEIIO4X0wYTXFIXfzUXHpHMi-uu5MwDcqzxYGXVzA-23o9YO2psDoWGqO5I2v_uuvV6K9ayRy2In_C7FZyJBtOkisOer8RBDwX6UgJ2dO6pq2njPhF3iAoux7d0Km6KN6kfzBzcQtqc30/s200/IMG_20170906_110453.jpg" width="200" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvASQtldJnfRtqa6XlRMCHiq7nUoxvoraE1bPb0eQn3Xsbul9Inzjn02JoeODmZB_70858vmFfeGoE8qzf6x8dqLSYlQFRJkSGD9OvsolzYSpg3XpZzs6FfmLbNogKMIqF4NlBgzxIaUI/s1600/duckhunt.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="366" data-original-width="650" height="111" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvASQtldJnfRtqa6XlRMCHiq7nUoxvoraE1bPb0eQn3Xsbul9Inzjn02JoeODmZB_70858vmFfeGoE8qzf6x8dqLSYlQFRJkSGD9OvsolzYSpg3XpZzs6FfmLbNogKMIqF4NlBgzxIaUI/s200/duckhunt.jpg" width="200" /></a></div>
<div class="" style="clear: both; text-align: center;">
<span style="background-color: yellow;"><br /></span></div>
<div class="" style="clear: both; text-align: center;">
<i style="background-color: white;">Like in Duckhunt, you can never ever get rid of this dog.</i></div>
<div class="" style="clear: both; text-align: left;">
<span style="background-color: yellow;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
And switching the HDMI input to another other computer involves four or five button presses on the remote control... which is around here somewhere... Wait, are you kidding me?!? I just want to change the input? We had buttons on TVs figured out since the 1950s</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Well I've been itching to build something using the <a href="https://developer.android.com/things/hardware/index.html" target="_blank">Android Things</a> platform for a while now, so why not use it for this?</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In the end the project was absurdly simple. It seems that recent LG TVs have a built in serial protocol that lets you send commands to the TV if you have the right kind of USB serial adapter plugged in the back <span style="background-color: white;">(with a PL2303 chipset)</span>. You can find a description of the command language if you search for "External Control Device Setup" (the links seem to move around).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So, my simple hack to make my smart TV dumb(er) is some buttons, a RPi3 running Android Things, and a USB serial adapter.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeEdk2vndPlZA17sqoyUSOGOO6KJD_NUskXkYFkwuXN9kC0O1uAlW5DZIldhZawjGiOyL5FAc_5J3MSgUtOd5wqHpr3oq2By-z9LkSmIDobNrl6wIInizvkpJj7YK-7lUrHpfwt4uOjVs/s1600/JustATv_schem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="795" data-original-width="1524" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeEdk2vndPlZA17sqoyUSOGOO6KJD_NUskXkYFkwuXN9kC0O1uAlW5DZIldhZawjGiOyL5FAc_5J3MSgUtOd5wqHpr3oq2By-z9LkSmIDobNrl6wIInizvkpJj7YK-7lUrHpfwt4uOjVs/s400/JustATv_schem.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The code is also pretty simple (<a href="https://github.com/jpuderer/JustaTV" target="_blank">you can find it here</a>). It just listens for button presses and then switches the HDMI input when a button is pressed. It also sends periodic commands to disable to On Screen Display (OSD), which amazingly seems to banish the dog!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The only thing that was mildly out of the ordinary was that you need to <a href="http://disable%20the%20default%20serial%20console%20in%20order%20to%20use%20the%20serial%20port/" target="_blank">disable the default serial console</a> in order to use the serial port.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Yay! My TV is dumb again!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRGzcrm5jqA-gVQ9qce1bwloA87DrbZ_q7-13v6U0K4wJbjlfaHH43wVRI9yAzUgxZ4aKSJ2W80DTQ5ZNyB5v6E1gVCH4zQpIPj2Q81su1VayaQ0QnCuo4wJbMAaiGaDugEm86xm3XzsY/s1600/IMG_20170913_204249.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhzX7M9mi5d7Ztuu13BF0gIC8pYBGTl2ai5oIabL_U1SMH06ul5Wqo_Bj_6i5KYkHJrh6j-kXQ8YoSgLBJOCEfWRUGe49uhyphenhyphenGQxGqaHmu_T7YnVhrAyTRWTBEZdRFF4y3ptIOAW0u7qrg/s1600/IMG_20170913_220212.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1000" data-original-width="1600" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhzX7M9mi5d7Ztuu13BF0gIC8pYBGTl2ai5oIabL_U1SMH06ul5Wqo_Bj_6i5KYkHJrh6j-kXQ8YoSgLBJOCEfWRUGe49uhyphenhyphenGQxGqaHmu_T7YnVhrAyTRWTBEZdRFF4y3ptIOAW0u7qrg/s320/IMG_20170913_220212.jpg" width="320" /></a><img border="0" data-original-height="1536" data-original-width="1600" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRGzcrm5jqA-gVQ9qce1bwloA87DrbZ_q7-13v6U0K4wJbjlfaHH43wVRI9yAzUgxZ4aKSJ2W80DTQ5ZNyB5v6E1gVCH4zQpIPj2Q81su1VayaQ0QnCuo4wJbMAaiGaDugEm86xm3XzsY/s200/IMG_20170913_204249.jpg" width="200" /></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="info-box alert">
<div class="msg">
Addendum<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You might be asking, why use a RPi3 to do this? Isn't your solution ridiculously over powered? Well, yes. Yes, it is. Two reasons: </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
1. I wanted to do something with Android Things, and I don't really care if my solution is over powered.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
2. I had *hoped* to use the RPi to send <a href="https://en.wikipedia.org/wiki/Consumer_Electronics_Control" target="_blank">HDMI-CEC</a> commands, which I know the RPi3 hardware can manage. Unfortunately, it doesn't look like Google has enabled/implemented the <a href="https://source.android.com/devices/tv/hdmi-cec" target="_blank">HdmiControlService</a> on the RPi3. It's also a SystemAPI which is not normally visible to regular developers (though I can still get to it via reflection), which is something Google will probably want to address in future releases (hint, hint).</div>
</div>
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1666356413718259678.post-31651068763859954172017-01-21T07:26:00.000-05:002017-01-21T07:32:24.200-05:00My Garage Door is now part of the Internet of Things<div class="p1">
<div class="p1">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiO0euAI3Hbs66qocnw_Md6eSas7z7igWAdKrHGFFJmg01J6LsodqkjKAwDjhtBr8AxCOt3HqUr_KoxNdzjnzaGJ73I2n6INtJxkvZautyKThg38-nFZwD5rpX_9QiL_2zlafm0FK5UKU/s1600/Androidfight.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiO0euAI3Hbs66qocnw_Md6eSas7z7igWAdKrHGFFJmg01J6LsodqkjKAwDjhtBr8AxCOt3HqUr_KoxNdzjnzaGJ73I2n6INtJxkvZautyKThg38-nFZwD5rpX_9QiL_2zlafm0FK5UKU/s320/Androidfight.png" width="320" /></a></div>
<span class="s1"><br /></span>
<span class="s1">I am a firm believer in my phone being the only thing I need to have with me…. EVER!</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">… and I am looking forward with great anticipation to the day I can finally defeat my constant and unwanted companions: wallet and keys.</span></div>
<div class="p2">
<span class="s1"></span><br />
<br />
<a name='more'></a></div>
<div class="p1">
</div>
<br />
So when for security reasons, the apartment building where my family lives decided to install a <b>big</b>, <b>thick,</b> <b>blocking-my-way</b> garage door, I was a little miffed when they handed me this:<br />
<br /></div>
<div class="p1">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfxsUFD44ALW_XdeMsoKzj6j10R55MTekCSC5Bv12l05ICSrTG7ApXO8zIdJACimZygzaDVNDKArjioyFFNA1XslI1kS7b6QMFcDIcd1ybwcSfibCMuM182ZtsYb_lg7dd-hfLNy_QgYc/s1600/remote_control.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfxsUFD44ALW_XdeMsoKzj6j10R55MTekCSC5Bv12l05ICSrTG7ApXO8zIdJACimZygzaDVNDKArjioyFFNA1XslI1kS7b6QMFcDIcd1ybwcSfibCMuM182ZtsYb_lg7dd-hfLNy_QgYc/s1600/remote_control.jpg" /></a></div>
<br /></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Doors seem to be a perennial problem for me (see my previous posts here). One that I hope to beat into submission with cleaver techno-hackery.</span></div>
<div class="p2">
<span class="s1"></span></div>
<div class="p1">
<br /></div>
<div class="p1">
<span class="s1">So yeah… </span></div>
<div class="p2">
<span class="s1"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSmHlEpYGninvKtQv0uM-st8wmiXy5a2QhYKAEbmc8daZ99qOygSGYOwJfhhSRMwhDx4eg-sfRz_FBCYzcz1KqmVGWDhyphenhyphenTvSOS5ZttNkV50_ySNbfnUtMggtIOO6f5gCh-yhPH39p_XoQ/s1600/15n0ib.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSmHlEpYGninvKtQv0uM-st8wmiXy5a2QhYKAEbmc8daZ99qOygSGYOwJfhhSRMwhDx4eg-sfRz_FBCYzcz1KqmVGWDhyphenhyphenTvSOS5ZttNkV50_ySNbfnUtMggtIOO6f5gCh-yhPH39p_XoQ/s400/15n0ib.jpg" width="400" /></a></div>
<br /></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">So, how to do it?</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Well, I have a storage locker in the garage that is in line of site to the garage door. And, I can use a Raspberry Pi wired up with a simple relay block to “press” the button on my garage remote.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">But how to communicate with it from my phone?</span></div>
<div class="p2">
<br />
<span class="s1"></span></div>
<div class="p1">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuZmmdGvyJ2IdoGaTBP4qHZL-c2v7G0Qtz_k-J6eVnLXLC1dW4WoYLjJaQztubHwxXKi3fYZOv1Npd21IAy4QzR4DYXeRynSSB6G_mm-JuvtN8erTRe00Mi7xkl4nv8HrIhVwVVHqzg5M/s1600/garage_door_diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuZmmdGvyJ2IdoGaTBP4qHZL-c2v7G0Qtz_k-J6eVnLXLC1dW4WoYLjJaQztubHwxXKi3fYZOv1Npd21IAy4QzR4DYXeRynSSB6G_mm-JuvtN8erTRe00Mi7xkl4nv8HrIhVwVVHqzg5M/s320/garage_door_diagram.png" width="320" /></a></div>
<span class="s1"><br /></span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Well, Bluetooth doesn’t have the range, so that probably means I need to connect it to the internet somehow.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">Now, I don’t really love the idea of having to make my little Raspberry Pi accessible over the public internet (for many reasons). Fortunately, there’s a pretty good alternative: <a href="https://developers.google.com/cloud-messaging/" target="_blank">Google Cloud Messaging</a> (GCM). </span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">
</span><br />
<div class="info-box alert">
<div class="msg">
<span class="s1">Note, I wrote most of this article a <b><i>while</i></b> ago and am just getting around to cleaning it up, I guess it’s called <a href="https://firebase.google.com/docs/cloud-messaging/" target="_blank">Firebase Cloud Messaging</a> now (FCM), but it’s the same thing really. I’m going to keep calling it GCM for now (because that’s what I wrote it with), and if your inner marketer needs to, you can perform the mental substitution yourself.</span></div>
</div>
<span class="s1">
</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">GCM is used to push messages to client devices (generally cellphones). Now the reason things like GCM exist in the first place is because mobile devices like cellphones don’t usually have permanent IP addresses you can reach them at. They often switch between networks, hide behind firewalls, and are generally assigned dynamic (and therefore unpredictable) addresses. Cellphones are the itinerant vagabonds of the internet.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">In GCM you generally have a server that publishes messages to the GCM service, and a bunch of clients (cell phones) that can receive the messages from the GCM service. This is possible, since the client devices maintain constant connectivity to the GCM service.</span></div>
<div class="p2">
<span class="s1"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf95dfSeuRo6SCxmUHAmuxJql4xxXxAfQ6mC407dOpzlY0GxvYuJISkUxlX0MfTuz61RHYeDW-WpnY0ca-WboNlMebBENhEVotQ2wbF6B9MjnV3pl-Xn0fDhjWYn_7wwVXJFEFEwwbOfg/s1600/firebase.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf95dfSeuRo6SCxmUHAmuxJql4xxXxAfQ6mC407dOpzlY0GxvYuJISkUxlX0MfTuz61RHYeDW-WpnY0ca-WboNlMebBENhEVotQ2wbF6B9MjnV3pl-Xn0fDhjWYn_7wwVXJFEFEwwbOfg/s320/firebase.png" width="320" /></a></div>
<br /></div>
<div class="p1">
<span class="s1">Now, one really cool feature of GCM is that it also supports upstream messaging. Basically, if you decide to support it, your clients (phones) can send messages upstream to the server. It does this using XMPP (<a href="https://developers.google.com/cloud-messaging/upstream" target="_blank">more info here</a>).</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">So here’s what I did… I implemented a very simple Android application that registers itself with GCM that can send upstream messages to a server. It is literally a home screen widget that acts as a button. It does absolutely nothing else.</span></div>
<div class="p2">
<br />
<span class="s1"></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZec5IMKh4zC2MgjH23XKnmhUOCpkW4WvtZoce4Jpyrrn_YHdAzzb8VO54dAePqJS8F0zEcAQgLPJmtBRHkZYILamZgVOxGOZsEklVIohjJdxAlM1dKvmIYIs-Jjk90VcJYRMIkuVhyJk/s1600/garagedoor_screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZec5IMKh4zC2MgjH23XKnmhUOCpkW4WvtZoce4Jpyrrn_YHdAzzb8VO54dAePqJS8F0zEcAQgLPJmtBRHkZYILamZgVOxGOZsEklVIohjJdxAlM1dKvmIYIs-Jjk90VcJYRMIkuVhyJk/s320/garagedoor_screenshot.png" width="269" /></a></div>
<br /></div>
<div class="p1">
<span class="s1"><br /></span>
<span class="s1">You can find the source code on Github: <a href="https://github.com/jpuderer/GarageDoor">https://github.com/jpuderer/GarageDoor</a></span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">The Raspberry Pi is connected to my home LAN, since I was able to use an <a href="https://www.amazon.ca/TP-Link-TL-PA4010KIT-Powerline-Adapter-Starter/dp/B00AWRUICG" target="_blank">Ethernet over power line adapter </a>to bridge the Raspberry Pi into my home network from the garage.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">And the server application is a (relatively) simple Python script that runs on the Raspberry Pi, which triggers the relay (and opens the door) whenever it receives a message over GCM. </span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
You can find the server Python script <a href="https://github.com/jpuderer/GarageDoor/blob/master/Raspberry%20Pi/rootfs/usr/sbin/garageDoorService.py" target="_blank">here</a>.<br />
<br /></div>
<div class="p1">
<span class="s1">
</span>
<br />
<div class="info-box alert">
<div class="msg">
<span class="s1">Actually, it does a few other little things like some simple minded authentication against a user/password file, checking the time stamp (to make sure the request isn’t old), and ignoring requests that come too close together (to avoid button mashing).</span></div>
</div>
<span class="s1">
</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">And here it is:</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRhm-pJ1yyjEaN2n2HvgnmgURC8Cnkp9BVSldU4SHtGoAvRCfF2KAcZ4S_Qeb-KHlXb4PgB6B2vIBfjgKUNpwyzDYcHOZSEDV3Ig5tNW6o6riYkQGieo2diwUNa3N4kZX1WuY-GJXFs0U/s1600/pi2_rc_box.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="292" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRhm-pJ1yyjEaN2n2HvgnmgURC8Cnkp9BVSldU4SHtGoAvRCfF2KAcZ4S_Qeb-KHlXb4PgB6B2vIBfjgKUNpwyzDYcHOZSEDV3Ig5tNW6o6riYkQGieo2diwUNa3N4kZX1WuY-GJXFs0U/s320/pi2_rc_box.jpg" width="320" /></a></div>
<br /></div>
<div class="p2">
<br />
<span class="s1"></span>
<br />
<div style="text-align: center;">
<span style="font-family: "trebuchet ms" , sans-serif; font-size: x-large;"><b>TA-DA!</b></span></div>
<div style="text-align: center;">
<br /></div>
</div>
<div class="p1">
<span class="s1"> I’ve been using my garage opener app reliably for many months now, without much issue. No longer do I have a need for a clunky remote in my pocket!</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">In summary, Google Cloud Messaging (ahem! Firebase Cloud Messaging) is a really cool (and unexpected) way to implement IoT type applications without a lot of hassle. Libraries, SDKs, and sample code are all readily available, the service is free, and it works reliably. I will definitely consider using it again for similar projects.</span><br />
<span class="s1"><br /></span>
Actually, if I had to do this all over again, I would probably try the new <a href="https://developer.android.com/things/index.html" target="_blank">Android Things</a> preview image for the Raspberry Pi 3. <a href="https://firebase.google.com/docs/cloud-messaging/" target="_blank">Firebase Cloud Messaging</a> (FCM) is much more seamlessly integrated and easy to use. Hopefully I'll have some time to hack something together that uses this cool new framework.</div>
<div class="p2">
<span class="s1"></span><br /></div>
<br />
<div class="p2">
<span class="s1"></span><br /></div>
Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-1666356413718259678.post-79906868646677825002016-03-31T17:46:00.000-05:002017-09-29T10:44:12.893-05:00Controlling my Door Lock from Android using Bluetooth-LE<br />
<i style="background-color: white; color: #909090; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2px;">Part 3 of <b><a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html" style="color: #351c75; text-decoration: none;">My Fancy Bluetooth-LE Operated Door Lock</a> </b>series</i><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKD5H_OY_7JI-q_e5FAIyj05ZdVZQCVl-YNET2U2H8AaPWJAOFzo3OdNC-r54ySQiM5eEuLxt1hke99sOoxteBIEf8IWEk2zE1Zlz9L0Io4jEqZs9BIrbos9OM95Kozif7MDfUMFJXLLY/s1600/AndroidBluetoothApp.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Original Nexus 5 image (Fetx2002 / Flickr CC BY 2.0)" border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKD5H_OY_7JI-q_e5FAIyj05ZdVZQCVl-YNET2U2H8AaPWJAOFzo3OdNC-r54ySQiM5eEuLxt1hke99sOoxteBIEf8IWEk2zE1Zlz9L0Io4jEqZs9BIrbos9OM95Kozif7MDfUMFJXLLY/s320/AndroidBluetoothApp.jpg" title="" width="240" /></a></div>
<i style="background-color: white; color: #909090; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2px;"><br /></i>
This is the last post of my <a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html" target="_blank">3 part series</a> on hacking an off-the-shelf electronic lock to be controlled by my Android phone using a Bluetooth capable Arduino board. Whew!<br />
<div class="p1">
<br />
So the final pieces to this is to create a usable Android App that I can use to control my door lock.</div>
<div class="p1">
<br />
It's easier said than done!<br />
<a name='more'></a><br />
What I ended up creating is an app with four screens, and a notification.<br />
<br />
<div class="nivoSlider" id="slider" style="margin-left: auto; margin-right: auto; width: 200px;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAEuiiUv6LOzVLcDybVB5OSyXqyFdOMFfrdyBK1SdrD1fk0nlrnQXplQ4Jy-C9Gu8SZz8HMnc-TrcTpGOPBEJ3Y3rR_oGAaYQF14EEE6eYEYEexmElx6Qt61IQh1tUaq1VNd1v0lmL7mQ/s1600/Screenshot_20160316-095502.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAEuiiUv6LOzVLcDybVB5OSyXqyFdOMFfrdyBK1SdrD1fk0nlrnQXplQ4Jy-C9Gu8SZz8HMnc-TrcTpGOPBEJ3Y3rR_oGAaYQF14EEE6eYEYEexmElx6Qt61IQh1tUaq1VNd1v0lmL7mQ/s320/Screenshot_20160316-095502.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-uLED62AJGw97oOJ688wNLJuxyHpBPhE2jwzJLuysKWQXnfPGO2SEsLPpmjfnHrca760tSMptbHYS0T92bq6-trnwCvmwmeFXGfhDsUFa2znnH5coHqbPftQh0-S0T0zbAKl3KH2i6dY/s1600/Screenshot_20160316-095511.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-uLED62AJGw97oOJ688wNLJuxyHpBPhE2jwzJLuysKWQXnfPGO2SEsLPpmjfnHrca760tSMptbHYS0T92bq6-trnwCvmwmeFXGfhDsUFa2znnH5coHqbPftQh0-S0T0zbAKl3KH2i6dY/s320/Screenshot_20160316-095511.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLciH9d5xDfvR58g2CUDomevQtG2j9Vr7XiM7eDix6Tc9WJTw_y0vWaVmlngXnBpF4CXr394-fZu7tpwTCv5pypGyea3ZMzru8CLy692W9FNu4BpC8hl5O0vEN9WInq_biiClhkfB3958/s1600/Screenshot_20160316-095518.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLciH9d5xDfvR58g2CUDomevQtG2j9Vr7XiM7eDix6Tc9WJTw_y0vWaVmlngXnBpF4CXr394-fZu7tpwTCv5pypGyea3ZMzru8CLy692W9FNu4BpC8hl5O0vEN9WInq_biiClhkfB3958/s320/Screenshot_20160316-095518.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhImJN1tyryP22lZ8Gy_A8XdOdm0nyeFz1CpfKUl1JxrhPLZP0Xw-M_8GYH8KUjVR4XPL_t-GgCvIwjcxeNfGXVCRjhIVUfvNZ9dfvKa_jdlrI3GjlykLWflDENOee4uEuGhC9WZDbuyLQ/s1600/Screenshot_20160316-095527.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhImJN1tyryP22lZ8Gy_A8XdOdm0nyeFz1CpfKUl1JxrhPLZP0Xw-M_8GYH8KUjVR4XPL_t-GgCvIwjcxeNfGXVCRjhIVUfvNZ9dfvKa_jdlrI3GjlykLWflDENOee4uEuGhC9WZDbuyLQ/s320/Screenshot_20160316-095527.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMYbDYmf6og1SdXj0obSThVwO9A-sVakqssbYThhV_TFgEiSRu7mARlh32w6XeCwAigw5k-J8WBJSpk845VmZknIeHxa2mt0lbr-wQYjLEiO0okOpf6SaQvIdEjWqUIlB-P-39KpB70Hg/s1600/Screenshot_20160316-151408.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMYbDYmf6og1SdXj0obSThVwO9A-sVakqssbYThhV_TFgEiSRu7mARlh32w6XeCwAigw5k-J8WBJSpk845VmZknIeHxa2mt0lbr-wQYjLEiO0okOpf6SaQvIdEjWqUIlB-P-39KpB70Hg/s320/Screenshot_20160316-151408.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtUR8AExN7beycuh1LsV3yEg0wtl8FJBEf4xoC-Co-JPp6uX7sCGPlUh88hHFQYOjagl-s2JS58oHXstae_dO3MPzFv5V_8RDUyxnUU0fqIWRcTaolAsfzQP_5aD_gauFMVlVfb5tK6D4/s1600/Screenshot_20160316-151357.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtUR8AExN7beycuh1LsV3yEg0wtl8FJBEf4xoC-Co-JPp6uX7sCGPlUh88hHFQYOjagl-s2JS58oHXstae_dO3MPzFv5V_8RDUyxnUU0fqIWRcTaolAsfzQP_5aD_gauFMVlVfb5tK6D4/s320/Screenshot_20160316-151357.png" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIeIuQFWEAajq9ZbSJfE11Zw1K5VSl2GKInYVdr8teB_T-XOYH018N8RJBtym1cj7COzibXd1WV_x83GM3cGKCs2EhDP5Zk5M466CovkadQlcyLNfayf2vL3CETWgb1ax7SWDXvIMcKf8/s1600/Screenshot_20160316-095535.png"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIeIuQFWEAajq9ZbSJfE11Zw1K5VSl2GKInYVdr8teB_T-XOYH018N8RJBtym1cj7COzibXd1WV_x83GM3cGKCs2EhDP5Zk5M466CovkadQlcyLNfayf2vL3CETWgb1ax7SWDXvIMcKf8/s320/Screenshot_20160316-095535.png" /></a>
</div>
<br />
<br />
<ul>
<li><i>Door Control</i> is just a giant animated button that opens and closes the door (if configured).</li>
<li><i>Keypad</i> is pretty much the door lock's keypad on the phone</li>
<li><i>Bluetooth Device</i> is for discovering and pairing with the doorlock</li>
<li><i>Preferences</i> are... well... preferences (just the door code at the moment).</li>
<li><i>Notification</i></li>
</ul>
<div>
<i><br /></i></div>
<br />
If any of this looks at all useful to you, feel free to grab the <a href="https://github.com/jpuderer/Bluedoor" target="_blank">code</a> on Github. <br />
<br />
It's free, as in beer.<br />
<br />
But before you get too excited though, read on (hint: The antagonist of this story is Bluetooth-LE on Android).<br />
<br />
Now, I'm not going to get into all the gritty details of how to develop Android Applications, or provide a detailed tutorial on Bluetooth-LE for Android. There's lots of documentation and existing tutorials for that, and as a last resort the actual source code. You'll find some links at the bottom of this article.<br />
<br />
Ideally, I just wanted some easy way to lock/unlock my door whenever I pressed a button. Opening the app everytime I want to lock/unlock the door is a pain, so I use a notification as my primary interface.<br />
<br />
<b><i>Click. Locked. Click. Unlocked. Click. Locked. Click. Unlocked.</i></b> <br />
<br />
What fun! I could do this all day.<br />
<br />
The trickiest part was actually implementing a service to discover, connect to, and communicate with Bluetooth Board.<br />
<br />
I based my initial code for the service off of the <a href="https://github.com/googlesamples/android-BluetoothLeGatt" target="_blank">Android BluetoothLeGatt sample code</a>. The <a href="https://github.com/DFRobot/BlunoBasicDemo" target="_blank">Bluno Sample Code</a> is also based off of the Android sample code, but I didn't like the code quality, so I created mine from scratch.<br />
<br />
The service's (<span style="background-color: white;"><span style="background-color: yellow;"><a href="https://github.com/jpuderer/Bluedoor/blob/master/app/src/main/java/net/jpuderer/android/bluedoor/DoorlockService.java" style="background-color: white;" target="_blank">DoorlockService.java</a></span><span style="background-color: white;">)</span></span> job is to:<br />
<ul>
<li>Scan for the Bluetooth-LE device (the doorlock) in the background</li>
<li>Connect the doorlock whenever it's in range</li>
<li>Keep track of, and query the state of the doorlock (connected/disconnected + locked/unlocked)</li>
<li>Send messages (button presses) to the doorlock</li>
<li>Display the notification when in range</li>
</ul>
<br />
Sounds straightforward at least, right?<br />
<br />
Not really, no. You see, Bluetooth-LE on Android is buggy as shit.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxJ638JDwRx9_Lzb1WTHynHVb0jWcIV9NopM_YcqaIMbxlh7VItz8KLWlM6pHlzri61yyVsJBh7GdeGmQ-axLaP4B6ht-FUgoWSFUnTTqk9hG99QgitEJLpDBCcJ1XizQVdfqPJlPtCkc/s1600/CodeIsBad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxJ638JDwRx9_Lzb1WTHynHVb0jWcIV9NopM_YcqaIMbxlh7VItz8KLWlM6pHlzri61yyVsJBh7GdeGmQ-axLaP4B6ht-FUgoWSFUnTTqk9hG99QgitEJLpDBCcJ1XizQVdfqPJlPtCkc/s320/CodeIsBad.png" width="320" /></div>
<br />
<div>
<br /></div>
<div>
Actually, that may not be entirely fair. The coding is probably fine (I've looked at it), it's just incredibly complicated. There's are a <b>lot</b> of functionality the Bluetooth-LE code needs to cover.<br />
<br />
What makes it over-the-top difficult for the Google developers is the large number of different Bluetooth-LE radios on each and every Android handset, combined with the vast number buggy or broken Bluetooth-LE consumer devices. Apple by way of comparison, only has to deal with 1/2 of this problem.</div>
<div>
<br /></div>
<div>
Awesome. Here's a fun list of issues I ran into, along with emoticons that depict how I felt upon discovering each of them.<br />
<br />
<table>
<tbody>
<tr>
<td><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6JPzg5BsYT1LD4volQgLnS_UHzejt8Q0_h537Ogg5tEyBvXHYRguvC4la3CmMd5PbRJQXOUlGahCE1DBb-v9jvGKGlZnJE4WBLoR6CmWKyxrRa5hkbs2PCBQTnHawBAN9dUjlhEZtiCA/s400/confused.png" /></td>
<td>Bluno uses an UUID in a reserved range. This isn't an Android issue, but the DFRobot guys didn't appear to have read the BT-LE spec.</td>
</tr>
<tr><td width="20%"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr7N-n18gk4ijpdjdnBib_9bvLkfZVezKctAiTH4Y8oM_stsNnu0V1jWSdyZj2T6QFZJzYJ4GkJ7BlC0xda2az-4eEBk6gOl5AUvCeibAktKO-OeMExJzAX-nR7fOJBBsNV2JoUd0CGwI/s400/worried.png" /></td>
<td><a href="https://code.google.com/p/android/issues/detail?id=59490" target="_blank">BLE filtering doesn’t work for 128-bit UUIDs</a> (at least until very recently).</td></tr>
<tr><td><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSKt_mrcoL6rOrcdUzgjNQcW1GKwTCUvA4mHb0y3bdKHalhCQGlXK-yfPDzMD9zWseYR-qiy5kdB-6PcRO9iCrGOhqimK5Do8jPKq365kKNzqWbP29gsz0UV2x-sigqFFsIaepOrueCFc/s400/frowning.png" /></td>
<td><a href="https://code.google.com/p/android/issues/detail?id=180675" target="_blank">BLE offloaded filtering doesn't work consistently and misses devices</a></td><td></td></tr>
<tr><td><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgltnUUOZxN4w6FTorYYRcHizxY7o-dREXZbsY_GkIlM8yBWRZ1n5Ixa0ZnieBrh2N-kGR9QzN6_avjrYVAq3eltmJsP63jChixS9Dh98AvcyQWXwySVa16a7us2zUj4498ivOxFpwIPjo/s1600/anguished.png" /></td>
<td><a href="http://stackoverflow.com/questions/35266845/how-to-fix-android-ble-scan-failed-feature-unsupported-on-nexus-5" target="_blank">Not all devices even support offload filtering</a>, and you have to test for it before using certain methods. Do the docs explain which methods need offloadFiltering and that they will fail if its not present? Nope.</td></tr>
<tr><td><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7RuHmia7Tv_6Dri6lUXqmLI3Qcb26p4ph8DzG7GpZHSl9bpuKsGchSK4vbOF2xA4z4uzvgcvqCTgMZNlsxlixviy9N8ZyRjj6_TTipdhOuA3vu6bHG2OXWntz8kTjm-RcjWoorz_RF9c/s1600/crying.png" /></td>
<td><a href="https://code.google.com/p/android/issues/detail?id=193996" target="_blank">BluetoothGatt fails repeatedly with ("Register with GATT stack failed.")</a>. Even better is why it fails. There's a concurrency issue in the Bluetooth stack, and after your device has been scanning for while, you may eventually hit it.</td><td></td></tr>
</tbody></table>
</div>
</div>
<br />
<br />
<div>
<b><u>Conclusion</u></b><br />
<b><u><br /></u></b></div>
<div>
Bluetooth-LE on Android: Very cool once you get it working, but be prepared to spend some time to get it there. However, there's a <b>huge</b> difference in the implementation pre-Lollipop (5.0). Had I been writing this for someone other than myself and needed to support more devices, it would have been a much rougher experience.</div>
<div>
<br /></div>
<div>
In the end, I'm pretty happy with my app, but it was more work that I was expecting.</div>
<div>
<br /></div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7g0yg8IJJebK0pCph7tCOd3-owMeiqqQHlcp-ZO2kq0RhU0h9IkZHHeL2utNuihY2Z7KJUYiOvWD0Y210JiqdKor_96If6mphD5dIN4N01TplgalvwCrHAnxBuxefeMKCyuD5zYywCLY/s1600/fin.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Fin (julianrod/ Flickr CC BY-NC-ND)" border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7g0yg8IJJebK0pCph7tCOd3-owMeiqqQHlcp-ZO2kq0RhU0h9IkZHHeL2utNuihY2Z7KJUYiOvWD0Y210JiqdKor_96If6mphD5dIN4N01TplgalvwCrHAnxBuxefeMKCyuD5zYywCLY/s320/fin.jpg" title="" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
</div>
<div>
<b><u>Epilogue</u></b></div>
<div>
<br /></div>
If you're <b>still</b> interested in writing a Bluetooth-LE app for Android despite the potential difficulties, here are some links that I would suggest reading to give more of a flavour for the state of Bluetooth-LE on Android.<br />
<br />
<i><b>Official Android Docs on Bluetooth-LE: </b></i><br />
<div>
<a href="https://developer.android.com/guide/topics/connectivity/bluetooth-le.html" target="_blank">https://developer.android.com/guide/topics/connectivity/bluetooth-le.html</a></div>
<div>
<br />
<b><i>Marc Allison's Tutorial on Bluetooth-LE: </i></b></div>
<div>
<a href="http://blog.stylingandroid.com/bluetooth-le-part-1/" target="_blank">http://blog.stylingandroid.com/bluetooth-le-part-1/</a><br />
<div>
<br />
<div>
<b><i>My code (don't look too closely, or you'll go blind):</i></b><br />
<a href="https://github.com/jpuderer/Bluedoor" target="_blank">https://github.com/jpuderer/Bluedoor</a></div>
<div>
<div class="p3">
<br /></div>
<div class="p1">
<span class="s1"><b><i>Good article on beacons and 4.3 problems:</i></b></span></div>
<div class="p2">
<span class="s2"><a href="http://blog.conjure.co.uk/2014/08/ibeacons-and-android-parsing-the-uuid-major-and-minor-values/" target="_blank">http://blog.conjure.co.uk/2014/08/ibeacons-and-android-parsing-the-uuid-major-and-minor-values/</a></span></div>
<div class="p2">
</div>
<div class="p3">
<span class="s1"></span><br />
<div class="p1">
<span class="s1"><b><i>Good article on BLE advertisements:</i></b></span></div>
<div class="p2">
<span class="s2"><a href="http://www.argenox.com/bluetooth-low-energy-ble-v4-0-development/library/a-ble-advertising-primer/" target="_blank">http://www.argenox.com/bluetooth-low-energy-ble-v4-0-development/library/a-ble-advertising-primer/</a></span><br />
<br /></div>
</div>
<div class="p1">
<span class="s1"><b><i>Lollipop BLE Overview:</i></b></span></div>
<div class="p2">
<span class="s2"><a href="http://www.argenox.com/blog/android-5-0-lollipop-brings-ble-improvements/" target="_blank">http://www.argenox.com/blog/android-5-0-lollipop-brings-ble-improvements/</a></span><br />
<div class="p2">
</div>
<div class="p2">
<br /></div>
<div class="p1">
<span class="s1"><b><i>Spotty support for BT-LE on older (N5) devices:</i></b></span></div>
<div class="p2">
</div>
<div class="p2">
<span class="s2"><a href="http://stackoverflow.com/questions/26441785/does-bluetoothleadvertiser-work-on-a-nexus-5-with-android-5-0" target="_blank">http://stackoverflow.com/questions/26441785/does-bluetoothleadvertiser-work-on-a-nexus-5-with-android-5-0</a></span></div>
<br />
<div class="p1">
<span class="s1"><b><i>Power consumption while scanning:</i></b></span></div>
<div class="p3">
<span class="s2"><a href="https://www.quora.com/Bluetooth-Smart-v4-0-Low-Energy/How-much-power-can-actually-be-saved-when-using-BLE-on-a-Phone" target="_blank">https://www.quora.com/Bluetooth-Smart-v4-0-Low-Energy/How-much-power-can-actually-be-saved-when-using-BLE-on-a-Phone</a></span><br />
<br /></div>
<div class="p3">
<br /></div>
Also, while developing it's very helpful to be able to interact with your Bluetooth-LE device (be it a <span style="background-color: white;"><a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386" target="_blank">Bluno Beetle</a></span>, or something else). Nordic Semiconductor makes an absolutely <b>awesome</b> application for debugging Bluetooth-LE devices called <a href="https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp" target="_blank">nRF Master Control Panel </a>(these guys probably know way more about Bluetooth-LE than I do).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&utm_source=global_co&utm_medium=prtnr&utm_content=Mar2515&utm_campaign=PartBadge&pcampaignid=MKT-AC-global-none-all-co-pr-py-PartBadges-Oct1515-1" style="margin-left: 1em; margin-right: 1em;"><img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/apps/en-play-badge-border.png" width="200" /></a></div>
<br /></div>
</div>
</div>
</div>
Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-1666356413718259678.post-76320629799599591742016-01-14T20:42:00.000-05:002016-03-22T15:58:43.502-05:00Controlling my Electronic Door Lock using an Arduino<div dir="ltr">
<div class="separator" style="clear: both; text-align: left;">
<i style="text-align: start;">Part 2 of <b><a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html">My Fancy Bluetooth-LE Operated Door Lock</a> </b>series</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuJoFUcoJdwYImyDwMChTcpvfTLkBpwhOapXrVOlTWFOECMveibeANYOv1Zk8UPr8aD4NAsol6wd9HrhnPQultTz-tNMvM2BzojPqiB7X2nFz1Q-bgJiURZSBxbU4tPTzcxn5ZllCTCVo/s1600/arduino_lock.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Arduino Community Logo licensed under CC-SA-BY-NC 3.0" border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuJoFUcoJdwYImyDwMChTcpvfTLkBpwhOapXrVOlTWFOECMveibeANYOv1Zk8UPr8aD4NAsol6wd9HrhnPQultTz-tNMvM2BzojPqiB7X2nFz1Q-bgJiURZSBxbU4tPTzcxn5ZllCTCVo/s320/arduino_lock.png" title="" width="320" /></a></div>
<br /></div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
This post is part <a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html" target="_blank">2 in a 3 part series</a> that shows how I hacked an off-the-shelf electronic lock to be controlled by my Android phone using a Bluetooth capable Arduino board. </div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Ostensibly to prevent my cute children from raiding my home office, but more likely because I think it's cool.<br />
<a name='more'></a></div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
In the last post, I used a small digital oscilloscope (<a href="http://bitscope.com/" target="_blank">Bitscope</a>) and an Arduino compatible board (<a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386" target="_blank">Bluno Beetle</a>) to figure out the protocol that the two halves of my electronic doorlock use to communicate.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
So, now that I know the protocol to the electronic door lock, I can hack it! So the first thing I did was wire up TX pin on my <a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386" target="_blank">Bluno Beetle</a> board (the Arduino compatible board with BT-LE) to the TX line from the keypad, the RX pin to the RX line to the keypad, and Vin to +6 VDC from the battery [<a href="http:/#">1</a>]. </div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYL9nRTM9NNji1UTwu-Ncu8MeWvecSq3mrqEVx1epAr71UP5RIdUqp2NtOyDZdlBuR0wFDmKXTRsNCDkYg1Yugpy-2FrSqT6FyJPGxTfLdzABeO0hFkNvkj63n-P6IDiwr2CY9-K9tP7A/s1600/Diagram2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYL9nRTM9NNji1UTwu-Ncu8MeWvecSq3mrqEVx1epAr71UP5RIdUqp2NtOyDZdlBuR0wFDmKXTRsNCDkYg1Yugpy-2FrSqT6FyJPGxTfLdzABeO0hFkNvkj63n-P6IDiwr2CY9-K9tP7A/s400/Diagram2.png" width="400" /></a></div>
<br /></div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Before continuing, a few things to consider. I'm tapping the wires going between the two halves of the door lock, but electrically this may not be the greatest idea:</div>
<ul>
<li>I have no idea how much current either half will source or sink, so this may not work at all. We *hope* that the inputs are high impedance, and that that outputs don't source too much current.</li>
<li>The TX line from the keypad is normally high, so we're actually pulling the voltage down on the TX line down whenever we send data. </li>
<li>The RX line from the keypad isn't an issue, since Arduino pins configured as inputs have very high impedance.</li>
<li>I'm trying to wire it up this way anyway since I don't want the Bluno board to sit between the two halves of the door lock.</li>
</ul>
<div>
That being said, here's the source to control the doorlock:</div>
<div>
<br /></div>
<pre class="prettyprint linenums">#include <SoftwareSerial.h>
SoftwareSerial doorSerial(2, 4); // RX, TX
void setup() {
// initialize the real (UART) Serial
Serial.begin(115200);
// initialize the SoftwareSerial port
doorSerial.begin(9600);
// Put TX in a high impedance state when not sending
pinMode(4, INPUT);
}
void writeDoorCommand(uint8_t command) {
pinMode(4, OUTPUT);
digitalWrite(4, 0);
delay(30);
digitalWrite(4, 1);
delayMicroseconds(1200);
doorSerial.write((uint8_t)command);
pinMode(4, INPUT);
}
void loop() {
if (doorSerial.available()) {
Serial.print("0x");
// send what has been received
Serial.println(doorSerial.read(), HEX);
}
if (Serial.available()) {
// send what has been received
writeDoorCommand(Serial.read());
}
// Add a delay to avoid characters being sent too quickly to the door lock
delay(100);
}
</pre>
<br />
<div dir="ltr">
<br /></div>
<div dir="ltr">
I'm using the timing information that I figured out in <a href="http://www.jpuderer.net/2015/08/reverse-engineering-my-electronic-door.html">part 1</a> of this series.<br />
<br /></div>
<div dir="ltr">
You'll also notice that I actually switch the TX pin to high impedance (input mode) when not actively sending data. This way it won't source or sink any current when it doesn't have to, or interfere with the normal communications between the two halves of the door lock.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Now to test it! Fortunately, the <a href="http://www.dfrobot.com/" target="_blank">DF Robot</a> guys provided some Android code for sending and receiving characters via Bluetooth to and from the Bluno Beetle, so I don't need to do this over USB serial.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
I took the simple sample code they provided [<a href="https://github.com/DFRobot/BlunoBasicDemo" target="_blank">here</a>], and modified it to send commands to the electronic door lock [<a href="https://github.com/jpuderer/DoorTester" target="_blank">modified version here</a>]. And guess what, it works! I can now remotely enter the code from my Android device, and unlock the door.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidWCR_ePh6LYe86GXo9MdsmXrRZBsKchhHr1exhquQiKBWbUmsECePjKCHme7tt0cpF3btm7jY4BDkKusa3d0WqvOzycO5EZmxQYNFkVN1VBeAD5rIB6he9QcI0aiK0Ak3hEA2gne0NrI/s1600/Screenshot_2015-09-02-10-33-03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidWCR_ePh6LYe86GXo9MdsmXrRZBsKchhHr1exhquQiKBWbUmsECePjKCHme7tt0cpF3btm7jY4BDkKusa3d0WqvOzycO5EZmxQYNFkVN1VBeAD5rIB6he9QcI0aiK0Ak3hEA2gne0NrI/s320/Screenshot_2015-09-02-10-33-03.png" width="180" /></a></div>
<br /></div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
The next small change I made was to make the Arduino code more power friendly, by going into sleep mode when not sending or receiving data. I found the following page pretty useful:<br />
<br />
<a href="http://playground.arduino.cc/Learning/ArduinoSleepCode" target="_blank">http://playground.arduino.cc/Learning/ArduinoSleepCode</a><br />
<br />
Using this information, I modified the code to the following:</div>
<div dir="ltr">
<br />
<br /></div>
<pre class="prettyprint linenums">#include <SoftwareSerial.h>
#include <avr/power.h>
#include <avr/sleep.h>
SoftwareSerial doorSerial(2, 4); // RX, TX
void setup() {
// initialiaze the real (UART) Serial
Serial.begin(115200);
// initialize the SoftwareSerial port
doorSerial.begin(9600);
// Put TX in a high impedance state when not sending
pinMode(4, INPUT);
}
void writeDoorCommand(uint8_t command) {
pinMode(4, OUTPUT);
digitalWrite(4, 0);
delay(30);
digitalWrite(4, 1);
delayMicroseconds(1200);
doorSerial.write((uint8_t)command);
pinMode(4, INPUT);
}
// Put the device into sleep mode
void sleep() {
set_sleep_mode(SLEEP_MODE_IDLE);
// Set Power Reduction register to disable timer (used by SoftSerial)
PRR = PRR | 0b00100000;
power_adc_disable();
power_spi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_twi_disable();
// Enter sleep mode
sleep_enable();
sleep_mode();
// Return from sleep
sleep_disable();
// Re-enable timer
PRR = PRR & 0b00000000;
power_all_enable();
}
void loop() {
bool canSleep = true;
while (doorSerial.available()) {
canSleep = false;
// send what has been received
Serial.print("0x");
Serial.println(doorSerial.read(), HEX);
}
while (Serial.available()) {
canSleep = false;
// send what has been received
writeDoorCommand(Serial.read());
}
// Sleep if there is no activity on the serial port
if (canSleep) sleep();
// Add a delay to avoid characters being sent too quickly to the door lock
delay(100);
}
</pre>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Data from either the door or the Bluetooth module will now wake the Arduino module from sleep mode, so that it's not constantly consuming full power [2].<br />
<br />
Now that I've got something that works, I'll put the whole thing into a project box to make it look like I know what I'm doing. Here are the before and after pictures:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijqAuCQjvcigGu7-a0kk_sCvRxNu-nuCmdaSvmpdQa5jrhMMAD5eJ59ob9UO4gUJUnHZJY0SjeqPS1xz8mC7nHWYiA9DZFtCePRR1D6wC1prCAEnRjBIigKR0NNe_QmP_6q-27e6AfrqY/s1600/IMG_20150626_115919.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijqAuCQjvcigGu7-a0kk_sCvRxNu-nuCmdaSvmpdQa5jrhMMAD5eJ59ob9UO4gUJUnHZJY0SjeqPS1xz8mC7nHWYiA9DZFtCePRR1D6wC1prCAEnRjBIigKR0NNe_QmP_6q-27e6AfrqY/s200/IMG_20150626_115919.jpg" width="127" /></a></td>
<td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgilx820Uvakbqh6T-ihir0zUbYeuZv9QKqC-mhINOeVshZSXvKC4EPLz1PTpUTKycfMeppHjQyLQEOtI7cay9-6J_JpSEZRdy6eCJDx9eFc4Ym57_9Mu1GjbPTaHosVyleff3QawMNzNc/s1600/IMG_20150907_081755.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgilx820Uvakbqh6T-ihir0zUbYeuZv9QKqC-mhINOeVshZSXvKC4EPLz1PTpUTKycfMeppHjQyLQEOtI7cay9-6J_JpSEZRdy6eCJDx9eFc4Ym57_9Mu1GjbPTaHosVyleff3QawMNzNc/s200/IMG_20150907_081755.jpg" width="83" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b>Before</b></td>
<td class="tr-caption" style="text-align: center;"><b>After</b></td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Ok, so that's great, but this Android app is really just cut and copied example code, and doesn't add much in the way of convenience. In the next part, I'll going to describe how to write a better app. The app I actually want to use everyday.</div>
<div dir="ltr">
<br /></div>
<div class="info-box alert">
<div class="msg">
[1] Unfortunately the Bluno Beetle does not run on 3.3v, otherwise I could power it from the door lock's 3.3v wire. The Bluno Beetle really should use a 3.3v ATMega chip, since the BT module requires 3.3v anyway which the Bluno Beetle produces using a voltage regulator located on the PCB. This conversion to 3.3v (not to mention from 6v to 5v) wastes a lot of power in the form of heat.</div>
</div>
<br />
<br />
<div class="info-box alert">
<div class="msg">
[2] Another unfortunate issue is that although the ATMega chip can be put into low power mode, the firmware for BT radio doesn't yet support this. So we can only reduce the power consumption to a certain point, since the BT radio is still drawing full power.</div>
</div>
<br />
<br />
<div dir="ltr">
<i>See part 3 of </i><b style="font-style: italic;"><a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html">My Fancy Bluetooth-LE Operated Door Lock</a> </b>series<b style="font-style: italic;">:</b><br />
<br />
<b>Controlling my Electronic Door Lock from Android using Bluetooth-LE (coming soon...)</b></div>
<div dir="ltr">
<br /></div>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-1666356413718259678.post-45557288390875200162015-12-25T21:49:00.000-05:002016-01-14T20:45:39.931-05:00Reverse Engineering my Electronic Door Lock<i>Part 1 of <b><a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html">My Fancy Bluetooth-LE Operated Door Lock</a> </b>series</i><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNpqpF0lIOLBVLVyKrjFQQuQCi8nQjlIwyDUI3PLRDJDw-sw4ktWM4G6DA71uFSgJXjGR66EW3jPQ1EeqR4M0rWelzsgr0dLqT6m7TGEPN3BlHYV6MdpZhxOSUpcP9SxmTPFqCdXbWKaw/s1600/320px-Rs232_oscilloscope_trace.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNpqpF0lIOLBVLVyKrjFQQuQCi8nQjlIwyDUI3PLRDJDw-sw4ktWM4G6DA71uFSgJXjGR66EW3jPQ1EeqR4M0rWelzsgr0dLqT6m7TGEPN3BlHYV6MdpZhxOSUpcP9SxmTPFqCdXbWKaw/s1600/320px-Rs232_oscilloscope_trace.svg.png" /></a></div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhlKSQxxp7bLUnfpB6fSpIIJcSaD0xQykP5bXvwY7fC1Iv-iYbsn5ZI370QHR-L6QPFjYK-Ymn9DaAEQNGtb-ArKFqGugKcMrDYAks70nLm0W838prMQef8Qt6zXrWl1jMVvwufWRwo2A/s1600/IMG_20150423_142125.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhlKSQxxp7bLUnfpB6fSpIIJcSaD0xQykP5bXvwY7fC1Iv-iYbsn5ZI370QHR-L6QPFjYK-Ymn9DaAEQNGtb-ArKFqGugKcMrDYAks70nLm0W838prMQef8Qt6zXrWl1jMVvwufWRwo2A/s200/IMG_20150423_142125.jpg" width="147" /></a><br />
<br />
<br />
This all began with me buying a simple electronic door lock (Kwikset Model: 92690-001) at the local hardware store. It had a keypad, handle, and not much else.<br />
<br />
It worked great. Enter the combination on the keypad, the door unlocks. Simple. Boring. Tedious.<br />
<br />
<pre class="s2" style="background: rgb(244, 244, 244); border-radius: 5px; border: 1px solid rgb(187, 187, 187); color: #333333; display: table; font-family: 'Lucida Console', Monaco, monospace; font-size: 1em; font-stretch: inherit; line-height: inherit; margin: 8px auto; outline: 0px; overflow: auto; padding: 10px; vertical-align: baseline; width: auto;">( ¯ ö¯ )</pre>
<br />
<a name='more'></a><br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWUMLiGxkDwDjphZmhj0vqI7JQ_jwNBEr5lBxgFJrMtz5uOEl2D2ytMTG9vJ64MM0GsEhyI_R3TH-JQFMluvQGmcPEUXFAETkUwnOu-6eQ-Udj4q2RXy5NjF2aXXBZJaxD2AFS2tXVQ9s/s1600/IMG_20150626_150930.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWUMLiGxkDwDjphZmhj0vqI7JQ_jwNBEr5lBxgFJrMtz5uOEl2D2ytMTG9vJ64MM0GsEhyI_R3TH-JQFMluvQGmcPEUXFAETkUwnOu-6eQ-Udj4q2RXy5NjF2aXXBZJaxD2AFS2tXVQ9s/s200/IMG_20150626_150930.jpg" width="180" /></a><br />
<br />
<br />
<br />
I quickly tired of having to enter the door code each time I wanted in and out of the room... and I <b>HAD</b> to lock it. Otherwise the little <i>darlings</i> would sneak in while I was grabbing coffee in between conference calls.<br />
<br />
<br />
<br />
<br />
<br />
<br />
So, maybe I can figure out a way to hook up one of these nifty <a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386">Bluno Beatles</a> (which is basically a very small and cheap Arduino Uno that includes a Bluetooth-LE chip), and automagically open the door.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcHCgPI_BCJCD8pKNSqDB0oSz-4EgORl235c8sTnvMLSZYrbf4IXsH8W1mj2SDt6II_ct5baTGiKrOTRYJUNdWUy2mhAqsvpmWuZ6vlUrjULDMoXPkWdeTBg_MVA0zhM45zfGyAvJpRtA/s1600/IMG_20150423_142759.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcHCgPI_BCJCD8pKNSqDB0oSz-4EgORl235c8sTnvMLSZYrbf4IXsH8W1mj2SDt6II_ct5baTGiKrOTRYJUNdWUy2mhAqsvpmWuZ6vlUrjULDMoXPkWdeTBg_MVA0zhM45zfGyAvJpRtA/s320/IMG_20150423_142759.jpg" width="320" /></a><br />
<br />
<br />
The door lock itself has two halves. The exterior facing half that has the keypad, and the interior facing half that has the batteries, motors, and micro-controller. There are four wires that connect the two halves.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi9VCqGLiN1TABXK4ZzlOqfPRtTqvpye-JxypdZz062mY8bEWDCS6HhD6vqBNIfbidGPWEydbl-hiodU5t147mKrmv-NpCNLrP8Djd7RfHXw-LQ1ZOT0u5lhm0ai-hPPetIgMNP6Zd8R0/s1600/IMG_20150625_124145.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi9VCqGLiN1TABXK4ZzlOqfPRtTqvpye-JxypdZz062mY8bEWDCS6HhD6vqBNIfbidGPWEydbl-hiodU5t147mKrmv-NpCNLrP8Djd7RfHXw-LQ1ZOT0u5lhm0ai-hPPetIgMNP6Zd8R0/s320/IMG_20150625_124145.jpg" width="154" /></a>I'd always wanted an oscilloscope, but could never justify shelling out the dough to actually own one. If I wanted to figure out how the two halves of the door were communicating, I was going to need one. Fortunately, a simple digital scope that hooks up to a computer is no longer quite so expensive, so after a little bit of research, I bought one from <a href="http://bitscope.com/">BitScope</a> and so far I've been pretty happy with it (I bought the more expensive BitScope 10, but a BitScope Micro would have worked just as well).<br />
<br />
So, the first thing I wanted to do was to probe these four wires, and see what they do while the door is operating.<br />
<br />
I very quickly identified two of the wires as 3.3v (VCC) and ground (GND). This makes sense, since the keypad half has no batteries and needs to be provided with power from somewhere.<br />
<br />
For the other two wires, I needed to capture what was happening. The inside half of the lock contains a <a href="http://www.sonix.com.tw/article-en-1004-12914">Sonix SN8F27E65</a> micro-controller, so it seemed likely that SPI, I2C, or UART was being used to communicate. SPI seemed unlikely, since it would require more wires.<br />
<br />
After playing with various triggers, and the timebase controls <span style="background-color: white;">in the oscilloscope software, I managed to figure out that the other two wires were using what *looked like* asynchronous serial to send data between the two halves of the door lock.</span><br />
<span style="background-color: white;"><br /></span>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-41V_S7dwdYpgohXRpdguSHF5Uhf7p9FYybhAL9GqdGl2eAWI9s3KJOt5XioONbZ0U5fYjvVIFgQsT0Upmk4JviFqF8uKqmTVIcBdDuONrdndnGxmQhCoFIv0UBPDCu90vq1_bI0G6ro/s1600/Preamble.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="93" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-41V_S7dwdYpgohXRpdguSHF5Uhf7p9FYybhAL9GqdGl2eAWI9s3KJOt5XioONbZ0U5fYjvVIFgQsT0Upmk4JviFqF8uKqmTVIcBdDuONrdndnGxmQhCoFIv0UBPDCu90vq1_bI0G6ro/s400/Preamble.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">From Keypad - Brown Wire</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDlgMx6DGX24kOcSii1LkRhb79AMVD0HlDSGHhu027D7yyjDLCDfcWyBqSORRFrsIpoNpBWAOgWCmWFuIcB-AYqwjS-vV15vBltD2NkBJB1tG48JFm3d02ddHx65ykrIXvKDohpGNggeQ/s1600/Keypad+Escape.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="83" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDlgMx6DGX24kOcSii1LkRhb79AMVD0HlDSGHhu027D7yyjDLCDfcWyBqSORRFrsIpoNpBWAOgWCmWFuIcB-AYqwjS-vV15vBltD2NkBJB1tG48JFm3d02ddHx65ykrIXvKDohpGNggeQ/s400/Keypad+Escape.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">To Keypad - Orange Wire</td></tr>
</tbody></table>
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">The orange wire seems to be used to send data to the keypad (e.g. data is sent whenever the door is opened or locked), and the brown wire seems to send data from the keypad (e.g. data is sent whenever I press a button on the keypad).</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">Awesome, but the timing looks a little odd.</span><br />
<br />
<table class="realtable">
<caption>Signal Timing</caption>
<tbody>
<tr><td>From keypad (brown wire)</td><td>Starts high, 30000 µs low, [async data]</td></tr>
<tr><td>To keypad (orange wire)</td><td>Starts high, 100 µs low, 1200 µs high, [async data]</td></tr>
</tbody></table>
</div>
<br />
<span style="background-color: white;">For both wires, the stuff that looks like async serial is at the end of each sequence that I capture. There's some preamble for both wires, before the stuff that looks like serial data gets sent.</span><br />
<br />
<div>
<span style="background-color: white;">The timing of the async data at the end looks almost exactly like 9600 8N1, since the pulses are about 10 µs apart (</span>1s/9600 ~= 104 µs)<span style="background-color: white;">, and there appears to be the right number of bits (1 start bit, 8 data bits - the stop bit is not visible, since only one byte is sent at a time).</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">The other stuff preceding the serial data didn't make much sense, until I realized that the processors in both halves of the electronic door lock are probably in some sort of low power mode, and need to <i><b>wake up</b></i> before being able to process the serial data. The purpose of the preamble is to trigger a <a href="https://en.wikipedia.org/w/index.php?title=Hardware_interrupt">hardware interrupt</a> to wake the processor up, and give it time to wake up.</span><br />
<span style="background-color: white;"><br /></span>
<span style="background-color: white;">The next step was to connect up my Arduino compatible board (the <a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386">Bluno Beetle</a>) to the door lock, and try to decode the signals. At this point, I'm connected to the Beetle by USB serial, which provides the supply voltage for the board, so I only need to connect a tap wire to GND, and either Keypad RX or Keypad TX.</span><br />
<span style="background-color: white;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA7_mlqayxxszZas04oqMXtBbmsFyursUedn4LN-CobKwqgv_VH9-eFZwibn91HGZkxZT_7VjFh9EF3Mr8ZmV6yDQoEHHrOfQXMJqPEEEWOdjdy2h9-zlaneOYUqLTMpdSM3-tFbSWDjs/s1600/Diagram1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA7_mlqayxxszZas04oqMXtBbmsFyursUedn4LN-CobKwqgv_VH9-eFZwibn91HGZkxZT_7VjFh9EF3Mr8ZmV6yDQoEHHrOfQXMJqPEEEWOdjdy2h9-zlaneOYUqLTMpdSM3-tFbSWDjs/s400/Diagram1.png" width="400" /></a></div>
<span style="background-color: white;"><br /></span>
<span style="background-color: white;"><br /></span><span style="background-color: white;">I used the following simple Arduino program to sniff the messages being sent between the two halves of the door lock (switching the RX pin as needed). Really, you could use any Arduino board, but the </span><br />
<div>
<span style="background-color: white;"><a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386">Bluno Beetle</a> is the board I'm eventually going to use in the finished version, since it has Bluetooth-LE already built in.</span><br />
<span style="background-color: white;"><br /></span></div>
<pre class="prettyprint linenums">#include <SoftwareSerial.h>
SoftwareSerial doorSerial(2, 4);
void setup() {
// initialize the real (UART) Serial
Serial.begin(115200);
// initialize the SoftwareSerial port
doorSerial.begin(9600);/
}
void loop() {
if (doorSerial.available()) {
Serial.print("0x");
// send what has been received
Serial.println(doorSerial.read(), HEX);
}
}
</pre>
<br />
<br />
After using the small program above to capture messages in both directions while playing with the door lock, I now have a pretty good understanding of how the two halves of the door lock communicates!<br />
<div>
<table class="realtable">
<caption>Doorlock Protocol</caption>
<tbody>
<tr><th colspan="2">To keypad (orange wire)</th>
</tr>
<tr><td>0xFF 0x62</td><td>Locked <b>or</b> Handle Turned</td></tr>
<tr><td>0xFF 0x61</td><td>Unlocked <b>and</b> Handle not turned</td></tr>
<tr><th colspan="2">From keypad (brown wire)</th>
</tr>
<tr><td>0x00 0x69</td><td>Keypad active (backlight on)</td></tr>
<tr><td>0x00 0x6A</td><td>Keypad idle (not illuminated)
</td></tr>
<tr><td>0x00 0x42</td><td>Keyguard button
</td></tr>
<tr><td>0x00 [0x30-0x39]</td><td>Number buttons 0-9</td></tr>
<tr><td>0x00 0x2A</td><td>Cancel
</td></tr>
<tr><td>0x00 0x23</td><td>Enter
</td></tr>
</tbody></table>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRuYh780x7lawsou8idTJpB9DuFKs8EDK-GOn86Ysd2KBeGMuWXxEyxoH1jNiioX1ayno92RD2EBdHlAzR_IhK04hGpdDblHcJBQPiQXnPEANMwkcHrwOhiP9TOBnFZyLTGw6svsXCXeU/s1600/pi5s1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRuYh780x7lawsou8idTJpB9DuFKs8EDK-GOn86Ysd2KBeGMuWXxEyxoH1jNiioX1ayno92RD2EBdHlAzR_IhK04hGpdDblHcJBQPiQXnPEANMwkcHrwOhiP9TOBnFZyLTGw6svsXCXeU/s400/pi5s1.jpg" width="400" /></a></div>
<br />
<br />
Now, I just need figure out how to use the Arduino to actually control the lock.<br />
<br />
<div class="info-box alert">
<div class="msg">
Although the SoftwareSerial library reads the first characters as 0x00 and 0xFF, we know from the oscilliscope captures that these characters are not actually being sent. We'll have to keep that in mind in the next part, where we use the Arduino to actually control the door lock.</div>
</div>
<br />
<br />
<i>See part 2 of </i><b style="font-style: italic;"><a href="http://www.jpuderer.net/2015/12/my-fancy-bluetooth-le-operated-door-lock.html">My Fancy Bluetooth-LE Operated Door Lock</a> </b>series<b style="font-style: italic;">:</b><br />
<a href="http://www.jpuderer.net/2016/01/controlling-my-electronic-door-lock.html"><br /></a>
<b><a href="http://www.jpuderer.net/2016/01/controlling-my-electronic-door-lock.html">Controlling my Electronic Door Lock using an Arduino</a></b><br />
<div>
<br /></div>
</div>
Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-1666356413718259678.post-88288429486003616722015-12-25T15:15:00.000-05:002016-03-31T17:48:59.407-05:00My Fancy Bluetooth-LE Operated Door Lock<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcEnQoKA3DlXPft2isJRQHB9CR4-5iU_UJb10qR-6lu-aPU3iMCUZGt6X4lae1BOoO_CpfutXKqffek3yx7ICe2rA43ccz_kq6oDMVenTpstTHfNwRKtDRCv2q23prTMEGjqezURF_7gM/s1600/BluetoothLE_operated_door_lock.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcEnQoKA3DlXPft2isJRQHB9CR4-5iU_UJb10qR-6lu-aPU3iMCUZGt6X4lae1BOoO_CpfutXKqffek3yx7ICe2rA43ccz_kq6oDMVenTpstTHfNwRKtDRCv2q23prTMEGjqezURF_7gM/s400/BluetoothLE_operated_door_lock.png" width="400" /></a></div>
<br />
<span style="background-color: yellow;"><br /></span>
<span style="background-color: white;">This series of blog posts shows how to reverse engineer an electronic door lock (such as are typically available at any hardware store), and modify it so that it can be controlled (via Bluetooth-LE) from an Android phone. [1]</span><br />
<span style="background-color: white;"></span><br />
<br />
<a name='more'></a><br />
<br />
This all started with a small itch I wanted to scratch, that I got carried away with.<br />
<br />
I have a home office where I work out of every day. The only problem with a home office is that home is where the kids live too. Being the kind of guy I am, my office is filled with tons of high-tech, expensive, breakable, potentially dangerous, and age inappropriate toys.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAxoA6H8kn3sGqhYHu45F8fUrAMhY74azFRPi6YLGXOLmBEur9wsX_dtX45MJhS2h4dIZW2t3fmyPt_X65RKsFYC8MBUX6dfaJKKC7lT7qHtTQwwBcc9YBJKEGCLkobxCriVEhWtTYcrk/s1600/IMG_20150906_121043.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAxoA6H8kn3sGqhYHu45F8fUrAMhY74azFRPi6YLGXOLmBEur9wsX_dtX45MJhS2h4dIZW2t3fmyPt_X65RKsFYC8MBUX6dfaJKKC7lT7qHtTQwwBcc9YBJKEGCLkobxCriVEhWtTYcrk/s400/IMG_20150906_121043.jpg" width="400" /></a></div>
<br />
<br />
So I bought an electronic door lock at the local hardware store. Nothing fancy, just a locking handle with a simple electronic keypad.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBaUd2wVMnjz-7EEX1RwG91nna-OZwGe8ejAd4CcmIbzSG9T1yWl4KNTKgVk2AJn7S546FqRWV0ofhcE9Wdp7bryshDmFjDgc3h0mIZWusp_V7yFXo6Av6_9G5szFXIpH4p-9IK2n5i6s/s1600/IMG_20150814_132915%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBaUd2wVMnjz-7EEX1RwG91nna-OZwGe8ejAd4CcmIbzSG9T1yWl4KNTKgVk2AJn7S546FqRWV0ofhcE9Wdp7bryshDmFjDgc3h0mIZWusp_V7yFXo6Av6_9G5szFXIpH4p-9IK2n5i6s/s320/IMG_20150814_132915%257E2.jpg" width="213" /></a></div>
<br />
<br />
... but I got tired of having to key in the code every time, so I wanted to figure out how to modify to door lock to use Bluetooth (LE) to automagically unlock the door whenever my Android phone was close to the door (none of that NFC nonsense where I actually have to take it out of my pocket -- too much work).<br />
<br />
...but first I needed to reverse engineer the door lock.<br />
<br />
<b>Part 1 - <a href="http://www.jpuderer.net/2015/08/reverse-engineering-my-electronic-door.html">Reverse Engineering an Electronic Door Lock using an Oscilloscope</a></b><br />
<br />
... then I needed to control the Door Lock over BT, so I used an Arduino Uno compatible device with BT-LE capabilities (<a href="http://www.dfrobot.com/index.php?route=product/product&product_id=1259&tracking=55c3b6aee8386">Bluno Beetle</a>) to control the doorlock.<br />
<br />
<b>Part 2 - <a href="http://www.jpuderer.net/2016/01/controlling-my-electronic-door-lock.html" target="_blank">Controlling my Electronic Door Lock using an Arduino</a><span id="goog_1298966645"></span><span id="goog_1298966646"></span><a href="https://www.blogger.com/"></a></b><br />
<br />
... then I needed to write a somewhat decent Android app to actually lock and unlock the door automagically<br />
<br />
<b>Part 3 - <a href="http://www.jpuderer.net/2016/03/controlling-my-door-lock-from-android.html" target="_blank">Controlling my Door Lock from Android using Bluetooth-LE</a></b><br />
<br />
[1] I actually chose a pretty uncommon door lock (since it just happened to be what the store had in stock), but I suspect that a similar technique would work for other door locks as well.<br />
<br />
IN FACT, if you buy me another more popular doorlock, that you'd like me to reverse engineer, I'll give it a shot.<br />
<br />
<br />
<br />
<br />Unknownnoreply@blogger.com7tag:blogger.com,1999:blog-1666356413718259678.post-79501447032163274622015-11-10T07:10:00.000-05:002015-11-10T08:50:55.373-05:00Animated buttons without any Java codeUsing vector drawables and animated state lists to make UI widgets look cool.<br />
<div style="text-align: center;">
<figure>
<img border="0" data-alt="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_nIMPH5RpuOvFKmc2dJMXi9YzCn87KC0ZLlYI9vX7oBX7rNF1uy-oYtBgY5uANHWWoewLz3t2niKaDuDcxitWgbUXYyoV8TQAW7IJzshJUFaoAUqDZI1ryoRpdoM85eNue1XHa3rMoaE/s320/AnimatedLockButton.gif" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRLgEqR__oYmu_LErP2EkCxDYg-JVDLHzwREtvlelc9KLOcu8gnLvo49JzsyFZiJy1hyphenhyphenkUEcCBgeJIDdAYLXSMewIvbpXCWnOiftZgXkRKfFsblN7EOHj8FrDReGmRXN750qIu00A0fbE/s1600/AnimatedLockButton0.gif" width="179" />
<figcaption style="text-align: center;">Click to show animation</figcaption></figure></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">This post explains how you can create nice animated buttons using existing button widgets, and XML files. </span><br />
<span class="s1"></span>
<a name='more'></a></div>
<div class="p1">
<br />
This started out of a fairly simple desire to have some nice animated buttons for a personal project of mine (which I’ll describe in another post). I’m writing this because I ran into enough caveats that I feel it's worthwhile documenting it for the next person.<span class="s1"></span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">I’m also somewhat allergic to writing new code unless absolutely necessary. Although it's generally possible to create custom UI elements by extending existing classes in Android, I hate the idea of creating lots of barely extended classes just to tweak your UI. </span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">I ended up stumbling upon some very cool (but not much discussed) functionality that was introduced in Lollipop (Android 5.0, SDK 21):</span></div>
<ul class="ul1">
<li class="li2"><span class="s1"><a href="https://developer.android.com/reference/android/graphics/drawable/AnimatedVectorDrawable.html" target="_blank">VectorDrawable</a> / <vector></span></li>
<li class="li2"><span class="s1"><a href="https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html" target="_blank">AnimatedVectorDrawable</a> / <animated-vector></span></li>
<li class="li2"><span class="s1"><a href="http://developer.android.com/reference/android/graphics/drawable/AnimatedStateListDrawable.html" target="_blank">AnimatedStateListDrawable</a> / <animated-selector></span></li>
<li class="li2"><span class="s1"><a href="http://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html" target="_blank">RippleDrawable</a> / <ripple></span></li>
</ul>
<div class="p2">
<span class="s1">These classes can be used to easily animate buttons (and other UI elements). Fortunately for me and my spartan aesthetic, using them requires no code changes whatsoever.</span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">Before getting into the grizzly details, I suggest taking a quick look at Mark Allison’s four part series on Vector Drawables (<a href="https://blog.stylingandroid.com/vectordrawables-part-1/" target="_blank"><span class="s4">https://blog.stylingandroid.com/vectordrawables-part-1/</span></a>) which does a great job of introducing how to use the <i>VectorsDrawable</i> and <i>AnimatedVectorDrawable</i> classes.</span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">Ok, so assuming you now know a little about Vectors and Animated Vector, we can go about creating an animated button.</span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">For simplicity, we're going to use a <i>ToggleButton</i>, since it automatically changes the checked state when pressed, and lets us specify different text for when it’s ON (checked) or OFF (not checked).</span></div>
<br />
<div class="info-box alert">
<div class="msg">
We could also use other types of buttons (or UI components) here. Ironically, although already animated and very similar to <i>ToggleButton</i>, we could not have used the <i>Switch</i> widget. The <i>Switch</i> widget has its drawables and animations hardcoded, so we can’t override its background drawable to any great effect. In fact, it seems to be a very good example of how <b>NOT</b> to animate a button (code <a href="https://android.googlesource.com/platform/frameworks/base/+/marshmallow-release/core/java/android/widget/Switch.java" target="_blank">here</a>) if you want it to be stylable and extensible. It is probably this way for legacy reasons.</div>
</div>
<br />
<br />
Here's the layout for our application:
<span class="s1"><br /></span>
<br />
<pre class="prettyprint linenums"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context="net.jpuderer.animatedbutton.MainActivity">
<ToggleButton
android:layout_width="200dp"
android:layout_height="200dp"
android:textAllCaps="true"
android:textStyle="bold"
android:textSize="40sp"
android:background="@drawable/circle_button"
android:textOn="On"
android:textOff="Off"/>
</LinearLayout><span style="font-family: "courier new" , "courier" , monospace;">
</span></pre>
<div class="p4">
<div style="text-align: center;">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><b>layout/activity_main.xml</b></span></div>
<div style="text-align: center;">
<span class="s1"><br /></span></div>
</div>
<div class="p2">
<span class="s1">The important element above is the background drawable, which defines the way our button looks and animates. Without it, the <i>ToggleButton</i> would look like a normal (albeit large) <i>ToggleButton</i>.</span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<pre class="prettyprint linenums"><?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<ripple
android:color="?android:attr/colorControlHighlight”/>
</item>
<item>
<animated-selector>
<item
android:id="@+id/off"
android:drawable="@drawable/circle_button_off"
android:state_checked="false" />
<item
android:id="@+id/on"
android:drawable="@drawable/circle_button_on"
android:state_checked="true" />
<!--
Need to put each animated-vector in its own file, since
inlining them exposes a bug in the XML parsing. Boo!!!
https://code.google.com/p/android/issues/detail?id=164361
-->
<transition
android:drawable="@drawable/circle_button_to_on"
android:fromId="@id/off"
android:toId="@id/on"
android:reversible="false"/>
<transition
android:drawable="@drawable/circle_button_to_off"
android:fromId="@id/on"
android:toId="@id/off"
android:reversible="false"/>
</animated-selector>
</item>
</layer-list><span style="font-family: "courier new" , "courier" , monospace;">
</span></pre>
<div class="p4">
<div style="text-align: center;">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><b>drawable/circle_button.xml</b></span></div>
<div style="text-align: center;">
<span class="s1"><br /></span></div>
</div>
<div class="p2">
<span class="s1">The top level of our circle_button drawable is <i><layer-list></i>. This allows us to layer multiple drawables that respond to state. </span></div>
<ul class="ul1">
<li class="li2"><span class="s1">The first layer containing the <i><ripple></i> element (which corresponding to the <a href="http://developer.android.com/reference/android/graphics/drawable/RippleDrawable.html" target="_blank">RippleDrawable</a> class), responds to changes of <i>android:state_pressed</i>. It’s the same effect that gets used to animate screen presses for other widgets in Lollipop.</span></li>
<li class="li2"><span class="s1">The second layer contains our <i><animated-selector></i> element that contains the drawables for the checked and unchecked states, as well as the animations for transitioning between them.</span></li>
<li class="li2"><span class="s1">We could have put either of these elements at the top level (without using <i><layer-list></i>), but then we wouldn’t have an easy way to handle both sets of state changes independently.</span></li>
</ul>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">Below are the links to the two vector drawables representing the checked and unchecked states. You’ll notice (if you look carefully) that they differ by only a single attribute: <i>android:trimPathEnd</i></span></div>
<ul class="ul1">
<li class="li2"><span class="s1"><a href="https://github.com/jpuderer/AnimatedButton/blob/master/app/src/main/res/drawable/circle_button_off.xml" target="_blank">drawable/circle_button_off.xml</a></span></li>
<li class="li2"><span class="s1"><a href="https://github.com/jpuderer/AnimatedButton/blob/master/app/src/main/res/drawable/circle_button_on.xml" target="_blank">drawable/circle_button_on.xml</a></span></li>
</ul>
<div>
<br /></div>
<div class="p2">
<div class="info-box alert">
<div class="msg">
I find it somewhat annoying that there does not appear to be a away to inherit from another drawable. There’s really no good reason that I have to repeat the path information in both <i>circle_button_on.xml </i>and <i>circle_button_off.xml</i>, when they differ by only a single attribute (<i>android:trimPathEnd</i>).</div>
</div>
<br />
<div class="p2">
<span class="s1">The drawables specified in the <i><transition></i> elements are simple enough. The <i><animated-drawable></i> element defines which properties we animate, and the animation(s) to apply to those properties:</span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<pre class="prettyprint linenums"><?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/circle_button_on">
<target
android:name="circle_green"
android:animation="@animator/circle_on" />
<!--
I would LOVE to inline the animation here directly (like
drawables), instead of creating yet another file that gets
referenced in only one place once. I wish I understood how
Google determines when you can inline definitions (hint:
should be always), or where the rules are documented.
-->
</animated-vector><span style="font-family: "courier new" , "courier" , monospace;">
</span></pre>
<div class="p4">
<div style="text-align: center;">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><b>drawable/circle_button_to_on.xml</b></span></div>
</div>
<div class="p5">
<div style="text-align: center;">
<span class="s1"></span><br /></div>
</div>
<div class="p4">
<span class="s1">And here is the definition of the animation that gets applied:</span></div>
<div class="p5">
<span class="s1"></span><br /></div>
<pre class="prettyprint linenums"><?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:duration="500"
android:valueType="floatType"
android:interpolator="@android:interpolator/decelerate_cubic">
</objectAnimator>
</set>
</pre>
<div style="text-align: center;">
<span class="s1" style="font-family: "courier new" , "courier" , monospace;"><b>animator/circle_on.xml</b></span></div>
<div style="text-align: center;">
<br /></div>
<div class="p2">
<span class="s1">The transition in the opposite direction is much the same, so I won’t repeat it here. You can find links to these files here:</span></div>
<ul class="ul1">
<li class="li2"><span class="s1"><a href="https://github.com/jpuderer/AnimatedButton/blob/master/app/src/main/res/drawable/circle_button_to_on.xml" target="_blank">drawable/circle_button_to_on.xml</a></span></li>
<li class="li4"><span class="s1"><a href="https://github.com/jpuderer/AnimatedButton/blob/master/app/src/main/res/animator/circle_on.xml" target="_blank">animator/circle_on.xml</a></span></li>
</ul>
<div class="info-box alert">
<div class="msg">
Observant readers might be asking themselves at this point, why the repetition? Why can’t Android simply reverse the transition. Well, in theory I think it can, but it seems to be broken, which is why I set <i>android:reversible="false"</i> in the transitions. I <b>think</b> it’s supposed to allow the transition to be played backwards, but when set to true, it causes a number of issues (not the least of which are strange artifacts when rotating the screen). If anyone can figure this out (or point me to the relevant bug number), it would be much appreciated.</div>
</div>
<br />
<div class="p2">
<span class="s1">You can find the complete code for the above example here: <a href="https://github.com/jpuderer/AnimatedButton" target="_blank">https://github.com/jpuderer/AnimatedButton</a></span><br />
<br />
Which looks like this:<br />
<div style="text-align: center;">
<figure>
<img border="0" data-alt="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkVRRrQ0rM3rpRDzxfpAqAScdgPfz1XO35gmiobTy4oON0uDRK5rmrDBQNIW-8RzA0oPv7v_vQHShqLzmVP9pWUPY-PsHAK0dIok7vB1HJRVUVouJbYUAY0aPP3G5rRhWIo73LTqpREbE/s1600/AnimatedButton.gif" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6lOPDwAF1ScNN6OgFtTe435ztPoMvvhAyzj-i2XxMaDq3lv1RbsL9PS8SwWNZDSIHEle8aqn8qlQmC48h0-W7vxEQfOfJAX3pVuWCSMFMAIkP_LbQmsE9NoJwKYG4rvK6G2z3Z_0_qR4/s1600/AnimatedButton0.gif" width="179" />
<figcaption style="text-align: center;">Click to show animation</figcaption></figure></div>
</div>
<div class="p2">
<span class="s1">You can also find the code for the more complicated animation (featured at the top of the page) here:</span><br />
<span class="s1"><a href="https://github.com/jpuderer/AnimatedButton/tree/AnimatedLockButton" target="_blank">https://github.com/jpuderer/AnimatedButton/tree/AnimatedLockButton</a></span></div>
<div class="p1">
<span class="s1"></span><br /></div>
<div class="p2">
<span class="s1">It’s almost identical to the one above (same git project, just a different branch), except that the path and animations have a few more components to them.</span></div>
<div class="p1">
<br />
<span class="s1"></span></div>
<div class="p2">
<br />
<div class="info-box alert">
<div class="msg">
For completeness sake I'll mention that you might also have been able to do some of this using a regular <i>StateListDrawable</i> with <i>ObjectPropertyAnimators</i> to animate states, as described <a href="http://developer.android.com/training/material/animations.html#ViewState" target="_blank">here</a>. However, these don't define individual transition between states, which is the benefit of using <i>AnimatedStateListDrawable</i></div>
</div>
<br />
<div class="p1">
<span class="s1"></span><br /></div>
</div>
</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1666356413718259678.post-4258112792836299112015-09-15T20:53:00.003-05:002015-11-10T08:02:35.581-05:00Repairing a Macbook Pro - Yes it's possible!<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBfu-YQnoEDJeI9tsorbernbydVyoiyxhyphenhyphen7NnGu1pIW1E-qK8eEEfSDisNuqOmywU5ifRjcs8vW2sTFMK7zbX9bycdUXFN3pqRDUT-Z2agsCbYamZA0yjQTCOELKfojJHtDOt1xOLE5ZU/s1600/IMG_20150819_101143.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBfu-YQnoEDJeI9tsorbernbydVyoiyxhyphenhyphen7NnGu1pIW1E-qK8eEEfSDisNuqOmywU5ifRjcs8vW2sTFMK7zbX9bycdUXFN3pqRDUT-Z2agsCbYamZA0yjQTCOELKfojJHtDOt1xOLE5ZU/s400/IMG_20150819_101143.jpg" width="400" /></a></div>
<br />
<br />
Originally my first blog post wasn't going to be about how I broke and then repaired my Macbook, but to be honest it's been the center of my world for these last few weeks, so I'll write about this first.
<br />
<br />
<div class="info-box alert">
<div class="msg">
<b>tl;dr</b> version - Don't spill stuff on your Macbook. If you do, <b>it may still be possible</b> to repair it, or have someone repair it. That being said, I strongly suspect that there aren't more than a handful of businesses (other than this <a href="https://www.youtube.com/user/rossmanngroup/about">guy</a>) that can actually attempt a half decent repair.
</div>
</div>
<div dir="ltr">
<br />
<br />
<a name='more'></a><br />
<br /></div>
<div dir="ltr">
It all started with a small amount of orange juice getting spilled in the same bag as my laptop. After realizing my mistake, I quickly wiped it down, and everything seemed to be fine. I <b>*thought*</b> I had gotten off lightly.<br />
<br /></div>
<div class="notice-box alert">
<div class="msg">
Protip: Don't try to save that single serve container of orange juice from the airplane in the same bag as your laptop. Especially, if you are travelling to somewhere at high altitude (Bogota). Your container of juice will puff up like a blow fish, and probably explode everywhere.</div>
</div>
<br />
A few days later I noticed that my laptop was no longer charging, and that telltale charger light wouldn't turn on any more (and I <b><u>know</u></b> that the charger itself still works). Shit.
<br />
<div dir="ltr">
<br /></div>
<div dir="ltr">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqO1UDizO063gDVPImsZ6LVSDt7B4eAN3_3UQqHeu4ONDb1O9BbjdYauqvXX8Go9_Lq3qBI-iKgcSLYVg3tduhnPN-1zKPPIMvgU3cPKTkatEaOC4NsgjFrYPJBzB193HVZXcuL0nqdfY/s1600/IMG_20151104_084947%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqO1UDizO063gDVPImsZ6LVSDt7B4eAN3_3UQqHeu4ONDb1O9BbjdYauqvXX8Go9_Lq3qBI-iKgcSLYVg3tduhnPN-1zKPPIMvgU3cPKTkatEaOC4NsgjFrYPJBzB193HVZXcuL0nqdfY/s200/IMG_20151104_084947%257E2.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
</div>
<div dir="ltr">
Unfortunately, my Macbook is no longer under warranty, and even if it were, orange juice spills are not covered (You can lie, but they'll know - Apple puts moisture sensors inside the Macbooks, so they can tell if the damage was the result of a spill).</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
So the first thing I did was google Macbook repair, and landed on the <a href="https://www.ifixit.com/">IFixit</a> website. They have some really good instructions on how to disassemble and reassemble your Macbook, but not much in the way of actually figuring out what's wrong. </div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
I've occasionally fixed a few pieces of electronics, by opening them up and looking for anything obvious (gunk shorting out wires, obviously blown components, etc.) So I <b>*carefully*</b> followed the instructions to disassemble my Macbook A1502, cleaning off anything thing that looks like it might have gotten orange juice on it (using rubbing alcohol), and hoping for the best. Unfortunately, nothing was <b>*obviously*</b> broken, and that pesky charger light is still off.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
The insides of a Macbook Pro are hideously complex, dense, and not easily amenable to DIY repair. In fact, the <a href="https://www.ifixit.com/Teardown/MacBook+Pro+15-Inch+Retina+Display+Late+2013+Teardown/18696">IFixIt page for Macbook Pro</a> gives it a repairability score of only <b>1 out of 10</b>! Ouch.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
I was highly sceptical of sending it somewhere for repair, since the conventional wisdom is that modern electronics are effectively unfixable. Modern electronics and computers are highly complex, but relatively low cost, making it difficult for local repair shops to turn a profit by repairing them. So, most can't or won't, limiting their services to replacing larger modules such as screens and hard drives.<br />
<br />
<div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF8uufMUOjuSyEoW4CXwwiE1j5WSR5ka-TKMWkm6Mhb1pG47fmaSyz0XiforBYkhM6V87j8XzKO3yVz5O4cZKlFuGS5kS1gQ7Da0yWGMJ4ptksIW6ulO7J061lJckvqh31Oa4GogibOV4/s1600/ifixit_self-repair_manifesto_900x1390.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF8uufMUOjuSyEoW4CXwwiE1j5WSR5ka-TKMWkm6Mhb1pG47fmaSyz0XiforBYkhM6V87j8XzKO3yVz5O4cZKlFuGS5kS1gQ7Da0yWGMJ4ptksIW6ulO7J061lJckvqh31Oa4GogibOV4/s320/ifixit_self-repair_manifesto_900x1390.jpg" width="206" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Repair Manifesto [Source: <a href="https://www.ifixit.com/Manifesto">iFixit</a>]</td></tr>
</tbody></table>
<br />
I'm not the only one who's frustrated. There's even a something of a movement called "The Right to Repair". In my mind it's not really so much a right, as it is acknowledging that modern electronics are often borderline unfixable without schematics and replacement parts. Also, by making electronics that are not cost effective to repair, electronics manufactures are significantly contributing to the <a href="https://en.wikipedia.org/wiki/Electronic_waste">eWaste</a> problem.<br />
<br />
<ul>
<li><a href="http://www.wsj.com/articles/we-need-the-right-to-repair-our-gadgets-1441737868">http://www.wsj.com/articles/we-need-the-right-to-repair-our-gadgets-1441737868</a></li>
<li><a href="http://hackaday.com/2015/09/15/the-rise-of-the-fix-it-culture/">http://hackaday.com/2015/09/15/the-rise-of-the-fix-it-culture/</a></li>
</ul>
</div>
<div dir="ltr">
<br />
<br /></div>
</div>
<div dir="ltr">
So at this point, I'm considering throwing in the towel and ordering a new Macbook. However, I use my Macbook for building <a href="https://source.android.com/">Android (AOSP) </a>from source, and:<br />
<br />
<ol>
<li>It is a very expensive Macbook Pro (~$3000)</li>
<li>It would require about a month or more of lead time to order and ship a new Macbook, since it's not kept in stock. Meanwhile, I'm in limbo without a (good) computer.</li>
</ol>
... So, I'm going to keep trying just a bit longer (<span style="background-color: white; font-family: "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 13px; line-height: 16px;">がんばって)</span><br />
<br /></div>
<div dir="ltr">
More googling revealed mostly ad-hoc theories for what can cause various Macbook power problems (this sort of thing happens quite frequently). I didn't find anything that was very helpful.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Then I find this guy: <a href="https://www.youtube.com/user/rossmanngroup">Louis Rossmann.</a></div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
He's got a Youtube <a href="https://www.youtube.com/user/rossmanngroup">channel</a> where he either rants about things he feels strongly about (hint: almost everything), or walks you through (in detail, and with some warranted profanity [1]) the various Macbook repairs that he performs in his <a href="http://www.rossmanngroup.com/">Manhattan repair shop</a>.<br />
<br />
I watched a few hours of these videos before I started to get the hang of how to go about Macbook repairs. In fact, after watching a few of these videos I was convinced that if I sent my Macbook to Louis, it could be repaired.<br />
<br />
But... I'd gotten this far, so rather than send my machine in, and wait a few weeks for my Macbook to be repaired, I decided to see if I could persist <b><i>just</i></b> a bit longer and do it myself. If the repair ended up being too complicated, I could always send it to Louis. Besides, I'd be pretty proud of myself if I actually managed to fix this myself (with help of course).<br />
<br />
I managed to find the schematic and <i>board view</i> for my Macbook logic board online. I suspect that the whole business of schematics and board view files is somewhat of a grey area in the repair industry, and is one of the main gripes that fuels the whole "Right to Repair" movement. Technically, the schematics and boardview files are proprietary, but on the other hand everybody seems to have them. Nobody would actually be able to repair these things without them. <br />
<br />
<div class="p1">
<span class="s1">After watching about 2 or 3 hours of videos, I learned that the Macbook Pro power subsystem is quite complicated. That little green light on your connector will not turn on until it receives a 1-wire message from the Macbook SMC, and for that to happen the power controller checks <b>*everything*</b></span></div>
<br />
<div class="p1">
<span class="s1">The long story short, a Macbook is so well protected against shorts, it will refuse to turn on at the first hint of trouble.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
I found one video in particular that walked me through how to diagnose my problem: <a href="https://www.youtube.com/watch?v=FLH2Ns7Zqo8">Macbook charger green light; or what is the onewire circuit and why should I care?</a><br />
<br />
After checking some of the test points that Louis describes, I finally find the problem. At 21:35 in the video, Louis literally states my problem: <i>"So if this [adapter sense] is 16 volts, this [1-wire circuit] doesn't work right, and that usually happens with a bad DC-in board"</i>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeUoOt_IwmUtW1LFdgjoC1zKogUjKXL_CR-C2LhDhxscA1qmJ8lwMFKsRXKjGBOU6PPxsrtZtKz3EUDABpmHI3KYml0EsMrKXPca76A5iaLeYP3NohXKE-GQhGWFwWAb9iQ3EDLn6G1Pc/s1600/IMG_20150908_141643.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeUoOt_IwmUtW1LFdgjoC1zKogUjKXL_CR-C2LhDhxscA1qmJ8lwMFKsRXKjGBOU6PPxsrtZtKz3EUDABpmHI3KYml0EsMrKXPca76A5iaLeYP3NohXKE-GQhGWFwWAb9iQ3EDLn6G1Pc/s320/IMG_20150908_141643.jpg" width="320" /></a></div>
<br />
Woohoo! <br />
<br />
There's not much left to this story. <br />
<br />
I managed to find and order the $20 part from some really nice guys at <a href="http://commandmacparts.com/">commandmacparts.com</a>, and within an hour of the part arriving, my Macbook Pro was working like new.<br />
<br />
Wow. That felt good. I think I'll buy myself <a href="https://www.ifixit.com/Store/Tools/iFixit-Skill-Badge/IF145-251-1">this skill badge</a> (from iFixIt) to remind myself of how awesome it feels to fix stuff yourself.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://www.ifixit.com/Store/Tools/iFixit-Skill-Badge/IF145-251-1" style="margin-left: auto; margin-right: auto;"><img border="0" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-ra7MytqU7udvpdR3rsHAKMeDd8ZuTP8TPHyEwkyeXLGm5YLVU8ziOkbTnVZbIQo9YVhcEw-aOXPvnCoQ0vH6G97H2F0EeHL30LlvOigfxgmTIQaokgQh1VpSOvBb9XJdl49yPXDC6vM/s200/ifixit-badge.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<b>Conclusion</b>: It is possible to fix some modern electronics., even Macbooks. Fixing stuff by yourself is awesome, but if you can't if you can't (or don't want to) fix it yourself), find someone like <a href="http://www.rossmanngroup.com/">Louis</a> who really knows what they're doing.<br />
<br />
<br />
<div class="info-box alert">
<div class="msg">
[1] If anyone feels that the profanity isn't warranted, they probably haven't spent much time either fixing or building stuff. Especially fiddly stuff, like very fine pitch electronics. When I was growing up, my father completely renovated our home and later went on to build a summer home, pretty much by himself. I don't think he would have bothered if he wasn't able to swear a blue streak when things started to get frustrating. Swearing feels good, admit it.</div>
</div>
</div>
Unknownnoreply@blogger.com2