<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9081323508483983405</id><updated>2012-02-16T18:47:50.204-08:00</updated><title type='text'>LOAD "$",8,1</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://load-8-1.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://load-8-1.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Thomas M</name><uri>http://www.blogger.com/profile/07039830852932050307</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9081323508483983405.post-6507196757748748156</id><published>2010-10-24T03:37:00.000-07:00</published><updated>2010-10-25T14:22:50.527-07:00</updated><title type='text'>Arduino + Ethernet + RESTful JSON</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_JBAwrp44dhA/TMQq2bJIMcI/AAAAAAAAABA/fIiDTMEWuzM/s1600/ArduinoX10RESTfulJSONprotocol.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="315" src="http://1.bp.blogspot.com/_JBAwrp44dhA/TMQq2bJIMcI/AAAAAAAAABA/fIiDTMEWuzM/s400/ArduinoX10RESTfulJSONprotocol.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: darkred; font-weight: bold;"&gt;Why use &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank"&gt;REST&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/JSON" target="_blank"&gt;JSON&lt;/a&gt;?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;REST and JSON have become very popular the last few years and is currently supported by most platforms/development-frameworks (iPhone, Android, Java, .Net). REST with JSON is lightweight compared to protocols like SOAP, and in my opinion, much easier to understand. It is also quite easy to implement a RESTful web service on the Arduino.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Getting started:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Before you start implementing a REST web service in your app, it's a good idea to get familiar with it using a tool like the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2691/" target="_blank"&gt;Poster&lt;/a&gt; add-on for Firefox. This add-in lets you interact with the service and use HTTP methods like POST and DELETE. Another great Firefox add-on is &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/10869/"&gt;JSONView&lt;/a&gt;, that lets you view JSON response in the browser similar to how XML documents are shown.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: darkred; font-weight: bold;"&gt;The Arduino X10 RESTful JSON protocol:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've chosen to use JSON only, XML is not supported. If you go to the base URI of the web service (http://arduino_ip/), you'll get a response containing the info and state of modules seen by the Arduino. "Seen" means all modules that have received messages on their address over the power line. Additionally the protocol supports storing module types (0 = Unknown, 1 = Appliance, 2 = Dimmer and 3 = Sensor) and user defined module names of up to 16 characters. State data, module types and module names are stored in Arduino EEPROM and survives power loss and resets. Here's an example of what the response looks like when I issue a GET request to the base URI on my setup:&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"module":&lt;br /&gt;&amp;nbsp;&amp;nbsp;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"unit": 1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"url": "/A/1/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"type": 1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"name": "Amplifier",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"on": true&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"unit": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"url": "/A/2/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"type": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"name": "Dining Table",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"on": true,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"brightness": 40&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"unit": 4,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"url": "/A/4/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"type": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"name": "TV Backlight",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"on": true,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"brightness": 26&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"unit": 8,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"url": "/A/8/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"type": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"name": "Hall",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"on": false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"brightness": 69&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"unit": 9,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"url": "/A/9/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"type": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"name": "Kitchen",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"on": false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"brightness": 100&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;If you are using several house codes you can get the JSON response for one specific house by adding the house code to the base URI like this: http://arduino_ip/A/. All my X10 modules use house code A, so in my case the response would be the same.&lt;br /&gt;To get response for one module only you add both house code and unit code to the base URI as follows: http://arduino_ip/A/2/. The output would look like this:&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"unit": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"url": "/A/2/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"type": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"name": "Dining Table",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"on": false,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"brightness": 40&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: darkred; font-weight: bold;"&gt;Updating fields with HTTP POST:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;All fields except house, unit and url can be updated using post. If you are posting to the base URI of the service you need to include the house and unit code fields in the post data, if you are posting to a base + house URI you only need to include the unit code and when posting to a base + house + unit URI you only need to include the fields you would like to update.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 1 (turn of unit 2 on house A):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/&lt;br /&gt;METHOD: POST&lt;br /&gt;BODY: house="A"&amp;amp;unit=2&amp;amp;on=false&lt;br /&gt;RESPONSE: Info for all "seen" modules&lt;br /&gt;&lt;br /&gt;Note:&lt;br /&gt;When specifying house and unit in POST data the URI is ignored for update, but you still get the response for that URI. You could, for example, update state of module B3 by posting: house="B"&amp;amp;unit=3&amp;amp;on=true to URI: http://arduino_ip/A/1/, but the response will contain data for module A1.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 2 (set brightness of unit A4 to 90%):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/A/4/&lt;br /&gt;METHOD: POST&lt;br /&gt;BODY: brightness=90&lt;br /&gt;RESPONSE:&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"unit": 4,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"url": "/A/4/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"type": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"name": "TV Backlight",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"on": true,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"brightness": 90&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note:&lt;br /&gt;All POST data fields that result in something being sent over the power line (on, brightness and cmd) are exclusive. As soon as the parser finds one of these fields it will execute the command and stop the parser. Therefore: on, brightness and cmd commands should be the last field in the POST body.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 3 (changing type and name of unit A1):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/A/1/&lt;br /&gt;METHOD: POST&lt;br /&gt;BODY: type=3&amp;amp;name="Light Sensor 1"&lt;br /&gt;RESPONSE:&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"unit": 1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"url": "/A/1/",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"type": 3,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"name": "Light Sensor 1",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"on": true&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: darkred; font-weight: bold;"&gt;Deleting module state and info with HTTP DELETE:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since there is no way for the Arduino to know if a module no longer exists in your setup, the web service lets you delete module data by issuing a HTTP DELETE request.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 1 (delete info for module A2):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/A/2/&lt;br /&gt;METHOD: DELETE&lt;br /&gt;RESPONSE:&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"house": "A",&lt;br /&gt;&amp;nbsp;&amp;nbsp;"unit": 2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;"url": "/A/2/"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note:&lt;br /&gt;The response will not be empty when you send the request to specific module URI. But when requesting all modules or all modules on one house code a deleted module will no longer be visible.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 2 (delete info for all modules on house A):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/A/&lt;br /&gt;METHOD: DELETE&lt;br /&gt;RESPONSE:&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"module":&lt;br /&gt;&amp;nbsp;&amp;nbsp;[&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 3 (delete info for ALL modules):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/&lt;br /&gt;METHOD: DELETE&lt;br /&gt;RESPONSE:&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;"module":&lt;br /&gt;&amp;nbsp;&amp;nbsp;[&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Warning:&lt;br /&gt;State data, types and names of &lt;span style="color: darkred;"&gt;ALL&lt;/span&gt; modules will be deleted permanently.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: darkred; font-weight: bold;"&gt;Using special HTTP POST field "cmd":&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A complete RESTful representation of the X10 Extended protocol would be difficult to implement on the Arduino, and the binary size would grow out of proportions. Therefore I have implemented a simple way of using the &lt;a href="http://load-8-1.blogspot.com/2010/10/x10-with-arduino-serial-protocol.html"&gt;X10 with Arduino Serial Protocol&lt;/a&gt; to send complex messages.&lt;br /&gt;&lt;br /&gt;When using the "cmd" field it's possible to send multiple commands at once, simply by concatenating all the messages. This is useful if you want to implement scenarios in your application. The total length of the field value cannot exceed 60 characters (20 standard messages or 6 extended messages), anything longer than this will be ignored. Also keep in mind that the default command buffer size, defined in X10ex.h, is 16. This means that the buffer will run out of space after the 16th command.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://load-8-1.blogspot.com/2010/10/x10-with-arduino-serial-protocol.html"&gt;Click here for more info on the X10 with Arduino Serial Protocol&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 1 (Turn off module A2 and A4):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/ (URI is not important)&lt;br /&gt;METHOD: POST&lt;br /&gt;BODY: cmd="A13A33"&lt;br /&gt;RESPONSE: Depends on the URI&lt;br /&gt;&lt;br /&gt;Note:&lt;br /&gt;REST service will not wait for command execution to finish when using "cmd" field. Because of this, the response you get back will not represent the state of the modules after the command has been executed. You can get updated state by sending one or more HTTP GET requests.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 2 (Turn on module A4 and set brightness of A2):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/ (URI is not important)&lt;br /&gt;METHOD: POST&lt;br /&gt;BODY: cmd="A32A17x31x1E"&lt;br /&gt;RESPONSE: Depends on the URI&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example 3 (Turn on modules 3 to 16 in house A):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;URI: http://arduino_ip/ (URI is not important)&lt;br /&gt;METHOD: POST&lt;br /&gt;BODY: cmd="A22A32A42A52A62A72A82A92AA2AB2AC2AD2AE2AF2"&lt;br /&gt;RESPONSE: Depends on the URI&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9081323508483983405-6507196757748748156?l=load-8-1.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://load-8-1.blogspot.com/feeds/6507196757748748156/comments/default' title='Legg inn kommentarer'/><link rel='replies' type='text/html' href='http://load-8-1.blogspot.com/2010/10/arduino-x10-ethernet-restful-json.html#comment-form' title='0 Kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/6507196757748748156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/6507196757748748156'/><link rel='alternate' type='text/html' href='http://load-8-1.blogspot.com/2010/10/arduino-x10-ethernet-restful-json.html' title='Arduino + Ethernet + RESTful JSON'/><author><name>Thomas M</name><uri>http://www.blogger.com/profile/07039830852932050307</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_JBAwrp44dhA/TMQq2bJIMcI/AAAAAAAAABA/fIiDTMEWuzM/s72-c/ArduinoX10RESTfulJSONprotocol.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9081323508483983405.post-4879637684343840446</id><published>2010-10-16T13:26:00.000-07:00</published><updated>2010-10-21T01:33:58.350-07:00</updated><title type='text'>X10 library performance optimization</title><content type='html'>When creating the X10 libraries I spent a lot of time on optimizing code  performance and figuring out how to make all the code "non-blocking".  The solution is a combination of using external interrupts, pin change  interrupts and a timer overflow interrupt.&lt;br /&gt;&lt;br /&gt;The ATmega168/328 chip has three timers, one of which is used to update  the counters for the millis() and micros() functions. You can find a  great article about the timers here:&lt;br /&gt;&lt;a href="http://www.arduino.cc/playground/Code/Timer1/"&gt;http://www.arduino.cc/playground/Code/Timer1/&lt;/a&gt;&lt;br /&gt;And one about pin change interrupts here:&lt;br /&gt;&lt;a href="http://www.arduino.cc/playground/Main/PcInt/"&gt;http://www.arduino.cc/playground/Main/PcInt/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What is blocking code, why avoid it?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Arduino functions delay(), delayMicroseconds(), pulseIn() and  pulseOut() all rely on some sort of loop that blocks other code from  executing while their running. There is really no other simple way of  implementing these functions. In general, any loop waiting for something  to happen, f. ex. a pin going high, will block for as long as it's  running. Another example of code that might block for some time is heavy  calculations, like floating point math.&lt;br /&gt;&lt;br /&gt;An interrupt can put any piece of code running in the main loop on hold, but &lt;b&gt;an interrupt cannot disrupt another interrupt&lt;/b&gt;.  Only one interrupt can execute at any given time. When the CPU finishes  executing one interrupt it will trigger the next interrupt if the flag  for this interrupt was set. If the code execution time of one interrupts  is longer than the trigger interval of another interrupt, then the  latter will only fire once when you might expect it to fire several  times.&lt;br /&gt;&lt;br /&gt;In code triggered by interrupts you should always avoid using blocking  code. When using blocking code in an interrupt you not only stop  execution of the main loop, but you might also prevent other interrupts  from firing reliably. Even the timer overflow interrupt that updates the  millis() and micros() counters is affected by this. If you rely on more  than one interrupt to trigger consistently, like I do when sending or  receiving power line messages at the same time as receiving RF and IR  commands, you need to make sure that your interrupt triggered code runs  as fast as possible. If you don't: expect execution/timing to become  unreliable.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to verify that code executes the way you planned:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A crude but quite effective way is using Serial.print(). You can even  measure the performance of a piece of code using a combination of  micros() and print(). There's an obvious problem though: using print()  and other functions affect the performance of the code. The only way to  really see what's happening on the inputs and outputs of the Arduino, is  to use an oscilloscope.&lt;br /&gt;&lt;br /&gt;I just borrowed an oscilloscope from a friend of mine and I'll show you  the differences in performance between version 1.0, 1.1 and 1.2 of the  X10ex library. One of the reasons the performance of the X10ex library  is critical is described in the PLC interface manual. X10 messages are  sent, one bit at the time, by applying a voltage to an input on the PLC  interface in synchronization with a power line zero cross detection  output. Basically: when the zero cross detect output goes high, you have  about 50 microseconds to figure out whether to leave the input low or  set it high by enabling an output pin on the Arduino. Another reason is  to make sure it doesn't mess up the timings of the RF and IR libraries,  since it uses interrupts to do most of the work.&lt;br /&gt;&lt;br /&gt;The following images are screen shots of oscilloscope output. The first  set of images show the delay from the zero cross detect pin on the PLC  interface goes high until the output pin on the Arduino is set high by  the X10ex library when transmitting.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXDQWcC2I/AAAAAAAAAAo/bgNDWdPAKU8/s1600/Scope_ZeroCrossDelayAfterRise_v1.0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXDQWcC2I/AAAAAAAAAAo/bgNDWdPAKU8/s400/Scope_ZeroCrossDelayAfterRise_v1.0.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.0. Zero Cross detect in red, Output in blue.&lt;br /&gt;70us delay after Zero Cross detect reaches 2V.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXDm1ca1I/AAAAAAAAAAs/fF9LyG_4JPE/s1600/Scope_ZeroCrossDelayAfterRise_v1.1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXDm1ca1I/AAAAAAAAAAs/fF9LyG_4JPE/s400/Scope_ZeroCrossDelayAfterRise_v1.1.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.1. Zero Cross detect in red, Output in blue.&lt;br /&gt;50 us delay after Zero Cross detect reaches 2V.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXEZA-a5I/AAAAAAAAAAw/yE-aITKprA8/s1600/Scope_ZeroCrossDelayAfterRise_v1.2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXEZA-a5I/AAAAAAAAAAw/yE-aITKprA8/s400/Scope_ZeroCrossDelayAfterRise_v1.2.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.2. Zero Cross detect in red, Output in blue.&lt;br /&gt;10 us delay after Zero Cross detect reaches 2V.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The following are the same measurements done when flooding the Arduino with serial, RF and IR commands.&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXE8KyffI/AAAAAAAAAA0/3ooOzfA8exc/s1600/Scope_ZeroCrossDelayStressTest_v1.0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXE8KyffI/AAAAAAAAAA0/3ooOzfA8exc/s400/Scope_ZeroCrossDelayStressTest_v1.0.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.0. Zero Cross detect in red, Output in blue.&lt;br /&gt;Under stress the delay is up to 85 us after Zero Cross.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXGHwKw_I/AAAAAAAAAA4/uOqrZf-sn5E/s1600/Scope_ZeroCrossDelayStressTest_v1.1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://3.bp.blogspot.com/_JBAwrp44dhA/TLnXGHwKw_I/AAAAAAAAAA4/uOqrZf-sn5E/s400/Scope_ZeroCrossDelayStressTest_v1.1.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.1. Zero Cross detect in red, Output in blue.&lt;br /&gt;Under stress the delay is up to 60 us after Zero Cross.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_JBAwrp44dhA/TLnXGvqmv_I/AAAAAAAAAA8/lI6juiP_1TI/s1600/Scope_ZeroCrossDelayStressTest_v1.2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://4.bp.blogspot.com/_JBAwrp44dhA/TLnXGvqmv_I/AAAAAAAAAA8/lI6juiP_1TI/s400/Scope_ZeroCrossDelayStressTest_v1.2.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.2. Zero Cross detect in red, Output in blue.&lt;br /&gt;Under stress the delay is no more than 25 us after Zero Cross.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The two last images are measurements done with the latest version of  theX10ex library,showing signal length and three phase coupling at 50Hz.&lt;/div&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXCVpTQLI/AAAAAAAAAAg/tfcgAgs08sE/s1600/Scope_OutputSignalLength_v1.2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXCVpTQLI/AAAAAAAAAAg/tfcgAgs08sE/s400/Scope_OutputSignalLength_v1.2.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.2. Output in blue. This image verifies that the output timer is&lt;br /&gt;working correctly, disabling the output after exactly 1 millisecond.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXCzlI8UI/AAAAAAAAAAk/EpXTID16iJ0/s1600/Scope_PhaseCouplingAt50Hz_v1.2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXCzlI8UI/AAAAAAAAAAk/EpXTID16iJ0/s400/Scope_PhaseCouplingAt50Hz_v1.2.png" style="margin-left: auto; margin-right: auto;" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;v1.2. Output in blue. This image verifies that the output timer is working&lt;br /&gt;correctly, repeating the 1ms output to align with zero cross of all phases.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9081323508483983405-4879637684343840446?l=load-8-1.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://load-8-1.blogspot.com/feeds/4879637684343840446/comments/default' title='Legg inn kommentarer'/><link rel='replies' type='text/html' href='http://load-8-1.blogspot.com/2010/10/x10-library-performance-optimization_16.html#comment-form' title='0 Kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/4879637684343840446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/4879637684343840446'/><link rel='alternate' type='text/html' href='http://load-8-1.blogspot.com/2010/10/x10-library-performance-optimization_16.html' title='X10 library performance optimization'/><author><name>Thomas M</name><uri>http://www.blogger.com/profile/07039830852932050307</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_JBAwrp44dhA/TLnXDQWcC2I/AAAAAAAAAAo/bgNDWdPAKU8/s72-c/Scope_ZeroCrossDelayAfterRise_v1.0.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9081323508483983405.post-5583775004303649536</id><published>2010-10-12T09:00:00.000-07:00</published><updated>2010-10-12T13:30:49.117-07:00</updated><title type='text'>X10 with Arduino Serial Protocol</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_JBAwrp44dhA/TLSZiQ4SI9I/AAAAAAAAAAc/D422gSnDTxA/s1600/X10withArduinoSerialProtocol.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="346" src="http://3.bp.blogspot.com/_JBAwrp44dhA/TLSZiQ4SI9I/AAAAAAAAAAc/D422gSnDTxA/s400/X10withArduinoSerialProtocol.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;When creating a serial protocol for the &lt;a href="http://load-8-1.blogspot.com/2010/06/x10-plc-rf-ir-and-computer-interface.html"&gt;Arduino X10 libraries&lt;/a&gt;, my goal was to create a protocol that was "human readable" yet lightweight and easy to parse/interface with. In my opinion, making a serial protocol human readable also makes it more understandable and hence easier to integrate with and debug. But there is a tradeoff: making it too literate makes it harder to parse.&lt;br /&gt;&lt;br /&gt;Another goal was to use the same protocol when receiving and sending. By this I mean that whatever serial messages that originate from the power line, RF or IR libraries should look the same as the commands you send to the Arduino to control stuff. With the latest version of the protocol, it's possible to copy almost any message you receive and send it back to the Arduino to trigger the same command. This also makes the protocol easier to interface with, since you can use the same logic when reading and creating commands.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here are some of the things I did to make it more human readable:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The first version of the serial protocol used ASCII values 0-255. A number of these ASCII values do not map to any displayable character or to characters like line-feed or tab. The obvious improvement here was to use two hex nibbles instead of one byte. Hex is easily parsable in C and is directly supported by the Arduino Serial libraries.&lt;/li&gt;&lt;li&gt;I've tried to use characters that would make sense to identify different groups of commands. The way the protocol is created all commands are sent in chunks of 3 characters, where the first character identifies the command type. Letters A-P are reserved for house codes, R = Request Module State, S = Scenario Execute and X or x means that the following two characters is a byte written in hex.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here are some things I did that made it less human readable but easier to parse:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In the first version of the protocol the messages you received from the Arduino used a lot of words like "On", "Off", "PreSetDim", etc. Although this is easier to understand when you read it, it did not meet my goal of making it possible to use the same messages when receiving and sending commands to the Arduino. Although parsing commands like "A1_ExtendedCode_PreSetDim _50" is possible, it's definitely not easy to do in a few lines of code. So I decided to sacrifice some readability to get a smaller binary size. You can still enable debug mode to get the literate output though.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Code:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk"&gt;Arduino X10 libraries&lt;/a&gt; – Libraries for power line, RF and IR communication and an Arduino test sketch implementing the X10 with Arduino Serial Protocol.&lt;code&gt;&lt;/code&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk/dotNet"&gt;X10.Net library&lt;/a&gt; – X10.Net serial communication library with test application. Written in C#.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="color: DarkRed; font-weight: bold;"&gt;The protocol:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The libraries and protocol support sending and receiving all standard and extended code X10 messages. Additionally I've added three custom commands: "Scenario Execute", "Request Module State" and "Wipe Module State".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Scenario Execute&lt;/span&gt; is a way of triggering sequences of commands and logic using a simple command. By sending message S01 you could, for example, set several X10 modules to different brightness levels and even make the events depend on some variable like the current time, ambient light or the state of another module. The scenario logic must be defined in the Arduino Sketch.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Request Module State&lt;/span&gt; let's you query the state of any appliance/dimmer module in your setup. Most X10 modules are one-way, which means that you can't query them for state directly. Because of that I added functionality to the &lt;a href="http://load-8-1.blogspot.com/2010/06/x10-plc-rf-ir-and-computer-interface.html"&gt;X10ex&lt;/a&gt; library that enables it to monitor the power line and keep track of state automatically.&lt;br /&gt;Another feature is the possibility to query state of all known modules on one or all house codes. This also serves the purpose of listing all modules used (that the Arduino has seen) in your setup. With standard X10 commands you would need to know the address of every module in use, or query every possible address, which would take about 4 minutes because of slow X10 power line signaling.&lt;br /&gt;Request Module state has its own return prefix "MS:" and uses X10 extended code to return the on/off state and brightness level. Modules that haven't been "seen" by the Arduino (no state data stored) simply return nothing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wipe Module State&lt;/span&gt; makes it possible to wipe/clear module state stored in the Arduino EEPROM. State data is stored in EEPROM to make it survive resets and power loss. Currently you can either wipe module state of all modules by sending RW* message, or all modules on one house code by sending RWA (A = House Code A).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Return data Prefixes:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Prefixes are used when messages are sent from the Arduino to identify the message origin.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: DarkRed;"&gt;SD:&lt;/span&gt; Acknowledges a Serial Data message sent to the Arduino.&lt;br /&gt;&lt;span style="color: DarkRed;"&gt;PL:&lt;/span&gt; Message originates from data received over the Power Line.&lt;br /&gt;&lt;span style="color: DarkRed;"&gt;RF:&lt;/span&gt; Message originates from data received from RF remotes.&lt;br /&gt;&lt;span style="color: DarkRed;"&gt;IR:&lt;/span&gt; Message originates from data received from Infrared remotes.&lt;br /&gt;&lt;span style="color: DarkRed;"&gt;MS:&lt;/span&gt; Data originates from Memory State stored in Arduino EEPROM.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Error Handling:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"&lt;span style="color: DarkRed;"&gt;SD:_ExTimOut&lt;/span&gt;" Complete 3 or 9 character serial message was not received within one second from start to end.&lt;br /&gt;"&lt;span style="color: DarkRed;"&gt;SD:_ExSyntax&lt;/span&gt;" Syntax error in serial message sent to the Arduino.&lt;br /&gt;"&lt;span style="color: DarkRed;"&gt;PL:_ExBuffer&lt;/span&gt;" Power line message buffer full. Since X10 power line signaling is slow (about .3 to .6 seconds per message) the &lt;a href="http://load-8-1.blogspot.com/2010/06/x10-plc-rf-ir-and-computer-interface.html"&gt;X10ex&lt;/a&gt; library needs to buffer incoming messages. The size of the buffer is defined in X10ex.h and defaults to 16 messages.&lt;br /&gt; &lt;br /&gt;&lt;span style="font-weight: bold;"&gt;X10 Standard Messages examples:&lt;/span&gt;&lt;br /&gt;&lt;span lang="EN-US" style="font-family: Consolas;"&gt;&lt;br /&gt;A12 (House=A, Unit=2, Command=On)&lt;br /&gt;AB3 (House=A, Unit=12, Command=Off)&lt;br /&gt;A_5 (House=A, Unit=N/A, Command=Bright)&lt;br /&gt;|||&lt;br /&gt;||└- Command 0-F or _&amp;nbsp; Example: 2=On, 7=ExtCode, _ =No Cmd&lt;br /&gt;|└-- Unit 0-F or _&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Example: 0=Unit 1, F=Unit 16, _ =No Unit&lt;br /&gt;└--- House code A-P&amp;nbsp;&amp;nbsp;&amp;nbsp; Example: A=House A, P=House P :)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;X10 Extended Message examples:&lt;/span&gt;&lt;br /&gt;&lt;span lang="EN-US" style="font-family: Consolas;"&gt;&lt;br /&gt;A37x31x21 (A4, Cmd=ExtCode, ExtCmd=PRE_SET_DIM, ExtData=33)&lt;br /&gt;B87x01x0D (B9, Cmd=ExtCode, ExtCmd=ShutterOpen, ExtData=13)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; |/ |/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; |  └- Extended Data byte in hex&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Example: 1F=50% bright.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; └---- Extended Command byte in hex&amp;nbsp; Example: 31=PreSetDim&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Scenario Execute examples:&lt;/span&gt;&lt;br /&gt;&lt;span lang="EN-US" style="font-family: Consolas;"&gt;&lt;br /&gt;S03 (Execute scenario 3)&lt;br /&gt;S14 (Execute scenario 20)&lt;br /&gt;||/&lt;br /&gt;|└-- Scenario byte in hex (Hex: 00-FF, Dec: 0-255)&lt;br /&gt;└--- Scenario Execute Character&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Request Module State examples:&lt;/span&gt;&lt;br /&gt;&lt;span lang="EN-US" style="font-family: Consolas;"&gt;&lt;br /&gt;R** (Request buffered state of all modules)&lt;br /&gt;RG* (Request buffered state of modules using house code G)&lt;br /&gt;RA2 (Request buffered state of module A3)&lt;br /&gt;|||&lt;br /&gt;||└- Unit 0-F or *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Example: 0=Unit 1, A=Unit 10, * =All&lt;br /&gt;|└-- House code A-P or *&amp;nbsp; Example: A=House A, P=House P, * =All&lt;br /&gt;└--- Request Module State Character&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wipe Module State examples:&lt;/span&gt;&lt;br /&gt;&lt;span lang="EN-US" style="font-family: Consolas;"&gt;&lt;br /&gt;RW* (Wipe state data for all modules)&lt;br /&gt;RWB (Wipe state data for all modules using house code B)&lt;br /&gt;|||&lt;br /&gt;||└- House code A-P or *&amp;nbsp; Example: A=House A, P=House P, * =All&lt;br /&gt;|└-- Wipe Module State Character&lt;br /&gt;└--- Request Module State Character&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;X10 protocol external resources:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.x10.com/support/technology1.htm"&gt;X10 PLC protocol&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ftp.x10.com/pub/manuals/xtdcode.pdf"&gt;X10 Standard and Extended Code Protocol&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9081323508483983405-5583775004303649536?l=load-8-1.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://load-8-1.blogspot.com/feeds/5583775004303649536/comments/default' title='Legg inn kommentarer'/><link rel='replies' type='text/html' href='http://load-8-1.blogspot.com/2010/10/x10-with-arduino-serial-protocol.html#comment-form' title='0 Kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/5583775004303649536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/5583775004303649536'/><link rel='alternate' type='text/html' href='http://load-8-1.blogspot.com/2010/10/x10-with-arduino-serial-protocol.html' title='X10 with Arduino Serial Protocol'/><author><name>Thomas M</name><uri>http://www.blogger.com/profile/07039830852932050307</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_JBAwrp44dhA/TLSZiQ4SI9I/AAAAAAAAAAc/D422gSnDTxA/s72-c/X10withArduinoSerialProtocol.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9081323508483983405.post-204669055762630591</id><published>2010-06-29T19:18:00.000-07:00</published><updated>2011-01-07T03:49:14.142-08:00</updated><title type='text'>X10 PLC, RF and IR with Arduino</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_JBAwrp44dhA/TJFC96AJwGI/AAAAAAAAAAU/nhoIiTcxCbk/s1600/X10ex.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="321" src="http://4.bp.blogspot.com/_JBAwrp44dhA/TJFC96AJwGI/AAAAAAAAAAU/nhoIiTcxCbk/s400/X10ex.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Goals:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a platform independent solution that makes it easy to interface with X10 hardware and that supports sending and receiving both standard and extended X10 messages.&lt;/li&gt;&lt;li&gt;Make a cheap alternative to the Marmitek CM15PRO Computer Interface with better functionality, performance and RF-range.&lt;/li&gt;&lt;li&gt;Incorporate X10 IR into the solution to make products like the Marmitek IRRF7243 or the XanuraHome IRIX35 interfaces redundant.&lt;/li&gt;&lt;li&gt;Base it on the Arduino platform using a single Arduino Duemilanove controller.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Challenges:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Writing interrupt triggered non-blocking PLC&lt;sup&gt;1&lt;/sup&gt;, RF and IR libraries that can be run in parallel on one ATmega168 chip without using too much resources or getting in the way of each other.&lt;/li&gt;&lt;li&gt;Making RF and IR performance good enough to be able to receive BRIGHT and DIM commands and forward them to the PLC&lt;sup&gt;1&lt;/sup&gt; interface without getting choppy dimming.&lt;/li&gt;&lt;li&gt;Using one of the ATmega168 pin change interrupts. Separate interrupts are needed for PLC&lt;sup&gt;1&lt;/sup&gt;, RF and IR. The Arduino Duemilanove only has two external interrupts, but it's possible to use three additional pin change interrupts. Check out chapter 11 in the ATmega168 datasheet for more information.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Limitations:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;RF library (X10rf) only tested with 434MHz KR22 remotes. Timing min and max values (defined in X10rf.h) may need changes to make library work with other remotes.&lt;/li&gt;&lt;li&gt;IR library (X10ir) only tested with Logitech Harmony remotes. Timings defined in X10ir.h can be changed to make it work with other remotes using the same protocol.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Future Enhancements:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Support for the WiShield 2.0 by &lt;a href="http://asynclabs.com/"&gt;AsyncLabs&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Android and iPhone apps.&lt;/li&gt;&lt;li&gt;Bluetooth Support.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Download the code:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk/Libraries/X10ex"&gt;X10ex library&lt;/a&gt; – X10 message transmission and reception using a PLC interface.&lt;code&gt;&lt;/code&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk/Libraries/X10rf"&gt;X10rf library&lt;/a&gt; – X10 message reception using a standard 434 or 315MHz RF receiver.&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk/Libraries/X10ir"&gt;X10ir library&lt;/a&gt; – X10 message reception using a standard, low cost IR receiver.&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk/Sketch/X10_Ethernet"&gt;X10 test sketch&lt;/a&gt; – Example code using above libraries, including X10 serial protocol that works with the X10.Net library and code for the Ethernet shield.&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/arduino-x10/source/browse/#svn/trunk/dotNet"&gt;X10.Net library&lt;/a&gt; – X10.Net serial communication library with test application. Written in C#.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;The hardware you need:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Arduino Duemilanove board (ATmega328).&lt;br /&gt;Price: SparkFun ~$30, eBay ~$20&lt;/li&gt;&lt;li&gt;Marmitek XM10 Two-way PLC Interface&lt;sup&gt;2&lt;/sup&gt; or equivalent US version.&lt;br /&gt;Price: IntelliHome.be ~$50 (I live in Europe, X10 stuff is expensive)&lt;/li&gt;&lt;li&gt;434MHz receiver module (I'm using one based on the Infineon TDA 5200 chip).&lt;br /&gt;Price: Similar product from SparkFun ~$5&lt;/li&gt;&lt;li&gt;IR Receiver (I'm using the Everlight IRM 3638N3).&lt;br /&gt;Price: Elfa.se ~$2, Similar product from SparkFun ~$2&lt;/li&gt;&lt;/ul&gt;Total Price: ~$77&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The hardware it's replacing:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Marmitek CM15PRO Computer Interface.&lt;br /&gt;Price: ~$115&lt;/li&gt;&lt;li&gt;Marmitek IRRF7243 IR Mini Controller&lt;sup&gt;3&lt;/sup&gt; or XanuraHome IRIX35 Infrared Interface&lt;sup&gt;4&lt;/sup&gt;.&lt;br /&gt;Price: ~$58 or ~$150 for the IRIX35&lt;/li&gt;&lt;/ul&gt;Total Price: ~$173 or ~$265&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Harware used for testing:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;X10 extended code capable two-way dimmers, appliance modules, etc.&lt;/li&gt;&lt;li&gt;Two Marmitek KR22 RF remotes (~$25 a piece).&lt;/li&gt;&lt;li&gt;Logitech Harmony 785 (using device Marmitek IR7243 to send X10 IR).&lt;/li&gt;&lt;li&gt;So far the library has been tested with the 50Hz European XM10 and the 60Hz North American PSCO5 PLC interfaces. Other models should work fine too. Thanks to the guy at &lt;a href="http://brohogan.blogspot.com/"&gt;http://brohogan.blogspot.com/&lt;/a&gt; for testing the PSC05 :)&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Resources:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://arduino.cc/en/Reference/HomePage/"&gt;Arduino Reference&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf"&gt;ATmega168 datasheet&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.intellihome.be/UserFiles/manuals/XM10.pdf"&gt;Marmitek XM10&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.x10.com/support/technology1.htm"&gt;X10 PLC protocol&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://davehouston.net/rf.htm"&gt;X10 RF protocol&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://davehouston.net/ir.htm"&gt;X10 IR protocol&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ftp.x10.com/pub/manuals/xtdcode.pdf"&gt;X10 Standard and Extended Code Protocol&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;span style="font-size: x-small;"&gt; PLC = Power Line Communication&lt;/span&gt;&lt;br /&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;span style="font-size: x-small;"&gt; The XM10 seems to have way better PLC signal strength compared to the  CM15PRO.&lt;/span&gt;&lt;br /&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;span style="font-size: x-small;"&gt; In my opinion the IRRF7243 is not worth the money because of poor IR  range and choppy dimming.&lt;/span&gt;&lt;br /&gt;&lt;sup&gt;4&lt;/sup&gt;&lt;span style="font-size: x-small;"&gt; Never tested the IRIX35, but with a price of ~$150 I assume it’s a lot  better than the IRRF7243.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9081323508483983405-204669055762630591?l=load-8-1.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://load-8-1.blogspot.com/feeds/204669055762630591/comments/default' title='Legg inn kommentarer'/><link rel='replies' type='text/html' href='http://load-8-1.blogspot.com/2010/06/x10-plc-rf-ir-and-computer-interface.html#comment-form' title='12 Kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/204669055762630591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9081323508483983405/posts/default/204669055762630591'/><link rel='alternate' type='text/html' href='http://load-8-1.blogspot.com/2010/06/x10-plc-rf-ir-and-computer-interface.html' title='X10 PLC, RF and IR with Arduino'/><author><name>Thomas M</name><uri>http://www.blogger.com/profile/07039830852932050307</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_JBAwrp44dhA/TJFC96AJwGI/AAAAAAAAAAU/nhoIiTcxCbk/s72-c/X10ex.png' height='72' width='72'/><thr:total>12</thr:total></entry></feed>
