Archive for the ‘Technology’ Category

NETMF and the SparkFun SerLCD

Tuesday, August 17th, 2010

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);
        }
    }
}

Vici CoolStorage ported to MonoTouch

Tuesday, February 23rd, 2010

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.

French Police Save Millions Switching To Ubuntu

Friday, March 13th, 2009

Always nice to see positive stories about migrations from Windows to Linux. This time it’s the French police.

Read the full article on Ars Technica.

I want one of these: ElectraFlyer – C

Friday, December 5th, 2008

Besides computers, programming, cars, movies, friends, family and my girlfriend, I’ve another interest: planes! I don’t have a flying license, but I hope to get one some time. In the meantime I enjoy flying RC models when the weather in Belgium allows me to.

My plan is to get a license to fly ULM’s one day and maybe move onto something bigger later on. In my search for information I came across different types of planes that are affordable (Afford a Plane), but now I came across a “green” one: the ElectraFlyer – C. It’s a modified glider that has an electrical motor which can make the plane fly for 90 minutes at +/- 110 km/h. When you decides to start “gliding” to land, you can turn the propeller into wind powered generator to charge the batteries.

Maybe this will become my private company plane, one day, maybe, whenever, we’ll see, …

Songbird 1.0 finally released

Wednesday, December 3rd, 2008

After about 2 years of development, we can finally embrace the first major release of Songbird. It’s an open-source media player using the Mozilla Application Framework that has the capability to surf the web and is able to play, queue or subscribe to embedded media from a web page. Video support isn’t all that super, yet!

There is support of portable media devices, although the support of iPod devices is limited. As a (might-be-maybe-we-will-see) future owner of an iPhone, I would love to see Songbird supporting it. I do not like iTunes at all.

And of course… it’s cross platform! So your Mac, Linux box or Windows PC will happy to run it for you.

UPDATE: After writing this post I searched around a little and came upon this page: 10 Alternatives to iTunes for managing your iPod. Enjoy :o)

Compromising Electromagnetic Emanations of Wired Keyboards

Monday, October 20th, 2008

Or how they can know what you’re typing in the room next door: Article + 2 video’s

From Russia With Love: mp3zr

Friday, October 10th, 2008

Another reason why you gotta love Russians: http://mp3zr.com

Search and listen to thousands (even millions?) of MP3s… Very nice for previewing a CD etc before buying it!

Electricity 2.0

Friday, October 10th, 2008

Eric Schmidt, Chairman and CEO, Google interviews Jeffrey Immelt, Chairman and CEO, GE.


Originally found on YouTube, but I’ve got to support GarageTV, don’t I :)

Seam carving for content-aware resizing

Friday, October 3rd, 2008

GIMP plugin implementation: Article on Arse Technica