<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Simon Dobson (Posts about framework)</title><link>https://simondobson.org/</link><description></description><atom:link href="https://simondobson.org/categories/framework.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:simoninireland@gmail.com"&gt;Simon Dobson&lt;/a&gt; </copyright><lastBuildDate>Fri, 07 Aug 2026 09:08:07 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Some improvements to SleepySketch</title><link>https://simondobson.org/2013/07/26/improvements/</link><dc:creator>Simon Dobson</dc:creator><description>&lt;p&gt;It's funny how even early experiences change the way you think about a design. Two minor changes to SleepySketch have been suggested by early testing.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;The first issue is obvious: milliseconds are a really inconvenient way to think about timing, especially when you're planning on staying asleep for long periods. A single method in SleepySketch to convert from more programmer-friendly days/hours/minutes/seconds times makes a lot of difference.&lt;/p&gt;
&lt;p&gt;The second issue concerns scheduling -- or rather regular
scheduling. Most sampling and communication tasks occur on predictable
schedules, say every five hours. In an &lt;a href="https://simondobson.org/2013/06/01/actor-systems/" target="_blank"&gt;actor
framework&lt;/a&gt;, that means the actor instance (or another one) has to
be re-scheduled after the first has run. We can do this within the
definition of the actor, for example using the &lt;code&gt;post()&lt;/code&gt;
action:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PeriodicActor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Actor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;behaviour&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PeriodicActor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduleIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expandTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(This also demonstrates the &lt;code&gt;expandTime()&lt;/code&gt; function to re-schedule after 0 days and 5 hours, incidentally.) Simple, but bad design: we can't re-use &lt;code&gt;PeriodicActor&lt;/code&gt; on a different schedule. If we add a variable to keep track of the repeating period, we'd be mixing up "real" behaviour with scheduling; more importantly, we'd have to do that for &lt;em&gt;every&lt;/em&gt; actor that wants to run repeatedly.&lt;/p&gt;
&lt;p&gt;A better way is to use an actor combinator that takes an actor and a period and creates an actor that runs first re-schedules the actor to run after the given period, and then runs the underlying actor. (We do it this way so that the period isn't affected by the time the actor actually takes to run.)&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;Actor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RepeatingActor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SomeActor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expandTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduleIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expandTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;RepeatingActor&lt;/code&gt; runs the behaviour of
&lt;code&gt;SomeActor&lt;/code&gt; every 5 hours, and we initially schedule it to
run in 5 hours. We can actually encapsulate all of this by adding a
method to &lt;code&gt;SleepySketch&lt;/code&gt; itself:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduleEvery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SomeActor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expandTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;to perform the wrapping and initial scheduling automatically.&lt;/p&gt;
&lt;p&gt;Simple sleepy sketches can now be created at set-up, by scheduling
repeating actors, and we can define the various actors and re-use them
in different scheduling situations without complicating their own
code.&lt;/p&gt;</description><category>actors</category><category>framework</category><category>making</category><category>power management</category><category>project:ditch</category><category>sleepysketch</category><category>software</category><guid>https://simondobson.org/2013/07/26/improvements/</guid><pubDate>Fri, 26 Jul 2013 15:20:38 GMT</pubDate></item><item><title>Sleepy sketches</title><link>https://simondobson.org/2013/07/25/sleepy-sketches/</link><dc:creator>Simon Dobson</dc:creator><description>&lt;p&gt;Keeping the microcontroller asleep as much as possible is a key goal for a sensor system, so it makes sense to organise the entire software process around that.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;The standard Arduino software model is, well, standard: programs ("sketches") are structured in terms of a &lt;code&gt;setup()&lt;/code&gt; function that runs once when the system restarts and a &lt;code&gt;loop()&lt;/code&gt; function that is run repeatedly. This suggests that the system spends its time running, which possibly isn't all that desirable: a sensor system typically tries to &lt;a href="https://simondobson.org/2013/07/25/sleepy-sketches/2013/07/23/arduino-watchdog"&gt;stay in a low-power mode&lt;/a&gt; as much as possible. The easiest way to do this is to provide a programming framework that handles the sleeping, and where the active bits of the program are scheduled automatically.&lt;/p&gt;
&lt;p&gt;There are at least two ways to do this. The simplest is a library that lets &lt;code&gt;loop()&lt;/code&gt; sleep, either directly or indirectly. This is good for simple programs and not so good for more complicated ones, as it means that &lt;code&gt;loop()&lt;/code&gt; encapsulates all the program's logic in a single block. A more modern and compositional approach is to let program fragments request when they want to run somehow, and have a scheduler handle the sleeping, waking up, and execution of those fragments. That lets (for example) one fragment decide at run-time to schedule another&lt;/p&gt;
&lt;p&gt;If we adopt this approach,we have to worry about the fact that one fragment might lock-out another. A desktop system might use threads; this is more problematic for a microcontroller, but an alternative is to force all fragments to only execute for a finite amount of time, so that the scheduler always gets control back. This might lead to a fragment not running when it asked (if other fragments were still running), but if we assume that the system spends most of its time asleep anyway, there will be plenty of catch-up time. Doing this results in an &lt;a href="https://simondobson.org/2013/06/01/actor-systems/"&gt;actor system&lt;/a&gt; where the fragments are actors that are scheduled from an actor queue.&lt;/p&gt;
&lt;p&gt;Turning this into code, we get the &lt;code&gt;SleepySketch&lt;/code&gt; library: a library for building Arduino sketches that spend most of their time sleeping.&lt;/p&gt;
&lt;p&gt;&lt;img alt="SleepySketch design" src="https://simondobson.org/images/citizen-sensing/sleepysketch.png"&gt;&lt;/p&gt;
&lt;p&gt;There are a few wrinkles that need to be taken care of for running on a resource-constrained system. Firstly, the number of actors available is fixed at start-up (defaulting to 10), so that we can balance RAM usage.(With only 2k to play with, we need to be careful). Secondly, we use a class to manage the sleeping functionality in different ways: a &lt;code&gt;BusySleeper&lt;/code&gt; that uses the normal &lt;code&gt;delay()&lt;/code&gt; function (a busy loop) with no power-saving functions, a &lt;code&gt;HeavySleeper&lt;/code&gt; that uses the watchdog timer to shut the system down as far as possible, and possibly some other intermediate strategies. Actors are provided by sub-classing the &lt;code&gt;Actor&lt;/code&gt; class and providing a behaviour. We also allow pre- and post-behaviour actions to define families of actors, for example sensor observers. We separate the code for an actor from its scheduling.&lt;/p&gt;
&lt;p&gt;The standard library uses singleton classes quite a lot, so for example the &lt;code&gt;Serial&lt;/code&gt; object represents the USB connection from an Arduino to its host computer and is the target for all methods. We use the same approach and define a singleton, &lt;code&gt;Sleepy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The program structure then loops something like this. If we assume
that we've defined an actor class &lt;code&gt;PingActor&lt;/code&gt;, then we can
do the following:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HeavySleeper&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduleIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PingActor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ping!"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Sleepy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;setup()&lt;/code&gt; code initialises the serial port and the sleepy sketch using a &lt;code&gt;HeavySleeper&lt;/code&gt;, and then schedules an actor to run in 10000ms. The loop() code runs the actors while there are actors remaining to schedule. If the &lt;code&gt;PingActor&lt;/code&gt; instance just prints its message, then there will be no further actors to execute and the program will end; alternatively the actor could schedule further actors to be run later, and the sketch will pick them up. The sketch will remain asleep for as long as possible (probably for over 9s between start-up and the first ping), allowing for some fairly significant power saving.&lt;/p&gt;
&lt;p&gt;This is a first design, now just about working. It's still not as easy
as it could be, however, and needs some testing to make sure that the
power savings do actually materialise.&lt;/p&gt;</description><category>actors</category><category>framework</category><category>making</category><category>power management</category><category>project:ditch</category><category>sleepysketch</category><category>software</category><guid>https://simondobson.org/2013/07/25/sleepy-sketches/</guid><pubDate>Thu, 25 Jul 2013 12:00:01 GMT</pubDate></item><item><title>Representing samples</title><link>https://simondobson.org/2013/07/10/representing-samples/</link><dc:creator>Simon Dobson</dc:creator><description>&lt;p&gt;Any sensor network has to represent sampled data somehow. What would be the most friendly format for so doing?&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;Re-usable software has to take an extensible view of how to represent data, since the exact data that will be represented may change over time. There are several approaches that are often taken, ranging from abstract classes and interfaces (for code-based solutions) to formats such as XML for data-based approaches.&lt;/p&gt;
&lt;p&gt;Neither of these is ideal for a sensor network, for a number of reasons.&lt;/p&gt;
&lt;p&gt;A typical sensor network architecture will use different languages one the sensors and the base station, with the former prioritising efficiency and compactness and the latter emphasising connectivity to the internet and interfacing with standard tools. Typically we find C or C++ on the sensors and Java, JavaScript, Processing, or some other language on the base station. (Sometimes C or C++ too, although that's increasingly rare for new applications.) It's therefore tricky to use a language-based approach to defining data, as two &lt;em&gt;different&lt;/em&gt; versions of the &lt;em&gt;same&lt;/em&gt; structure would have to be defined and -- more importantly -- kept synchronised across changes.&lt;/p&gt;
&lt;p&gt;That suggests a data-based approach, but these tend to fall foul of the need for a compact and efficient encoding sensor-side. Storing, generating, and manipulating XML or RDF, for example, would typically be too complex and too memory-intensive for a sensor. These formats also aren't really suitable for in-memory processing -- unsurprisingly, as they were designed as transfer encodings, not primary data representations. Even though they might be attractive, not least for their friendliness to web interactions and the Semantic Web, they aren't really usable directly.&lt;/p&gt;
&lt;p&gt;There are some compromise positions, however. &lt;a href="http://www.json.org" target="_blank"&gt;JSON&lt;/a&gt; is a data notation derived initially from JavaScript (and usable directly within it) but which is sufficiently neutral to be used as an exchange format in several web-based systems. JSON essentially lets a user form objects with named fields, whose values can be strings, numbers, arrays, or other objects. (Note that this doesn't include code-valued fields, which is how JSON stays language-neutral: it can't encode computations, closures, or other programmatic features.)&lt;/p&gt;
&lt;p&gt;JSON's simplicity and commonality have raised the possibility of using it as a universal transport encoding: simpler than XML, but capable of integration with RDF, ontologies, and the Semantic Web if desired. There are several initiatives in this direction: one I came across recently is &lt;a href="http://json-ld.org/" target="_blank"&gt;JSON-LD&lt;/a&gt; (JSON for Linked Data) that seeks to integrate JSON records directly into the &lt;a href="http://linkeddata.org/" target="_blank"&gt;linked open data world&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This raises the possibility of using JSON to define the format of sensor data samples, sample collections (datasets), and the like, and linking those descriptions directly to ontological descriptions of their contents and meaning. There are some problems with this, of course. Foremost, JSON isn't very compact, and so would require more storage and wireless bandwidth than a binary format. However, one approach might be to define samples &lt;em&gt;etc&lt;/em&gt; in JSON format and then either use them directly (server-side) or compile them to something more static but more efficient for use sensor-side and for exchange. This would retain the openness but without losing performance.&lt;/p&gt;</description><category>data</category><category>framework</category><category>javascript</category><category>json</category><category>json-ld</category><category>making</category><category>project:ditch</category><category>rdf</category><category>xml</category><guid>https://simondobson.org/2013/07/10/representing-samples/</guid><pubDate>Wed, 10 Jul 2013 07:03:31 GMT</pubDate></item></channel></rss>