Recently I have been making little programs that I have thought about for years wandering how they are done only to find out now I actually know how to do it and do it properly.
Today’s program I was thinking about was an ASCII art generator. That is a program that takes an image file and converts it into a representation made of text. For example below is the wikipedia logo but if you look view the original you will notice it is comprised of different letters.

The easiest way to achieve this is to take all of the letters you want the image to comprise of put them in order of pixel density (I.E. “M” is much denser than “.”). Then you take a grey scale version of your input and translate each grey colour into a letter. I decided this would be a bit too easy and so to make it slightly more challenging I would output this to console and use every character the console could output not just A-Z. To achieve this the encoding for the console would have to be taken into account. I ended up with the following code:

Encoding enc = Console.OutputEncoding;
List charDensity = Enumerable.Range((int)char.MinValue, (int)char.MaxValue).
           Select(c=>enc.GetString(enc.GetBytes((char)c))[0]).
           Distinct().
           Where(c=>!char.IsControl(c)).
           Select().(c=>{
            Bitmap bm = new Bitmap(20,20);
            using(Graphic g = Graphics.FromImage(bm)){
              g.DrawString( c.ToString(), new Font("Arial",8), Brushes.Black, new RectangleF(0,0,20,20));
            }
            var Sum = Enumerable.Range(0,bm.Width).Select(x=>
             Enumerable.Range(0,bm.Height).Select(y=>
              bm.GetPixel(x,y).ToArgb()==Brushes.Black.ToArgb()?1:0)).ToList().Sum();
            return new{ ch=c, sum=Sum};
           }.OrderBy(c=>c.sum).Select(c=>c.ch).ToList();

Now this may look like quite a mouthful but thats mainly because I was trying out all of my linq knowledge. If I was to do this properly I most likely not lay it out like the above as it is hard to read. But its not too hard to work out what is happening. After sorting out all the characters that we can output we draw that character count how many pixels it uses and call that its density. Then we sort the characters by density.

After producing the character density list its not hard to translate pixel values into an appropriate char value.

charDensity[charDensity.Count-1-(pixel.color*charDensity.Count)/(256*3)]

In this instance pixel color is the addition of the RGB values.

And that is how you make an ascii art generator that uses all of the characters that can be outputted.

I remember watching a really nerdy youtube video many years ago with two people having a challenge to create a 3d rotating wire frame cube outputed onto console as fast as possible. At the time it intrigued me and I had a little think about how I would go about doing it. In the end I couldn’t quite work out how to do all of the transformations. That was until I was bored one day and I cam across this post on stack overflow. This did all of the cube related part but didn’t actually show how to transform the pixels. After having a read of wikipedia I had a good a understanding of how I could do the 3D projection transforms so I now had all of the parts. In an effort to try understand all of it I did end up taking bits from all of the above resources to make my solution.

First I defined a cube by getting the coordinates all of its corners:

List corners = new List{
           new Point3D(-1,-1,-1),
           new Point3D(1,-1,-1),           
           new Point3D(1,-1,1),
           new Point3D(-1,-1,1),
           new Point3D(-1,1,1),
           new Point3D(-1,1,-1),
           new Point3D(1,1,-1),
           new Point3D(1,1,1)};

Note that the cube has 2 unit long sides. Now I needed to convert these points into all of the different sides. This bit is shamelessly taken from stackoverflow:

var lines = from a in corners
                 from b in corners
                 where (a - b).Length == 2 && a.x + a.y + a.z > b.x + b.y + b.z
                 select new { a, b };

The where clause prevents any duplicate lines by only allowing lines going one direction. In order to prevent diagonal lines the length of the two points has to always be 2.

At this point I decided mainly after reading the stackoverflow post the best idea would be to split the line into lots of points as defined by a resolution variable. I would then translate the points with 3D projection to work out where to place them.

var point = line.a + (i * 1.0f / (resolution-1)) * (line.b - line.a);

In the above i is how far along the line the point is in increments of 1/resolution. It uses the simple formula of a point P between points A and B equals A + x(B-A) where x is less than 1.
The final task is now to turn all of the points into X,Y points by using the wikipedia article. At this point I have not shown what the Point3D class is made of and it can now be discussed. As it is a bit too long to paste straight into the blog I will just link to my github version of it. The -,+ and * operator are pretty self explanatory as well as the length method. RotateX, Y, Z are easy to understand when you think back to school maths. The previously linked wikipedia article does show how to derive this if you still can’t work it out.
The clever part is the project function:

float factor = fov / (viewDist + z);
Point3D p = new Point3D(x, y, z);
return new Point3D(p.x * factor + width / 2, -p.y * factor + height / 2, 1);

This is a slightly different form than the one mentioned in wikipedia but it does the same thing. This can all then be combined to make a rotating cube.

Well I took a break after making my IP stack that could sometimes transmit.  Now that I have had a bit of time to sleep on it I am deciding to go back and make sure it crashes less often.

I still don’t know quite why it likes to crash but I have found one or two mistakes in my code so hopefully as I go through everything writing extensive tests the bugs will be found.  The first bug I have noticed is that there is an errata for the ENC28J60 that was missed that could corrupt the received packets.  This has now being fixed.

The first test was to check the SPI link as shown in part 3. The test file can be found on github. It does include the ENC28J60 driver but that is only for the register names and locations.  Whilst writing this test I found another small bug in the ENC28J60 driver.  When the device is reset by SPI 0xff is sent. You are meant to wait for 1ms after this occurs as the register that should tell you that it is busy is broken. In my code I was waiting for 1ms but this was not working.  Turns out you should also wait for the PHY component to come online as well. To be on the safe side I also increased the delay to 0.2s as this is at the start time is never really an issue.

The next test was to send an ARP packet and receive a reply. This ensures that the ENC28J60 driver is working correctly for reading and writing a packet of data. It also shows that the EtherNetII and ARP headers are working as expected.  This test file can also be found on github. When I started writing this test I decided that I should probably rewrite a lot of the old ip stack as it doesn’t really read well and is a bit of a mish mash of tests and actual code.  No bugs were found in this section though so that makes a change. I did manage to reduce the memory footprint of the program though.

The next stage is to get the ping example working. This will require a bit more thought than the other sections as I want to make it part of the rewritten ip stack.

I had thought that I could get away with just making a few small changes to the code written in part 3 but in the end I decided a complete rewrite was in order. The old version was designed for colour output since this is only going to be black/white we only need 1 bit for each pixel and can fit 8 pixels into each byte. The output code ended up looking like as follows:

vidOut:	
	out VGAPORT,r7 ;1 - 1	
	bst r8,1 ;1
	bld r7,BWHITE ;1
	bst r8,2 ;1
	nop ;1
	out VGAPORT,r7 ;1 - 2
	lpm r6,Z+ ;3
	bld r7,BWHITE ;1
	out VGAPORT,r7 ;1 - 3
	bst r8,3 ;1
	bld r7,BWHITE ;1
	nop ;1
	nop ;1
	out VGAPORT,r7 ;1 - 4
	bst r8,4 ;1
	bld r7,BWHITE ;1

The above is just an extract of the final code. The rest can be found on the github page. It works by loading the current pixel into the T flag. This is then loaded into r7 which is our output register. This only takes 3 cycles since we need to output every 5 cycles it gives us a bit of room for getting ready for the next pixel. It might actually be possible to shorten this to 4 cycles per pixel but I didn’t need anything better. When a tile has ended we add on the current tile line offset onto the tile position and repeat. It ended up producing a good simple B/W output with room for improvement. For example more tiles could be displayed each frame vertically and vertical resolution could be improved.

The next stage was to introduce input courtesy of the USI.

After that brief distraction of trying to interface with the enc28j60 I finally have a project to use my VGA output on AVR for. The main aim of this project is to end up producing a count down clock.  Output will be black and white and it will be controlled by a ATTiny45. This is a considerably smaller micro in pretty much all regards compared to the mega644p that I had been using previously. The main reason behind using the ATTiny is to try get all of the circuitry inside of a VGA cable to make a hidden controller. I haven’t quite thought how I will power it yet but I guess that can be left for when the issue arises. The project is hosted on github.

The pin out for the micro is as follows:

      RESET --|  |-- VCC
      CLK I --|  |-- PB2--BW
COMS--PB4   --|  |-- PB1--HSync
      GND   --|  |-- PB0--VSync

CLK I is sent to a oscillator that is at 20MHz. Since this is only going to be used to display the time the output will be 00:00 where 0 are different numbers. Assuming I can mange to output a pixel every 5 cycles max horizontal resolution is 512/5=102 pixels. We need to display 5 characters of same size. I will go for 20 pixels wide for each number the extra two pixels will be black. The vertical resolution by default will be 480 this though will make some odd shaped pixels so to simplify things there will be a black bar top and bottom of 40 pixels. We will also divide this by 4 just to make everything square. Each character therefore will be 20×20 pixels. I already have a working output so the next stage is to draw the actual characters. There is no point in actually doing this manually so a quick c# program will take care of that.

Now that the msp430 is interfacing correctly over the internet it is time to show exactly how this will be used. The main aim of the project is to be able to tell when cardio vascular suite equipment is in use over the internet. To achieve this we have attached sensors to the equipment with each one attached to a wireless msp430.  For now it is just a EZ430-RF2500. Messages are then sent to the base station which is the part that is also connected to the ENC28J60.

The messages are then sent to a server and users can see exactly when a machine is free for use from a website.

The wires are connected as follows 1st number is msp430 no. 2nd is enc28j60. 1 GND > 9. 2 VCC > 10. 3 P2.0 > 7. 15 SOMI > 3. 16 CLK > 1. 18 SIMO > 2.

The above image shows the wiring for the base station. This will eventually be converted into a PCB once everything has been confirmed working. The only thing that is left to do now is to join the two sections of code together the part controlling wireless coms and the part controlling the enc28j60. This should in theory just be a little bit of modification to the provided temperature gauge source code so I don’t plan on showing it in much detail. The code base also still needs to be cleaned up and the TCP section needs to have finish added to it.

In theory this should be able to be ported over to the launchpad and if I have the time I will try give that a shot.  The finished IP stack can be found on github. I also plan to add a few examples showing working seperate parts so that changes can easily be tested.

I have been putting off writing about the TCP part for quite some time but I guess there is nothing else I can talk about apart from that. TCP requires a handshake before data can be sent/received. This is done by first sending a SYN which is replied by a SYN + ACK this is then ACKed back. Finally a PSH + ACK is sent to send data. After this you should receive data and close the connection but since this is only a very basic html data sender it will be a bit naughty and just go quite after sending.

The TCP header has the following layout:

typedef struct
{
  IPhdr ip;
  unsigned int sourcePort;
  unsigned int destPort;
  unsigned char seqNo[4];
  unsigned char ackNo[4];
  unsigned char NS:1;
  unsigned char reserverd : 3;
  unsigned char hdrLen : 4;
  unsigned char FIN:1;
  unsigned char SYN:1;
  unsigned char RST:1;
  unsigned char PSH:1;
  unsigned char ACK:1;
  unsigned char URG:1;
  unsigned char ECE:1;
  unsigned char CWR:1;
  unsigned int wndSize;
  unsigned int chksum;
  unsigned int urgentPointer;
  //unsigned char options[8];
}TCPhdr;

We are sending HTML data so the destination port will be 80 the source port can be anything but in general it is a value greater than 50,000 and it will change for every different connection. As this will be only html to one server we will keep this constant. SeqNo is the sequence number and is increased by how much data the server you are communicating with received. Its initial number is random and for this application it was set to 1 just to make it easier to see in wireshark. The AckNo is the acknowledgement number and is like SeqNo except is about the data that the server is sending. Its initial number is 0 but when the first packet is replied it will be set to a random number by the server.

The next part is a bunch of different flags. NS and reserved are not used and are set to zero. Hdrlen is the length of the header in 4 bytes. The rest of the flags are set depending on what data is being sent/received.

WndSize is the maximum size of data that can be sent we don’t have very much room and is set to the size of the buffer – the size of this header. The chksum is calculated in the same way as UDP chksum so see the previous post. Urgent point is used in fragmented packets and will not be used. I have an array of chars called options commented out which can also be used for specifying other things but they are optional.

The first packet to send was therefore a simple SYN packet with everything set to default values. When the server responded we received a packet that was a SYN + ACK. To reply to this first all of the ports, IP address’, MAC address’ and AckNo/SeqNo had to be swapped. After this the SeqNo number has to be incremented if there is a SYN and incremented by the amount of data if there is data. Next the SYN flag is removed so that it was just a ACK packet and finally all lengths and checksums are recalculated. This packet is then sent and just after it another packet is sent that has our data inside of it as well. For a test message the following was sent to google.com.

"GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n"

I haven’t actually got around to processing the reply messages but just from debugging I was able to see a reply with the correct data inside. The next step is therefore to tidy up the code and try make a cleaner finish to sending data.