<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OoeyGUI</title>
	<atom:link href="http://www.ooeygui.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.ooeygui.com</link>
	<description></description>
	<lastBuildDate>Wed, 19 May 2010 03:18:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Rehydrating the blog</title>
		<link>http://www.ooeygui.com/?p=339</link>
		<comments>http://www.ooeygui.com/?p=339#comments</comments>
		<pubDate>Wed, 19 May 2010 03:18:42 +0000</pubDate>
		<dc:creator>Lou</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=339</guid>
		<description><![CDATA[I&#8217;ve found that if I&#8217;m not sharing my successes and failures, I don&#8217;t do anything. Well, I&#8217;m going to give this blog a go again. Fortunately, I didn&#8217;t delete any of my old posts, but it&#8217;s been a bit frustrating getting wordpress back up and running again. wish me luck]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve found that if I&#8217;m not sharing my successes and failures, I don&#8217;t do anything. Well, I&#8217;m going to give this blog a go again. Fortunately, I didn&#8217;t delete any of my old posts, but it&#8217;s been a bit frustrating getting wordpress back up and running again. wish me luck</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=339</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ToorCamp</title>
		<link>http://www.ooeygui.com/?p=332</link>
		<comments>http://www.ooeygui.com/?p=332#comments</comments>
		<pubDate>Mon, 29 Jun 2009 21:06:42 +0000</pubDate>
		<dc:creator>Lou</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=332</guid>
		<description><![CDATA[I&#8217;ll be at ToorCamp (with Fabr) July 1st through July 5th, at the Hackerbot Labs Campsite. See you there?]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be at <a href="toorcamp.org">ToorCamp</a> (with Fabr) July 1st through July 5th, at the Hackerbot Labs Campsite. </p>
<p>See you there?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=332</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>almost there&#8230;</title>
		<link>http://www.ooeygui.com/?p=327</link>
		<comments>http://www.ooeygui.com/?p=327#comments</comments>
		<pubDate>Fri, 05 Jun 2009 04:38:09 +0000</pubDate>
		<dc:creator>Lou</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=327</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ooeygui.com/wp-content/uploads/2009/06/img_0141.jpg"><img class="aligncenter size-medium wp-image-328" title="img_0141" src="http://www.ooeygui.com/wp-content/uploads/2009/06/img_0141-300x225.jpg" alt="img_0141" width="300" height="225" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=327</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fabr v3</title>
		<link>http://www.ooeygui.com/?p=320</link>
		<comments>http://www.ooeygui.com/?p=320#comments</comments>
		<pubDate>Sat, 09 May 2009 06:32:53 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=320</guid>
		<description><![CDATA[Fabr v2 uses a moving platform for the Z axis. This means it has a maximum volume is quite difficult to change. The platform requires a significant number of moving parts. I had been wondering if I could change fabr so that one axis could be changed out&#8230; For Fabr v3, I wanted to see [...]]]></description>
			<content:encoded><![CDATA[<p>Fabr v2 uses a moving platform for the Z axis. This means it has a maximum volume is quite difficult to change. The platform requires a significant number of moving parts. I had been wondering if I could change fabr so that one axis could be changed out&#8230;
<p>
For Fabr v3, I wanted to see if I could replace the Y axis with a replaceable platform, driven by an edge motor. With this arrangement, I could replace the platform with any length I needed for the job at hand. I&#8217;m not quite sure if this will work, but something I&#8217;ve been thinking about.
<p><a href="http://www.ooeygui.com/wp-content/uploads/2009/05/3d-printer-v3.jpg"><img src="http://www.ooeygui.com/wp-content/uploads/2009/05/3d-printer-v3-218x300.jpg" alt="3d-printer-v3" title="3d-printer-v3" width="218" height="300" class="alignnone size-medium wp-image-321" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=320</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Super &#8216;Struder</title>
		<link>http://www.ooeygui.com/?p=312</link>
		<comments>http://www.ooeygui.com/?p=312#comments</comments>
		<pubDate>Tue, 05 May 2009 05:08:13 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=312</guid>
		<description><![CDATA[I&#8217;ve been having problems keeping the my extruder up to temperature, and eventually, well dissolved my working extruder. So&#8230; I&#8217;m building a new &#8216;super extruder&#8217; based on research by nophead&#8217;s work.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been having problems keeping the my extruder up to temperature, and eventually, well dissolved my working extruder. So&#8230; I&#8217;m building a new &#8216;super extruder&#8217; based on research by nophead&#8217;s work.<br />
<a href="http://www.ooeygui.com/wp-content/uploads/2009/05/img_01251.jpg"><img src="http://www.ooeygui.com/wp-content/uploads/2009/05/img_01251-300x225.jpg" alt="Super Extruder - business end" title="Super Extruder - business end" width="300" height="225" class="alignnone size-medium wp-image-316" /></a><br />
<a href="http://www.ooeygui.com/wp-content/uploads/2009/05/img_01261.jpg"><img src="http://www.ooeygui.com/wp-content/uploads/2009/05/img_01261-300x225.jpg" alt="Super Extruder - isolation" title="Super Extruder - isolation" width="300" height="225" class="alignnone size-medium wp-image-317" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=312</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fabr motherboard</title>
		<link>http://www.ooeygui.com/?p=307</link>
		<comments>http://www.ooeygui.com/?p=307#comments</comments>
		<pubDate>Mon, 13 Apr 2009 06:54:01 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=307</guid>
		<description><![CDATA[&#8220;I love it when a plan comes together&#8221; The Fabr motherboard is complete, and the firmware refactor I&#8217;ve been working on is ready for testing. Here are some glamor shots of the motherboard (which are reprap firmware and connector compatible, just in case). Hoping to have this thing up and running for the Robotics meeting [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;I love it when a plan comes together&#8221;
<p>
The Fabr motherboard is complete, and the <a href="http://reprap.svn.sourceforge.net/svnroot/reprap/trunk/users/lamadio/FirmwareRefactorPrep/main/">firmware refactor</a> I&#8217;ve been working on is ready for testing.
<p>
Here are some glamor shots of the motherboard (which are reprap firmware and connector compatible, just in case).
<p>
<a href="http://www.ooeygui.com/wp-content/uploads/2009/04/img_0119.jpg"><img src="http://www.ooeygui.com/wp-content/uploads/2009/04/img_0119-150x150.jpg" alt="img_0119" title="img_0119" width="150" height="150" class="alignnone size-thumbnail wp-image-308" /></a>
<p>
<a href="http://www.ooeygui.com/wp-content/uploads/2009/04/img_0121.jpg"><img src="http://www.ooeygui.com/wp-content/uploads/2009/04/img_0121-150x150.jpg" alt="img_0121" title="img_0121" width="150" height="150" class="alignnone size-thumbnail wp-image-309" /></a>
<p>Hoping to have this thing up and running for the Robotics meeting this weekend.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=307</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Anyone else having problems with the 328?</title>
		<link>http://www.ooeygui.com/?p=306</link>
		<comments>http://www.ooeygui.com/?p=306#comments</comments>
		<pubDate>Mon, 30 Mar 2009 20:28:44 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=306</guid>
		<description><![CDATA[I purchased a 328 upgrade from Adafruit, and am wondering if I got a bad firmware. My symptom is failure to sync during a firmware update. Happens in both the TextMate plugin as well as Arduino 14.]]></description>
			<content:encoded><![CDATA[<p>I purchased a 328 upgrade from Adafruit, and am wondering if I got a bad firmware. My symptom is failure to sync during a firmware update. Happens in both the TextMate plugin as well as Arduino 14.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=306</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Behavior &#8211; Device Abstraction</title>
		<link>http://www.ooeygui.com/?p=301</link>
		<comments>http://www.ooeygui.com/?p=301#comments</comments>
		<pubDate>Sat, 28 Mar 2009 16:42:47 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=301</guid>
		<description><![CDATA[You&#8217;ve coded your project with your x-axis step pin on GPIO11. But my device has it on GPIO3. Or even worse, I use a a servo and counter, which doesn&#8217;t have a concept of a step. How do we resolve this? If instead of considering the device itself when coding the logic, what if we [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve coded your project with your x-axis step pin on GPIO11. But my device has it on GPIO3. Or even worse, I use a a servo and counter, which doesn&#8217;t have a concept of a step. How do we resolve this?
<p>
If instead of considering the device itself when coding the logic, what if we were to abstract the meaning of the device from its behavior? That&#8217;s the basic idea behind Behavior-Device abstraction.</p>
<h3>Navigation sample of the idea</h3>
<p>Say I&#8217;m building a Unmanned Aerial  Vehicle (UAV). I have a navigation behavior which needs realtime orientation data. A typical orientation circuit requires a Gyro and accelerometer for accuracy and drift compensation. If the navigation system had to deal with those calculations, that code becomes unwieldy. However, if it were coded to a single OrientationDevice, then the implementation of that device could be two sub devices &#8211; the GyroDevice and AccelerometerDevice, and can build a homogenized notification of orientation changes. What if a manufacturer were to build a single chip that handles both and provides a single interface to it? All one would need to do is replace out the Orientation device without rewriting the Navigation behavior.
<p>
The example above described a composition &#8211; Each component has a singular responsibility. These are aggregated into a composite or logical device, which then can be actioned upon or notified from independent of the internal implementation.<br />
<h3>GCode behavior &#8211; Cartesian bot/Extruder</h3>
<p>RepRap has 1 main behavior &#8211; The GCode interpreter. It receives commands from the host machine, and drives two logical components &#8211; the extruder and the Cartesian bot. The Cartesian bot is composed of 3 linear actuators. The Extruder has a temperature sensor, heater and feed device.
<p>
The RepRap project uses Stepper motors for linear actuation, with end stops for collision avoidance and homing. It could be implemented using a servo motor or linear stepper driver. Since driving the linear actuator is now abstracted from the behavior, changes to the driving mechanism becomes much less complicated.
<p>
In other words, the behavior tells the bot where to go, the bot figures out how to get there, and the linear actuators figure out how to do it.<br />
<h4>The Cartesian Bot</h4>
<pre lang="c++">class CartesianDevice : public Device,
                         public Observable,
                         public Observer
 {
     LinearActuator&#038; _x;
     LinearActuator&#038; _y;
     LinearActuator&#038; _z;
     bool _xInMotion;
     bool _yInMotion;
     bool _zInMotion;
public:
     CartesianDevice(LinearActuator&#038; x, LinearActuator&#038; y, LinearActuator&#038; z);

     void moveTo(float newX, float newY, float newZ);
     void moveHome();
     inline bool axesInMotion() { return _xInMotion || _yInMotion || _zInMotion; }
     virtual void notify(uint32_t eventId, void* context);
 };</pre>
<p><h4>Linear Actuator</h4</p>
<pre lang="c++">class LinearActuator : public Device,
                       public Observable,
                       public Observer
{
    float _currentPos;
    float _revPerMM;
    StepperDevice&#038; _stepper;
    OpticalInterrupt&#038; _nearInterrupter;
    OpticalInterrupt&#038; _farInterrupter;

public:
    LinearActuator(float _revPerMM, StepperDevice&#038; stepper,
      OpticalInterrupt&#038; far, OpticalInterrupt&#038; near);
    inline float currentPosition() { return _currentPos; }
    inline void setTempRate(float rate) { _stepper.setTempRate(rate); }
    void moveTo(float newPosMM);
    void moveHome();
    virtual void notify(uint32_t eventId, void* context);
};</pre>
<p><h4>Stepper Device</h4>
<pre lang="c++">class StepperDevice : public EventLoopTimer,
                      public Device,
                      public Observable
{
    int8_t _stepPin;
    int8_t _dirPin;
    bool _forward;
    int _currentTick;
    int _targetTick;
    int _ticksPerRev;
    milliclock_t _maxRate;
public:
    StepperDevice(int8_t stepPin, int8_t dirPin, int ticksPerRev, milliclock_t rate);

    void goForward();
    void goBackward();
    void turn(float numberOfRevolutions = 0.0f);
    void start();
    void stop();
    void setTempRate(float rate);
    virtual void fire();
};</pre>
<p><h4>OpticalInterrupt</h4>
<pre lang="c++">class OpticalInterrupt : public Device,
                         public Observable,
                         public PeriodicCallback
{
    int _inputPin;
public:
    OpticalInterrupt(int pin);
    virtual void service();
};</pre>
<p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=301</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Event Loop for the Arduino</title>
		<link>http://www.ooeygui.com/?p=293</link>
		<comments>http://www.ooeygui.com/?p=293#comments</comments>
		<pubDate>Fri, 27 Mar 2009 16:36:39 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=293</guid>
		<description><![CDATA[Making an LED blink or driving a single stepper using the Arduino is very easy &#8211; pulse a pin in the Arduino loop handler is all you need. However, as builds become more complex, there is often the need to manage multiple devices. The RepRap firmware is such a project. The firmware has numerous steppers, [...]]]></description>
			<content:encoded><![CDATA[<p>Making an LED blink or driving a single stepper using the Arduino is very easy &#8211; pulse a pin in the Arduino loop handler is all you need. However, as builds become more complex, there is often the need to manage multiple devices.
<p>
The RepRap firmware is such a project. The firmware has numerous steppers, motors, heaters, fans and sensors &#8211; it is chalk full of features. The developers have literally performed magic with the tiny little Arduino. However, I believe they will admit that the code base is becoming a little unwieldy and difficult to modify.
<p>
As an operating systems developer, my job is to identify patterns in application development, build abstractions which simplify these common cases and generate boiler plate or error prone code. In my post on the <a href="http://www.ooeygui.com/?p=143">RepRap firmware refactor</a>, I described several design patterns which are applicable to not just RepRap, but many other complex embedded projects. The best place to start is with the root of all evil &#8211; the event loop.</p>
<h3>Event Loop</h3>
<p>Event driven programing is a staple of modern application development. In my experience, event driven patterns are not as prevalent in embedded development &#8211; it&#8217;s a shame, because it is very useful. The main conceptual leap requires the developer to give up control to the power of the loop &#8211; a leap that is often very difficult as they are used to complete control. I&#8217;ve completed an implementation, which in its current state is more of a timer loop, but will grow to enable queued events (both on and off board).</p>
<p>
This code is currently checked into <a href="https://reprap.svn.sourceforge.net/svnroot/reprap/trunk/users/lamadio/FirmwareRefactorPrep/main/">the RepRap source forge repository</a>. It is only dependent on the Dynamic Array implementation checked into the tree as well.
<p>
There are several features of this event loop:</p>
<ul>
<li>Periodic (or cycle) events</li>
<li>Timed events, with support for wrapping (since the milliclock quickly overflows)</li>
<li>Reentrant &#8211; You can add or remove events while processing an event</li>
<li>Support for nested, independent Eventloops (for those special cases)</li>
</ul>
<p><small>(NOTE: It is not interrupt safe at the moment)</small></p>
<h3>Sample Use</h3>
<pre lang="c++">void StepperDevice::turn(float numberOfRevolutions)
{
    if (_currentTick)
    {
        stop();
    }

    _targetTick = (int)(numberOfRevolutions / _ticksPerRev);

    notifyObservers(StepperEvent_Start, this);
    EventLoop::current()->addTimer(this);
}

void StepperDevice::fire()
{
    digitalWrite(_stepPin, HIGH);
    delayMicroseconds(5);
    digitalWrite(_stepPin, LOW);

    ++_currentTick;

    if (_targetTick &#038;&#038; (_currentTick == _targetTick))
    {
        notifyObservers(StepperEvent_Complete, this);
        stop();
    }
}</pre>
<h3>The Event Loop Header</h3>
<pre lang="c++">
#ifndef EventLoop_h
#define EventLoop_h

typedef unsigned long milliclock_t;
extern const unsigned long MILLICLOCK_MAX;

//
// Periodic Event Callback
//  Derive from this class to implement a periodic servicing
//
class PeriodicCallback
{
public:
  // NOTE: This is a harmless warning:
  //  alignment of 'PeriodicCallback::_ZTV16PeriodicCallback'
  // is greater than maximum object file alignment.
  // Bug in avr-g++.
  // See http://www.mail-archive.com/avr-chat@nongnu.org/msg00982.html
    PeriodicCallback();
    virtual ~PeriodicCallback();

    virtual void service() = 0;
};

//
// Timer
//  Derive from this class to implement a periodic timer.
//  This class also contains information needed for
//  maintianing a timer, designed to be memory efficient.
//
class EventLoopTimer
{
private:
    milliclock_t _lastTimeout;
    milliclock_t _period;
protected:
    inline void setPeriod(milliclock_t period)
        { _period = period; }

public:
    EventLoopTimer(unsigned long period);
    virtual ~EventLoopTimer();

    virtual void fire() = 0;

    inline milliclock_t period() const
    { return _period; }
    inline milliclock_t lastTimeout() const
        { return _lastTimeout; }
    milliclock_t nextTimeout() const;

    inline void setLastTimeout(milliclock_t nextTimeout)
        { _lastTimeout = nextTimeout; }
};

//
// Event Loop
//  This class implements the main loop.
//  It allows clients to register for periodic
//      servicing, or timed servicing.
//
class EventLoop
{
private:
    DArray _periodicEvents;
    DArray _timers;
    milliclock_t _lastTimeout;
    bool _running;

    void sortTimers();
    DArray* findFiringTimers();
public:
    EventLoop();
    ~EventLoop();

    void addPeriodicCallback(PeriodicCallback* callback);
    void removePeriodicCallback(PeriodicCallback* callback);

    int periodicCallbacks() { return _periodicEvents.count(); }

    void addTimer(EventLoopTimer* timer);
    void removeTimer(EventLoopTimer* timer);
    int timers() { return _timers.count(); }

    bool running() { return _running; }
    void exit() { _running = false; }

    void run();

    static EventLoop* current();
};

#endif</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=293</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated Arduino plugin</title>
		<link>http://www.ooeygui.com/?p=290</link>
		<comments>http://www.ooeygui.com/?p=290#comments</comments>
		<pubDate>Wed, 25 Mar 2009 06:39:45 +0000</pubDate>
		<dc:creator>lou.amadio</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.ooeygui.com/?p=290</guid>
		<description><![CDATA[I updated the Arduino plugin with the following features: ATMega328 support Arduino programming model (setup/loop instead of main) Support for pde files (which are just C++ source files) Download link Let me know if you have any issues. (or send a quick note to say you use it)]]></description>
			<content:encoded><![CDATA[<p>I updated the Arduino plugin with the following features:
<ul>
<li>ATMega328 support</li>
<li>Arduino programming model (setup/loop instead of main)</li>
<li>Support for pde files (which are just C++ source files)</li>
</ul>
<p><a href="Arduino.tmplugin.zip">Download link</a>
<p>Let me know if you have any issues. (or send a quick note to say you use it)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ooeygui.com/?feed=rss2&amp;p=290</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
