[C#] Display Grove-LCD RGB Backlight

Hi,

I have just bought GrovePi+ Starter Kit for Raspberry Pi.
I would like to display some messages from my code in Grove LCD RGB Backlight.
I use C# as my language.
I can confirm that GrovePi+ works fine because I tested LED and it works fine.

Here’s my sample code which I run on my Raspberry Pi.

using System;
using System.Device.Gpio;
using System.Device.I2c;
using System.Threading;
using System.Threading.Tasks;
using Iot.Device.CharacterLcd;
using Iot.Device.GrovePiDevice;
using Iot.Device.GrovePiDevice.Models;
using Iot.Device.GrovePiDevice.Sensors;

namespace helloworld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            I2cConnectionSettings i2CConnectionSettings =
                new I2cConnectionSettings(1, GrovePi.DefaultI2cAddress);

            var i2cDevice = I2cDevice.Create(i2CConnectionSettings);

            var grovePi = new GrovePi(i2cDevice);
            Console.WriteLine($"Manufacturer :{grovePi.GrovePiInfo.Manufacturer}");
            Console.WriteLine($"Board: {grovePi.GrovePiInfo.Board}");
            Console.WriteLine($"Firmware version: {grovePi.GrovePiInfo.SoftwareVersion}");
            grovePi.PinMode(GrovePort.DigitalPin4, PinMode.Output);
            grovePi.PinMode(GrovePort.DigitalPin3, PinMode.Output);
            Led led = new Led(grovePi, GrovePort.DigitalPin4);
            LcdRgb1602 display = new LcdRgb1602(i2cDevice, i2cDevice);
            Task.Delay(100).Wait();     // Delay 0.1 second

            display.BlinkingCursorVisible = true;
            display.DisplayOn = true;
            display.Write("Hello World");
            display.BacklightOn = true;

            int counter = 0;
            while (true)
            {
                display.ShiftDisplayLeft();

                led.Value = PinValue.High;
                Console.WriteLine("High");
                Task.Delay(2000).Wait();
                display.Write($"Hello World {counter}");

                led.Value = PinValue.Low;
                Console.WriteLine("Low");
                Task.Delay(2000).Wait();
                counter++;
            }


        }
    }
}

LED works fine but I cannot display any message on LCD.

Could you please give me any advice on how can I do it?

1 Like

Greetings!

Caveat: I really don’t know much about C#, but having done some display programming in a C-like language on the Arduino, and messed with classes and methods on the GoPiGo, let me take a stab at this. If I make a bloody knob-head idiot of myself, please excuse my ignorance.

Looking at the following code:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            I2cConnectionSettings i2CConnectionSettings =
                new I2cConnectionSettings(1, GrovePi.DefaultI2cAddress);

            var i2cDevice = I2cDevice.Create(i2CConnectionSettings);

            var grovePi = new GrovePi(i2cDevice);
            Console.WriteLine($"Manufacturer :{grovePi.GrovePiInfo.Manufacturer}");
            Console.WriteLine($"Board: {grovePi.GrovePiInfo.Board}");
            Console.WriteLine($"Firmware version: {grovePi.GrovePiInfo.SoftwareVersion}");
            grovePi.PinMode(GrovePort.DigitalPin4, PinMode.Output);
            grovePi.PinMode(GrovePort.DigitalPin3, PinMode.Output);
            Led led = new Led(grovePi, GrovePort.DigitalPin4);
            LcdRgb1602 display = new LcdRgb1602(i2cDevice, i2cDevice);
            Task.Delay(100).Wait();     // Delay 0.1 second

            display.BlinkingCursorVisible = true;
            display.DisplayOn = true;
            display.Write("Hello World");
            display.BacklightOn = true;

            int counter = 0;
            while (true)
            {
                display.ShiftDisplayLeft();

                led.Value = PinValue.High;
                Console.WriteLine("High");
                Task.Delay(2000).Wait();
                display.Write($"Hello World {counter}");

                led.Value = PinValue.Low;
                Console.WriteLine("Low");
                Task.Delay(2000).Wait();
                counter++;
            }


        }

. . . lines like

I2cConnectionSettings i2CConnectionSettings =
                new I2cConnectionSettings(1, GrovePi.DefaultI2cAddress);
=======
var i2cDevice = I2cDevice.Create(i2CConnectionSettings);

and such like set my teeth on edge, because the declared variable/class instance is way too similar to the canonical class name or method. I would make the names distinctly different by changing it to all lower case, adding underscores, etc.

Another thing that jumps out at me is the lack of any initialization code. Since this is a distinct and separate hardware device, instead of a simple software method, you typically have to send initialization bytes to the device, clear it, set it to “read” mode, (if not already set that way), declare a display resolution and/or number of lines, etc.

Maybe instantiating the class for that display does this, but I’d make sure.

Another thing: Are you absolutely sure that “GrovePi.DefaultI2cAddress” is the same i2c address as the display itself? I’d check that. You might want to try, (from a console) sudo apt-get install python-smbus i2c-tools and sudo i2cdetect -y 1 to make sure the display is being detected.

There’s a real interesting article over at Adafruit that talks about adding another i2c device to a Raspberry Pi - a real time clock - that might help point you in the right direction. This drops you into the middle of the article where they actually configure and set up the i2c interface.

Viz.:

Lastly, as stupid as it sounds, have you double-checked the wiring? If I had twenty Russian kopeks for every time I would have SWORN the wiring was correct, and it turns out it wasn’t, I’d be a multi-gazillionare now.

Please let us know what you find, and how things work out.

Hope this helps:

        // Initialize the GPIO controller
        var gpio = new GpioController();

        I2cConnectionSettings lcdTextConnectionSettings = new(1, 0x3e);
        var lcdTextDevice = I2cDevice.Create(lcdTextConnectionSettings);
        var groveLcdText = new GrovePi(lcdTextDevice);

        const byte TextCommandAddress = 0x80;
        const byte ClearDisplayCommandAddress = 0x01;
        const byte DisplayOnCommandAddress = 0x08;
        const byte NoCursorCommandAddress = 0x04;
        const byte TwoLinesCommandAddress = 0x28;
        const byte SetCharacterCommandAddress = 0x40;
        
        lcdTextDevice.Write(new[] { TextCommandAddress, ClearDisplayCommandAddress });
        Thread.Sleep(50);
        lcdTextDevice.Write(new[] { TextCommandAddress, (byte)(DisplayOnCommandAddress | NoCursorCommandAddress) });
        lcdTextDevice.Write(new[] { TextCommandAddress, TwoLinesCommandAddress });

        var count = 0;
        var row = 0;
        var text = "Hello world";
        int GroveRgpLcdMaxLength = 20;
        int GroveRgpLcdRows = 2;

        foreach (var c in text)
        {

            if (c.Equals('\n') || count == GroveRgpLcdMaxLength)
            {
                count = 0;
                row += 1;
                if (row == GroveRgpLcdRows)
                    break;
                lcdTextDevice.Write(new byte[] { TextCommandAddress, 0xc0 }); //TODO: find out what this address is
                if (c.Equals('\n'))
                    continue;
            }
            count += 1;
            lcdTextDevice.Write(new[] { SetCharacterCommandAddress, (byte)c });
        }

        const byte RedCommandAddress = 4;
        const byte GreenCommandAddress = 3;
        const byte BlueCommandAddress = 2;

        byte red = 255;
        byte green = 0;
        byte blue = 255;

        I2cConnectionSettings lcdRgbConnectionSettings = new(1, 0x62);
        var lcdRgbDevice = I2cDevice.Create(lcdRgbConnectionSettings);
        var groveLcdRgb = new GrovePi(lcdRgbDevice);

        lcdRgbDevice.Write(new byte[] { 0, 0 });
        lcdRgbDevice.Write(new byte[] { 1, 0 });
        lcdRgbDevice.Write(new byte[] { DisplayOnCommandAddress, 0xaa });
        lcdRgbDevice.Write(new[] { RedCommandAddress, red });
        lcdRgbDevice.Write(new[] { GreenCommandAddress, green });
        lcdRgbDevice.Write(new[] { BlueCommandAddress, blue });
1 Like