Programming the ATmega168

There are several ways to get your program onto an ATmega168, the way I'm doing it is with one of these programmers and some jumper wires  - essentially I followed the SparkFun tutorial here.  This is something that I'm working on at the moment:

 

But you could also use one of these Olimex development boards, which is another way I have tried (and means that you can dispense with all those jumper wires).

The AVR pocket programmer is good because pretty much any PC has USB these days (you can also use serial or parallel ports to program an ATmega).  But the pocket programmer can also provide a 5v power supply from USB.

If you want to build your own programmer (which would probably be the cheapest option) then take a look that this, which should get you able to build a programmer for the cost of some wire, resistors and a parallel port connector (assuming that you have a PC with a parallel port).  For me, I found it easiest to just buy something from SparkFun.  In my experience the pocket programmer only works when attached to a USB hub, I've never managed to get it to work when plugged directly into the USB port of my PC - I've never bothered to find out why.

Of course, the other thing you'll need is a development tool, so that you can compile your source code and get the resulting output file copied to the processor.  I'm using WinAVR, or more specifically the portable version which is here.  The portable version means that I can put my development environment on a memory stick and use it on whatever computer I happen to be sat in front of.  Very nifty.

So when you're armed with 1) a programmer, and 2) a copy of WinAVR ...you should be ready to go.  You'll need some code to compile!  I'm going to post that next.

Optimising StringBuilder Appending

I have been working on some C# code optimisation, for speed.  The code in question does a lot of work with strings, so we already use StringBuilder to make it more efficient.  But what is the fastest way to append stuff to the StringBuilder?  In this instance, we're building a lot of comma seperated lists, and even with StringBuilder there are several ways, for example:

 

Method 1, AppendFormat:

sb.AppendFormat("{0},",myStr);

 

Method 2, Multiple Append:

sb.Append(myStr);

sb.Append(",");

 

Method 3, Multiple Append (with a comma already in a string):

string sep = ",";

...

sb.Append(myStr);

sb.Append(sep);

 

Method 4, Single Append:

sb.Append(myStr+sep);

 

... so I decided to check it out.  Here are the results (in seconds), after using each technique one hundred million times (I did five tests and then averaged the results):

 

 

#1

#2

#3

#4

#5

Average

1 AppendFormat

17.20

17.56

17.36

17.58

17.55

17.45

2 Multiple Append

6.61

7.27

6.70

7.27

7.28

7.03

3 Multiple Append (comma in string)

6.65

7.20

6.75

7.20

7.20

7.00

4 Single Append

8.13

8.34

8.31

8.34

8.34

8.29

 

I was quite surprised at how much slower AppendFormat was (although I can understand why).  But it's also worth remembering that the lazy coders way of using a single Append with the + operator to attach the comma is quite a bit slower than calling two Append methods (again, you can understand why when you think about it).

 

Here is the code that I used to test:

 

static void Main(string[] args)

{

    DateTime start = DateTime.Now;

    StringBuilder sb = new StringBuilder();

    string myStr = "hi";

 

    for (int t = 0; t < 100000000; t++)

    {

        sb.AppendFormat("{0},",myStr);

        if ((t % 1000)==0) sb.Remove(0, sb.Length - 1); 

    }

    TimeSpan gap = DateTime.Now - start;

    Console.WriteLine("AppendFormat takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    start = DateTime.Now;

    for (int t = 0; t < 100000000; t++)

    {

        sb.Append(myStr);

        sb.Append(",");

        if ((t % 1000) == 0) sb.Remove(0, sb.Length - 1);

    }

    gap = DateTime.Now - start;

    Console.WriteLine("Multiple Appends takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    string sep = ",";

    start = DateTime.Now;

    for (int t = 0; t < 100000000; t++)

    {

        sb.Append(myStr);

        sb.Append(sep);

        if ((t % 1000) == 0) sb.Remove(0, sb.Length - 1);

    }

    gap = DateTime.Now - start;

    Console.WriteLine("Multiple Appends (comma in string) takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    start = DateTime.Now;

    for (int t = 0; t < 100000000; t++)

    {

        sb.Append(myStr+sep);

        if ((t % 1000) == 0) sb.Remove(0, sb.Length - 1);

    }

    gap = DateTime.Now - start;

    Console.WriteLine("Single Append (comma in string) takes: {0}", gap);

    sb.Remove(0, sb.Length - 1);

 

    Console.ReadKey(); 

}

Sorting a jagged array

This week, I had a need to sort a jagged array of integers, and this is the solution that I came up with:

 

public class IntArraySorter

{

    public static void ExampleSorting()

    {

        int[] a = new int[5] { 1,2,3,4,0 };

        int[] b = new int[4] { 1,2,3,0 };

        int[] c = new int[3] { 1,2,0 };

        int[] d = new int[2] { 1,0 };

        int[] e = new int[1] { 1 };

 

        // sort a 2 dimensional array of integers

        int[][] multi = new int[5][] {a,b,c,d,e};

        Array.Sort(multi, CompareIntArrays);

 

        // we can also use it to sort a List of integer arrays

        List<int[]> list = new List<int[]>();

        list.AddRange(new int[][] {a,b,c,d,e });

        list.Sort(CompareIntArrays);

        int your_breakpoint_here = 0;

    }

 

    public static int CompareIntArrays(int[] x, int[] y)

    {

        int length = x.Length > y.Length ? x.Length : y.Length;

        int diff = 0;

        for (int t = 0; t < length; t++)

        {

            diff = safeGet(x, t) - safeGet(y, t);

            if (diff != 0) return diff;

        }

        return x.Length - y.Length;

    }

    private static int safeGet(int[] arr, int element)

    {

        return (element > arr.Length - 1) ? 0 : arr[element];

    }

}

 

...this technique will work with 2 dimensional arrays of integers if they are jagged or not.  So I thought that it was the type of thing that was worth posting up here for future reference.

Improved Annoyatron Schematic

I have been starting to learn to use Eagle, so that I can document my circuit diagrams.  Being quite new to designing hardware I'm learning that it's not good enough to just keep a copy of the source code anymore!  So, here is the very simple circuit that makes up my improved Annoyatron:

It's very simple to knock this up on a small breadboard, you just need the ATMega168, a speaker and a battery, just like this:

Obviously, the ATmega168 is overspecified, but I have a few of them and it's easier to mess around with one type of processor.  I really will try to post the source code and some notes on how to get the source code onto the processor as a program.  Honest.