NETMF and the SparkFun SerLCD

Well… I’ve been spending some quality time with the .NET Micro Framework the last couple weeks. I’ve been always interested in electronics and the inner parts of devices. I even bought some Atmel AVR microcontrollers and a handful of components last year to get started with microcontrollers, but it didn’t work out (so many hobby projects, so less time…).

In May/June I discovered NETMF and I just had to try it. Embedded devices driven by C# code is just a dream come true.

So after some surfing I ordered a GHI Electronics EMX Development System to get started. Since I’m not that good at time management (and it’s holiday season with lots of social obligations) I didn’t come as far as I hoped to be. BUT… I would like to share some piece of code, though.

While working on a secret project called “BeerGuard” I created a small class to use the SparkFun SerLCD (16×2 and 20×4) with NETMF. I’m probably not the only one who has written such a class, but I’ll dump it on the Internet anyway.

Be aware that this is a quick implementation to get me started real quick. Not everything is tested and there is probably a lot of code improvement possible. I hope this might be a starting point for some people. Please don’t start bashing my coding style and please… post improvements and corrections!

using System;
using System.IO.Ports;

namespace LXIT.Hardware
{
    public sealed class SerLCD
    {
        public enum Direction { Left, Right }

        public enum DisplayType { C16L2, C16L4, C20L2, C20L4 }

        public enum Status { On, Off }

        private readonly SerialPort _serialPort;

        private readonly DisplayType _displayType;

        public SerLCD(string portName) : this(portName, DisplayType.C16L2)
        {}

        public SerLCD(string portName, DisplayType displayType)
        {
            // Defaults for SerialPort are the same as the settings for the LCD, but I'll set them explicitly
            _serialPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);

            _displayType = displayType;
        }

        public void ClearDisplay()
        {
            Write(new byte[] { 0xFE, 0x01 });
        }

        public void MoveCursor(Direction direction)
        {
            MoveCursor(direction, 1);
        }

        public void MoveCursor(Direction direction, int times)
        {
            byte command;

            switch (direction)
            {
                case Direction.Left: command = 0x10; break;
                case Direction.Right: command = 0x14; break;
                default: return;
            }

            for (int i = 0; i < times; i++)
            {
                Write(new byte[] { 0xFE, command });
            }
        }

        public void Open()
        {
            if (!_serialPort.IsOpen)
                _serialPort.Open();
        }

        public void SaveAsSplashScreen()
        {
            Write(new byte[] { 0x7C, 0x0A });
        }

        public void Scroll(Direction direction)
        {
            Scroll(direction, 1);
        }

        public void Scroll(Direction direction, int times)
        {
            byte command;

            switch (direction)
            {
                case Direction.Left: command = 0x18; break;
                case Direction.Right: command = 0x1C; break;
                default: return;
            }

            for (int i = 0; i < times; i++)
            {
                Write(new byte[] { 0xFE, command });
            }
        }

        public void SetBlinkingBoxCursor(Status status)
        {
            byte command;

            switch (status)
            {
                case Status.On: command = 0x0D; break;
                case Status.Off: command = 0x0C; break;
                default: return;
            }

            Write(new byte[] { 0xFE, command });
        }

        public void SetBrightness(int brightness)
        {
            if (brightness < 128 || brightness > 157)
                throw new ArgumentOutOfRangeException("brightness", "Value of brightness must be between 128-157.");

            Write(new byte[] { 0x7C, (byte)brightness });
        }

        public void SetCursorPosition(int line, int column)
        {
            if ((_displayType == DisplayType.C16L2 || _displayType == DisplayType.C16L4) && (column < 1 || column > 16))
                throw new ArgumentOutOfRangeException("column", "Column number must be between 1 and 16.");

            if ((_displayType == DisplayType.C20L2 || _displayType == DisplayType.C20L4) && (column < 1 || column > 20))
                throw new ArgumentOutOfRangeException("column", "Column number must be between 1 and 20.");

            if ((_displayType == DisplayType.C16L2 || _displayType == DisplayType.C20L2) && (line < 1 || line > 2))
                throw new ArgumentOutOfRangeException("line", "Line number must be 1 or 2.");

            if ((_displayType == DisplayType.C16L4 || _displayType == DisplayType.C20L4) && (line < 1 || line > 4))
                throw new ArgumentOutOfRangeException("line", "Line number must be between 1 and 4.");

            int[] startPos16 = { 0, 64, 16, 80 };
            int[] startPos20 = { 0, 64, 20, 84 };
            int charPos;

            switch (_displayType)
            {
                case DisplayType.C16L2:
                case DisplayType.C16L4:
                    charPos = startPos16[line - 1] + (column - 1);
                    break;
                case DisplayType.C20L2:
                case DisplayType.C20L4:
                    charPos = startPos20[line - 1] + (column - 1);
                    break;
                default:
                    return;
            }

            Write(new byte[] { 0xFE, (byte)(charPos + 0x80) });
        }

        public void SetDisplay(Status status)
        {
            byte command;

            switch (status)
            {
                case Status.On: command = 0x0C; break;
                case Status.Off: command = 0x08; break;
                default: return;
            }

            Write(new byte[] { 0xFE, command });
        }

        public void SetDisplayType(DisplayType displayType)
        {
            switch (displayType)
            {
                case DisplayType.C16L2:
                    Write(new byte[]{0x7C, 0x04}); // 16 characters
                    Write(new byte[]{0x7C, 0x06}); // 2 lines
                    break;
                case DisplayType.C16L4:
                    Write(new byte[]{0x7C, 0x04}); // 16 characters
                    Write(new byte[]{0x7C, 0x05}); // 4 lines
                    break;
                case DisplayType.C20L2:
                    Write(new byte[]{0x7C, 0x03}); // 20 characters
                    Write(new byte[]{0x7C, 0x06}); // 2 lines
                    break;
                case DisplayType.C20L4:
                    Write(new byte[]{0x7C, 0x03}); // 20 characters
                    Write(new byte[]{0x7C, 0x05}); // 4 lines
                    break;
            }
        }

        public void SetUnderlineCursor(Status status)
        {
            byte command;

            switch (status)
            {
                case Status.On: command = 0x0E; break;
                case Status.Off: command = 0x0C; break;
                default: return;
            }

            Write(new byte[] { 0xFE, command });
        }

        public void ToggleSplashScreen()
        {
            Write(new byte[] { 0x7C, 0x09 });
        }

        public void Write(byte buffer)
        {
            Write(new[] { buffer });
        }

        public void Write(byte[] buffer)
        {
            Open();

            _serialPort.Write(buffer, 0, buffer.Length);
        }

        public void Write(char character)
        {
            Write((byte)character);
        }

        public void Write(string text)
        {
            byte[] buffer = new byte[text.Length];

            for (int i = 0; i < text.Length; i++)
            {
                buffer[i] = (byte)text[i];
            }

            Write(buffer);
        }
    }
}
Posted in Programming, Technology | Tagged , , , , , | Leave a comment

Vici CoolStorage ported to MonoTouch

Philippe ported Vici CoolStorage to MonoTouch over the weekend. This makes Vici CoolStorage available for iPhone development using the MonoTouch framework.

Due to the lack of reflection on MonoTouch class declarations are not abstract. Classes have to be declared as concrete classes with getters and setters.

SQLite is the only supported relational database on iPhone, so Vici CoolStorage for MonoTouch only supports SQLite.

The port is still in beta, but is more or less functional. Input from beta testers is highly appreciated!

Check out the beta at the Vici CoolStorage webpage.

Posted in Apple/Mac & iPhone, Programming, Technology | Tagged , , , , | Leave a comment

Helping people by lending money through micro credits

Kiva.org LogoI don’t know exactly how I found out about Kiva.org, but once I visited their website I just had to become a member.

Kiva.org is an online platform that helps microfinancing organisations around the world get in touch with (potential) lenders. Lenders select the projects they want to support after reading through the information page and can start helping by lending as low as $25.00 and as high as their budget tells them.

The only fact that made me hesitate starting to lend money was the high interest rates. It didn’t seem fair that the loaners had to pay 20+ % interest, but after some searching and reading I got convinced this isn’t an argument not to start helping out.

If you’re interested you can visit my lender page on Kiva.org to follow the loans I’m currently participating in.

Posted in Misc | Tagged , , , | Leave a comment

Moscow-Vladivostok: A virtual trip thanks to Google

While planning our trip to Moscow (by car) later this year, I came across a virtual trip from Moscow to Vladivostok with the help of Google Maps and YouTube.

The virtual trip consists of a video stream showing the view from a train while you can see the position on Google Maps. To make things more interesting, you can listen to the rumble of the train wheels, a Russian radio station, some balalaika music or one of the three Russian books.

It’s a joint project of Google and the Russian railways to promote the Trans Siberian Railway.

Well… we are planning to make the Trans Siberian journey in 2011, so this gives us a little taste of what we can expect.

You can enjoy the trip yourself at this page.

Posted in Misc, The Web | Tagged , , , , | Leave a comment

Houston… we have a logo!

Yes, indeed… LXIT has a logo. And a business card design. The concept has lead to some discussions between colleagues and friends, but no one made me a counter proposal so I went with my original idea.
LXIT logo

Some patient designer at Design Outpost realized my idea after weeks of revisions and pixel tweaking. I’m happy with the final result, but as all things: it could be different, it could be better, it could be…

Some quotes from the project description as presented to the designers:

The idea behind the way I want to profile my company is as follows. It’s a company serving IT solutions (mainly web programming).Everyone associates IT guys with being (pussy) nerd. I would like to profile my company as being tough-ish, but still a bit nerdy.The tagline will be “When IT gets tough”. That way I want to express that I’m not only doing the easy stuff, but we handle tougher problems too.

That all said, the concept: If you think about who/what is tough, you might end up with a Viking.
So, I would like to have the head of a tough Viking wearing nerdy glasses as a company logo.

And some more:

What attributes would you like your logo to reflect about your business?
- Bit nerdy/geeky, but strong, tough and decisive

What is the overall message you are trying to convey to your target audience?
- We tackle all you IT problems

Now I need to create a new company website, but because the logo took about a year to accomplish and clients projects get priority, this might take some months… Hopefully I find a designer willing to create a design for me (a small hint to b-visual).

Feel free to grab a digital version of my business card.

Posted in Misc | Leave a comment

Vici Project support has moved to StackExchange

We all love Stack Overflow, so when Joel Spolsky told the world that the platform would be made publicity available we move the Vici Project support to StackExchange.

All questions regarding Vici MVC, Vici CoolStorage, Vici Parser, Vici WinService and all other future Vici projects can be viewed and answered on http://vici.stackexchange.com.

The old http://support.viciproject.com URL will redirect you to the new support location.

Posted in Programming, Software, The Web | Tagged , , , , | Leave a comment

Add an sitemap to your web site easily

Surf to XML-Sitemaps.com, fill out your web site’s URL and let it generate your sitemap automatically.

Posted in Uncategorized | Tagged , , | Leave a comment

GameSeat.be (finally) launched

GameSeat.be gives everyone the opportunity to enjoy virtual rides with his/her dream cars. You can rent a steering wheel, a racing seat, a monitor, … or everything as a whole for one day or more.

Ideally for the car enthousiast or console racer who normally doesn’t have the place to store such racing seat and occasionally wants to enjoy the ride of his life in his living room. Top: check out rFactor!

The website is built using Vici MVC, a open-source lightweight and powerful ASP.NET MVC framework (part of the Vici Project).

Posted in Uncategorized | Tagged , , , , , | Leave a comment

Developer Evangelism

Yesterday I attended the StackOverflow DevDays in Amsterdam. Some minor attempts were made to put out the word of the Vici Project (and in particular Vici MVC).

A reply to a tweet of @B_Virtual lead us to this website: Developer Evangelism

We’ll be digging into the website and hopefully we can get some information that will help us spreading the word of “our” open-source project(s).

Posted in The Web | Tagged , , , | Leave a comment

Online SVG to PNG conversion

Sometimes you need a PNG/JPG/TIFF version of a SVG file.

While there are lots of possible applications, this online tool will fit your needs most of the time: SVG to raster image conversion.

Posted in Software, The Web | Tagged , , , , | Leave a comment