diff --git a/src/devices/CharacterLcd/Hd44780.cs b/src/devices/CharacterLcd/Hd44780.cs index dfef9d8830d6d99c7ca5fa4f8f1bc03c745336c2..e267f4ebeacf3373af36294eddb87428648c52f6 100644 --- a/src/devices/CharacterLcd/Hd44780.cs +++ b/src/devices/CharacterLcd/Hd44780.cs @@ -103,18 +103,13 @@ namespace Iot.Device.CharacterLcd _displayControl |= DisplayControl.DisplayOn; _displayMode |= DisplayEntryMode.Increment; - ReadOnlySpan commands = stackalloc byte[] - { - // Function must be set first to ensure that we always have the basic - // instruction set selected. (See PCF2119x datasheet Function_set note - // for one documented example of where this is necessary.) - (byte)_displayFunction, - (byte)_displayControl, - (byte)_displayMode, - ClearDisplayCommand - }; - - SendCommands(commands); + // Function must be set first to ensure that we always have the basic + // instruction set selected. (See PCF2119x datasheet Function_set note + // for one documented example of where this is necessary.) + SendCommandAndWait((byte)_displayFunction); + SendCommandAndWait((byte)_displayControl); + SendCommandAndWait((byte)_displayMode); + SendCommandAndWait(ClearDisplayCommand); } /// @@ -138,6 +133,14 @@ namespace Iot.Device.CharacterLcd /// Byte representing the command to be sent protected void SendCommand(byte command) => _lcdInterface.SendCommand(command); + /// + /// The initialization sequence and some other complex commands should be sent with delays, or the display may + /// behave unexpectedly. It may show random, blinking characters + /// or display text very faintly only. + /// + /// The command to send + protected void SendCommandAndWait(byte command) => _lcdInterface.SendCommandAndWait(command); + /// /// Sends data to the device /// @@ -259,7 +262,7 @@ namespace Iot.Device.CharacterLcd public bool DisplayOn { get => (_displayControl & DisplayControl.DisplayOn) > 0; - set => SendCommand((byte)(value ? _displayControl |= DisplayControl.DisplayOn + set => SendCommandAndWait((byte)(value ? _displayControl |= DisplayControl.DisplayOn : _displayControl &= ~DisplayControl.DisplayOn)); } @@ -269,7 +272,7 @@ namespace Iot.Device.CharacterLcd public bool UnderlineCursorVisible { get => (_displayControl & DisplayControl.CursorOn) > 0; - set => SendCommand((byte)(value ? _displayControl |= DisplayControl.CursorOn + set => SendCommandAndWait((byte)(value ? _displayControl |= DisplayControl.CursorOn : _displayControl &= ~DisplayControl.CursorOn)); } @@ -279,7 +282,7 @@ namespace Iot.Device.CharacterLcd public bool BlinkingCursorVisible { get => (_displayControl & DisplayControl.BlinkOn) > 0; - set => SendCommand((byte)(value ? _displayControl |= DisplayControl.BlinkOn + set => SendCommandAndWait((byte)(value ? _displayControl |= DisplayControl.BlinkOn : _displayControl &= ~DisplayControl.BlinkOn)); } @@ -289,7 +292,7 @@ namespace Iot.Device.CharacterLcd public bool AutoShift { get => (_displayMode & DisplayEntryMode.DisplayShift) > 0; - set => SendCommand((byte)(value ? _displayMode |= DisplayEntryMode.DisplayShift + set => SendCommandAndWait((byte)(value ? _displayMode |= DisplayEntryMode.DisplayShift : _displayMode &= ~DisplayEntryMode.DisplayShift)); } @@ -299,7 +302,7 @@ namespace Iot.Device.CharacterLcd public bool Increment { get => (_displayMode & DisplayEntryMode.Increment) > 0; - set => SendCommand((byte)(value ? _displayMode |= DisplayEntryMode.Increment + set => SendCommandAndWait((byte)(value ? _displayMode |= DisplayEntryMode.Increment : _displayMode &= ~DisplayEntryMode.Increment)); } @@ -393,14 +396,13 @@ namespace Iot.Device.CharacterLcd /// public void Write(string text) { - byte[] buffer = ArrayPool.Shared.Rent(text.Length); + Span buffer = stackalloc byte[text.Length]; for (int i = 0; i < text.Length; ++i) { buffer[i] = (byte)text[i]; } - SendData(new ReadOnlySpan(buffer, 0, text.Length)); - ArrayPool.Shared.Return(buffer); + SendData(buffer); } /// diff --git a/src/devices/CharacterLcd/LcdInterface.I2c4Bit.cs b/src/devices/CharacterLcd/LcdInterface.I2c4Bit.cs index 5f2af1bd04f298c429e1541559fb849ef48493ed..a97b2cb217f6538907de50f20d01047e063715c7 100644 --- a/src/devices/CharacterLcd/LcdInterface.I2c4Bit.cs +++ b/src/devices/CharacterLcd/LcdInterface.I2c4Bit.cs @@ -54,7 +54,7 @@ namespace Iot.Device.CharacterLcd { _backlightOn = value; // Need to send a command to make this happen immediately. - SendCommand(0); + SendCommandAndWait(0); } } @@ -87,7 +87,7 @@ namespace Iot.Device.CharacterLcd SendCommandAndWait(LCD_ENTRYMODESET | LCD_ENTRYLEFT); } - private void SendCommandAndWait(byte command) + public override void SendCommandAndWait(byte command) { // Must not run the init sequence to fast or undefined behavior may occur SendCommand(command); diff --git a/src/devices/CharacterLcd/LcdInterface.cs b/src/devices/CharacterLcd/LcdInterface.cs index 9160b6b54efb7a2c00239f97a506b71203915366..ce5443175ef6a7ffcf11423ab0ae3cef89d55a9b 100644 --- a/src/devices/CharacterLcd/LcdInterface.cs +++ b/src/devices/CharacterLcd/LcdInterface.cs @@ -5,6 +5,7 @@ using System; using System.Device; using System.Device.Gpio; using System.Device.I2c; +using System.Threading; namespace Iot.Device.CharacterLcd { @@ -81,6 +82,19 @@ namespace Iot.Device.CharacterLcd /// Each byte represents command to be send public abstract void SendCommands(ReadOnlySpan values); + /// + /// The initialization sequence and some other complex commands should be sent with delays, or the display may + /// behave unexpectedly. It may show random, blinking characters + /// or display text very faintly only. + /// + /// The command to send + public virtual void SendCommandAndWait(byte command) + { + // Must not run the init sequence to fast or undefined behavior may occur + SendCommand(command); + Thread.Sleep(1); + } + /// /// True if device uses 8-bits for communication, false if device uses 4-bits ///