Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

LCD Help needed, 16x2s are boring


  • Please log in to reply
100 replies to this topic

#61 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 09 January 2011 - 10:39 PM

Okay, I moved the bitmap code into its own class (BMap), added a Rect() procedure and cleaned it up a bit and removed any code that was not relevant to the task at hand.

Posted Image

And for fun, I drew a cute picture!

I hope you enjoy!

Nice image!

I was wondering what algorithm you used for drawing lines? I was looking into this one: http://en.wikipedia.org/wiki/Bresenham's_line_algorithm it is optimized to rely on addition only.

#62 AlfredBr

AlfredBr

    Advanced Member

  • Members
  • PipPipPip
  • 138 posts
  • LocationConnecticut, USA

Posted 09 January 2011 - 11:04 PM

You found it!

#63 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 10 January 2011 - 03:24 AM

Hey Alfred, I was wondering how I could change an (x,y) directly to the index of the byte[504] where that would fall.... I've been trying to figure it out but I cant. so (0,0) would return 0, (83, 0) would return 83, (0, 1) would return 0 ... and (83, 47) would return 504. any clue? I'm still working on it, but I can't get it to work!

#64 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 10 January 2011 - 01:56 PM

I was wondering how I could change an (x,y) directly to the index of the byte[504] where that would fall....

I don't have the LCD for testing, but if I understand correctly how it works, you are looking for something along the following lines:

private const int DisplayWidth = 84;
private const int DisplayHeight = 48;
private byte[] byteMap = new byte[504];

private void SetPixel(int x, int y, bool value = true)
{
  if(x < 0 || x >= DisplayWidth)
  {
    throw new ArgumentOutOfRangeException("x");
  }
  if(y < 0 || y >= DisplayHeight)
  {
    throw new ArgumentOutOfRangeException("y");
  }
  var index = (x % DisplayWidth) + (y/8)*DisplayWidth;
  var bitMask = (byte)(1 << (y % 8));
  if(value)
  {
    byteMap[index] |= bitMask;
  }
  else
  {
    byteMap[index] &= (byte)~bitMask;
  }
}


#65 Omar (OZ)

Omar (OZ)

    Advanced Member

  • Members
  • PipPipPip
  • 564 posts

Posted 10 January 2011 - 02:02 PM

I don't have the LCD for testing, but if I understand correctly how it works, you are looking for something along the following lines:

private const int DisplayWidth = 84;
private const int DisplayHeight = 48;
private byte[] byteMap = new byte[504];

private void SetPixel(int x, int y, bool value = true)
{
  if(x < 0 || x >= DisplayWidth)
  {
    throw new ArgumentOutOfRangeException("x");
  }
  if(y < 0 || y >= DisplayHeight)
  {
    throw new ArgumentOutOfRangeException("y");
  }
  var index = (x % DisplayWidth) + (y/8)*DisplayWidth;
  var bitMask = (byte)(1 << (y % 8));
  if(value)
  {
    byteMap[index] |= bitMask;
  }
  else
  {
    byteMap[index] &= (byte)~bitMask;
  }
}

Works great! Thanks :)

#66 Basiclife

Basiclife

    Member

  • Members
  • PipPip
  • 27 posts

Posted 14 January 2011 - 11:41 PM

Hi I'd just like to thank the above users for working out how to get this display to work - Mine arrived yesterday and works perfectly for text. I'm playing with BMPs now.. :D

#67 Jarrod Sinclair

Jarrod Sinclair

    Advanced Member

  • Members
  • PipPipPip
  • 50 posts
  • LocationSF Bay Area, CA

Posted 20 January 2011 - 04:53 PM

AlfredBr and OMAR, i have been using this LCD for a while now it it works great. Thanks for all that hard work you have done to get it working!! have a question though. does anyone know of a way to release D12 from the SPI since it is not being used by the LCD? I have been working on a project for a while and just discovered that I really need that I/O port (cause all the others are full :) ) Also I would like to avoid having to get an I/O Shield but if do, can you set interrupts on those pins or only those pis native tot he netduino? Thanks, Jarrod

#68 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 20 January 2011 - 07:13 PM

have a question though. does anyone know of a way to release D12 from the SPI since it is not being used by the LCD? I have been working on a project for a while and just discovered that I really need that I/O port (cause all the others are full :) )


You _might_ be able to modify the core C firmware to support this. We've never tried that...

Also I would like to avoid having to get an I/O Shield but if do, can you set interrupts on those pins or only those pis native tot he netduino?


It depends on the I/O shield and its driver. If the I/O shield has an "interrupt pin" and the interrupt functionality is included in the driver, then you should be set.

Chris

#69 Lefty

Lefty

    New Member

  • Members
  • Pip
  • 1 posts

Posted 06 February 2011 - 01:37 AM

Just a quick fyi guys - I've managed to brick my 5110 LCD whilst soldering header pins on. :( I'm assuming the heat did it, but I've never had this happen to me before. I didn't realise the LCD came off the breakout board as easily as it does (just the 4 metal tabs on the casing) until after it stopped working :rolleyes: , but it may be an idea to remove it whilst soldering if anyone is considering this. Alex

#70 svoynick

svoynick

    New Member

  • Members
  • Pip
  • 2 posts

Posted 26 February 2011 - 09:45 PM

Just a quick fyi guys - I've managed to brick my 5110 LCD whilst soldering header pins on. :( I'm assuming the heat did it, but I've never had this happen to me before.

Wow - it's really hard to imagine that enough heat would make it down the thin PCB traces and onto the LCD to damage anything like that. Unless one or more traces just flat out broke maybe?

Now, on the other hand, static could certainly do that...

I didn't realise the LCD came off the breakout board as easily as it does (just the 4 metal tabs on the casing) until after it stopped working :rolleyes: , but it may be an idea to remove it whilst soldering if anyone is considering this.

I haven't taken mine off the board yet - I'm imagining it has one of those spongy-foam type elatomeric connectors between the LCD glass and the breakout board, is that right? I also notice (and someone here or elsewhere commented) that the board "bows" away from the LCD glass along the "upper" edge of the LCD. I'm assuming this is the edge nearest the elastomeric strip, and this is what's putting the bowing force on the breakout board. I wish they had added one more hold-down tab to the metal bracket/frame along that top edge, which would have mitigated the bowing. I know a couple of signal traces run straight through there, but they could have routed around the tab.

#71 svoynick

svoynick

    New Member

  • Members
  • Pip
  • 2 posts

Posted 26 February 2011 - 10:14 PM

OMAR! I got it working on the Netduino! This seems to be the key section, I didn't change much else...

        private static void LcdInitialize()
        {
            ResetPort.Write(false);
            ResetPort.Write(true);

            LcdWrite(Command, 0x21);  // LCD Extended Commands.
            LcdWrite(Command, 0xBf);  // Set LCD Vop (Contrast). //B1
            LcdWrite(Command, 0x04);  // Set Temp coefficent. //0x04
            LcdWrite(Command, 0x14);  // LCD bias mode 1:48. //0x13
            LcdWrite(Command, 0x0C);  // LCD in normal mode.   <<== NOTE 1
            
            LcdWrite(Command, 0x20);
            LcdWrite(Command, 0x0C);
        }


Alfred - my thanks to you and others who figured out these details - your work helped me get mine going.

Two comments about this initialization sequence:

(1) I find that the 0x0C byte I have marked with "NOTE 1" in your listing above is spurious, and has no effect. At this time in your init sequence, you are in extended command mode, and according to the Table 1 instruction set in the PDC8544 datasheet, a 0x0C command in the H=1 extended command mode falls under a "Reserved - do not use" function. (Any byte of binary 0b00001XXX.) It probably doesn't hurt, but it is marked as a reserved command under this command set. It's the 0x0C you send after going back to the basic instruction set (with the 0x20 byte) that properly ensures the display is in normal mode.

(2) For anyone trying to get this display going with this command string, if you try it and still don't see anything on the display, try varying the LCD Vop parameter (shown as 0xBf in the sequence above.) Operating around VDD=3.20 V, and after what I thought was a proper initialization sequence, my display had appeared almost completely blank with the 0xBF parameter - I was just barely able to see a little flickering of the entire display area with a bright light reflecting off it at a high angle - but at least this gave me hope that something was going on. Trying different Vop values got it dialed in, and in my case, I found Vop=0xB3 to give me a very nice contrast display.

So, if your display is intializing to all-black or all-blank, try playing with that Vop parameter.

#72 K0demonkey

K0demonkey

    New Member

  • Members
  • Pip
  • 9 posts
  • LocationRochester, NY

Posted 13 May 2011 - 12:42 PM

I am new to this whole netduino stuff.

I have the Nokia 5110/3110 LCD screen and wired it up as shown on my netduino plus.

Posted Image

I loaded the latest code posted and when I go to debug in VS2010 and the netduino I get the following error:

Cannot find PWM.CS

A diaglog box opens and it wants me to find PWM.CS. I've searched my PC thoroughly and the file doesn't exist.

I did flash my firmware to version 4.1.0.6 hoping this would fix the issue, but it still happens.

Any help would be greatly appreciated!

Shannon

#73 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 13 May 2011 - 04:45 PM

Hi Shannon, Are you running your code in the emulator or in Visual Studio? It appears that Visual Studio is looking for the PWM managed code source. You can download that from the downloads page to make it happy if you'd like :) Not sure why it would want that--but you should be able to skip it as well. Welcome to the Netduino community, Chris

#74 K0demonkey

K0demonkey

    New Member

  • Members
  • Pip
  • 9 posts
  • LocationRochester, NY

Posted 13 May 2011 - 05:09 PM

Hi Shannon,

Are you running your code in the emulator or in Visual Studio?

It appears that Visual Studio is looking for the PWM managed code source. You can download that from the downloads page to make it happy if you'd like :) Not sure why it would want that--but you should be able to skip it as well.

Welcome to the Netduino community,

Chris


Chris,

I am running the code in Visual Studio and sending it to the netduino.

On downloads page it states:
● pwm beta C++ code coming soon

There is not a link. Am I not looking in the correct spot?

Thanks for the help.

Shan

#75 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 13 May 2011 - 05:22 PM

I loaded the latest code posted and when I go to debug in VS2010 and the netduino I get the following error:
Cannot find PWM.CS

If you are stepping though the code using "Step Into" command (usually F11), try "Step Over" (F10) instead. PWM.cs is included in Netduino SDK source.

#76 K0demonkey

K0demonkey

    New Member

  • Members
  • Pip
  • 9 posts
  • LocationRochester, NY

Posted 13 May 2011 - 05:47 PM

If you are stepping though the code using "Step Into" command (usually F11), try "Step Over" (F10) instead. PWM.cs is included in Netduino SDK source.


Thanks everyone. I am wondering if my issue is due to installing the 32-bit SDK instead of the 64-bit SDK on my Windows7 x64.

I've reinstalled and will try again this weekend.

Shan

#77 geduxaz

geduxaz

    New Member

  • Members
  • Pip
  • 4 posts

Posted 14 May 2011 - 08:35 PM

Need help. I am using pcd8544 lcd from nokia 3310. i get text to lcd, but it shows to dark. how contrast is adjusted? tried to set Vop to 0x80 (10000000), didn't helped.. if i adjust Vcc to ~ 3V, lcd has good contrast. but i think it should work from 3.3V :/ :blink: I made it out.. destroyed another nokia :D and new lcd works great, i can control contrast.. well who could know.. :blink:

#78 K0demonkey

K0demonkey

    New Member

  • Members
  • Pip
  • 9 posts
  • LocationRochester, NY

Posted 18 May 2011 - 08:02 PM

I purchased the Nokia display from Adafruit.

It looks like this:
Posted Image

Posted Image

In following AlfredBr's code [HERE] I have this board wired like this:

Nokia Pin 1: Netduino Gnd
Nokia Pin 2: Netduino 3.3v
Nokia Pin 3: Empty
Nokia Pin 4: Empty
Nokia Pin 5: D1
Nokia Pin 6: D8
Nokia Pin 7: D1
Nokia Pin 8: D5

Posted Image

I am no longer getting the PWM.cs error, but I still cannot get this display to work. I do see the backlight come on when I load the program to debug, but nothing is being drawn on the screen.

Is there anything else I should be looking at? This hardware stuff is totally new to me.

Shan

#79 mikepo

mikepo

    Member

  • Members
  • PipPip
  • 29 posts

Posted 19 May 2011 - 07:04 AM

@K0demonkey It seems your wiring is not quite correct. Pins 3 and 4 on the LCD are the clock pin and the data pin, you definitely need those to send data to the display. They need to be connected to the SPI clock pin (Netduino PIN 13) and the SPI MOSI pin (Netduino PIN 11).

#80 K0demonkey

K0demonkey

    New Member

  • Members
  • Pip
  • 9 posts
  • LocationRochester, NY

Posted 19 May 2011 - 11:27 AM

@K0demonkey

It seems your wiring is not quite correct.
Pins 3 and 4 on the LCD are the clock pin and the data pin, you definitely need those to send data to the display.
They need to be connected to the SPI clock pin (Netduino PIN 13) and the SPI MOSI pin (Netduino PIN 11).


THANK YOU!

Posted Image

My next question is ... how do I print text to the screen?

I've tried Omar's code,
    public class Nokia_5110
    {
        private bool[] _offRow = new bool[84];

        private readonly byte[] _pow = new byte[] { 1, 2, 4, 8, 16, 32, 64, 128 };

        private OutputPort _resetPort, _daComPin;
        private PWM _backlightPort;
        private SPI _dataPort;

        public bool[][] _pixelMap = new bool[48][];
        private byte[] _byteMap = new byte[504];

        private uint _backlight = 0;
        private bool _invd = false, _autoRefresh = true;

        public Nokia_5110(Cpu.Pin chipSelect = Pins.GPIO_PIN_D3, Cpu.Pin backlight = Pins.GPIO_PIN_D9,
            Cpu.Pin reset = Pins.GPIO_PIN_D7, Cpu.Pin dataCommand = Pins.GPIO_PIN_D8)
        {
            SPI.Configuration spiConfiguration = new SPI.Configuration(
                chipSelect,            // chip select port 
                false,                 // IC is accessed when chip select is low 
                0,                     // setup time 1 ms 
                0,                     // hold chip select 1 ms after transfer 
                false,                 // clock line is low if device is not selected 
                true,                  // data is sampled at leading edge of clock 
                2000,                 // clockrate is 15 MHz 
                SPI.SPI_module.SPI1   // use first SPI bus 
                );

            _dataPort = new SPI(spiConfiguration);
            _backlightPort = new PWM(backlight);
            _resetPort = new OutputPort(reset, true);
            _daComPin = new OutputPort(dataCommand, true);

            Initialize();
            Clear();
        }

        private void Initialize()
        {
            _resetPort.Write(false);
            _resetPort.Write(true);
            DataMode = false;
            _dataPort.Write(new byte[] { 0x21, 0xBF, 0x04, 0x14, 0x0C, 0x20, 0x0C });
            DataMode = true;
            Clear();
        }

        public void SetCursor(float x, float y)
        {
            DataMode = false;
            _dataPort.Write(new byte[] { (byte)(0x80 | (int)(x * 4)), (byte)(0x40 | (int)(y)) });
            DataMode = true;
        }

        public void WriteText(string text, bool noSpace = true)
        {
            DataMode = true;

            if (noSpace)
                foreach (char c in text.ToCharArray())
                    _dataPort.Write(NokiaCharacters.ASCII[c - 0x20]);
            else
            {
                byte[] letter = new byte[6];
                foreach (char c in text.ToCharArray())
                {
                    for (int i = 0; i < 5; i++)
                        letter[i] = NokiaCharacters.ASCII[c - 0x20][i];

                    letter[5] = 0x00;
                    _dataPort.Write(letter);
                }

            }
        }

        public void DrawRectangle(int x, int y, int width, int height, bool filled)
        {
            // thats what lines are for! oh right... I need to make a Draw line method...  
            if (width <= 1 || height <= 1)
                return;

            int endX = x + width, endY = y + height - 2;

            bool[] line = new bool[84];

            for (int p = x; p < endX; p++)
                line[p] = true;

            _pixelMap[y] = line;
            _pixelMap[endY] = line;

            if (!filled)
            {
                line = new bool[84];
                line[x] = true;
                line[endX - 1] = true;
            }

            for (int h = y + 1; h < endY; h++)
                _pixelMap[h] = line;

            if (AutoRefresh)
                Refresh();
        }

        public void Refresh()
        {
            int byteID = 0;

            for (int y = 0; y < 6; y++)
            {
                for (int x = 0; x < 84; x++)
                {
                    _byteMap[byteID] = ConvertToByte(_pixelMap[y * 8][x], _pixelMap[y * 8 + 1][x],
                                       _pixelMap[y * 8 + 2][x], _pixelMap[y * 8 + 3][x], _pixelMap[y * 8 + 4][x],
                                       _pixelMap[y * 8 + 5][x], _pixelMap[y * 8 + 6][x], _pixelMap[y * 8 + 7][x]);
                    byteID++;
                }
            }

            _dataPort.Write(_byteMap);
            SetCursor(0, 0);
        }

        private byte ConvertToByte(bool b0, bool b1, bool b2, bool b3, bool b4, bool b5, bool b6, bool b7)
        {
            byte result = 0;

            result += (byte)((b7) ? _pow[7] : 0);
            result += (byte)((b6) ? _pow[6] : 0);
            result += (byte)((b5) ? _pow[5] : 0);
            result += (byte)((b4) ? _pow[4] : 0);
            result += (byte)((b3) ? _pow[3] : 0);
            result += (byte)((b2) ? _pow[2] : 0);
            result += (byte)((b1) ? _pow[1] : 0);
            result += (byte)((b0) ? _pow[0] : 0);

            return result;
        }

        public void Clear()
        {
            for (int r = 0; r < 48; r++)
                _pixelMap[r] = _offRow;

            if (_autoRefresh)
                Refresh();
        }

        private void Inverse(bool inverse)
        {
            _invd = inverse;
            DataMode = false;
            _dataPort.Write(inverse ? new byte[] { 0x0D } : new byte[] { 0x0C });
            DataMode = true;
        }

        public bool InverseColors
        {
            get { return _invd; }
            set { Inverse(value); }
        }

        private bool DataMode
        {
            get { return _daComPin.Read(); }
            set { _daComPin.Write(value); }
        }

        public uint BacklightBrightness
        {
            get
            { return _backlight; }
            set
            {
                if (value > 100)
                    value = 100;

                _backlightPort.SetDutyCycle(value);
                _backlight = 100;
            }
        }

        public bool AutoRefresh
        {
            get { return _autoRefresh; }
            set { _autoRefresh = value; }
        }
    }

but the dev environment is complaining that NokiaCharacters does not exist in the current context.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.