Socket.GetSocket

I have just started to play around with my FEZ Spider and I decided to see if I can create my own module. For this, I have decided to use a 2x16 LCD (and yes, I know I could have just bough one, but what is the fun in that?). To make a long story short, I got all working, took a photo of it and now I have my own module.

Now here is what I can not seem to crack:

I have a routine called “Initialize” that set the Socket up amongst other things, but similar to most of the examples out there, I have to specify the actual port number, it is not automatically detected. How do I in my module code determine in which socketNumber the module is plugged into? My existing code looks something like this, where I have specify the “int socketNumber”.

public void Initialize(int socketNumber)
{
// set the socket up
_socket = Socket.GetSocket(socketNumber, true, this, null);

        // define all the pins on the selected socket
        _LCD_RS = new DigitalOutput(_socket, Socket.Pin.Four, false, this);
        _LCD_E = new DigitalOutput(_socket, Socket.Pin.Three, false, this);
        _BackLight = new DigitalOutput(_socket, Socket.Pin.Five, false, this);
        _LCD_D4 = new DigitalOutput(_socket, Socket.Pin.Six, false, this);
        _LCD_D5 = new DigitalOutput(_socket, Socket.Pin.Seven, false, this);
        _LCD_D6 = new DigitalOutput(_socket, Socket.Pin.Eight, false, this);
        _LCD_D7 = new DigitalOutput(_socket, Socket.Pin.Nine, false, this);

        // start the LCD initialization procedure
        _LCD_RS.Write(false);
        Thread.Sleep(50);
    }

I guess there must be some other method where “_socket = Socket.GetSocket(socketNumber, true, this, null);” should rather be “_socket = Socket.GetSocket(SOMECOMMAND, true, this, null);”

Thanks in advance!

Best Regards
Jan

Hi and welcome to the forum.

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

@ janleroux -

It is not possible.

If you look at the source code of any module’s driver you will see that all of them have a constructor that has one parameter - socket number. This is done so that when you connect a socket using visual designer, VS will generate the code behind that will use the right socket number and will instantiate module driver object for you.

Why do you need your own Initialize method?

Ok, I understand that VS will create the code behind, but I still do not understand what I need to put into my code so that VS will know where to put the socket number and instantiate the module driver.

With regard to the initialize method for my module, my background is with PIC micro’s and I am used to create a initialization section where I run all my initialization routines to set all the different component and devises up. This normally only runs during start-up of PIC. So with a HD44780 compatible 2 x16 LCD as a first step my first step have to initialize the LCD itself. So what I am trying to achieve is to capture the socket number, and then to send the initialization sequence to the LCD. My module code looks like this:


using System;
using Microsoft.SPOT;
using Gadgeteer;
using Gadgeteer.Modules;
using Gadgeteer.Interfaces;
using System.Threading;

namespace Gadgeteer.Modules.Zoftworx
{
    /// <summary>
    /// A LCD2X16 module for Microsoft .NET Gadgeteer
    /// </summary>
    public class LCD2X16 : Gadgeteer.Modules.Module
    {
        Socket _socket;

        DigitalOutput _LCD_RS;
        DigitalOutput _LCD_E;
        DigitalOutput _BackLight;
        DigitalOutput _LCD_D4;
        DigitalOutput _LCD_D5;
        DigitalOutput _LCD_D6;
        DigitalOutput _LCD_D7;
        
        const byte DISPLAY_ON = 0xC;        // Turn visible LCD on
        const byte DISPLAY_CLEAR = 0x01;    // Clear display
        const byte DISPLAY_BLANK = 0x08;	// Blank the display (without clearing) 
        const byte DISPLAY_RESTORE = 0x0C;	// Restore the display (with cursor hidden)
        const byte CURSOR_HOME = 0x02;      // Move cursor home and clear screen memory
        const byte SET_CURSOR = 0x80;       // SET_CURSOR + X: Sets cursor position to X
        const byte SCROLL_RIGHT = 0x1E;	    // Scroll display one character right (all lines) 
        const byte SCROLL_LEFT = 0x18;	    // Scroll display one character left (all lines)
        const byte CURSOR_LEFT = 0x10;	    // Move cursor one character left
        const byte CURSOR_RIGHT = 0x14;	    // Move cursor one character right
        const byte CURSOR_UNDERLINE = 0x0E;	// Turn on visible underline cursor 
        const byte CURSOR_BLINKING = 0x0F;	// Turn on visible blinking-block cursor 
        const byte CURSOR_INVISIBLE = 0x0C;	// Make cursor invisible


        /// <summary>
        /// Initialize the LCD Display for 4 bit data communication.
        /// </summary>
        /// /// <param name="socketNumber">The socket the module is plugged in to.</param>
        public void Initialize(int socketNumber)
        {
            // set the socket up
            _socket = Socket.GetSocket(socketNumber, true, this, null);
            //_socket = Socket.GetSocket(, true, this, null);

            // define all the pins on the selected socket
            _LCD_RS = new DigitalOutput(_socket, Socket.Pin.Four, false, this);
            _LCD_E = new DigitalOutput(_socket, Socket.Pin.Three, false, this);
            _BackLight = new DigitalOutput(_socket, Socket.Pin.Five, false, this);
            _LCD_D4 = new DigitalOutput(_socket, Socket.Pin.Six, false, this);
            _LCD_D5 = new DigitalOutput(_socket, Socket.Pin.Seven, false, this);
            _LCD_D6 = new DigitalOutput(_socket, Socket.Pin.Eight, false, this);
            _LCD_D7 = new DigitalOutput(_socket, Socket.Pin.Nine, false, this);

            // start the LCD initialization procedure
            _LCD_RS.Write(false);
            Thread.Sleep(50);

            _LCD_D7.Write(false);
            _LCD_D6.Write(false);
            _LCD_D5.Write(true);
            _LCD_D4.Write(true);
            _LCD_E.Write(true);
            _LCD_E.Write(false);
            Thread.Sleep(50);

            _LCD_D7.Write(false);
            _LCD_D6.Write(false);
            _LCD_D5.Write(true);
            _LCD_D4.Write(true);
            _LCD_E.Write(true);
            _LCD_E.Write(false);
            Thread.Sleep(50);

            _LCD_D7.Write(false);
            _LCD_D6.Write(false);
            _LCD_D5.Write(true);
            _LCD_D4.Write(true);
            _LCD_E.Write(true);
            _LCD_E.Write(false);
            Thread.Sleep(50);

            _LCD_D7.Write(false);
            _LCD_D6.Write(false);
            _LCD_D5.Write(true);
            _LCD_D4.Write(false);
            _LCD_E.Write(true);
            _LCD_E.Write(false);

            BacklightOff();
            SendCommand(DISPLAY_ON);
            SendCommand(DISPLAY_CLEAR);
        }

        /// <summary>
        /// Sends a LCD command.
        /// </summary>
        /// <param name="c">Sends a commands to LCD for example '0xC' that is the command to turn the DISPLAY ON</param>
        void SendCommand(byte c)
        {
            _LCD_RS.Write(false); //set LCD to data mode on

            _LCD_D7.Write((c & 0x80) != 0);
            _LCD_D6.Write((c & 0x40) != 0);
            _LCD_D5.Write((c & 0x20) != 0);
            _LCD_D4.Write((c & 0x10) != 0);
            _LCD_E.Write(true); //Toggle the Enable Pin on
            _LCD_E.Write(false); //Toggle the Enable Pin off

            _LCD_D7.Write((c & 0x08) != 0);
            _LCD_D6.Write((c & 0x04) != 0);
            _LCD_D5.Write((c & 0x02) != 0);
            _LCD_D4.Write((c & 0x01) != 0);
            _LCD_E.Write(true); //Toggle the Enable Pin on
            _LCD_E.Write(false); //Toggle the Enable Pin off

            Thread.Sleep(1);
            _LCD_RS.Write(true); //set LCD to data mode off
        }

        /// <summary>
        /// Sends an ASCII character to the LCD
        /// </summary>
        /// <param name="c">ASCII character</param>
        void PutChar(byte c)
        {
            _LCD_D7.Write((c & 0x80) != 0);
            _LCD_D6.Write((c & 0x40) != 0);
            _LCD_D5.Write((c & 0x20) != 0);
            _LCD_D4.Write((c & 0x10) != 0);
            _LCD_E.Write(true); //Toggle the Enable Pin on
            _LCD_E.Write(false); //Toggle the Enable Pin off

            _LCD_D7.Write((c & 0x08) != 0);
            _LCD_D6.Write((c & 0x04) != 0);
            _LCD_D5.Write((c & 0x02) != 0);
            _LCD_D4.Write((c & 0x01) != 0);
            _LCD_E.Write(true); //Toggle the Enable Pin on
            _LCD_E.Write(false); //Toggle the Enable Pin off
            
            Thread.Sleep(1);
        }

        /// <summary>
        /// Sends a string of ASCII characters to the LCD
        /// </summary>
        /// <param name="str">Text string (ASCII characters)</param>
        public void PutString(string str)
        {
            for (int i = 0; i < str.Length; i++)
                PutChar((byte)str[i]);
        }

        /// <summary>
        /// Clear the contents of the screen
        /// </summary>
        public void DisplayClear()
        {
            SendCommand(DISPLAY_CLEAR);
        }

        /// <summary>
        /// Blank the display (without clearing)
        /// </summary>
        public void DisplayBlank()
        {
            SendCommand(DISPLAY_BLANK);
        }

        /// <summary>
        /// Restore the display (with cursor hidden)
        /// </summary>
        public void DisplayRestore()
        {
            SendCommand(DISPLAY_RESTORE);
        }

        /// <summary>
        /// Move cursor home and clear screen memory
        /// </summary>
        public void CursorHome()
        {
            SendCommand(CURSOR_HOME);
        }

        /// <summary>
        /// Sets cursor position to postion X on the LCD. You have to specify the Line number and Column number.
        /// </summary>
        /// <param name="row">Indicates the row number. "0" indicates Line 1, "1" indicates Line 2, etc.</param>
        /// <param name="col">Indicates the position from the leftmost character of the LCD. For example, if you put "0" then it points to the left-most position on the line</param>
        public void CursorSet(byte row, byte col)
        {
            SendCommand((byte)(SET_CURSOR | row << 6 | col));
        }

        /// <summary>
        /// Takes the cursor to first character position on Line 1 of the LCD display
        /// </summary>
        public void GotoLine1()
        {
            CursorSet(0, 0);
        }

        /// <summary>
        /// Takes the cursor to the first characted position on Line 2 of the LCD display
        /// </summary>
        public void GotoLine2()
        {
            CursorSet(1, 0);
        }

        /// <summary>
        /// Turn the LCD backlight on
        /// </summary>
        public void BacklightOn()
        {
            _BackLight.Write(false);
        }

        /// <summary>
        /// Turn the LCD backlight off
        /// </summary>
        public void BacklightOff()
        {
            _BackLight.Write(true);
        }

        /// <summary>
        /// Scroll display one character right (all lines)
        /// </summary>
        public void DisplayScrollRight()
        {
            SendCommand(SCROLL_RIGHT);
        }

        /// <summary>
        /// Scroll display one character left (all lines)
        /// </summary>
        public void DisplayScrollLeft()
        {
            SendCommand(SCROLL_LEFT);
        }

        /// <summary>
        /// Move cursor one character left
        /// </summary>
        public void CursorLeft()
        {
            SendCommand(CURSOR_LEFT);
        }

        /// <summary>
        /// Move cursor one character right
        /// </summary>
        public void CursorRight()
        {
            SendCommand(CURSOR_RIGHT);
        }

        /// <summary>
        /// Turn on visible underline cursor
        /// </summary>
        public void CursorUnderline()
        {
            SendCommand(CURSOR_UNDERLINE);
        }

        /// <summary>
        /// Turn on visible blinking-block cursor
        /// </summary>
        public void CursorBlinking()
        {
            SendCommand(CURSOR_BLINKING);
        }

        /// <summary>
        /// Make cursor invisible
        /// </summary>
        public void CursorInvisible()
        {
            SendCommand(CURSOR_INVISIBLE);
        }
    }
}

So, at the moment, if I connect the LCD to FEZ Spider, then I have to call the

Initialize(int socketNumber)

and input the actual socketNumber that I used to plug my module into.

If this is not the correct way of achieving this, then how and where should I include the LCD initialization code for my own LCD module?

Thanks for your futher information.

You will need a constructor:


public LCD2X16( int socketNumber )
{
    Initialize(socketNumber);
}

In case you haven’t done this, please read module builders guide. There is a section about module’s software. To take full advantage of the Visual Studio you will need to create a special setup project that is described in the document as well. I hope this helps.

@ janleroux

Just checking if you got it working?

@ Architect

At last I can report that I got it working! I just could not get the socket assigned.

To be honest, I am not 100% sure why it did not work in the beginning. When I named my module, I called it “LCD2X16”. This was also the namespace name. The interesting hing was that once I did a build on the component, it will actually appear in the intellisense of the project in which I am using my module as “lCD2x16”. In the end I renamed everything (project and namespace) to “lcd2x16”, and now it works perfectly!

So could the uppercase vs lowercase naming have anything to do with the problem?

I have described my whole process as well as the veroboard files and code on my blog: http://zoftworx.org/

Thanks for your help though!

Glad you got it working. What is the name of the autogenerated variable for your driver when you use visual designer?