tag:blogger.com,1999:blog-1588601560921313070Sun, 04 Dec 2016 14:14:44 +0000AndroidAppArduinoSerialHome AutomationTabletTouch ScreenATtinyAudioBluetoothCameraCapacitive TouchCommunicationCookingCyborgFlashlightLEDLampLanternLightLight SwitchMicrocontrollerScaleSnakeSoundToolUIUSB hostWatchWidgetsWirelessgoogle mapsiPadmapmashuptheUltimateLabshttp://blog.theultimatelabs.com/noreply@blogger.com (Rob B)Blogger18125tag:blogger.com,1999:blog-1588601560921313070.post-7970188044802397175Thu, 30 Jan 2014 20:11:00 +00002014-01-30T12:11:14.054-08:001ClickShare App<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-TCVVDHPo6-A/UuqvfdjLxNI/AAAAAAAAAPc/Noz4PYJQyOI/s1600/Resized-PZ89Y.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-TCVVDHPo6-A/UuqvfdjLxNI/AAAAAAAAAPc/Noz4PYJQyOI/s1600/Resized-PZ89Y.jpg" height="320" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.share.manager" target="_blank">Google Play Link: 1ClickShare</a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><span id="goog_1930482191"></span><span id="goog_1930482192"></span>I published an app a while back that think is pretty unique. My wife uses Pintrest, I use Reddit, she uses Faceboook, I use Google+. So when we want to share a cool site or an article that we've found we have to fall back to the common denominator, email. Android has a great system wide share menu that most apps use. One of the options is Gmail, but after you click this you still need to start typing the name of the contact until it pop up in the auto complete, click the contact, then click send. This got repetitive since 9/10 times I was sending the link to my wife. So I've built an app to complete this process in just 1 click.<br /><h3>Prior Work</h3>I did find one app the sort of fills this nich. AdramadaShare registers for the intent used to display the share menu and allows you to replace it with a custom menu. This works great in many cases. However, in newer apps the share menu is now displayed within the app so this method won't work with those apps. I also noticed the app required my gmail password to setup a default email action. I hate putting my gmail password into an app.<br /><h3>Solution</h3>&nbsp;Ideally you would be able to add custom icons to the system share menu and link those icons to custom actions. Unfortunately the only way to get an icon added to the system share menu is to register it in the manifest file. This cannot be changed at runtime. So to add custom icons my app had to be able to install new apps on the fly, which is exactly what my app does. It starts with a simple template app that is modified by replacing the icon and title with the title and icon the user specifies. Permission to install from unknown sources will need to be temporarily enabled. The new app requests only one permission, the "1ClickShare" permission. This is a custom permission that enables this app to send intents to the main 1ClickShare app. Without this, any app could start sending emails on you behalf. This also means any other third-party app developer could add the 1ClickShare permission to their app if they wanted to give their user a way to share content with one click without using the system share menu.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-xq16SiKxaCQ/Uuqvi_VsALI/AAAAAAAAAPk/DCVdZuYnuSU/s1600/Screenshot_2013-10-09-07-21-38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-xq16SiKxaCQ/Uuqvi_VsALI/AAAAAAAAAPk/DCVdZuYnuSU/s1600/Screenshot_2013-10-09-07-21-38.png" height="400" width="240" /></a><a href="http://3.bp.blogspot.com/-W4XBtJLiUqw/Uuqv07NgH-I/AAAAAAAAAQE/Uc6r6nZj3kc/s1600/Screenshot_2013-10-09-07-21-49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-W4XBtJLiUqw/Uuqv07NgH-I/AAAAAAAAAQE/Uc6r6nZj3kc/s1600/Screenshot_2013-10-09-07-21-49.png" height="400" width="240" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>Since this app is intended to be used only for your most important contacts, you are probably going to be sharing with them a lot. So by using s special trick with unicode, the added icon will now show up at the top of the share menu. After the new app/icon is installed an action must be associated with it. Currently Gmail is the only available action, but in the future I plan to add more actions. Each app icon can have multiple actions associated with it, they will all be activated when the user clicks on the icon. Fortunately at this step I was able to make use of OAuth2 to request the credentials to send emails as the user. This means I don't need to ask the user for their password, which is a big pet-peeve of mine in other apps. Next the user can add any number of To, Cc, Bcc, recipients to each new gmail action.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-tlg5kjfoQlE/UuqvjuQenYI/AAAAAAAAAPs/cuVFxZ5_30Y/s1600/Screenshot_2013-10-09-07-22-23.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-tlg5kjfoQlE/UuqvjuQenYI/AAAAAAAAAPs/cuVFxZ5_30Y/s1600/Screenshot_2013-10-09-07-22-23.png" height="400" width="240" /></a><a href="http://2.bp.blogspot.com/-NOyOm4t5O9Y/UuqvmOR_V0I/AAAAAAAAAP8/b2uUAj1-85k/s1600/Screenshot_2013-10-09-07-24-24.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-NOyOm4t5O9Y/UuqvmOR_V0I/AAAAAAAAAP8/b2uUAj1-85k/s1600/Screenshot_2013-10-09-07-24-24.png" height="400" width="240" /></a></div>While implementing this I noticed that chrome on Android adds a little Easter egg when you share a link. It adds a screenshot in the intent extras. If this screenshot is detected it's added to the email that's sent to the user so they get a snapshot of the link you are sending them to. For some reason the colors of this image are inverted!, so I have to invert the colors back.<br /><h3>Future</h3>I'd like to add more actions, such as, "Post to Facebook", "Post to Google+", "Save to Google Docs", etc. The tricky part is figuring out a way to do this with 1 click. I'd like to add a thumbnail engine for links that are not from chrome. And I'd like to add ways for the user to change the message before the email is sent if they want to. This may include voice dictation, or adding a edit button in the drop down menu temporarily.<br /><br /><br /><br />http://blog.theultimatelabs.com/2014/01/1clickshare-app.htmlnoreply@blogger.com (Rob B)1tag:blogger.com,1999:blog-1588601560921313070.post-358712140064883649Mon, 27 Jan 2014 14:42:00 +00002014-01-27T06:46:23.638-08:00Alere CareLine Automator<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-AuisH1qYOe8/UuZsfyR8t_I/AAAAAAAAAPA/zoJ05k0Pumk/s1600/trueresultglucosemeter-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-AuisH1qYOe8/UuZsfyR8t_I/AAAAAAAAAPA/zoJ05k0Pumk/s1600/trueresultglucosemeter-1.jpg" height="400" width="342" /></a><a href="http://3.bp.blogspot.com/-h9Kp-4cCgIY/UuZw1z6_2pI/AAAAAAAAAPM/HnTeDVo0ueQ/s1600/Screenshot_2014-01-26-16-18-53+(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-h9Kp-4cCgIY/UuZw1z6_2pI/AAAAAAAAAPM/HnTeDVo0ueQ/s1600/Screenshot_2014-01-26-16-18-53+(1).png" height="400" width="225" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="" style="clear: both; text-align: left;">A friend of mine was recently diagnosed with gestational diabetes. Her doctor enrolled her in a monitoring plan from Alere. She has to record her glucose levels four times a day and her ketones levels once a day. She is supposed to call in her results to an automated call system everyday. It takes over 5 minutes to enter all your information into their silly system. Such a waste!</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="" style="clear: both; text-align: left;">So I wrote an app to automate the process. It now takes less than two minutes with no interaction from the user required.&nbsp;&nbsp;It works by constructing a special telelphone URI with pauses in all the right places. Here's an example of a constructed URI (',' is a 1-2 second pause):</div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="" style="clear: both;">18666148333,155522244441,0227,11288%23,,1,,1132102%23,,1,,115298%23,,1,,118111%23,,1,,122,,1,,</div><div class="separator" style="clear: both;"><br /></div><div class="separator" style="clear: both;">The call is started with an intent:&nbsp;</div><div class="" style="clear: both;">startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + callString.toString())));</div><div class="" style="clear: both;">Note, %23 is #, putting # directly in the URI will not work. Also note, this will not work with Google Voice.<br /><br /></div><div class="" style="clear: both;"><a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.alerecareline&amp;hl=en" target="_blank">Google Play Link</a></div>http://blog.theultimatelabs.com/2014/01/alere-careline-automator.htmlnoreply@blogger.com (Rob B)0tag:blogger.com,1999:blog-1588601560921313070.post-845673859621664493Fri, 29 Nov 2013 05:59:00 +00002013-11-28T22:13:03.172-08:00google mapsmapmashupCity Park Heatmap Mashup<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-le0893SlZIg/Upgv0Q5tdNI/AAAAAAAAAN0/JVqGUK0-yco/s1600/heatmap.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="344" src="http://1.bp.blogspot.com/-le0893SlZIg/Upgv0Q5tdNI/AAAAAAAAAN0/JVqGUK0-yco/s640/heatmap.PNG" width="640" /></a></div><br />I live in a neighborhood without a park nearby. It seemed most other areas in town had several parks in smaller neighborhoods. To prove my hypothesis I created a heatmap mashup of parks using Google Maps API. Use the slider in the top left to adjust the radius of each spot. There's also an option to include schools, since most schools have playgrounds. Here's the results:<br /><br />Direct Link [Full Screen]: <a href="http://goo.gl/xel0K0">http://goo.gl/xel0K0</a><br /><iframe frameborder="0" height="400" src="http://goo.gl/xel0K0" width="100%"></iframe>http://blog.theultimatelabs.com/2013/11/city-park-heatmap-mashup.htmlnoreply@blogger.com (Rob B)0tag:blogger.com,1999:blog-1588601560921313070.post-4655471803934078452Sat, 11 May 2013 13:41:00 +00002013-05-11T06:45:57.216-07:00AndroidArduinoAudioCommunicationSerialSoundWirelessWirelessly Communicating with Arduino using Sound<div class="separator" style="clear: both; text-align: center;"><a href="http://cladlab.com/wp-content/gallery/electronics-misc/piezo-photo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" height="320" src="http://cladlab.com/wp-content/gallery/electronics-misc/piezo-photo.jpg" title="" width="320" /></a></div>I've been playing with Audio communication the past few weeks. My goal is to acheive two-way communication between an Arduino and an Android device using inaudible sound pulses. This is not a new concept and I have seen the concept implemented by some comercial companies ( e.g.&nbsp;<a href="http://www.hex3.co/">http://www.hex3.co</a>/). So far I haven't seen an open source implementation though.<br /><h2>Hardware</h2><div>Lets start with the Arduino hardware. Turns out a cheap pizeo works really well for transmitting, just make sure you have a small resistor in&nbsp;series&nbsp;with it. You'll quickly find that the built-in arduino library "tone" is very limited and only fluctuates between 0 and 5 V which will not produce inaudible tones. <a href="https://code.google.com/p/arduino-tone-ac/">toneAC</a>&nbsp;solves this problem and allows you to produce a -5V to 5V tone. The drawback is it only works on select pins and can only produce one frequency at a time.</div><div><br /></div><div>For the microphone I first tried one of the cheap microphones you find on ebay from China, but it had really terrible response. It's only good for detecting a sound&nbsp;occurred. &nbsp;Next I tried the microphone from freetronics and it worked great (<a href="http://www.freetronics.com/products/microphone-sound-input-module#.UYuhIbWG1kE">http://www.freetronics.com/products/microphone-sound-input-module#.UYuhIbWG1kE</a>). I'd like to push the price down on this project, so I may end up creating a custom board, email me if you're&nbsp;interested&nbsp;in helping.&nbsp;</div><h2>Signal Processing</h2><div>There's a lot of ways this can be done, and I tried several. First thing I tried was the frequency detection tutorial here&nbsp;<a href="http://www.instructables.com/id/Arduino-Frequency-Detection/">http://www.instructables.com/id/Arduino-Frequency-Detection/</a>. This worked but it was not as reliable as I needed. My research quickly lead me to <a href="http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling">DTMF</a>. DTMF is a method of sending two frequencies interposed on top of each other. DTMF is what's used for touch tone phones, it has a lot of advantages.&nbsp;Unfortunately since toneAC can only produce a single tone at a time, DTMF won't work if I want to keep the tones inaudible, however I may implement it as an alternative mode for longer&nbsp;distance&nbsp;very audible communication.</div><div><br /></div><div>At first I started implementing an FFT on the Arduino based on someone&nbsp;else's&nbsp;library. This is overkill, since I only want to detect one or two frequencies. Enter&nbsp;<a href="http://en.wikipedia.org/wiki/Goertzel_algorithm">Goertzel algorithm</a>. This algorithm gives me exactly what I want with minimal processing. Implementing this in Android is very easy and straight forward, but on the Arduino has issues. First you need to setup the ADC to sample fast enough to&nbsp;accurately capture signals in the inaudible range (~20khz), which translate to &gt;40khz because of the&nbsp;nyquist&nbsp;theorem. I found good tutorials for&nbsp;setting up&nbsp;the ADC <a href="http://www.marulaberry.co.za/index.php/tutorials/code/arduino-adc/">here</a> and <a href="http://www.instructables.com/id/Arduino-Audio-Input/?ALLSTEPS">here</a>. The ADC sampling rate is calculated by the following algorithm: [core clock rate]/2^[ADC pre-scaler]/[ADC sample time] = 16Mhz/(2^prescaler)/13. So your choices are 38.46khz or 76.92khz, I went with 76.92khz. The ADC triggers an interrupt every time a new sample is ready, that way the Arduino can be listening&nbsp;continuously&nbsp;while it performs other tasks. This is now a realtime system because the Arduino must receive and process each sample at 76.92khz. Needless to say Arduino is not a high performance DSP so this is a challenge.</div><h4>Goertzel Optimizations</h4><div>I came up with a nice trick that makes processing orders of magnitude faster on the Arduino. For each sample the following calculation is performed:</div><div><pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); font-family: monospace, Courier; font-size: 13px; line-height: 1.3em; padding: 1em;"> s = x[k] + coeff * sprev - sprev2;<br /> sprev2 = sprev;<br /> sprev = s;</pre></div><div>The coefficient is 2*cos(2*PI*freq/sample_rate). The coefficient ranges between -2 and 2. Which means there is a frequency at which the coeff == 0. Solving the equation for freq when coeff=0, you get freq=sample_rate/4 or 19.23khz. The processing for Goertzel then becomes:</div><div><pre style="background-color: #f9f9f9; border: 1px dashed rgb(47, 111, 171); font-family: monospace, Courier; font-size: 13px; line-height: 1.3em; padding: 1em;"> s = x[k] - sprev2;<br /> sprev2 = sprev;<br /> sprev = s;</pre></div><div>Which can be done performed without floating point numbers which makes a significant difference.</div><h2>Protocol</h2><div>To&nbsp;simplify&nbsp;the design I'm using the exact same protocol for both receiving and sending. Because of the constrained processing on the Arduino, I can only use a single&nbsp;frequency. By modulating the frequency between the target frequency and any other frequency I can create a square wave. By modulating the pulse width of that square wave I can send either a 1 bit or 0 bit. A long gap between signals represents a new message. Each message is at least 2 bytes, a cmd and a crc checksum, and can be&nbsp;up to&nbsp;8 bytes. It takes between 16ms and 24ms per bit.</div><h2>Demo</h2><div>In this demo as I type the letter is transmitted wirelessly from the Android to the Arduino, the Arduino inverts the case and sends it back. I intentionally have music on in the background to show that it can work in a noisy&nbsp;environment. As you can see in the video, it's not perfect yet.&nbsp;</div><iframe allowfullscreen="" class="youtube-player" frameborder="0" height="385" src="http://www.youtube.com/embed/CWNe1t-YUgo" type="text/html" width="640"></iframe><br /><h2>Conclusions</h2><div>This technology is exciting because its one of the few&nbsp;truly&nbsp;universal communication protocols. A&nbsp;compatible&nbsp;app&nbsp;could&nbsp;easily be written for iOS and Windows or even a feature phone. I hope to find time to post again soon with some creative applications of this technology.&nbsp;</div><div><br /></div><div><br /></div>http://blog.theultimatelabs.com/2013/05/wirelessly-communicating-with-arduino.htmlnoreply@blogger.com (Rob B)3tag:blogger.com,1999:blog-1588601560921313070.post-1152849091692982432Sat, 02 Feb 2013 17:48:00 +00002013-02-02T09:53:42.071-08:00AndroidAppFlashlightLampLanternLEDLockscreen Flashlight & Lamp for Android<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-9Rck3R2NdzY/UQ0xy2oaVqI/AAAAAAAAAM0/flFhEEifzc0/s1600/flashlight.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-9Rck3R2NdzY/UQ0xy2oaVqI/AAAAAAAAAM0/flFhEEifzc0/s320/flashlight.png" width="320" /></a></div><br />I recently finished probably the most useful app I have ever written. It's well known that your phone's LED can be used as a flashlight. The problem I noticed is that it was too cumbersome to turn it on when it was really needed. So I created an app that allows you to use your phone's LED quickly without a GUI.<br /><br />This app is for anyone who's had trouble turning on their phone's LED late at night. It's a flashlight, lantern and lamp. It works so well it's replaced my nightstand lamp and I don't need to&nbsp;disturb&nbsp;my wife by turning on the room light when I use the bathroom at night. Best of all the app is free and open source under GPL.<br /><br />&nbsp;There's a few different ways to use this app. <br /><ul><li>Delay On: LED turns on after a specified delay after the phone is awakened and still at the lockscreen</li><li>Quick On: LED turns on if the screen is turned off then on quickly</li><li>Lantern Mode: LED turns on when phone is placed face down and lockscreen is on</li><li>Lamp Mode: Same as lantern mode, except it never turns off when plugged in</li></ul>The LED will turn off after a period to prevent battery loss. This timeout starts at 10 minutes when being used as a lantern and 1 minute otherwise. The LED will flicker before turning off. Every time the phone is moved the timeouts reset and more time is added. Specifically, 1 minute is added to the lantern timeout and 5 seconds is added to the normal timeout. i.e. if the phone is moved 5 times, the lantern timeout will now be 15 minutes. So shake your phone if you need more time.<br /><h4><a href="http://play.google.com/store/apps/details?id=com.theultimatelabs.flashlight" target="_blank">App Download (Google Play)</a></h4><h4><a href="https://github.com/theUltimateLabs/theUltimateFlashlight" target="_blank">Source Code (GPL)</a></h4>Let me know if it works for you.<br /><br /><br />http://blog.theultimatelabs.com/2013/02/lockscreen-flashlight-lamp.htmlnoreply@blogger.com (Rob B)1tag:blogger.com,1999:blog-1588601560921313070.post-4035663809253175523Sat, 15 Dec 2012 15:38:00 +00002012-12-15T07:46:01.860-08:00AndroidAppCookingScaleUSB hostthe Ultimate Scale<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-L5wAU7-2iyk/UMyQhTXbzyI/AAAAAAAAAMM/niqBb7Y9rvA/s1600/scale.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="http://3.bp.blogspot.com/-L5wAU7-2iyk/UMyQhTXbzyI/AAAAAAAAAMM/niqBb7Y9rvA/s640/scale.jpg" width="640" /></a></div><br />I wanted to write an app that my wife would actually use. She's an amazing cook, so I came up with the idea of using a scale to to assist with cooking. I just happened to have a old <a href="http://www.stamps.com/postage-online/digital-postage-scales/">Stamps.com 510 USB postage scale</a> laying around. The scale registers as a HID device and has a fairly <a href="http://nicholas.piasecki.name/blog/2008/11/reading-a-stamps-com-usb-scale-from-c-sharp/">simple protocol</a>. As of ICS Android has pretty good <a href="http://developer.android.com/guide/topics/connectivity/usb/host.html" target="_blank">support for USB host</a>. Newer devices like the nexus devices and the Samsung galaxy phones support this.<br /><br /><iframe allowfullscreen="allowfullscreen" frameborder="0" height="480" src="http://www.youtube.com/embed/FnahLlcdruo" width="640"></iframe> <br /><br /><h4><a href="http://play.google.com/store/apps/details?id=com.theultimatelabs.scale" target="_blank">App Download (Google Play)</a></h4><h4><a href="https://github.com/theUltimateLabs/theUtimateScale" target="_blank">Source Code (GPL)</a></h4><h3>Usage</h3>The app launches automatically when the scale is connected. The interface is intentionally very simple. Touch the main weight text to tare (zero) the scale. Long touch the same text to reset the zero offset, i.e. clear the tare. The weight is spoken out load as it changes.<br /><br />The units is where this app shines. Touch the units text and use voice recognition to change the units. I've included several unit types and more can be easily added by appending the JSON files.&nbsp;The units type is selected by doing a simple keyword match. Weights are just plain weights, such as pounds. Volumes require a matching density to work. Any volume can be paired with any&nbsp;density.&nbsp;Since the app is just looking for keywords the recognition is very flexible. You could say "flour in cups" or something more complex like "please switch the units to cups of flower", it works the same way.<br /><ul><li>Available Weights: <ul><li>ounces</li><li>pounds</li><li>grams</li><kilograms li="li"><li>quarters</li><li>dimes</li><li>pennies</li><li>nickles</li></kilograms></ul></li><li>Available Volumes: <ul><li>teaspoons</li><li>tablespoons</li><li>cups</li><li>quarts</li><li>fluid ounces</li><li>milliliters</li><li>liters</li><li>gallons</li><li>pints</li></ul></li><li>Available&nbsp;Densities: </li><ul><li>flour</li><li>sugar</li><li>rice</li><li>butter</li><li>milk</li><li>water</li><li>oil</li><li>powder sugar</li></ul></ul><div>If I missed something, which I surely have, please comment below.</div><div><h3>Ads, Donations &amp; Store</h3></div><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-RAF9MGV7DXc/UMyR2AtUpkI/AAAAAAAAAMU/rSibrDJtjkc/s1600/scale_kit_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://2.bp.blogspot.com/-RAF9MGV7DXc/UMyR2AtUpkI/AAAAAAAAAMU/rSibrDJtjkc/s400/scale_kit_1.jpg" width="400" /></a></div><div><br /></div><div>I'm&nbsp;experimenting&nbsp;with&nbsp;motorization&nbsp;in this app. I'm not so&nbsp;delusional&nbsp;to think I'm actually going to make any meaningful amount of money but it's fun to&nbsp;experiment. The ads in the app can be&nbsp;permanently&nbsp;disabled in a couple clicks, it's still open source after all. I've created a new page on the blog to accept&nbsp;<a href="http://blog.theultimatelabs.com/p/donate.html">donations</a>&nbsp;from those inclined. Finally I've bought a few extra scales and will be selling them as a kit with an OTG adapter in a new <a href="http://theultimatelabsstore.blogspot.com/p/store.html" target="_blank">store</a>. I'm using&nbsp;Google&nbsp;checkout, but for some reason it wouldn't work in the dynamic view of blogger, so it redirects to another blogger page.&nbsp;</div>http://blog.theultimatelabs.com/2012/12/the-ultimate-kitchen-scale.htmlnoreply@blogger.com (Rob B)0tag:blogger.com,1999:blog-1588601560921313070.post-2267125931671460038Mon, 03 Dec 2012 05:53:00 +00002012-12-03T21:29:13.523-08:00AndroidAppCameraSnakeToolMeasuring Snakes with Android<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-DAWIApF7ovQ/ULw57o5uiNI/AAAAAAAAALQ/ddw8J13g3is/s1600/my_snake47190605.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" src="http://3.bp.blogspot.com/-DAWIApF7ovQ/ULw57o5uiNI/AAAAAAAAALQ/ddw8J13g3is/s400/my_snake47190605.jpg" width="400" /></a></div><br /><br />My brother is a snake&nbsp;enthusiast&nbsp;(nut). He has about 20 pythons that he breads to create new variations. He wanted an easy way to measure his snakes so I wrote him an app that uses an Android smartphone camera, however this could be used to measure anything. There are a handful of other apps on Google Play that do something similar, but I didn't find any that work for curved objects.<br /><br />With a lot of image processing you could probably make this automatic, but that would be a lot of work. Instead, the user simply traces the image with their finger or touches several points around the snake. A&nbsp;reference object is required to convert the pixels into useful units like inches. In above image he used a credit card sized access card. Several other common references are built into the app. I learned a lot about line Android&nbsp;<a href="http://developer.android.com/reference/android/graphics/Path.html" target="_blank">Path</a>&nbsp;library that I'll be able to use in other apps.<br /><br />This app is not open source or free, at least not right now. I decided since it was designed for a very specific audience that I have little personal interest in, I would charge a nominal fee ($1.95) for it. This will allow me to&nbsp;experiment with marketing a paid app in Google Play. Not to worry, I still plan to open source the other apps I have in development.<br /><br />Link:&nbsp;<a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.snake">https://play.google.com/store/apps/details?id=com.theultimatelabs.snake</a>http://blog.theultimatelabs.com/2012/12/measuring-snakes-with-android.htmlnoreply@blogger.com (Rob B)1tag:blogger.com,1999:blog-1588601560921313070.post-2061576705432072851Wed, 21 Nov 2012 04:15:00 +00002012-11-20T20:16:41.597-08:00AndroidMicrocontrollerSerialThe Ultimate Guide to Connecting Android to a Microcontroller<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-zwgldQXIKe8/UKxQrgztL9I/AAAAAAAAAK0/A2fLLQ21nfE/s1600/androidMicro.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-zwgldQXIKe8/UKxQrgztL9I/AAAAAAAAAK0/A2fLLQ21nfE/s320/androidMicro.jpg" width="240" /></a></div><br />Android phones/tablets are&nbsp;packed with powerful processors with&nbsp;hundreds&nbsp;of potential IO ports, yet it is&nbsp;frustratingly&nbsp;difficult and&nbsp;relatively&nbsp;expensive to get a simple GPIO pin or serial port. This is my attempt to document all the possible ways to connect an Arduino type microcontroller to an Android device in one place. I'd like to keep this guide current so please send me corrections and suggestions and I will update it. &nbsp;These&nbsp;techniques&nbsp;may also be applicable to iOS devices, but they are not a specific focus of this article.<br /><h2>Background</h2>First it's useful to list all the sensors (inputs), actuators (outputs), and standard comm. channels on an Android device. Every sensor has the potential to be a serial input and every actuator has the potential to be a serial output. Of course not every device will have all these features, so I tried to order each list by&nbsp;ubiquity&nbsp; starting with the most&nbsp;ubiquitous.<br /><br /><h3>Standard Comm. Channels</h3><div><ul><li>USB Client</li><li>WiFi</li><li>Audio Jack</li><li>Bluetooth</li><li>USB Host</li><li>NFC</li><li>FM</li><li>IR</li></ul></div><br /><h3>Sensors (Inputs)</h3><div><ul><li>Touchscreen</li><li>Microphone</li><li>USB Connection</li><li>Accelerometer</li><li>Battery Level</li><li>Battery&nbsp;Temperature</li><li>Camera</li><li>Light Sensor</li><li>Magnetometer</li><li>Proximity Sensor</li><li>Gyroscope</li><li>Barometer</li><li>RGB Sensor</li><li>Ambient Temperature</li></ul></div><h3>Actuators (Outputs)</h3><div><ul><li>LCD</li><li>Speaker</li><li>LED</li><li>Vibration</li></ul><h2>Interface Methods</h2></div><div><h3> USB Client</h3><div>This is the&nbsp;approach&nbsp;used by the <a href="http://ytai-mer.blogspot.com/" target="_blank">IOIO</a>&nbsp;board and Google's <a href="http://developer.android.com/tools/adk/index.html" target="_blank">ADK</a>.&nbsp;In this mode the microcontroller actually acts as the USB host and the tablet is treated as the client.&nbsp;</div><b>Pros: </b>Universally&nbsp;supported via ADB and&nbsp;<a href="http://code.google.com/p/microbridge/" target="_blank">microbridging</a> and its&nbsp;officially&nbsp;supported by Google via the Open Accessory Protocol. The microcontroller can charge the Android device.<br /><b>Cons:&nbsp;</b>It's&nbsp;relatively&nbsp;expensive. ADK ~$65, IOIO ~$50. The microcontroller must be externally powered, cannot be powered by the Android device.&nbsp;</div><h3> USB Host&nbsp;</h3><div>It's becoming more common for Android tablets to have USB host. The Nexus 7, for example, does have USB host and I've used it to directly communicate with an Arduino.</div><div><b>Pros</b>: Very low cost. Connect directly to the USB client on the microcontroller, assuming the microcontroller has a USB client. The Android device provides power to the microcontroller.</div><div><b>Cons</b>:&nbsp;Likely&nbsp;requires an OTG cable. I've found that most super cheap Android tablets do not have the proper drivers installed to enable this. Since most Android devices only have one USB port so the device cannot be charged at the same time.</div><h3>Classic Bluetooth</h3><div>This solution has become quite economical lately.&nbsp;</div><div><b>Pros</b>: Wireless. Very common.&nbsp;<a href="http://dx.com/p/jy-mcu-arduino-bluetooth-wireless-serial-port-module-104299" target="_blank">Relatively&nbsp;cheap ~$8</a>.&nbsp;</div><div><b>Cons</b>: Cheap Android Tablets usually don't have bluetooth. Shorter range than WiFi. Maximum of 7 devices can be connected at once.<br /><br /><h3>Bluetooth Low Energy</h3><div>This is a <a href="http://en.wikipedia.org/wiki/Bluetooth_low_energy" target="_blank">new bluetooth standard</a> for low power Bluetooth devices. Also called Smart Bluetooth.</div><div><b>Pros: </b>Lower energy than classic Bluetooth</div><div><b>Cons</b>: Not very common.</div><h3>WiFi</h3><div>There's been <a href="http://www.seeedstudio.com/depot/index.php?main_page=advanced_search_result&amp;search_in_description=0&amp;keyword=wifi&amp;x=0&amp;y=0" target="_blank">wifi&nbsp;shields</a>&nbsp;around for a while (~$50). <a href="http://electricimp.com/" target="_blank">Electric Imp</a> is a new entry that includes a&nbsp;microprocessor and wifi radio for only ~$25+.&nbsp;</div><div><b>Pros:</b>&nbsp;High bandwidth. Long range.&nbsp;Ubiquitous.</div><div><b>Cons: </b>Usually expensive. High power.</div></div><h3> NFC</h3><div>I haven't seen this done yet, but in theory you could communicate with an NFC device continously though NFC using something like <a href="http://www.seeedstudio.com/depot/125khz-rfid-module-uart-p-171.html?cPath=144_153" target="_blank">this RFID module</a>.</div><div><b>Pro</b>: Low power. Wireless.</div><div><b>Con</b>: NFC is not very common. Very short range. Low bandwidth.</div><h3> Headphone Jack</h3><div><a href="https://play.google.com/store/apps/details?id=re.serialout&amp;feature=search_result#?t=W251bGwsMSwxLDEsInJlLnNlcmlhbG91dCJd" target="_blank">This project</a> claims to support serial communication through a hedphone jack, and they also provide a schematic. They sell <a href="http://robots-everywhere.com/site/purchase/audio-serial-module/" target="_blank">a kit</a>&nbsp;for $15, but I'm sure a cheaper one could be built. For some reason it&nbsp;doesn't seem to support serial in. Another example is <a href="http://web.eecs.umich.edu/~prabal/projects/hijack/" target="_blank">hijack</a>&nbsp;which sells for ~$79.</div><div><b>Pros</b>: Ubiquitous. No drivers needed.</div><div><b>Cons</b>: Lacking inexpensive hardware support.&nbsp;Headphone&nbsp;jack is&nbsp;occupied.<br /><br /><h3><b>Infrared</b></h3><div>Its very rare for a tablet to have a IR port (Vizo is one example). You can add a IR port in the headphone jack though. <a href="http://www.irdroid.com/" target="_blank">Irdroid </a>&nbsp;provides a DIY kit for $25+ and <a href="http://www.zokama.com/androlirc#audio-to-ir" target="_blank">this blog</a> has some other examples.</div><div><div><b>Pros</b>: Proven technology. Interface with a lot AV devices too.</div><div><b>Cons</b>: Rare on Android devices. May require after market device that takes up the headphone jack.&nbsp;Relatively&nbsp;expensive.</div></div></div><h3> Light</h3><div>Using visible light as a communication channel. This is used by several projects now including the <a href="http://electricimp.com/" target="_blank">Electric Imp</a>. I did a <a href="http://blog.theultimatelabs.com/2012/06/two-way-serial-interface-using-touch.html" target="_blank">proof of concept of this</a> using a photosistor a while back. It would also work connected to the camera LED or&nbsp;notification&nbsp;LED on a phone.&nbsp;</div><div><div><b>Pros</b>: Ubiquitous. Low cost.&nbsp;</div><div><b>Cons</b>: Low bandwidth. Need something very near the screen. Unidirectional. No hardware kit available.</div></div><h3>Capacitive&nbsp;Touchscreen</h3><div>Trigger the capacitive touch screen as if a user touched the screen. I did a&nbsp;<a href="http://blog.theultimatelabs.com/2012/06/two-way-serial-interface-using-touch.html" target="_blank">proof of concept of this here</a>&nbsp;and&nbsp;someone else&nbsp;built another example shown&nbsp;<a href="http://www.youtube.com/watch?v=z4eTjH4zjwE" target="_blank">here</a>.</div><div><div><b>Pros</b>: Ubiquitous.</div><div><b>Cons</b>: Low bandwidth. Still&nbsp;experimental. No hardware kits available. Requires something touching the screen.</div></div><div><h3>Sound</h3></div><div>Use high pitched noise outside the audible range of humans. This is the interface used by <a href="http://hex3.co/" target="_blank">hex3</a>. I haven't found any DIY examples.</div><div><b>Pros:&nbsp;</b>Ubiquitous. Wireless.</div><div><b>Cons: </b>Short range. No DIY documentation.<br /><h3>Magnets</h3>Using the&nbsp;magnetometer (compass) you can detect various powerful&nbsp;magnets. See this <a href="http://blog.makezine.com/2012/10/29/magnetic-appcessories-with-andrea-bianchi/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+makezineonline+%28MAKE%29" target="_blank">article</a>&nbsp;for a great example of using magnets for interaction. Here's a <a href="http://jdesbonnet.blogspot.com/2011/05/arduino-to-android-io-on-cheap-aka-poor.html" target="_blank">blog post</a>&nbsp;of someone using a coil of wire to create a electric magnet to communicate to the device.<br /><b>Pros: </b>Magnetometers in devices are common.<br /><b>Cons: </b>Can only detect one magnet at a time. Unidirectional. Low bandwidth.<br /><h3>Did I miss something? Please comment and I will add it to the list!</h3></div>http://blog.theultimatelabs.com/2012/11/the-ultimate-guide-to-connecting.htmlnoreply@blogger.com (Rob B)7tag:blogger.com,1999:blog-1588601560921313070.post-7182175659196458370Sun, 21 Oct 2012 05:10:00 +00002012-10-20T22:52:04.333-07:00AndroidAppCyborgWatchAndroid Phone Wrist Watch<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-lp0TSWOE9II/UIN7Muqvo0I/AAAAAAAAAKU/EnQsbY8LtY0/s1600/wrist_watch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="http://3.bp.blogspot.com/-lp0TSWOE9II/UIN7Muqvo0I/AAAAAAAAAKU/EnQsbY8LtY0/s640/wrist_watch.jpg" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>Most people have already replaced their wrist watch with their cell phone. <a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.watch" target="_blank">This app</a> allows you to literally use your phone as a wrist watch!<br /><br />There's been a bunch&nbsp;<a href="http://www.engadget.com/tag/bluetooth+watch/" target="_blank">Bluetooth Watches</a>&nbsp;popping up online, which is great, but you can accomplish the same thing with your existing phone or an old phone you have lying around. All you need is an <a href="http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&amp;field-keywords=ipod+armband" target="_blank">ipod armband</a> and this app.<br /><br /><iframe allowfullscreen="allowfullscreen" frameborder="0" height="380" src="http://www.youtube.com/embed/LxUduZR78c0?rel=0" width="640"></iframe> The really cool feature of this app turning the screen on automatically when you look at the watch and turning it back off when your done. You should need to fumble around with the power button to check the time. This is accomplished my monitoring the acclerometer. When the phone is at the write angle it turns on (the angle and threshold is adjustable). Monitoring the acclerometer requires&nbsp;acquiring&nbsp;a partial wake lock.&nbsp;This of course will decrease your phone's battery life, but that's the price you pay for the ultimate watch. To help save the battery, the app will release the wake lock if it detects no movement for a long period (like an hour). &nbsp;Turning the screen on restarts the service.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-tCPNo2lKiW0/UINq73RjNAI/AAAAAAAAAKE/VRWSygqW60k/s1600/watch1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="355" src="http://2.bp.blogspot.com/-tCPNo2lKiW0/UINq73RjNAI/AAAAAAAAAKE/VRWSygqW60k/s640/watch1.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>The date, analog time, and digital time. There's also&nbsp;a chronometer/stop-watch hidden at the bottom. It's activated with a single touch, reset with a long touch.<br /><br />Fitness armbands are the write form factor for this application, but the band may be too long. I bought an iPod armband because my Motorola Defy is about the size of an iPod. I had to shorten the armband.<br /><br />More ideas for the app:<br /><ul><li>Lap timer</li><li>Alarm</li><li>Beep/vibrate each hour</li><li>Pedometer</li><li>World times</li><li>Battery life display</li><li>Better&nbsp;</li></ul><div>Play Link:&nbsp;<a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.watch">https://play.google.com/store/apps/details?id=com.theultimatelabs.watch</a></div>GPL Code:&nbsp;<a href="https://github.com/theUltimateLabs/theUltimateWatch">https://github.com/theUltimateLabs/theUltimateWatch</a>http://blog.theultimatelabs.com/2012/10/android-phone-wrist-watch.htmlnoreply@blogger.com (Rob B)10tag:blogger.com,1999:blog-1588601560921313070.post-961440945161114334Sun, 07 Oct 2012 14:54:00 +00002012-10-07T07:54:54.946-07:00Automatic Android Picture Frame<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-6kpzmnROTdI/UHGTA1HquzI/AAAAAAAAAJ0/baTZCuuPZKY/s1600/family.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/-6kpzmnROTdI/UHGTA1HquzI/AAAAAAAAAJ0/baTZCuuPZKY/s320/family.jpg" width="320" /></a></div><h3>Overview</h3>I wrote a simple App recently and I even took the extra step of publishing it to <a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.frame" target="_blank">play</a>! It's a simple picture frame / screen saver app. It's triggered when the screen turns off. It automatically turns the screen back on and displays your current wallpaper as a screen saver. If you wall paper happens to be one of the several live photo wallpapers then you now have a digital picture frame. It only works when plugged in and can be&nbsp;temporarily&nbsp;disabled by hitting the power button a second time after it starts. I just display the current wallpaper so you can customize it however you'd like.<br /><br />This app is part of my grand vision of&nbsp;ubiquitous&nbsp;android. In other words, this is not&nbsp;intended&nbsp;to be run on your primary device, it should be used on an extra device mounted to a wall or on a end table. I'm also nearly finished with another app along this team: a widget based home intercom.<br /><br />This app is beta at the moment. There's a couple more features I need to add before it can be graduated to the ultimate picture frame. I want to add the ability to place app widgets inside the screen saver. This will allow you to customize what's shown, like a clock,&nbsp;weather, stocks, etc. I also want to add a&nbsp;presence&nbsp;detector using the camera or microphone so it's not on 24/7, instead it would only turn on when&nbsp;someone&nbsp;is around.<br /><br />Play Link:&nbsp;<a href="https://play.google.com/store/apps/details?id=com.theultimatelabs.frame">https://play.google.com/store/apps/details?id=com.theultimatelabs.frame</a><br /><h3>Technical</h3><div>I love this app because the code for it is so simple. First, the only way to detect user inactivity is the SCREEN_OFF broadcast. Seems registering for this in the manifest&nbsp;doesn't&nbsp;work, so I create a service who's only purpose is to register a broadcast receiver for this intent:</div><div><br /></div><pre> Log.v(TAG, "Service Started\n");<br /> IntentFilter filter = new IntentFilter();<br /> filter.addAction(Intent.ACTION_SCREEN_OFF);<br /> filter.addAction(Intent.ACTION_SCREEN_ON);<br /> filter.addAction(Intent.ACTION_POWER_DISCONNECTED);<br /> registerReceiver(new FrameReceiver(), filter);<br /></pre><div><br />In the broadcast reciver when I get a SCREEN_OFF intent and the device is charging I launch the acitivity. The flags passed to the activity are important:<br /><br /><pre> Intent startIntent = new Intent(context, FrameActivity.class);<br /> startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);<br /> startIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);<br /> startIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);<br /> startIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);<br /> startIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);<br /> startIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);<br /> startIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);<br /> startIntent.setAction("start");<br /> context.startActivity(startIntent);</pre><pre></pre><pre></pre>Next the activity needs to set some special layout flags to turn the screen on display the wallpaper:<br /><br /><pre> Window window = getWindow();<br /> window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);<br /> window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);<br /> window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);<br /> window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);<br /> window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);<br /> window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);<br /> if (Build.VERSION.SDK_INT &gt; 11) {<br /> getWindow().getDecorView().setSystemUiVisibility(<br /> View.SYSTEM_UI_FLAG_LOW_PROFILE);<br /> }<br /></pre><br />Finally there's a couple parameters needed in the activity manifest to make the activity translucent and still rotate:<br /><br /><pre> android:screenorientation="sensor"</pre><pre> android:theme="@android:style/Theme.Translucent.NoTitleBar";<br /></pre><br />GPL source:&nbsp;<a href="https://github.com/theUltimateLabs/theUltimateFrame">https://github.com/theUltimateLabs/theUltimateFrame</a></div>http://blog.theultimatelabs.com/2012/10/automatic-android-picture-frame.htmlnoreply@blogger.com (Rob B)0tag:blogger.com,1999:blog-1588601560921313070.post-4061848529335335592Fri, 14 Sep 2012 16:22:00 +00002012-09-14T09:22:09.476-07:00Learning the ABCs with NFCI've been having a lot of fun developing apps for my Nexus 7. It's the best Android development device available today. One of the features I wanted to play with is NFC. I ordered some <a href="http://www.ebay.com/sch/i.html?_nkw=rfid+sticker&amp;_sacat=0&amp;_odkw=nfc+sticker&amp;_osacat=0" target="_blank">small NFC stickers on ebay</a> for ~$1 each in quantities of 10, like this one.<br /><div><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-7COWJSA2oSY/UFFShMtQivI/AAAAAAAAAJU/Xvb7U0TjYoE/s1600/nfc-tag.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-7COWJSA2oSY/UFFShMtQivI/AAAAAAAAAJU/Xvb7U0TjYoE/s1600/nfc-tag.jpg" /></a></div><div><br /><div><br /></div><div>I came up with the idea of using NFC to make interactive an ABC game for the kids. The original plan was to make an ABC blanket, but an easier solution was to use some ABC foam tiles I found at Costco. The concept is simple, embed a tag in each letter, when the letter is scanned with a device an app reads the letter aloud. The hope is this will help the kids learn their ABCs faster than an app alone because they are actually interacting with the physical world.&nbsp;</div><div><br /></div><div>I nice feature of NFC in Android is the ability to map an app to tag so the app is launched automatically, meaning the kid doesn't need to actually launch an app to play. I created a list of basic words for each letter. The app randomly (and sometimes not so randomly) chooses a word from the list for the scanned letter. Rather than take the time to gather an image for each word I use Google Image Search to dynamically show an image for the selected word. I set the "safesearch" and "clipart" options to hopefully keep the images safe for kids. I use&nbsp;Google's text to speech to announce the letter, and spell the word. I animate each letter as it's read. I accomplished the animation by having a bunch of individual text views. In hindsight I could have used rich text formatting for better&nbsp;animation. Next the child is asked to say the word. I used Google's voice to text service to capture the child's voice. If they say the word clear enough for Google to understand they are rewarded with a youtube video (this is their favorite part). Like with the images I try to set the options to keep the videos safe,&nbsp;specifically&nbsp;I set the kids tag.&nbsp;</div><div><br /></div><iframe allowfullscreen="allowfullscreen" frameborder="0" height="480" src="http://www.youtube.com/embed/X-iojwDDG_g?rel=0" width="640"></iframe> <div><br /></div><div>Right now I have a&nbsp;separate&nbsp;app that writes the NFC tags initially, but I working on&nbsp;integrating&nbsp;this into a single app. The app isn't in Google Play yet but the code is available for downloaded from <a href="https://github.com/theUltimateLabs/theUltimateAbcs" target="_blank">my new GitHub page</a>.&nbsp;</div></div>http://blog.theultimatelabs.com/2012/09/learning-abcs-with-nfc.htmlnoreply@blogger.com (Rob B)1tag:blogger.com,1999:blog-1588601560921313070.post-436706377024711089Thu, 19 Jul 2012 14:09:00 +00002012-07-19T07:12:39.982-07:00USB Powered Breakout Board<span style="font-family: inherit;">One of the main challenges I've had in DIY home automation is finding a power supply with the characteristics I need. An ideal power supply would be small,&nbsp;enclosed, and cheap with only wired leads for the input and output. So far I have not found this supply on the market. The cheapest and smallest is certinly the knock-off ipod chargers availble on <a href="http://www.ebay.com/itm/EU-Plug-USB-Power-Home-Wall-Charger-Adapter-for-iPod-Touch-iPhone-4S-4-3GS-3G-/230814525810?pt=LH_DefaultDomain_2&amp;var=&amp;hash=item35bd9e2972#ht_6677wt_1397" target="_blank">ebay</a>&nbsp;and other sites.</span><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-at7ogDfETpI/UAgJ6sMY-1I/AAAAAAAAAH8/d6wvgZHoyrQ/s1600/AX014_2_ALL.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="320" src="http://3.bp.blogspot.com/-at7ogDfETpI/UAgJ6sMY-1I/AAAAAAAAAH8/d6wvgZHoyrQ/s320/AX014_2_ALL.jpg" width="320" /></span></a></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;">One issue with this adapter is the USB output. Using full USB cable would consume a lot of space. It'd be better if the circuit board connected to the adapter directly. I found a&nbsp;<a href="http://www.frank-zhao.com/cache/usbbusinesscard_details.php" target="_blank">blog post by Frank Zhao</a> that described how to shape a circuit board to fit into a USB adapter. He even provides a eagle library. Using this I designed a very simple usb powered breakout board for the ATtiny84 and had it fabricated by <a href="http://www.seeedstudio.com/depot/fusion-pcb-service-p-835.html?cPath=185" target="_blank">SeedStudio</a>.&nbsp;</span></div><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-lCTmyJXOlIM/UAgLyfXUA8I/AAAAAAAAAIE/oB-20v56euo/s1600/IMG_4055.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="http://2.bp.blogspot.com/-lCTmyJXOlIM/UAgLyfXUA8I/AAAAAAAAAIE/oB-20v56euo/s320/IMG_4055.JPG" width="240" /></a><a href="http://1.bp.blogspot.com/-hrNBKT1ur1s/UAgTllwPd2I/AAAAAAAAAI4/_Y58mGQceWI/s1600/breakout.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="257" src="http://1.bp.blogspot.com/-hrNBKT1ur1s/UAgTllwPd2I/AAAAAAAAAI4/_Y58mGQceWI/s320/breakout.png" width="320" /></a><span style="font-family: inherit; margin-left: 1em; margin-right: 1em;"></span></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;">The USB side connects directly into a USB adapter. The two outside pins are 5V &amp; GND, the other pins are not connected in this circuit. Each pin is broken out to one header. The two extra rows on either side are 5V &amp; GND for power external modules.</span></div><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-hEM5GkeHNoA/UAgL3vlQPYI/AAAAAAAAAIM/ZFwfVGqjjUU/s1600/IMG_4056.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="240" src="http://3.bp.blogspot.com/-hEM5GkeHNoA/UAgL3vlQPYI/AAAAAAAAAIM/ZFwfVGqjjUU/s320/IMG_4056.JPG" width="320" /></span></a></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;">Here it is with ATtiny and programming pins soldered on. Notice the solder on the USB pins, this is required since the board isn't quite thick enough on its own.&nbsp;</span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;">I made this specifically for the ATtiny84, but later&nbsp;realized&nbsp;it can accommodate a PIC and MSP430 as well since VCC and GND are on the same pins in the 14 pin&nbsp;packages. I also discovered that a genuine ipod charger actually outputs 3.6V on one of the other USB pins. I have not yet confirmed if the knock-off charges do as well.</span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><b><span style="font-family: inherit;">ATtiny</span></b><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-92i_OiCRqqI/UAgNvtIra6I/AAAAAAAAAIs/4DoQsb54AMQ/s1600/attinyx4.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="130" src="http://1.bp.blogspot.com/-92i_OiCRqqI/UAgNvtIra6I/AAAAAAAAAIs/4DoQsb54AMQ/s320/attinyx4.gif" width="320" /></span></a></div><b><span style="font-family: inherit;">MSP430</span></b><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-JQjcdAmPiEU/UAgNusri69I/AAAAAAAAAIc/_v1QIJPdVuI/s1600/0268.package.jpg-1024x1024.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: inherit;"><img border="0" height="132" src="http://3.bp.blogspot.com/-JQjcdAmPiEU/UAgNusri69I/AAAAAAAAAIc/_v1QIJPdVuI/s320/0268.package.jpg-1024x1024.jpg" width="320" /></span></a></div><div class="separator" style="clear: both; text-align: left;"><b><span style="font-family: inherit;">PIC</span></b></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: inherit; margin-left: 1em; margin-right: 1em;"><a href="http://4.bp.blogspot.com/-A_cc52E9jyM/UAgNvesDVBI/AAAAAAAAAIk/086ofLfqk_E/s1600/PIC16F506-pinout.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="111" src="http://4.bp.blogspot.com/-A_cc52E9jyM/UAgNvesDVBI/AAAAAAAAAIk/086ofLfqk_E/s320/PIC16F506-pinout.jpg" width="320" /></a></span></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;">Now how do I go from either EU or US prongs to wired leads in a safe, easy, cheap and compact way?&nbsp;</span><span style="background-color: white;"><span style="font-family: inherit;">How can I make the circuit board better, perhaps fewer power/gnd pins and more IO pins. I have a few extra boards, so I decided I'll give a free one to anyone with a good suggestion on how to improve this setup. Make a comment below, if I like your suggestion I'll ask you for an address over email then send you a free card. US only, sorry. (BTW, I'll will be out of email range during the&nbsp;</span>coming<span style="font-family: inherit;">&nbsp;week).&nbsp;</span></span></div><div class="separator" style="clear: both; text-align: left;"><span style="background-color: white;"><span style="font-family: inherit;"><br /></span></span></div><span style="background-color: white;"><span style="font-family: inherit;"><b><a href="http://the-ultimate-labs.googlecode.com/files/usbPoweredATtinyBreakout.zip" target="_blank">Eagle Files</a></b></span></span><br /><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><br /></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: inherit;"><br /></span></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div><br /></div>http://blog.theultimatelabs.com/2012/07/usb-powered-breakout-board.htmlnoreply@blogger.com (Rob B)7tag:blogger.com,1999:blog-1588601560921313070.post-4841413207120411716Fri, 13 Jul 2012 13:02:00 +00002012-07-13T20:55:28.394-07:00AndroidHome AutomationUIWidgetsHome Automation UIThere was several comments pointing out how lame the&nbsp;UI for my <a href="http://blog.theultimatelabs.com/2012/07/bluetooth-capacitive-touch-light-switch.html">bluettotoh light switch</a>&nbsp;was. It was just something I threw&nbsp;together&nbsp;if a few minutes to&nbsp;demonstrate a&nbsp;capability. I have actually put some thought into how the UI should really work.<br /><br />Take a look at the <a href="https://www.google.com/search?q=android+home+automation&amp;hl=en&amp;prmd=imvnsa&amp;source=lnms&amp;tbm=isch&amp;sa=X&amp;biw=1066&amp;bih=516&amp;sei=pc30T_7oHOT82gWckJD7Bg#hl=en&amp;tbm=isch&amp;sa=1&amp;q=android+home+automation+app&amp;oq=android+home+automation+app&amp;gs_l=img.3...17419.18115.6.18235.8.6.0.0.0.2.400.698.2-1j0j1.2.0...0.0.w3-n6lgYfKM&amp;pbx=1&amp;bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&amp;fp=b747d0736ceb0959&amp;biw=1066&amp;bih=516" target="_blank">existing home automation apps</a>,&nbsp;most of them are a static grid of buttons. I think the major problem with this approach is&nbsp;customization. Everyone's setup and&nbsp;preferences&nbsp;are so different it is very hard to make an app that fits every home. Instead I think the ultimate home automation UI is a combination of widgets and notifications. This has two major&nbsp;advantages&nbsp;over typical HA apps in my&nbsp;opinion.<br /><ul><li><span style="background-color: white;">Quick access</span></li><ul><li><span style="background-color: white;">You shouldn't have to exit out of your current app, go find the HA app, launch it, and then find your light, click it, then go back to your app</span></li><li><span style="background-color: white;">Instead you should be able to control your light straight from the home screen or notification pull down</span></li></ul><li>Customization</li><ul><li>Don't try to predict how a user want's their controller laid out, let them decide for themselves</li><li>A user can also combine one of the hundereds of existing widgets with the home automation widget on the same screen (e.g. weather or stocks)</li><li>If the API is written well, users can even write and distribute their own home automation UI widgets!</li></ul></ul><div>The way I imagine it working is having the user place one of&nbsp;several&nbsp;types of widgets on the screen, each customizable. For example, a light switch widget would allow the user to customize which lights are triggered, how long they stay on, and would display the current state of the light.</div><div><br /></div><div>I think the notification menu should be used to dynamically display controls for the stuff close to you. For example, if you are in your bedroom the notification menu should have an entry for each light in your bedroom. Geo-locating a phone in a home should be possible if each switch has a bluetooth module inside, like the&nbsp;<a href="http://wiki.linuxmce.org/index.php/Follow_Me" target="_blank">LinuxMCE </a>&nbsp;followme feature.</div><div><br /></div><span style="background-color: white;">Turns out programming widgets is much harder than regular apps because of the way they work and the restrictions on what you can do. </span>Below is a snapshot of what I came up with. It's similar to the Windows Phone scheme. It's the best I could come up without without having to start drawing things in photoshop. The circle in the top left represents the current on/off state.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-StIYozrNhNI/UAAZEJpsxDI/AAAAAAAAAE0/_ImYHRYM-o4/s1600/widget.png" imageanchor="1" style="background-color: white; margin-left: 1em; margin-right: 1em;"><img border="0" height="496" src="http://4.bp.blogspot.com/-StIYozrNhNI/UAAZEJpsxDI/AAAAAAAAAE0/_ImYHRYM-o4/s640/widget.png" width="640" /></a></div><br /><br />As soon as I get a big block of free time I'll finish coding this up.<br /><div><br /></div><br class="Apple-interchange-newline" />http://blog.theultimatelabs.com/2012/07/home-automation-ui.htmlnoreply@blogger.com (Rob B)1tag:blogger.com,1999:blog-1588601560921313070.post-5681437328455843035Tue, 03 Jul 2012 13:29:00 +00002013-01-17T21:46:23.976-08:00AndroidArduinoATtinyBluetoothCapacitive TouchHome AutomationLight SwitchBluetooth + Capacitive Touch Light Switch<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-GuH92ZaKy9I/T_LygrY8fnI/AAAAAAAAACQ/nTh287SMTH8/s1600/1-IMG_3660.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="285" src="http://1.bp.blogspot.com/-GuH92ZaKy9I/T_LygrY8fnI/AAAAAAAAACQ/nTh287SMTH8/s400/1-IMG_3660.JPG" width="400" /></a></div><br />I've been thinking about home automation for some time. My <a href="http://code.google.com/p/the-ultimate-light-switch/" target="_blank">last a approach</a> was to connect an Android tablet directly to the light switch via USB host and an Arduino. I still like this idea, but building FTDI drivers for cheap Android tablets became to much of a headache (<a href="http://www.sparkfun.com/products/10748" target="_blank">IOIO </a>and ADK are too expensive).<br /><br />In the mean time I've started playing around with Bluetooth. I've been surprised by how much the cost of bluetooth modules has decreased. First I used Bluetooth to control my <a href="http://blog.theultimatelabs.com/2012/06/colossal-bluetooth-crane.html" target="_blank">toy crane.</a>&nbsp;Now I've embedded Bluetooth into a light switch.<br /><h3> Disclaimer</h3><span style="font-size: x-small;">Working with high voltage electrical lines is very&nbsp;dangerous&nbsp;and can lead to shock,&nbsp;electrocution, or fire causing serious injury or death. I make no claims, promises, or guarantees about the accuracy, completeness, or adequacy of the contents of this site, and I expressly disclaim liability for errors and omissions in the contents of this site. No warranty of any kind, implied, expressed, or statutory. Use this information at your own risk. etc.</span><br /><h3> Quick Demo</h3><iframe allowfullscreen="" frameborder="0" height="480" src="http://www.youtube.com/embed/zUvN5WG-Peo" width="640"></iframe> <br /><h3> ATtiny + Bluetooth</h3>I started with the Arduino Nano, but decided I could accomplish what I needed with just an ATtiny85. Using the code from <a href="http://hlt.media.mit.edu/?p=1695" target="_blank">MIT High-Low Tech</a>&nbsp;I was easily able to program the ATtiny85 using a regular Arduino. I used the ATtiny supported SoftwareSerial library to&nbsp;communicate&nbsp;to the Bluetooth module.There's no constraint listed on which pins were used for SoftwareSerial, I used 3 &amp; 4. Bluetooth actually works really well for debug output when programming these chips since they don't have USB to serial converters built-in. I was also impressed by the distance on these bluetooth modules (rated at upto 30ft). I was able to control the light switch from anywhere in my house! Who needs WiFi?<br /><h3> Capacitive Touch</h3><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-uaUC2YMMxBY/T_LyEiPe7eI/AAAAAAAAACA/hqXI6ZJ-ZT8/s1600/1-IMG_3637.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://2.bp.blogspot.com/-uaUC2YMMxBY/T_LyEiPe7eI/AAAAAAAAACA/hqXI6ZJ-ZT8/s400/1-IMG_3637.JPG" width="400" /></a></div><div><br /></div>The goal is to control everything in my house wirelessly with my cellphone, so no physical light switches are actually needed. My wife, however, has a hard constraint that there must be a&nbsp;manual&nbsp;way to toggle the light. I really didn't want to drill a hole and mount a silly push button. Instead I discovered how easy it is to add capacitive touch to projects with just <a href="http://www.arduino.cc/playground/Main/CapSense" target="_blank">tinfoil and&nbsp;resistors</a>. I covered the back of the faceplate with tinfoil and used two 4.7 Mohm resistors between two pins on the ATtiny85. The CapSense library by Paul Bagder was written for ATMega and didn't work out of the box for ATtiny85, so I used the concepts and structure from the library and wrote it in pure Arduino code. It's not as accurate, but it works.<br /><h3> Android</h3><div>The current App is really simple, but I plan to do a lot more. Right now it will just send a toggle or calibrate command to the light switch. The calibrate command just tells the ATtiny85 to reset the baseline for the capacitive touch sensing. It's my understanding that upto 7 bluetooth modules can be connected to a bluetooth master at one time but I don't have any extra bluetooth modules available to test how well this is supported on Android. If so, then you'll need just a 7-to-1 android tablet to bluetooth actuator/sensor ratio in order to control your whole house. Fortunately the perfect Android tablet for this setup was anouced a few days ago: <a href="http://www.google.com/nexus/#/7" target="_blank">The Nexus 7</a>.</div><h3> Housing</h3><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-yOrmAP7NU7s/T_LyLUVUYwI/AAAAAAAAACI/cFBOXvPwI98/s1600/IMG_3646.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://2.bp.blogspot.com/-yOrmAP7NU7s/T_LyLUVUYwI/AAAAAAAAACI/cFBOXvPwI98/s400/IMG_3646.JPG" width="400" /></a></div><div><br /></div><div><span style="background-color: white;">Size and power is definitely&nbsp;the most difficult part of this project. There just isn't much space inside a single gang box.&nbsp;</span>The ATtiny is mounted on a mini breadboard and connected to the relay with jumper wires. I found an old 5V power supply and replaced the prongs and usb port with wires. There&nbsp;doesn't&nbsp;seem to exist a small&nbsp;enclosed&nbsp;power supply with wire leads instead of prongs? I am working on a PCB board to replace the breadboard.<br /><br /></div><h3> Bill of material:</h3><div><ol><li><a href="http://www.ebay.com/itm/5x-8-bit-Microcontroller-ATTINY85-20PU-AC3519-/320903421637?pt=LH_DefaultDomain_0&amp;hash=item4ab7559ec5#ht_676wt_1166" target="_blank">ATtiny85 $2.00</a></li><li><a href="http://dx.com/p/jy-mcu-arduino-bluetooth-wireless-serial-port-module-104299" target="_blank">Bluetooth Module $8.60</a></li><li><a href="http://dx.com/p/170-tie-points-prototype-solderless-breadboard-black-118821?item=1" target="_blank">Breadboard $2.20</a></li><li><a href="http://dx.com/p/ultra-mini-1000ma-usb-power-adapter-charger-100-240v-eu-plug-29417?item=20" target="_blank">Power Supply $2.20</a>&nbsp;(not the exact supply used this time)</li><li><a href="http://dx.com/p/arduino-5v-relay-module-blue-black-121354?item=1" target="_blank">Relay $3.10</a></li><li>Wires &amp; Resistors ~$1.00</li></ol>Total = $19.10</div><div><br /></div><div>Some alternatives:</div><div><ul><li><span style="background-color: white;"><a href="http://www.kickstarter.com/projects/453951341/sensordrone-the-6th-sense-of-your-smartphoneand-be" target="_blank">Sensdrone $99+</a></span></li><li><a href="http://www.kickstarter.com/projects/108684420/node-a-modular-handheld-powerhouse-of-sensors?ref=live" target="_blank">NODE $175+</a></li><li><a href="http://www.kickstarter.com/projects/rowdyrobot/tod-connect-real-world-actions-to-mobile-devices-a?ref=search" target="_blank">tod $32+</a></li><li><a href="http://www.amazon.com/GE-Z-Wave-Wireless-Lighting-Control/dp/B0035YRCR2" target="_blank">Z-Wave Switch $40</a></li><li><a href="http://www.amazon.com/Smarthome-2466SW-ToggleLinc-INSTEON-Non-Dimming/dp/B003ICY0M6" target="_blank">Insteon Switch $46</a></li><li><a href="http://www.zsmartcompany.com/products.htm" target="_blank">Smart Cord $39</a></li><li><a href="http://electricimp.com/" target="_blank">Electric Imp $25+</a></li></ul></div><h3> Code</h3><pre>#include &lt;SoftwareSerial.h&gt;;<br />SoftwareSerial Bluetooth(3, 4); <br />#define RELAY_PIN 2<br /><br /><br />int baseline;<br />byte touchState;<br /><br />void setup() {<br /> Bluetooth.begin(9600);<br /> pinMode(RELAY_PIN,OUTPUT);<br /> touchState = 0;<br /> delay(1000);<br /> baseline = readCapacitivePinAvg(1,0,50);<br />}<br /><br />uint8_t readCapacitivePinAvg(int sendPin, int receivePin, int samples) {<br /> unsigned long total = 0;<br /> for(int i=0; i&lt;samples; i++) {<br /> total += readCapacitivePin(sendPin, receivePin);<br /> delay(1);<br /> }<br /> return total/samples;<br />}<br /><br />uint8_t readCapacitivePin(int sendPin, int receivePin){<br /> uint8_t count = 0;<br /> <br /> pinMode(sendPin,OUTPUT);<br /> digitalWrite(sendPin,LOW);// set Send Pin Register low<br /> <br /> pinMode(receivePin,INPUT); // set receivePin to input<br /> digitalWrite(receivePin,LOW); // make sure pullups are off <br /> pinMode(receivePin,OUTPUT); // set pin to OUTPUT - pin is now LOW AND OUTPUT<br /> pinMode(receivePin,INPUT); // set pin to INPUT<br /> <br /> digitalWrite(sendPin,HIGH); <br /> <br /> while(digitalRead(receivePin)==LOW) {<br /> count++;<br /> }<br /> <br />// set receive pin HIGH briefly to charge up fully - because the while loop above will exit when pin is ~ 2.5V <br /> digitalWrite(receivePin,HIGH);<br /> pinMode(receivePin,OUTPUT);<br /> pinMode(receivePin,INPUT);<br /> digitalWrite(receivePin,LOW);<br /> <br /> digitalWrite(sendPin,LOW);<br /><br /> while(digitalRead(receivePin)==HIGH) {<br /> count++;<br /> }<br /><br /> <br /> return count;<br /> <br />}<br /><br /><br />void loop() {<br /> if (Bluetooth.available()) {<br /> int cmd = Bluetooth.read(); <br /> //Bluetooth.println("COMMAND");<br /> switch(cmd) {<br /> case '1':<br /> digitalWrite(RELAY_PIN,HIGH); <br /> Bluetooth.println('1');<br /> break;<br /> case '0':<br /> digitalWrite(RELAY_PIN,LOW);<br /> Bluetooth.println('0');<br /> break;<br /> case 'T':<br /> digitalWrite(RELAY_PIN,digitalRead(RELAY_PIN)^1); <br /> case 'S':<br /> Bluetooth.println(digitalRead(RELAY_PIN) ? '1' : '0');<br /> break;<br /> case '*':<br /> Bluetooth.println("*");<br /> break;<br /> case 'C':<br /> baseline = readCapacitivePinAvg(1,0,50);<br /> Bluetooth.println('C');<br /> break;<br /> default:<br /> break;<br /> }<br /> }<br /> <br /> int touch = readCapacitivePinAvg(1,0,30)-baseline;<br /> if (touch &amp;rt;= 4 &amp;&amp; touchState == 0) {<br /> //Bluetooth.println("TOUCH");<br /> digitalWrite(RELAY_PIN,digitalRead(RELAY_PIN)^1);<br /> Bluetooth.println(digitalRead(RELAY_PIN) ? '1' : '0');<br /> touchState = 1;<br /> }<br /> else if (touch &lt;=2) {<br /> touchState = 0;<br /> }<br /> <br /> //Bluetooth.println();<br /> //Bluetooth.println(baseline);<br />}</pre><div><br />The Android code isn't&nbsp;interesting&nbsp;enough to post.</div><h3> Future Work</h3><div><ul><li><span style="background-color: white;">I'm looking at ways to bring the price down even further. I'm focused on price because I want to replace every light switch in my house</span></li><li>Mesh networking between bluetooth switches and android tablets</li><li>Add other sensors: motion, light and temp</li></ul><h3>UPDATE:&nbsp;</h3><div>The light switch has been running reliably for months now.&nbsp;</div><div>By popular demand I have posted the android source code for this project here:&nbsp;<a href="https://github.com/theUltimateLabs/BlueSwitch">https://github.com/theUltimateLabs/BlueSwitch</a></div><div>I am not proud of this code and don't recommend using it beyond &nbsp;using it as a&nbsp;reference.&nbsp;I have started another project to write a good framework and UI for this, but it's not ready for release yet.&nbsp;</div><br /></div>http://blog.theultimatelabs.com/2012/07/bluetooth-capacitive-touch-light-switch.htmlnoreply@blogger.com (Rob B)40tag:blogger.com,1999:blog-1588601560921313070.post-5527111128504264499Tue, 26 Jun 2012 14:33:00 +00002012-06-26T07:36:47.435-07:00Colossal Bluetooth Crane<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-4V77CdtRs14/T-m9Q3p0hPI/AAAAAAAAABg/WS1aa783dl4/s1600/IMG_3591.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://3.bp.blogspot.com/-4V77CdtRs14/T-m9Q3p0hPI/AAAAAAAAABg/WS1aa783dl4/s400/IMG_3591.JPG" width="300" /></a></div>I inherited a 1984&nbsp;<span style="background-color: white;">"Digger Dan's Construction Co. Colossal Crane"</span><span style="background-color: white;">&nbsp;from my grandfather called. It has three axis of movement: rotate, lower/raise hook, extend/contract the boom. It used a really basic control&nbsp;mechanism. Basically a battery pack with 6 buttons that each complete a different circuit for each direction. It wasn't working very well so I decided to&nbsp;improve&nbsp;it. I thought it would be cool to control it with a smartphone.</span><br /><h4> BOM</h4><ul><li><span style="background-color: white;">Arduino Nano</span></li><li><span style="background-color: white;">2 x dual motor drivers (</span><a href="http://www.ebay.com/itm/L298N-Dual-H-Bridge-IC-Stepper-Motor-Driver-Controller-Board-Module-for-Arduino-/300700161104?pt=LH_DefaultDomain_2&amp;hash=item4603205450#ht_3951wt_1166" target="_blank">like this one</a>)</li><li>Bluetooth Module (<a href="http://www.dealextreme.com/p/jy-mcu-arduino-bluetooth-wireless-serial-port-module-104299?item=4" target="_blank">this one to be exact</a>)</li><li>Mini Breadboard</li><li>Wires</li><li>3 x AA batteries</li></ul><h4> Hardware Setup</h4><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-1Ofb3OdWCj8/T-m85zTKeOI/AAAAAAAAABY/lN810Fgq9I8/s1600/IMG_3573.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-1Ofb3OdWCj8/T-m85zTKeOI/AAAAAAAAABY/lN810Fgq9I8/s320/IMG_3573.JPG" width="320" /></a></div><a href="http://1.bp.blogspot.com/-ldCUVCsSeFI/T-m-v9VJ8sI/AAAAAAAAABw/DvYud2iFJpc/s1600/IMG_3575.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-ldCUVCsSeFI/T-m-v9VJ8sI/AAAAAAAAABw/DvYud2iFJpc/s320/IMG_3575.JPG" width="320" /></a><br /><div>Hardware setup was pretty straight forward. Just soldered the 3 of the 4 motor drivers to the 3 motors in the crane. Each drivers requires two DO pins, one output for each direction. I also added a capacitor to balance the current draw.&nbsp;</div><h4> Bluetooth</h4><div><span style="background-color: white;">The tricky part was getting the bluetooth module working.&nbsp;</span><span style="background-color: white;">The price on these modules have dropped&nbsp;</span><span style="background-color: white;">dramatically</span><span style="background-color: white;">&nbsp;opening up a lot of cool wireless&nbsp;</span><span style="background-color: white;">applications</span><span style="background-color: white;">.&nbsp;</span><span style="background-color: white;">This is the first time I've worked with these bluetooth modules though. First thing you need to figure out is what baudrate your module is running at. You may see a bunch of these bluetooth modules online that all look the same, but they probably have different firmwares. Speciffically HC-03, HC-05, or HC-06 (see&nbsp;</span><a href="http://byron76.blogspot.com/2012/01/draft-byrons-programmer-details.html" style="background-color: white;">http://byron76.blogspot.com/2012/01/draft-byrons-programmer-details.html</a>). Turns out the JY-MCU from DX has the Linvor or HC-06 firmware, which is probably the most limited firmware. It defaults to 9600 8N1. It was suggested somewhere to connect the module to the Rx-Tx pins on the Arduino. This works, but is really annoying since you need to disconnect the module every time you want to reprogram the Arduino. Instead use the code&nbsp;referenced&nbsp;<a href="http://arduino.cc/hu/Reference/SoftwareSerial" target="_blank">here&nbsp;</a>and connect the module to pins 10 &amp; 11. If it doesn't work there's a few things you can do to troubleshoot:<br /><br /><ul><li>Change the newline format in the Arduino serial monitor, or even better use python to read-write to the serial port</li><li>Try different baud rates</li><li>Make sure the Rx of the module is connected to the virtual Tx pin of the Arduino (eg. pin 11) and vice versa.&nbsp;</li><li>Try a different AT command set</li></ul><h4> User Interface&nbsp;</h4><div>After I got that figured out I wrote the simplest Android App I could to control the motors. Each button sends a letter (u,d,l,r,f,b) corresponding to a direction and the Arduino simply activates the corresponding motor direction for a short period.&nbsp;</div><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-geukXCvYQHI/T-m9Yra_bQI/AAAAAAAAABo/WeUjTkDbhAQ/s1600/IMG_3563.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-geukXCvYQHI/T-m9Yra_bQI/AAAAAAAAABo/WeUjTkDbhAQ/s320/IMG_3563.JPG" width="320" /></a></div><div><br /></div><div>I'd really like to improve the user interface to use the accelerometer and multitouch to control the crane.</div><h4> Demo</h4><div><div class="separator" style="clear: both; text-align: center;"><object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/Vsgt4EPCRjk/0.jpg"><param name="movie" value="http://www.youtube.com/v/Vsgt4EPCRjk?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="http://www.youtube.com/v/Vsgt4EPCRjk?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div><br /></div><h3> Code</h3><h4> Arduino</h4><pre>#include <softwareserial.h><br />SoftwareSerial Bluetooth(10, 11); <br /><br />void setup() {<br /> Serial.begin(9600);<br /> Bluetooth.begin(9600);<br /> pinMode(13,OUTPUT);<br /> for(int i=2; i&lt;=7; i++) {<br /> pinMode(i,OUTPUT);<br /> digitalWrite(i,LOW);<br /> }<br />}<br /><br />void move(int pin) {<br /> Serial.print("move");<br /> digitalWrite(pin,HIGH);<br /> delay(333);<br /> digitalWrite(pin,LOW);<br />}<br /><br />void loop() {<br /> int dir = Bluetooth.read();<br /> if (dir != -1) {<br /> Serial.write(dir);<br /> <br /> switch(dir) {<br /> case 'L':<br /> move(2);<br /> break;<br /> case 'R':<br /> move(3);<br /> break;<br /> case 'U':<br /> move(4); <br /> break;<br /> case 'D':<br /> move(5); <br /> break;<br /> case 'F':<br /> move(6); <br /> break;<br /> case 'B':<br /> move(7); <br /> break;<br /> default:<br /> Serial.print("unknown direction");<br /> }<br /> }<br />}</softwareserial.h></pre><h4> Android</h4><pre>package com.theultimatelabs;<br /><br />import java.io.IOException;<br />import java.io.OutputStream;<br />import java.util.ArrayList;<br />import java.util.List;<br />import java.util.Set;<br />import java.util.UUID;<br /><br />import android.app.Activity;<br />import android.app.AlertDialog;<br />import android.bluetooth.BluetoothAdapter;<br />import android.bluetooth.BluetoothDevice;<br />import android.bluetooth.BluetoothSocket;<br />import android.content.BroadcastReceiver;<br />import android.content.Context;<br />import android.content.DialogInterface;<br />import android.content.Intent;<br />import android.content.IntentFilter;<br />import android.os.Bundle;<br />import android.util.Log;<br />import android.view.View;<br />import android.view.View.OnClickListener;<br /><br />public class TheUltimateCraneActivity extends Activity {<br /> private static final int REQUEST_ENABLE_BT = 5;<br /> private static final String TAG = "TheUltimateCraneActivity";<br /> private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");<br /> private BluetoothDevice mBluetoothDevice;<br /> private BluetoothSocket mBluetoothSocket;<br /> private OutputStream mBluetoothOutputStream;<br /> private Set<bluetoothdevice> mPairedDevices;<br /> <br /> /** Called when the activity is first created. */<br /> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);<br /> <br /> <br /> BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();<br /> if (mBluetoothAdapter == null) {<br /> // Device does not support Bluetooth<br /> }<br /> <br /> if (!mBluetoothAdapter.isEnabled()) {<br /> Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);<br /> startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);<br /> }<br /> <br /> mPairedDevices = mBluetoothAdapter.getBondedDevices();<br /> // If there are paired devices<br /> if (mPairedDevices.size() &gt; 0) {<br /> List<string> pairdDeviceDescriptions = new ArrayList<string>();<br /> // Loop through paired devices<br /> for (BluetoothDevice device : mPairedDevices) {<br /> // Add the name and address to an array adapter to show in a ListView<br /> pairdDeviceDescriptions.add(device.getName() + "\n" + device.getAddress());<br /> }<br /> <br /> AlertDialog.Builder builder = new AlertDialog.Builder(this);<br /> builder.setTitle("Make your selection");<br /> builder.setItems(pairdDeviceDescriptions.toArray(new CharSequence[pairdDeviceDescriptions.size()]), new DialogInterface.OnClickListener() {<br /> public void onClick(DialogInterface dialog, int item) {<br /> Log.v(TAG,String.format("picked %d", item));<br /> mBluetoothDevice = (BluetoothDevice)mPairedDevices.toArray()[item];<br /> try {<br /> Log.v(TAG,"creating socket");<br /> mBluetoothSocket = mBluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID);<br /> Log.v(TAG,"connecting");<br /> mBluetoothSocket.connect();<br /> Log.v(TAG,"Get output stream");<br /> mBluetoothOutputStream = mBluetoothSocket.getOutputStream(); <br /> mBluetoothOutputStream.write(new String("*").getBytes());<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /> AlertDialog alert = builder.create();<br /> alert.show();<br /> <br /> }<br /> <br /> <br /> this.findViewById(R.id.ButtonBack).setOnClickListener(new OnClickListener() {<br /> public void onClick(View v) {<br /> try {<br /> Log.v(TAG,"BACK");<br /> mBluetoothOutputStream.write((int)'B');<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /> <br /> this.findViewById(R.id.ButtonForward).setOnClickListener(new OnClickListener() {<br /> public void onClick(View v) {<br /> try {<br /> Log.v(TAG,"FORWARD");<br /> mBluetoothOutputStream.write((int)'F');<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /> <br /> this.findViewById(R.id.ButtonLeft).setOnClickListener(new OnClickListener() {<br /> public void onClick(View v) {<br /> try {<br /> Log.v(TAG,"LEFT");<br /> mBluetoothOutputStream.write((int)'L');<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /> <br /> this.findViewById(R.id.ButtonRight).setOnClickListener(new OnClickListener() {<br /> public void onClick(View v) {<br /> try {<br /> Log.v(TAG,"RIGHT");<br /> mBluetoothOutputStream.write((int)'R');<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /><br /> <br /> this.findViewById(R.id.ButtonUp).setOnClickListener(new OnClickListener() {<br /> public void onClick(View v) {<br /> try {<br /> Log.v(TAG,"UP");<br /> mBluetoothOutputStream.write((int)'D');<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /> <br /> this.findViewById(R.id.ButtonDown).setOnClickListener(new OnClickListener() {<br /> public void onClick(View v) {<br /> try {<br /> Log.v(TAG,"DOWN");<br /> mBluetoothOutputStream.write((int)'U');<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> }<br /> }<br /> });<br /> <br /> }<br /> <br /> <br /> <br />}<br /></string></string></bluetoothdevice></pre><div class="separator" style="clear: both; text-align: center;"></div><br /></div>http://blog.theultimatelabs.com/2012/06/colossal-bluetooth-crane.htmlnoreply@blogger.com (Rob B)3tag:blogger.com,1999:blog-1588601560921313070.post-6139968959822802670Fri, 15 Jun 2012 16:08:00 +00002013-01-17T21:12:05.752-08:00AndroidArduinoLightSerialTabletTouch ScreenTwo Way Serial Interface Using a Touch ScreenUPDATE: I've had a couple readers point out some other related projects that pre-date my proof of concept:.&nbsp;From&nbsp;<a href="http://www.youtube.com/watch?v=z4eTjH4zjwE">Genoil</a>.&nbsp;From <a href="http://portfolio.spike5000.com/?p=67">Mike</a>.<br /><div><br /></div>I found some time to update the touch <a href="http://blog.theultimatelabs.com/2012/05/triggering-capacitive-touch-screen-with.html" target="_blank">screen interface project</a>. I wanted to show that it is possible to enable full two way communication using just the screen.<br /><h3> Physical Interfaces</h3>For&nbsp;communication&nbsp;from the device to the Arduino I'm flashing light on the screen and a photoresitor to detect the frequency. A photodiode would work better, but a photoresistor is all that I had on hand. This idea has been demostrated elswhere, like with the recently announced <a href="http://microcontroller%20to%20tablet%20interface/" target="_blank">electric imp</a>, which looks really&nbsp;promising&nbsp;BTW.<br /><br />For communication from the Arduino to the Android tablet I'm using a relay to vary the&nbsp;capacitance&nbsp;of a&nbsp;aluminum&nbsp;foil taped to the screen. In the previous version I was just connecting the wire directly to the Arduino and changing it from input to output. While this worked, it was not reliable. A relay allows me to float the foil or pull it to ground,&nbsp;effectively&nbsp;changing the&nbsp;capacitance. This is much more reliable, but requires a bulky relay. I think with some more experimentation I'll be able to find a solid sate solution.<br /><h3> Protocol</h3><div>The protocol I ended up using in both directions was pulse width of the signal. A double wide pulse width is a 1 and a single wide pulse width is a 0. Both the high (touch down or light on) and low pulse (touch up or light off) of the signal can be used to transmit a bit. A start bit is also used to start the transmission. A new byte is marked by a low signal for at least 4 pulse widths. This results in an average transmission rate of: 8(1.5*base_pulse_width)+(1+5)base_pulse_width&nbsp;bytes per second. So if the base_pulse_width = 60 milliseconds, then the average transmission rate is ~1byte/second.</div><h3> Demo</h3><div>I wrote an Android app to demo this concept. As each character is entered into the text box it is transmitted to the Arduino by flashing a box on the screen. The arduino inverts the case and sends it back by simulating touches in the same box. The app prints the response int he other box.</div><div class="separator" style="clear: both; text-align: center;"><object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/hCY8yCbdEK0/0.jpg" height="266" width="320"><param name="movie" value="http://www.youtube.com/v/hCY8yCbdEK0?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="http://www.youtube.com/v/hCY8yCbdEK0?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div><h3> Code</h3><h4> Sending a byte from the Arduino:</h4><pre>void sendByte(byte B) {<br /> digitalWrite(RELAY_PIN,HIGH);<br /> delay(DELAY);<br /> digitalWrite(RELAY_PIN,LOW);<br /> <br /> for(int i=0; i&lt;8; i+=2) {<br /> <br /> boolean b = ((B&gt;&gt;i) &amp; 0x1) != 0;<br /> if(!b) delay(2*DELAY);<br /> else delay(DELAY);<br /> digitalWrite(RELAY_PIN,HIGH);<br /> <br /> b = ((B&gt;&gt;(i+1)) &amp; 0x1) != 0;<br /> if(b) delay(2*DELAY);<br /> else delay(DELAY);<br /> digitalWrite(RELAY_PIN,LOW);<br /> }<br /> delay(4*DELAY);<br />}</pre><h4> Receiving a byte on the Arduino:</h4><pre>void loop() {<br /> <br /><br /> //Serial.println(analogRead(PHOTOCELL_PIN));<br /> switch(state) {<br /> <br /> case DARK:<br /> if (analogRead(PHOTOCELL_PIN)&gt;THRESHOLD) {<br /> state = TRANSITION_TO_LIGHT;<br /> transitionStart = millis();<br /> }<br /> else if (millis() - darkStart &gt; 3*DELAY) {<br /> if (i != -1) {<br /> Serial.println("ERROR, to few bits");<br /> Serial.println(millis() - darkStart);<br /> Serial.println(i);<br /> i = -1;<br /> x = 0;<br /> }<br /> } <br /> break;<br /> <br /> case TRANSITION_TO_LIGHT:<br /> if (analogRead(PHOTOCELL_PIN)<threshold else="" if="" millis="millis" state="DARK;" transitionstart="">qDELAY) {<br /> state = LIGHT;<br /> lightStart = transitionStart;<br /> unsigned long period = lightStart - darkStart;<br /> Serial.print("DARK ");<br /> Serial.println(period);<br /> <br /> if(period &lt; DELAY + hDELAY) {<br /> x |= 1 &lt;&lt; i++;<br /> Serial.println(1);<br /> }<br /> else if (period &lt; 3*DELAY) {<br /> x |= 0 &lt;&lt; i++;<br /> Serial.println(0);<br /> } <br /> if (i==8) {<br /> //Serial.println(x);<br /> Serial.println((char)x);<br /> sendByte(x^0x20);<br /> x = 0;<br /> i = -1;<br /> }<br /> <br /> }<br /> break;<br /> <br /> case LIGHT:<br /> if (analogRead(PHOTOCELL_PIN)<threshold analogread="analogread" break="break" case="" if="" photocell_pin="photocell_pin" state="TRANSITION_TO_DARK;" transition_to_dark:="" transitionstart="millis();">THRESHOLD) {<br /> state = LIGHT;<br /> }<br /> else if (millis()-transitionStart&gt;qDELAY) {<br /> state = DARK;<br /> darkStart = transitionStart;<br /> unsigned long period = darkStart - lightStart;<br /> Serial.print("LIGHT ");<br /> Serial.println(period);<br /> if(i == -1) {<br /> i++;<br /> //Serial.println("Start bit");<br /> }<br /> else if(period &lt; DELAY + hDELAY) {<br /> x |= 0 &lt;&lt; i++;<br /> Serial.println(0);<br /> }<br /> else if (period &lt; 3*DELAY) {<br /> x |= 1 &lt;&lt; i++;<br /> Serial.println(1);<br /> } <br /> if (i==8) {<br /> //Serial.println(x);<br /> Serial.println((char)x);<br /> Serial.println(x);<br /> sendByte(x^0x20);<br /> x = 0;<br /> i = -1;<br /> }<br /> }<br /> break;<br /> <br /> default:<br /> Serial.println("ERROR, unexpected state");<br /> }<br />}</threshold></threshold></pre><h4> Send bytes from Android:</h4><pre> private class BlinkMessage extends AsyncTask&lt;String, Integer, Void&amp;rt {<br /><br /> protected void onProgressUpdate (Integer... values) {<br /> Integer color = values[0];<br /> theButton.setBackgroundColor(color);<br /> }<br /> <br /> protected void delay(long millis) {<br /> try {<br /> Thread.sleep(millis);<br /> } catch (InterruptedException e) {<br /> e.printStackTrace();<br /> }<br /> }<br /> <br /> protected void sendByte(byte B) {<br /> <br /> //start bit<br /> publishProgress(Color.WHITE);<br /> delay(2*DELAY);<br /> publishProgress(Color.BLACK);<br /> <br /> for(int i=0; i&lt;8; i+=2) {<br /> <br /> Boolean b = ((B&amp;rt&amp;rti) &amp; 0x1) != 0; <br /> Log.v(TAG,b.toString());<br /> if(!b) delay(2*DELAY);<br /> else delay(DELAY);<br /> publishProgress(Color.WHITE);<br /> <br /> b = ((B&amp;rt&amp;rt(i+1)) &amp; 0x1) != 0;<br /> Log.v(TAG,b.toString());<br /> if(b) delay(2*DELAY);<br /> else delay(DELAY);<br /> publishProgress(Color.BLACK);<br /><br /> }<br /> <br /> delay(DELAY*3);<br /> <br /> }<br /> <br /> protected Void doInBackground(String... messages) {<br /> String message = messages[0];<br /> Log.v(TAG,"doInbackground");<br /> for (int i=0; i&lt;message.length(); i++) {<br /> Byte B = (byte) message.charAt(i);<br /> sendByte((byte)B);<br /> }<br /> return null;<br /> <br /> }<br /> }</pre><h4> Receiving a byte on Android:</h4><pre> final private OnTouchListener touch = new OnTouchListener() {<br /> private long upTime = 0;<br /> private int i = -1;<br /> private byte x = 0;<br /> public boolean onTouch(View v, MotionEvent event) {<br /> long period;<br /> //Log.v(TAG,String.format("action:%d",event.getActionMasked()));<br /> switch(event.getActionMasked()) {<br /> case MotionEvent.ACTION_DOWN: <br /> period = event.getEventTime() - upTime;<br /> //Log.v(TAG,String.format("up period:%d", period));<br /><br /> if(period &lt; DELAY + hDELAY) {<br /> x |= 1 &lt;&lt; i++;<br /> //Log.v(TAG,"1");<br /> }<br /> else if (period &lt; 3*DELAY) {<br /> x |= 0 &lt;&lt; i++;<br /> //Log.v(TAG,"0");<br /> }<br /> else {<br /> if (i&gt;-1) {<br /> Log.v(TAG,"ERROR");<br /> x = 0;<br /> i = -1;<br /> }<br /> }<br /> if (i==8) {<br /> //Serial.println(x);<br /> arduinoOutput.append(new Character((char) x).toString()); <br /> x = 0;<br /> i = -1;<br /> }<br /> <br /> break;<br /> case MotionEvent.ACTION_MOVE:<br /> //Log.v(TAG,"----MOVE----");<br /> break;<br /> case MotionEvent.ACTION_UP:<br /> upTime = event.getEventTime(); <br /> period = upTime - event.getDownTime();<br /> //Log.v(TAG,String.format("down period:%d", period));<br /> if(i == -1) {<br /> Log.v(TAG,"Start bit");<br /> i++;<br /> }<br /> else if(period &lt; DELAY + hDELAY) {<br /> x |= 0 &lt;&lt; i++;<br /> //Log.v(TAG,"0");<br /> }<br /> else if (period &lt; 3*DELAY) {<br /> x |= 1 &lt;&lt; i++;<br /> //Log.v(TAG,"1");<br /> } <br /> else {<br /> if (i&gt;-1) {<br /> Log.v(TAG,"ERROR");<br /> x = 0;<br /> i = -1;<br /> }<br /> }<br /> if (i==8) {<br /> //Serial.println(x);<br /> arduinoOutput.append(new Character((char) x).toString()); <br /> x = 0;<br /> i = -1;<br /> }<br /> <br /> break;<br /> default:<br /> Log.v(TAG,"UNKNOWN");<br /> break;<br /> }<br /> return false;<br /> } <br /> <br /> };<br /></pre>http://blog.theultimatelabs.com/2012/06/two-way-serial-interface-using-touch.htmlnoreply@blogger.com (Rob B)13tag:blogger.com,1999:blog-1588601560921313070.post-7621778536647962287Fri, 04 May 2012 13:02:00 +00002012-07-04T05:37:42.686-07:00ArduinoiPadSerialTabletTouch ScreenTriggering a Capacitive Touch Screen with an ArduinoOne of my goals is to leverage inexpensive Android tablets in my projects. The primary difficulty is getting the tablet to communicate with a&nbsp;microcontroller. I've mostly focused on getting the right drivers loaded on the tablets so they can be a USB host, like with the&nbsp;<a href="http://theultimatelightswitch.com/">The Ultimate Light Switch</a>&nbsp;project.<br /><br />The other day I saw a <a href="http://www.engadget.com/2012/04/24/mit-media-lab-droplet-stackar-hands-on/" target="_blank">video on Engadget </a>&nbsp;from MIT Media labs that inspired me to&nbsp;experiment&nbsp;with another way to interface with tablets. The video shows that light can be used as a channel from tablet to microcontroller. This should be possible with just a simple photo diode or&nbsp;photoresistor pressed against the screen. On the tablet you just need to flash that portion of the screen white and black.<br /><br />The video also gave me the idea of simulating touches on the screen. This should provide a very low speed&nbsp;communication&nbsp;channel from microcontroller to tablet. I know capacitive touch screens work by detecting changes in the capacitance of the screen. In other words your body acts&nbsp;as a big conductive plate. I found <a href="http://youtu.be/gSifTiR_e2E" target="_blank">this video</a> on YouTube of someone able to simulate a touch using just that, a big conductive brass plate.<br /><br />First thing I discovered is the surface area of the conductor touching the screen must be large enough. This can be tested by touching the screen with a wire while you hold the other end. It doesn't work. Using a flat piece of aluminum foil does. So I taped a piece of foil to the screen (make sure it's flat) and connected the other end to a pin on the arduino through a wire. I was able to get this to work by switching the pin from a floating input (no pullup) to a grounded output.<br /><br /><pre>void setup() {<br /> digitalWrite(2,LOW);<br />}<br /><br />void loop() {<br /> <br /> pinMode(2, INPUT);<br /> delay(500);<br /> <br /> pinMode(2, OUTPUT);<br /> delay(500);<br /> <br />}</pre><div class="separator" style="clear: both; text-align: center;"><br /></div><div style="text-align: center;"><object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/JDgDMBquBw0/0.jpg" height="266" width="320"><param name="movie" value="http://www.youtube.com/v/JDgDMBquBw0?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" /> <param name="bgcolor" value="#FFFFFF" /> <embed width="320" height="266" src="http://www.youtube.com/v/JDgDMBquBw0?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash"></embed></object></div><div class="separator" style="clear: both; text-align: center;"><br /></div>As you can see in the video it works, but in reality it was very fragile. I think some additional&nbsp;circuitry&nbsp;is needed to make this more reliable.&nbsp;Fortunately the other touches are still registered while this is connected. I also tried two pieces of foil for multitouch, but that wasn't reliable at all.<br /><br />UPDATED:&nbsp;<a href="http://blog.theultimatelabs.com/2012/06/two-way-serial-interface-using-touch.html">Two Way Serial Interface Using a Touch Screen</a><br /><br /><br />http://blog.theultimatelabs.com/2012/05/triggering-capacitive-touch-screen-with.htmlnoreply@blogger.com (Rob B)7tag:blogger.com,1999:blog-1588601560921313070.post-8266861850755376507Fri, 04 May 2012 12:14:00 +00002012-05-04T05:14:55.852-07:00Introduction<br />Welcome to theUltimateLabs. The primary purpose of this blog is to provide me a place to share details about the projects on working on, and hopefully engage others with similar&nbsp;interests.<br /><br />I love technology and I believe it enables&nbsp;incredible things, but IMHO technology could be doing much more. Companies and society are slow to adapt new technology, and when they finally do it is usually expensive and closed.<br /><br />My approach is to hack&nbsp;together&nbsp;existing inexpensive technologies to explore new&nbsp;solutions to existing problems. The name of the site, "theUltimateLabs", represents my desire to create the ultimate of whatever using technology.<br /><br /><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-seVtTVxrb9c/T6PH-fynjLI/AAAAAAAAAAc/aD819GdUb8Q/s1600/swiss_pocket_knife.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="313" src="http://4.bp.blogspot.com/-seVtTVxrb9c/T6PH-fynjLI/AAAAAAAAAAc/aD819GdUb8Q/s320/swiss_pocket_knife.jpg" width="320" /></a></div><br />http://blog.theultimatelabs.com/2012/05/introduction.htmlnoreply@blogger.com (Rob B)0