<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>l&apos;Hexapod</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.lhexapod.com/blog/atom.xml" />
    <id>tag:www.lhexapod.com,2009-04-08:/blog/1</id>
    <updated>2010-02-16T12:12:18Z</updated>
    <subtitle>Len Holgate&apos;s journey into robotics, embedded electronics and the design and creation of a hexapod robot... </subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.25</generator>

<entry>
    <title>Delays...</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2010/02/delays.html" />
    <id>tag:www.lhexapod.com,2010:/blog//1.69</id>

    <published>2010-02-16T12:09:18Z</published>
    <updated>2010-02-16T12:12:18Z</updated>

    <summary>I&apos;ve been very busy with other things just recently and so I haven&apos;t been able to spend much time on this project. Work has been busy as I&apos;m working towards a new release of my code and my son Scott...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[I've been very busy with other things just recently and so I haven't been able to spend much time on this project. Work has been busy as I'm working towards a <a href="http://www.lenholgate.com/archives/000881.html">new release</a> of my code and my son <a href="http://www.lenholgate.com/archives/000891.html">Scott</a> was born on 25th January. Right now I have very little spare time for my robotics but I'm sure that will change as things settle into a new routine.&nbsp;]]>
        
    </content>
</entry>

<entry>
    <title>Bug in v7.0 of the servo controller firmware</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2010/01/bug-in-v70-of-the-servo-controller-firmware.html" />
    <id>tag:www.lhexapod.com,2010:/blog//1.68</id>

    <published>2010-01-03T19:05:28Z</published>
    <updated>2010-01-03T19:15:45Z</updated>

    <summary>The simple servo sequencer that I&apos;ve been working on has exposed a bug in the servo controller firmware. The bug is due to stack corruption during movement completion notifications, so it only happens if you use the &apos;multi-move&apos; commands or...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Mechanical" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="bugs" label="bugs" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mistakes" label="mistakes" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servosequencing" label="servo sequencing" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servos" label="servos" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[The <a href="http://www.lhexapod.com/blog/2010/01/where-are-we.html">simple servo sequencer</a> that I've been working on has exposed a bug in the <a href="http://www.lhexapod.com/blog/2009/11/atmega168-64-channel-servo-controller-with-advanced-servo-commands.html">servo controller firmware</a>. The bug is due to stack corruption during movement completion notifications, so it only happens if you use the 'multi-move' commands or the delay move command. The problem is that at the end of <b>SerialSendMoveCompletionNotification</b> we jump back to the serial data accumulation loop rather than using a <b>ret</b> to return... Since we enter&nbsp;<b>SerialSendMoveCompletionNotification</b>&nbsp;via a call rather than a jump we are failing to balance the stack and so eating two bytes each time we call the function. Eventually the stack usage will &nbsp;start to overwrite our data space and cause 'strangeness'. The fix is simple, remove the jump and replace it with a <b>ret</b>.<div><br /></div><div>The sequencer has also exposed an issue which I think lies with my current servos. After continuous 'stepping'; i.e. running the single leg as if it were walking for around 40-50 commands (15 steps), some of the servos start to slow down, there doesn't seem to be anything wrong with the servo controller as the <a href="http://www.lhexapod.com/blog/2009/11/back-to-jit-testing.html">TextStar Serial LCD Display</a> in "Servo monitor mode" was showing that the signals were still good and my multimeter showed that the servos weren't trying to pull too much power. It seems to be a torque or heat issue; more investigation is required, but things seem fine if I'm just running servos that don't have a load on them...</div>]]>
        
    </content>
</entry>

<entry>
    <title>Where are we?</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2010/01/where-are-we.html" />
    <id>tag:www.lhexapod.com,2010:/blog//1.67</id>

    <published>2010-01-02T10:57:23Z</published>
    <updated>2010-01-02T14:21:19Z</updated>

    <summary>Once the servo controller code was feature complete I switched to looking at the hardware side of things and thinking about the next stage, the servo sequencing.From a hardware point of view I had several things to work on. Firstly...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Electronics" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Mechanical" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="electronics" label="electronics" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="fabrication" label="fabrication" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="legs" label="legs" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="prototype" label="prototype" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[Once the servo controller code <a href="http://www.lhexapod.com/blog/2009/11/atmega168-64-channel-servo-controller-with-advanced-servo-commands.html">was feature complete</a> I switched to looking at the hardware side of things and thinking about the next stage, the servo sequencing.<div><br /></div><div>From a hardware point of view I had several things to work on. Firstly I needed to get the servo controller and I/O multiplexor chips off of a breadboard and onto something a little more permanent. Since I still find building things with perfboard a little hard I decided to build the controller itself on one board and build separate daughter boards for the I/O multiplexing. This should mean that I can replace the parts separately as long as the connections required remain the same. I decided that each I/O daughter board could contain 2 <a href="http://www.lhexapod.com/blog/2009/05/cd74hct238e.html">CD74HCT238E</a>'s with some header pins for each of the 16 output channels, 3 pins for the address selection lines and 2 more for the signal lines. I deliberately left off the power and ground pins for the servos as these really didn't work well on the perfboard. The power and ground pins are connected in one direction and the IC to servo control connections are in another direction; without some fairly hairy board trace cutting and cross soldering doing both on a single perfboard would have been impossible. My solution was to build yet another separate board from a different style of perfboard for the servo power and ground connections; this was just two long strips of headers connected as two buses. &nbsp;The servo connectors themselves are then used to physically hold the two boards together. This has another advantage for me in that it will allow me to reuse the I/O board with a more complex power and ground supply board if I decide to investigate the <a href="http://www.lhexapod.com/blog/2009/12/sensing-servo-torque.html">servo torque feedback</a> idea some more (this may require monitoring each of the servo power lines and so would require a different style of power supply board).</div><div><br /></div><div>Here are some pictures of the resulting boards.</div><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="IOBoard.png" src="http://www.lhexapod.com/blog/pictures/IOBoard.png" width="244" height="326" class="mt-image-none" style="" /><img alt="" src="http://www.lhexapod.com/blog/pictures/ServoPowerBoard.png" width="244" height="326" class="mt-image-none" style="" /></span></div><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="IOAndPower.png" src="http://www.lhexapod.com/blog/pictures/IOAndPower.png" width="244" height="326" class="mt-image-none" style="" /><img alt="IOBoardUnderside.png" src="http://www.lhexapod.com/blog/pictures/IOBoardUnderside.png" width="244" height="326" class="mt-image-none" style="" /></span></div><div>I now need to build another I/O board and I'll have 32 PWM channels for my servos.&nbsp;</div><div><br /></div><div>The servo controller itself ended up being on a board which could probably be used for all manner of ATMega projects. The board contains header pins for the I/O lines that I need, a reset button, a socketed crystal, power buses and an ISP programming header. About the only thing that's been specially done for the servo controller application is the fact that the I/O multiplexor address lines have 4 banks of headers broken out so that I can connect multiple I/O boards to the servo board easily. The board is pretty much complete and works well; I'm especially pleased with the ISP header as it was quite tricky to fit onto the board due to the connections required. All that's currently missing are the caps on the clock lines, but the board works pretty well without them and they're currently on order and there's space on the board for them. Note that a slight physical design error meant that the single power and ground pins that I had intended to use were in the way of the ISP plug. I cut those off and replaces them with the longer header strips which work better as they give me somewhere else to get a power or ground connection from...</div><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="ServoControllerBoard.png" src="http://www.lhexapod.com/blog/pictures/ServoControllerBoard.png" width="244" height="326" class="mt-image-center" style="" /></span></div><div>Once all of this was done I tested things and then swapped out my Max232 board for the <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=9132">Sparkfun regulated XBee breakout board</a> and connected the XBee in place of the hard wired RS232 connection. This worked well and left me with a set of boards that only required a power line to tether them; the battery system is on my list of things to work out. Unfortunately I managed to brick one of my XBee's. I'm still not quite sure what happened but I think it could have been either a spike on the 5v power line or a 5v splash onto the XBee TX line. The Sparkfun board regulates the 5v supply to the 3.3v required by the XBee and uses a diode to drop some voltage on the RX line so that the 5v TTL logic line from the ATMega is dropped to be within the tolerances of the 3.3v logic required by the XBee but it leaves the TX line unprotected (the 3.3v logic levels of the XBee are enough to register as valid levels for the 5v side of the circuit but if 5v were applied to it then it would cause problems...). Ideally I'd like to put together a more robustly protected circuit with level shifting on both RX and TX lines but right now I don't quite know how to do that (even the <a href="http://www.ladyada.net/make/xbee/">AdaFruit XBee board</a> only level shifts the input lines and leaves the output lines vulnerable). I expect I'll use the <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8745">Sparkfun level converter board</a> when I get a replacement XBee.</div><div><br /></div><div>With my electronics off of my breadboard I began working on the servo sequencer. This will deal with moving the servos in sequence to create various walking gaits. Once I'd played with a simple sequencer I decided that I needed to solve the 'hip joint' problem once and for all and then build more legs; after all,sequencing a single leg isn't that much fun.</div><div><br /></div><div>The <a href="http://www.lhexapod.com/blog/2009/04/prototype-leg-v01.html">prototype leg</a> that I built way back at the start of this project <a href="http://www.lhexapod.com/blog/2009/04/thoughts-on-the-proto-leg.html">has always been weak</a> as far as the hip joint is concerned. The need to connect two servos at right angles using only a piece of plastic window board creates many problems. My experiments with using metal brackets made from <a href="http://www.lhexapod.com/blog/2009/08/prototype-fabrication.html">Mecanno</a> failed as the pieces I had were insufficient to hold the servos correctly. Unfortunately I don't currently have access to the custom machining facilities that <a href="http://forums.trossenrobotics.com/showthread.php?t=2762">this guy</a> has access to, so custom aluminium parts are out of the question. In the end I spent a lot of time with a craft knife and pieces of window board and eventually came up with a design that seems to work; at the very least it's stronger and more reliable than the original leg. The design is based on the custom aluminium pieces from the <a href="http://forums.trossenrobotics.com/showthread.php?t=2762">A-Pod</a> hexapod. I expect it will still change somewhat but it's enough for me to move forward...</div><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Legv3.0.png" src="http://www.lhexapod.com/blog/pictures/Legv3.0.png" width="326" height="244" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span></div><div>I now have 6 Hitec HS-645MG servos on order along with a couple more XBee radios and a few more bits and pieces. The plan is to build two legs with the new servos and get the sequencer working. Once I get to this point I should be able to purchase more servos, carve more legs and move to a full six legs. Perhaps this hexapod project will actually have a hexapod before we reach our one year&nbsp;anniversary&nbsp;in April.</div>]]>
        
    </content>
</entry>

<entry>
    <title>Sensing servo torque</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/12/sensing-servo-torque.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.66</id>

    <published>2009-12-07T08:34:04Z</published>
    <updated>2009-12-07T08:41:52Z</updated>

    <summary>Whilst playing around with my servo controller I realised that the power used by a servo goes up considerably when it&apos;s under heavy load (such as when it&apos;s pressing against the table and still trying to move). I can, potentially,...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Sensors" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="sensors" label="sensors" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servocontrollers" label="servo controllers" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[Whilst playing around with my <a href="http://www.lhexapod.com/blog/2009/11/atmega168-64-channel-servo-controller-with-advanced-servo-commands.html">servo controller</a> I realised that the power used by a servo goes up considerably when it's under heavy load (such as when it's pressing against the table and still trying to move). I can, potentially, get an idea of this load by <a href="http://chiphacker.com/questions/875/how-do-i-measure-the-current-flow-to-a-component">measuring the current</a> that each servo is using and using this feedback somehow. I've yet to work out how, but at the very least it could be used to protect the servos against overloading; if the load gets above a certain threshold then stop moving! Ideally the servo controller could feed this information back to the user of the servo controller as well. Anyway, this requires quite a large amount of breadboarding changes, the use of some active low multiplexor chips and some playing around with the ADC on the ATMega. I don't think I'll experiment with this just yet...]]>
        
    </content>
</entry>

<entry>
    <title>New soldering iron...</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/12/new-soldering-iron.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.65</id>

    <published>2009-12-03T10:32:45Z</published>
    <updated>2009-12-03T10:40:11Z</updated>

    <summary>I decided to treat myself to an early christmas present and bought a 60W temperature controlled soldering station (a ZD-916 which I got from Maplin). All I can say is WOW. Suddenly I can solder neatly rather than making a...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Electronics" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="soldering" label="soldering" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tools" label="tools" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[I decided to treat myself to an early christmas present and bought a 60W temperature controlled soldering station (a <a href="http://www.china-zhongdi.com/zd-916.htm">ZD-916</a> which I got from <a href="http://www.maplin.co.uk/Module.aspx?ModuleNo=218050">Maplin</a>). All I can say is WOW. Suddenly I can solder neatly rather than making a smeary mess. The difference between this and my cheapo 12W soldering iron is just unbelievable. It just makes the whole process SO much easier. Where in the past when soldering something with a large heat sink or onto a large pad would be painful as both items would never seem to get up to temperature now I hear the iron click on as I touch the items to be soldered and the heat stays constant and it just works... Highly recommended.]]>
        
    </content>
</entry>

<entry>
    <title>ATMega168 64 channel servo controller with &apos;advanced&apos; servo commands</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/11/atmega168-64-channel-servo-controller-with-advanced-servo-commands.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.64</id>

    <published>2009-11-29T19:51:15Z</published>
    <updated>2009-11-29T20:07:46Z</updated>

    <summary><![CDATA[This is the AVR Studio&nbsp;project&nbsp;and assembly language source code files for the latest version (v7.0) of my 64 channel serial servo controller.This is the latest version of the ATMega168 version of the code which includes all of the new servo...]]></summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Source code" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="atmelatmega168" label="Atmel ATMega168" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="pwm" label="PWM" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servocontrollers" label="servo controllers" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="sourcecode" label="Source code" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[This is the AVR Studio&nbsp;project&nbsp;and assembly language source code files for the latest version (v7.0) of my 64 channel serial servo controller.<div><br /></div><div>This is the latest version of the <a href="http://www.lhexapod.com/blog/2009/09/atmega168-64-channel-servo-controller.html">ATMega168 version</a> of the code which includes all of the new servo commands that I wrote about <a href="http://www.lhexapod.com/blog/2009/09/new-servo-controller-commands.html">here</a> including the <a href="http://www.lhexapod.com/blog/2009/10/moving-multiple-servos-at-once.html">multi-move command</a> and the unit tests that I spoke of <a href="http://www.lhexapod.com/blog/2009/10/repeatable-unit-testing-with-avr-assembler-and-avr-studio.html">here</a>. The controller allows you to set minimum, maximum and startup servo positions for each servo which can be <a href="http://www.lhexapod.com/blog/2009/09/storing-data-in-the-eeprom-of-an-atmega168.html">saved into eeprom</a> and used every time the controller is powered up. It also includes a programmable, per servo, "centre adjust" value which can be used to adjust for servos that are installed slightly off centre.</div><div><br /></div><div><span class="Apple-style-span" style="font-family: 'trebuchet ms'; ">Source code is available&nbsp;<span class="mt-enclosure mt-enclosure-file" style="display: inline; "><a href="http://www.lhexapod.com/blog/ATMega168-7.3728Mhz-64Channel-ServoController-v7.zip" style="text-decoration: underline; outline-style: none; outline-width: initial; outline-color: initial; color: rgb(171, 4, 4); ">here</a></span>.</span></div><div><br /></div><div><br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>Back to JIT testing</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/11/back-to-jit-testing.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.63</id>

    <published>2009-11-26T12:41:16Z</published>
    <updated>2009-11-26T12:53:58Z</updated>

    <summary>The latest version of the serial servo controller is now fully operational (I&apos;ll upload the source code shortly). There are still some bugs that I&apos;m finding but the work I put in to getting the unit tests in place makes...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="links" label="links" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[The latest version of the serial servo controller is now fully operational (I'll upload the source code shortly). There are still some bugs that I'm finding but the work I put in to getting the unit tests in place makes fixing these bugs pretty straight forward. Whilst I have pretty much 100% coverage for the simpler serial commands I've stopped writing tests for the 'multi-move' command now and I've switched to <a href="http://www.lenholgate.com/archives/000359.html">"Just in time"</a> testing; that is I write a test in response to finding a bug. The test duplicates the input that causes the bug to show up and then I fix the bug using the test harness to exercise the code with the correct input values... It would be nice to stay focused on getting 100% coverage on the multi-move command but right now that's not a priority.&nbsp;<div><br /></div><div>Whilst developing the servo controller I often wished I had an oscilloscope, being able to visualise the signals that I was generating would have been useful many times. Due to the cost, choice and the fact that I eventually worked out what I was doing wrong in each situation I am continuing to delay getting an oscilloscope but today I saw a cheap little device that could be useful as I tune the controller in future. My 'new products' feed from <a href="http://www.coolcomponents.co.uk/catalog/">CoolComponents</a> had the <a href="http://www.coolcomponents.co.uk/catalog/product_info.php?products_id=428&amp;osCsid=eedb84b8e1c3cc060a1a623fb75c62fc">TextStar Serial LCD Display</a> in it this morning. This is a neat little programmable display which has a 'servo signal display' mode which enables it to display the pulse length and refresh rate of a servo signal. Given the cheap price and the fact that I'm sure the LCD display in itself will be useful I ordered one. I hope to hook it up to my controller so that I can see what's being generated. The datasheet for the device is <a href="http://cats-whisker.com/resources/documents/cw-lcd-02_datasheet.pdf">here</a>.</div>]]>
        
    </content>
</entry>

<entry>
    <title>Testing backwards</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/11/testing-backwards.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.62</id>

    <published>2009-11-16T16:48:31Z</published>
    <updated>2009-11-17T13:34:13Z</updated>

    <summary>It&apos;s taken me almost a month but I&apos;m finally back to working on integrating the multiple servo move command into the rest of the code. Well, the integration was done long ago, unfortunately the debugging was the bit that was...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[It's taken me almost a month but I'm finally back to working on <a href="http://www.lhexapod.com/blog/2009/10/integrating-the-multi-move-command.html">integrating the multiple servo move command</a> into the rest of the code. Well, the integration was done long ago, unfortunately the debugging was the bit that was taking up my time.<div><br /></div><div>I decided that putting 'printf' style debug output into the routine to attempt to debug it from my PC based control software was just the wrong way to go about finding the problems and so I set off on a mission to&nbsp;finally&nbsp;get some <a href="http://www.lhexapod.com/blog/2009/10/repeatable-unit-testing-with-avr-assembler-and-avr-studio.html">unit testing</a> into my code. This worked out well and I now have over 80 tests for all of the serial command code. I found a few subtle bugs and I'm in a much better position for&nbsp;reactoring&nbsp;away some duplicate code and other design smells. I also feel much more confident about making the other wide ranging changes that I will eventually make when I switch to using <a href="http://www.lhexapod.com/blog/2009/10/new-design-please.html">interrupt driven serial comms</a> and move to a 16bit control value for the PWM signals...</div><div><br /></div><div>So now I have to write the tests for the code that I know has some bugs in it... The problem I have with the code under test is that it's quite big. In fact it's quite a bit bigger, and more complex, than all of the other serial protocol routines that I've tested. The initial tests are easy enough, parameter validation etc, but the main tests involve me testing a large block of code that appears to have at least one 'oh dear I've gone off into an infinite loop' bug in it somewhere under some input data conditions... At first I thought I would have to break the code down into smaller functions that were easier to test and then I realised that I can already test the code in smaller sections, just as long as I do so backwards.</div><div><br /></div><div>The code is one long function that we jump into and which jumps back out to the command accumulation loop. Throughout the code there are various labels that break up the various sections of the code. If I structure my tests so that I test the code from the end back towards the front I can simply set up the environment with the data that each stage expects and then jump to a label that processes the data. So, if the code takes input data at A and then processes it via B, C, D, E and F, I can first test pushing the kind of data that E should produce by jumping to F. Once that's works I can test E with the data that D would produce, etc... Once I get to A the whole thing is tested...</div><div><br /></div><div>We'll see how it goes...</div>]]>
        
    </content>
</entry>

<entry>
    <title>ChipHacker.com</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/11/chiphackercom.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.61</id>

    <published>2009-11-15T10:08:16Z</published>
    <updated>2009-11-14T15:20:52Z</updated>

    <summary>For those of you interested in the kind of thing that this blog is about you might also find ChipHacker.com useful. It&apos;s a &apos;stackoverflow&apos; for embedded programming and electronics people. Hopefully it will become a useful resource!...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="chiphacker" label="chiphacker" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="links" label="links" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="questions" label="questions" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[For those of you interested in the kind of thing that this blog is about you might also find <a href="http://chiphacker.com/">ChipHacker.com</a> useful. It's a '<a href="http://stackoverflow.com/">stackoverflow</a>' for embedded programming and electronics people. Hopefully it will become a useful resource!]]>
        
    </content>
</entry>

<entry>
    <title>Relative branch out of reach</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/11/relative-branch-out-of-reach.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.60</id>

    <published>2009-11-14T15:09:51Z</published>
    <updated>2009-11-16T17:05:55Z</updated>

    <summary>The test code for the serial command processing code for my serial servo controller is turning out to be the largest piece of assembly language that I&apos;ve written. This means that all of a sudden I&apos;m coming across &quot;Relative branch...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="design" label="design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[The <a href="http://www.lhexapod.com/blog/2009/10/testing-testing.html">test code</a> for the serial command processing code for my serial servo controller is turning out to be the largest piece of assembly language that I've written. This means that all of a sudden I'm coming across "Relative branch out of reach" errors during the compile. I've got to a point where every time I add a test I have shuffled the code to such an extent that several relative branches need adjusting from <b>rjmp</b> to <b>jmp</b> or <b>rcall</b> to <b>call</b>. Not a great problem but, of course, <b>jmp</b> and <b>call</b> take up more space so the first round of adjustments often triggers a second round, etc. It seems that once you get to the point where your code needs <b>jmp</b> and <b>call</b> its size can just explode due to the fact that you now need to use <b>jmp</b> and <b>call</b>...<div><br /></div><div>Ah well, it's not a problem really... I'm now at 66 tests and 59% of my code space used up. I've got pretty complete coverage up to the "stop servos" command. I have the query commands to test and then I'm finally on to the multiple servo move command... Then I have the PWM code to test, but I expect I'll take a break from the testing for a while once I get the multiple servo move command to actually work!</div>]]>
        
    </content>
</entry>

<entry>
    <title>Testing, Testing...</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/10/testing-testing.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.59</id>

    <published>2009-10-31T11:53:47Z</published>
    <updated>2009-11-16T17:06:58Z</updated>

    <summary>The AVR assembly language unit tests that I spoke of last week are going well. I decided to explore the idea of unit testing by writing tests for the easier to test aspects of the serial protocol code and then,...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="design" label="design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[The AVR assembly language <a href="http://www.lhexapod.com/blog/2009/10/repeatable-unit-testing-with-avr-assembler-and-avr-studio.html">unit tests</a> that I spoke of last week are going well. I decided to explore the idea of unit testing by writing tests for the easier to test aspects of the serial protocol code and then, as this went well, I decided to write tests for the serial protocol code in order rather that simply jumping to write tests for the code that I know is broken. I figure that I'm more likely to write the tests that I actually need (i.e. for all of the code) this way, rather than simply writing the tests that I think I need.<div><br /></div><div>So far this is going well. The test harness program is now considerably bigger than the real servo controller program. I have around 50 tests at present and I'm around half way through the serial protocol code. I've found a couple of otherwise hard to find bugs; which is good. As usual the tests act as documentation for how the code is used and what the inputs and outputs and side effects are. This doesn't remove the need for actual documentation but it helps.</div>]]>
        
    </content>
</entry>

<entry>
    <title>Repeatable Unit Testing with AVR Assembler and AVR Studio</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/10/repeatable-unit-testing-with-avr-assembler-and-avr-studio.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.58</id>

    <published>2009-10-22T14:49:09Z</published>
    <updated>2009-11-16T17:07:56Z</updated>

    <summary>As I mentioned yesterday the servo controller project has got to the point where being able to unit test the code would be useful to me. In my day job as a C++ server developer I&apos;ve been using unit tests...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="design" label="design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[As I <a href="http://www.lhexapod.com/blog/2009/10/unit-testing-avr-assembly-language.html">mentioned yesterday</a> the <a href="http://www.lhexapod.com/blog/2009/10/i-seem-to-have-developed-something-remarkably-similar-to-the-ssc-32.html">servo controller project</a> has got to the point where being able to unit test the code would be useful to me. In my <a href="http://www.lenholgate.com/">day job</a> as a C++ server developer I've been using <a href="http://www.lenholgate.com/archives/cat_testing.html">unit tests</a> for several years and most of the code that I write is written in a <a href="http://en.wikipedia.org/wiki/Test-driven_development">Test Driven Development</a> style. This works well for me and was <a href="http://www.lhexapod.com/blog/2009/05/avr-studio-4.html">one of the first things that I missed</a> when I started to develop in AVR assembler in AVR Studio. At the time I didn't know enough about how I would structure my code, or even how I'd write the code at all, and testing, though obviously missing, was something I managed to do without.<div><br /></div><div>Now that my code has got pretty large I've begun to split it into separate asm files. These are broken down by purpose, in effect I'm creating different modules of functionality. Due to the way that AVR Studio works with assembler projects these files are then included into a master file which is then assembled. Since my code is already broken down into modules, if I'm careful with how I split the code up I've found that I can build separate test projects which include one block of real functionality from the servo controller project and which then include test harness code that provides the functionality that the real code needs to build; for example, I have a function called <b>SerialEchoCommand</b> which will echo a command back to the serial port, this is used once the command's arguments have been validated. By placing this function in one file and the code that uses it in another I can build a test which can replace <b>SerialEchoCommand</b> with a function that the test harness can use to determine if the real code would have done the right thing if it were linked with the real implementation of <b>SerialEchoCommand</b>. In testing terms this is called <a href="http://en.wikipedia.org/wiki/Mock_object">mocking</a>. I've provided a mock implementation of an interface that the code under test uses and the test can interrogate the mock to determine if the code under test is behaving as expected. With most testing the challenge is to separate the code that you want to test from the code that you don't want to test, or the code that is too hard to manipulate within the test.</div><div><br /></div><div>Once I realised that I could use relatively standard mocking techniques to separate the code under test from the underlying hardware it became obvious that I could build a test harness that would run in the AVR Studio Simulator and that could test various parts of my servo controller. Unit testing was within reach.</div><div><br /></div><div>I've spent a few hours adding some tests to some of the simpler parts of the serial protocol handling code and it's going well. I seem to have a structure that works and so far it's been easy to provide data for the function under test and then to test that it produces the correct outcome and uses the correct services in the expected way. The next release of the servo controller source code will include my test harnesses.</div><div><br /></div><div>I expect an example will help. Especially if you're not used to testing!</div><div><br /></div><div>Suppose we have a function called <b>SerialProcessCommandSetServoMinPosn&nbsp;</b>which is called from the code that accumulates and executes serial commands and&nbsp;who's&nbsp;job it is to take a servo index and a position and to update the servo configuration data so that the supplied position is the minimum position that the servo can be moved to. This function might look something like this:</div><br />
<pre>SerialProcessCommandSetServoMinPosn : 

    ld servoIndex, X+

    cpi servoIndex, NUM_SERVOS                  ; check the servo index is valid
    brlt PC+2
    rjmp SerialServoOutOfRange

    ld temp1, X                                 ; load new min posn

    rcall SerialSelectServoData

    adiw XL, MAX_POS_OFFSET

    ld temp2, X                                 ; read existing max position

    cp temp2, temp1                             ; new min must be less than 
    brsh PC+2                                   ; or equal to exisiting max
    rjmp SerialPosnOutOfRange 

    sbiw XL, MAX_POS_OFFSET
    adiw XL, MIN_POS_OFFSET

    st X, temp1
        
    rcall SerialEchoCommand
    
    rjmp SerialStart</pre>
This is generally how all of the serial command processing code is structured. The call into us is a <b>rjmp</b> from the serial command dispatch code. We validate our parameters, report errors or echo our command back to the guy on the end of the serial port and then either jump back to the serial data accumulation code or execute the command and then jump back to the serial data accumulation code.<div><br /></div><div>It's probably clear from the code above that to be able to test it we need to set <b>X</b> to be pointing to some valid data; outside of the test this would be pointing into the serial data accumulation buffer at the point just after the command code that tells the dispatcher that this is the 'set min' command. In our test <b>X</b> can point anywhere that has two bytes of data available, our test harness will set this up and set the contents of the buffer that <b>X</b> is pointing to so that it contains a servo index and a position. Our test also needs to provide implementations of <b>SerialServoOutOfRange</b>, <b>SerialPosnOutOfRange</b>, <b>SerialEchoCommand</b> and <b>SerialStart</b>. As long as these labels exist in a different file we can replace the real code with mocks for our test simply by including the mock code rather than the real code. We'll use the real implemetation of <b>SerialSelectServoData</b> as that function is responsible for taking a servo index and pointing <b>X</b> to the right place in the servo position data. It looks like this:</div><br />
<pre>SerialSelectServoData :

    push temp2

    ldi XL, LOW(POSITION_DATA_START)       
    ldi XH, HIGH(POSITION_DATA_START)

    ldi temp2, BYTES_PER_SERVO
    
    mul servoIndex, temp2

    add XL, resl
    adc XH, resh

    pop temp2

    ret</pre>
Our test just needs to provide a valid position data buffer (i.e. an equate that sets <b>POSITION_DATA_START</b> to something sensible) with some known values in it.&nbsp;<div><br /></div><div>The test might look something like this:</div><br />
<pre>TestSerialProcessCommandSetServoMinPosn :

    ldi temp1, 15
    mov testIndex, temp1
    
    rcall InitialiseSerialOutputBuffer

    rcall InitialisePositionDataToKnownValues

    ldi XL, LOW(TEST_SERIAL_INPUT_BUFFER)     
    ldi XH, HIGH(TEST_SERIAL_INPUT_BUFFER)

    ldi temp1, 0                            
    st X+, temp1                            ; servo index to change

    ldi temp1, 20                            
    st X, temp1                             ; new min value

    ldi XL, LOW(TEST_SERIAL_INPUT_BUFFER)   ; reset X   
    ldi XH, HIGH(TEST_SERIAL_INPUT_BUFFER)

    rjmp SerialProcessCommandSetServoMinPosn

    rjmp TestsFailed</pre>
For now we can ignore the <b>testIndex</b> register. Here we set up an output buffer for our implementation of&nbsp;<b>SerialEchoCommand</b>&nbsp;and initialise&nbsp;<b>POSITION_DATA_START</b>&nbsp;and the data in the buffer to sensible values. We then set up the serial input buffer to contain a servo index and a position value and set <b>X</b> to point to the servo index in the buffer. This is how the serial dispatch code would leave the <b>X</b> pointer after examining the previous byte in the real serial accumulation buffer and switching on it depending on which command code it represents. We then jump to the code under test and, hopefully, never return. In case we DO return we then end the test by jumping to the <b>TestsFailed</b> label.&nbsp;<div><br /></div><div>The <b>TestsFailed</b> label is one place where the test code will end up after tests have been run. The other is the <b>TestsSucceeded</b> label. Both simply consist of a jump to themselves. By setting break points on each of these jumps we can run the tests and discover if there are any failures.</div><div><br /></div><div>This serial code is slightly harder to test than it could be because it isn't structured as functions which return to their caller. Instead we jump into the functions and they jump back to the serial command accumulation loop when they're done. This makes error handling easier; failures result in the code at the level of the failure reporting the error back to the serial port and then jumping straight back to accumulate a new command. As such all of the code under test will eventually jump to <b>SerialStart</b>. To be able to determine if the test passed we need to be able to examine what the code under test did whilst it was running. This is where the <b>testIndex</b> register comes in. The mocked out code for <b>SerialStart</b> contains a jump table that jumps based on the contents of the <b>testIndex</b> register. Each test has a corresponding 'check results' function and the <b>SerialStart</b> code jumps to the check results code associated with the test that's currently running.&nbsp;</div><div><br /></div><div><b>TestSerialProcessCommandSetServoMinPosnCheckResults</b> might look something like this:</div><br />
<pre>TestSerialProcessCommandSetServoMinPosnCheckResults : 

    ; The call should leave X pointing at the config value that we have changed...

    cpi XL, LOW(POSITION_DATA_START + MIN_POS_OFFSET)
    breq PC+2
    rjmp TestsFailed

    cpi XH, HIGH(POSITION_DATA_START + MIN_POS_OFFSET)
    breq PC+2
    rjmp TestsFailed

    ld temp1, X                     ; validate that we changed the value we wanted to change
    cpi temp1, 20                   ; to the correct value
    breq PC+2
    rjmp TestsFailed        

    clr temp1                       ; reset the value to its starting value 
    st X, temp1

    rcall ValidatePositionDataIsUnchanged   ; and then make sure nothing else was changed

    ; now validate that the correct mock functions were called...

    ldi XL, LOW(TEST_SERIAL_OUTPUT_BUFFER)     
    ldi XH, HIGH(TEST_SERIAL_OUTPUT_BUFFER)

    ld temp1, X+
    cpi temp1, 1            ; there should have been 1 call
    breq PC+2
    rjmp TestsFailed

    ld temp1, X+
    cpi temp1, 0xFF         ; echo command
    breq PC+2
    rjmp TestsFailed

    inc testResult
    ret</pre>
Note that we can check that the <b>X</b> pointer has been left where we expect it to end up and that the data that should have been manipulated has been changed as expected. We can then check that the correct mock functions were called. In this case we check that one function, <b>SerialEchoCommand</b>, was called. The implementation of this could be something like this:<br /><br />
<pre>SerialEchoCommand : 

    ldi serialChar, 0xFF

    rcall SendSerial
    
    ret</pre>
Where SendSerial might be implemented like this:<br /><br />
<pre>SendSerial :
    push XL                                     ; save the registers that we use
    push XH
    push temp1
    push temp2

    ldi XL, LOW(TEST_SERIAL_OUTPUT_BUFFER)     
    ldi XH, HIGH(TEST_SERIAL_OUTPUT_BUFFER)

    ld temp1, X                                 ; load the number of bytes currently stored in the serial
    clr temp2                                   ; output buffer.
                                    
    inc temp1                                   ; increment the number of bytes as the offset from the
                                                ; start of the buffer is one greater than the number of bytes
                                                ; as the buffer also holds the count itself at offset 0
    add XL, temp1
    adc XH, temp2

    st X, serialChar                            ; store the data that would be written to the serial port in
                                                ; out buffer for later analysis in the test

    ldi XL, LOW(TEST_SERIAL_OUTPUT_BUFFER) 
    ldi XH, HIGH(TEST_SERIAL_OUTPUT_BUFFER)

    st X, temp1                                 ; save the number of bytes stored, note that we incremented
                                                ; this value above

    pop temp2                                   ; clean up the stack
    pop temp1
    pop XH
    pop XL

    ret</pre>
This makes it easy to check for data that the functions under test might write directly to the serial port, using <b>SendSerial</b>, or other mock functions that they may call, such as <b>SerialEchoCommand</b>. There's no need to test the functionality of <b>SerialEchoCommand</b> here, we can test that separately, so it's adequate that it simply writes a single well known token into the test output buffer.<div><br /></div><div>Of course, things get more complex when we're testing for correct handling of invalid values (i.e. if we pass in a servo index that's too big, or if we try and set a min posn that's out of range) but most of the tests required can be built on the same framework.</div><div><br /></div><div>Most functions, even PWM generating timer interrupt code, can be tested in a similar way. The complex part is always getting the granularity of the code packaging correct so that you can mock the appropriate layers. This often causes several simple functions, or macros, to be required rather than direct hardware access but it's often a good design decision to abstract these hardware access points away anyway. I've found in the past that allowing the tests to lead your design where appropriate (as is the way with TDD) usually results in a better design!</div><div><br /></div><div>Now, off to fix those bugs in the multi-move command...&nbsp;</div>]]>
        
    </content>
</entry>

<entry>
    <title>Unit testing AVR assembly language</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/10/unit-testing-avr-assembly-language.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.57</id>

    <published>2009-10-21T15:24:55Z</published>
    <updated>2009-11-16T17:10:25Z</updated>

    <summary>Way back at the beginning of this journey I mentioned the fact that I&apos;d quite like to be able to use some of the development disciplines that I use in my day job during the development of the firmware for...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Unit Testing" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="design" label="design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="unittests" label="Unit Tests" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[Way back at the beginning of this journey <a href="http://www.lhexapod.com/cgi-bin/mt/mt-search.cgi?search=unit+testing&amp;IncludeBlogs=1&amp;limit=20">I mentioned the fact</a> that I'd quite like to be able to use some of the development disciplines that I use in my day job during the development of the firmware for my hexapod. Now that I've actually written some non trivial assembly language for the AVR I find that I'm missing not having my usual unit tests to support my ongoing development and refactoring. This has been most&nbsp;noticeable&nbsp;just recently during the <a href="http://www.lhexapod.com/blog/2009/10/integrating-the-multi-move-command.html">integration of the most complicated serial command</a> of the new servo controller; the multiple move command.<div><br /></div><div>I'm currently working on separating out the code that processes serial command messages from the code underlying support code. The idea being that I can then build the serial command processing code into a new AVR Studio project and 'mock' out the support code so that I can test the serial processing code. Once that's done I should be able to write a suite of tests that can be run on the serial code to make sure that the commands do what they're supposed to do. I'm lucky that the serial command code generally either calls other functions (which I can mock out by creating a testing version of the function and including the source for that rather than the source for the real function) or modifies data (which I can examine as part of the test to ensure that it has been modified in the correct way).&nbsp;</div><div><br /></div><div>So far it's going quite well. More once I have it working well enough to document and even more once I then use these new tests to fish out the bugs in the multiple move command!<br /><div><br /></div><div><br /></div></div>]]>
        
    </content>
</entry>

<entry>
    <title>Integrating the multi-move command</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/10/integrating-the-multi-move-command.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.56</id>

    <published>2009-10-15T20:26:11Z</published>
    <updated>2009-10-15T20:35:32Z</updated>

    <summary>I&apos;m in the process of integrating the stand alone code that implements my &apos;multi-servo move&apos; command and the rest of the controller. It&apos;s harder than it should be, probably because I&apos;m not experienced enough yet with assembly language not to...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="design" label="design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mistakes" label="mistakes" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servocontrollers" label="servo controllers" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[I'm in the process of integrating the stand alone code that implements my <a href="http://www.lhexapod.com/blog/2009/10/moving-multiple-servos-at-once.html">'multi-servo move' command</a> and the rest of the controller. It's harder than it should be, probably because I'm not experienced enough yet with assembly language not to have made some school boy errors. <a href="http://www.lhexapod.com/blog/2009/08/a-timer-driven-pwm-servo-controller---part-4.html">Once again</a> I've run out of registers, mainly because I'm trying not to have to push stuff on the stack that often. I've been juggling with the limited number of registers and up until now it's worked but...<div><br /></div><div>The first problem is that I need two pointers to be able to do the data sorting for the multi-move command. Up until now all of the serial code has only ever had to use one pointer. I've been using X in the serial code and Y and Z in the PWM code. My usage of both Y and Z precludes me sharing them with the non interrupt code, which is a shame. The reason I can't share Z is because I'm using it to switch between modes in the timer interrupt; I use <b>ijmp</b> which is an indirect jump using Z to select which interrupt handler I need to call next time around. This is cute but hardly necessary... Removing this use of Z means that I can use it in the serial code as well, now that it's just a normal register pair I can simply push it onto the stack during the PWM setup code that also needs to use it for sorting...&nbsp;</div><div><br /></div><div>My second problem is that I should always have simply been pushing registers onto the stack when I entered the PWM setup routine. Instead I tried very hard to simply not share registers between the PWM code and the serial code. Unfortunately I've no pretty much run out and so have to go back into the code and adjust the register usage which is a pain and error prone...</div><div><br /></div><div>Anyway, that's almost done now and, hopefully, the rest of the integration will be straight forward.</div>]]>
        
    </content>
</entry>

<entry>
    <title>After the servo controller</title>
    <link rel="alternate" type="text/html" href="http://www.lhexapod.com/blog/2009/10/after-the-servo-controller.html" />
    <id>tag:www.lhexapod.com,2009:/blog//1.55</id>

    <published>2009-10-11T18:47:14Z</published>
    <updated>2009-11-16T14:19:51Z</updated>

    <summary>The work on turning my excel spreadsheet into AVR assembler code which can move multiple servos to arrive at their target locations at the same time is proceeding well. I have the required code operating in a stand alone environment...</summary>
    <author>
        <name>Len</name>
        
    </author>
    
        <category term="Programming" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Servos" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="atmelatmega168" label="Atmel ATMega168" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="design" label="design" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="embeddedassemblyprogramming" label="embedded assembly programming" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="gait" label="gait" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="i2c" label="i2c" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="pwm" label="PWM" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servocontrollers" label="servo controllers" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="servosequencing" label="servo sequencing" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="twi" label="twi" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.lhexapod.com/blog/">
        <![CDATA[The work on turning <a href="http://www.lhexapod.com/blog/2009/10/moving-multiple-servos-at-once.html">my excel spreadsheet</a> into AVR assembler code which can move multiple servos to arrive at their target locations at the same time is proceeding well. I have the required code operating in a stand alone environment in the simulator and all I need to do now is merge that in with the rest of the code... Once that's done my servo controller is complete and whilst <a href="http://www.lhexapod.com/blog/2009/10/new-design-please.html">I already know</a> that there are at least two further versions in the pipeline I expect I'll move onto something more before working on them.&nbsp;<div><br /></div><div>This weekend I sketched out some ideas for the next programming phase; the servo sequencer or 'gait controller'. This will initially be written in C++ and run on a PC but the design sketches that I did this weekend were for the microprocessor version. The plan is that the servo sequencer is a state machine which can be triggered off of servo move completions and timers. The idea being that it can be programmed to know about a sequence of moves (such as all of the moves required to move a 6 legged robot in a forward direction) and then be told to execute those moves. The sequencer would then manage this and other processors would deal with sensors and other decisions (such as exactly where the feet should land or exactly how the body should be angled, etc.). The sequencer can be isolated from these things a little by allowing the other controllers to tell it the detail (i.e. where exactly each three servos for each leg should be) but the sequencer itself would know that it moves this leg after that leg etc. Step length, step depth and body orientation can then be adjusted by tuning parameters that the overall sequence of steps uses without changing the state machine that makes the middle left leg move after the front right, or whatever.</div><div><br /></div><div>My current ideas for the microprocessor version of the sequencer are quite ambitious; but then that's the point really, these micro projects should be pushing me forward and shouldn't be easy. The sequencer, since it's essentially a programmable state machine, needs to be able to allocate manipulate and free various blocks of memory; so it seems that I'll be building a dynamic memory allocator at some point. It will use interrupt driven serial I/O; and once that's done that work can be used for the next version of the servo controller. It will need to speak to the PC so that a PC program can be used to controller the sequencer (until the next level of robot controller is&nbsp;conceived&nbsp;and then designed) and it needs to talk to the servo controller to actually move the legs (this may be two UARTS; potentially meaning I have to create the second without hardware support and bit-bang the comms out, or perhaps serial to the PC and TWI/I2C to the servo controller). The sequencer's state machine is driven by the completion of delayed moves from the servo controller; so we can kick of a sequence by actioning the first state and then wait for the completion to trigger the state transition. Additionally a state transition can set a timer which can later trigger a new state transition. The programmable timer code will need to be developed...&nbsp;</div><div><br /></div><div>Deliberately the sequencer will not be limited to controlling blocks of 3 servos. This wont be a hexapod sequencer but a generic servo sequencer that will work with the servo controller that I'm currently finishing. So, theoretically when I want to develop l'arachnid once l'hexapod is complete I can 'simply' switch to using 8 x 4 servo legs and the same firmware...</div><div><br /></div><div>However, the fact that I've now got to the point where I've almost completed a 'non-trivial' assembler project means that I feel I'm able to move the hardware side of the project forward. So I expect that once the servo controller is complete and whilst the sequencer is being designed I'll try and get to a point where I actually have the required number of servos and a 6 legged robot to control...</div>]]>
        
    </content>
</entry>

</feed>
