Awesome, thanks for the code, even though it's not exactly what I'm looking for, it's a great place to start!
#21
Posted 27 February 2013 - 04:09 AM
#22
Posted 05 March 2013 - 05:32 PM
So after playing around with my project a bit, I eventually decided to go with the Micro Liquid Crystal library. It doesn't work right out of the box, but I managed to find the pinout for the SainSmart LCD with backpack to get it to work. There was one other oddity, the LCD needed to be turned off until just before starting the library (see the code sample below). If the LCD was on before then, the micro liquid crystal library would throw exceptions.
I used an NPN-transistor with the ground form the LCD connected to the emitter, the collector connected to ground, and the base connected to an OutputPort that would keep the LCD off until it should be truned on. I've included a basic example below that shows how to configure the micro liquid crystal library to work with the SainSmart I2C LCD (I should note that I'm using a Netduino 2):
using System; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.Netduino; using MicroLiquidCrystal; using FusionWare.SPOT.Hardware; namespace LCD { public class Program { private static OutputPort power = new OutputPort(Pins.GPIO_PIN_D0, false); private static I2CBus bus = new I2CBus(); private static BaseShifterLcdTransferProvider.ShifterSetup shifter = new BaseShifterLcdTransferProvider.ShifterSetup(); public static void Main() { shifter.RS = ShifterPin.GP0; shifter.RW = ShifterPin.GP1; shifter.Enable = ShifterPin.GP2; shifter.BL = ShifterPin.GP3; shifter.D4 = ShifterPin.GP4; shifter.D5 = ShifterPin.GP5; shifter.D6 = ShifterPin.GP6; shifter.D7 = ShifterPin.GP7; power.Write(true); MCP23008LcdTransferProvider lcdProvider = new MCP23008LcdTransferProvider(bus, 0x3F, shifter); Lcd lcd = new Lcd(lcdProvider); lcd.Begin(20, 4); // LCD is now ready, let's test it! lcd.SetCursorPosition(0, 0); lcd.Write("Hello, world!"); } } }
#23
Posted 25 April 2013 - 08:03 PM
Hello AxelG,
Thanks for the driver!
I'm sorry if this is a dumb question but how are you intending for us to instantiate the class? I tried making a child class but keep getting argument count errors even though intellisense is showing the three expected arguments.
public class Display : LiquidCrystal_I2C { LiquidCrystal_I2C _lcd = new LiquidCrystal_I2C(0x3F, 20, 4); }
#24
Posted 30 April 2013 - 11:52 AM
After some digging online regarding implimenting protected constructors, I am able to get it to compile now but I have my doubts I'm calling the methods correctly. I'm not getting anything (not even a flicker) on the LCD. I'm not getting any runtime errors either so I'm assuming it is 'sensing' the screen. Or do I2C ports fail quietly?
public class Display : LiquidCrystal_I2C { public Display(byte address, byte cols, byte rows) : base(address, cols, rows) { } public void writeValue(string s) { this.setCursor(0, 0); this.blink(); this.write(Tools.GetBytes(s)); }
#25
Posted 02 May 2013 - 11:35 AM
Here's my contribution to I2C driven LCDs:
http://forums.netdui...-and-ir-remote/
This one also works very well and is pretty fast since all LCD pins (not just the data pins) are driven over I2C. Brightness and contrast adjustment is controlled using PWM which omits the need for any potentiometers.
#26
Posted 30 May 2013 - 12:55 PM
Thanks for the quick replies.
I wrote a reset() method in the driver, and I have attached it to the onboard switch. Hitting the switch resets the screen. Seems like there should be a better way...
Maybe I will remove the i2c interface and go to a native HD4478 8 bit driver...
The class works well, however i have made some changes in the write function so it can handle strings.
Also a non wrapper to handle the maximum chars on the rows.
Also, usually it is Row, Column and not Column and then Rows for instance in the change position function.
ChangePosition(Row, Column)
#27
Posted 20 June 2013 - 10:03 AM
I have convert the LCD class to Visual Basic and make some changes i found
required for correct functioning. Just copy paste the Class in your program (I tested it well)
so now in de code:
dim Display As VBLiquidCrystal_I2C = New VBLiquidCrystal_I2C(lcdAddress, col, row)
edit: 21-06-2013 I have made some modifications in de class.
Public Class VBLiquidCrystal_I2C Private Const cnstClearDisplay As Integer = &H1 Private Const cnstReturnHome As Integer = &H2 Private Const cnstEntryModeSet As Integer = &H4 Private Const cnstDisplayControl As Integer = &H8 Private Const cnstCursorShift As Integer = &H10 Private Const cnstFunctionSet As Integer = &H20 Private Const cnstSETCGRAMADDR As Integer = &H40 Private Const cnstSETDDRAMADDR As Integer = &H80 Private Const cnstEntryRight As Integer = &H0 Private Const cnstEntryLeft As Integer = &H2 Private Const cnstEntryShiftIncrement As Integer = &H1 Private Const cnstEntryShiftDecrement As Integer = &H0 Private Const cnstDisplayOn As Integer = &H4 Private Const cnstDisplayOff As Integer = &H0 Private Const cnstCursorOn As Integer = &H2 Private Const cnstCursorOff As Integer = &H0 Private Const cnstBlinkOn As Integer = &H1 Private Const cnstBlonkOff As Integer = &H0 Private Const cnstDisplayMove As Integer = &H8 Private Const cnstCursorMove As Integer = &H0 Private Const cnstMoveRight As Integer = &H4 Private Const cnstMoverLeft As Integer = &H0 Private Const cnst8BitMode As Integer = &H10 Private Const cnst4BitMode As Integer = &H0 Private Const cnst2Line As Integer = &H8 Private Const cnst1Line As Integer = &H0 Private Const cnst5x10Dots As Integer = &H4 Private Const cnst5x8Dots As Integer = &H0 Private Const cnstBackLight As Integer = &H8 Private Const cnstNoBackLight As Integer = &H0 Private Const cnstMaxFreq As Integer = 100 Private _Addr As Byte Private _displayfunction As Byte Private _displaycontrol As Byte Private _displaymode As Byte Private _numlines As Byte Private _cols As Byte Private _rows As Byte Private _backlightval As Byte Private _I2C As MultiI2C ' When the display powers up, it is configured as follows: ' ' 1. Display clear ' 2. Function set: ' DL = 1; 8-bit interface data ' N = 0; 1-line display ' F = 0; 5x8 dot character font ' 3. Display on/off control: ' D = 0; Display off ' C = 0; Cursor off ' B = 0; Blinking off ' 4. Entry mode set: ' I/D = 1; Increment by 1 ' S = 0; No shift ' ' Note, however, that resetting the Arduino doesn't reset the LCD, so we ' can't assume that its in that state when a sketch starts (and the ' LiquidCrystal constructor is called).#Region "Constructors and Initializers" Public Sub New(ByVal lcd_Addr As Byte, ByVal lcd_cols As Byte, ByVal lcd_rows As Byte) Me._Addr = lcd_Addr Me._cols = lcd_cols Me._rows = lcd_rows Me._backlightval = cnstNoBackLight Me._I2C = New MultiI2C(lcd_Addr, cnstMaxFreq) Me.begin(Me._cols, Me._rows) End Sub Public Sub reset() Me.begin(Me._cols, Me._rows) End Sub ''' <summary> ''' Sends the initialization sequence for the device ''' </summary> ''' <param name="cols">Number of columns</param> ''' <param name="lines">Number of rows</param> ''' <param name="dotsize">Optional cursor size</param> Public Sub begin(ByVal cols As Byte, ByVal lines As Byte, Optional dotsize As Byte = cnst5x8Dots) Me._displayfunction = cnst4BitMode Or cnst1Line Or cnst5x8Dots If lines > 1 Then Me._displayfunction = CByte(Me._displayfunction Or cnst2Line) End If Me._numlines = lines ' for some 1 line displays you can select a 10 pixel high font If (dotsize <> 0) AndAlso (lines = 1) Then Me._displayfunction = CByte(Me._displayfunction Or cnst5x10Dots) End If ' SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! ' according to datasheet, we need at least 40ms after power rises above 2.7V ' before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 'Thread.Sleep(50); ' Now we pull both RS and R/W low to begin commands Me.expanderWrite(Me._backlightval) ' reset expander and turn backlight off (Bit 8 =1) Thread.Sleep(1000) 'put the LCD into 4 bit mode ' this is according to the hitachi HD44780 datasheet ' figure 24, pg 46 'UShort * 2^8 for left shifting 8 bit (<< 8) ' we start in 8bit mode, try to set 4 bit mode Me.write4bits(CByte(&H3 * 2 ^ 4)) Thread.Sleep(8) ' wait min 4.1ms ' second try Me.write4bits(CByte(&H3 * 2 ^ 4)) Thread.Sleep(8) ' wait min 4.1ms ' third go! Me.write4bits(CByte(&H3 * 2 ^ 4)) Thread.Sleep(4) ' finally, set to 4-bit interface Me.write4bits(CByte(&H2 * 2 ^ 4)) ' set # lines, font size, etc. Me.command(CByte(cnstFunctionSet Or Me._displayfunction)) ' turn the display on with no cursor or blinking default Me._displaycontrol = cnstDisplayOn Or cnstCursorOff Or cnstBlonkOff Me.display() ' clear it off Me.clear() ' Initialize to default text direction (for roman languages) Me._displaymode = cnstEntryLeft Or cnstEntryShiftDecrement ' set the entry mode Me.command(CByte(cnstEntryModeSet Or Me._displaymode)) Me.home() End Sub#End Region#Region "High Level me.commands" Public Sub clear() Me.command(cnstClearDisplay) Thread.Sleep(2) End Sub Public Sub home() Me.command(cnstReturnHome) Thread.Sleep(2) End Sub Public Sub noDisplay() Dim display As Byte = cnstDisplayOn Me._displaycontrol = Me._displaycontrol And CByte(Not display) Me.command(CByte(cnstDisplayControl Or Me._displaycontrol)) End Sub Public Sub display() Me._displaycontrol = CByte(_displaycontrol Or cnstDisplayOn) Me.command(CByte(cnstDisplayControl Or Me._displaycontrol)) End Sub Public Sub noBlink() Dim blink As Byte = cnstBlinkOn Me._displaycontrol = Me._displaycontrol And CByte(Not blink) Me.command(CByte(cnstDisplayControl Or Me._displaycontrol)) End Sub Public Sub blink() Me._displaycontrol = CByte(Me._displaycontrol Or cnstBlinkOn) Me.command(CByte(cnstDisplayControl Or Me._displaycontrol)) End Sub Public Sub noCursor() Dim cursor As Byte = cnstCursorOn Me._displaycontrol = Me._displaycontrol And CByte(Not cursor) Me.command(CByte(cnstDisplayControl Or Me._displaycontrol)) End Sub Public Sub cursor() Me._displaycontrol = CByte(Me._displaycontrol Or cnstCursorOn) Me.command(CByte(cnstDisplayControl Or Me._displaycontrol)) End Sub Public Sub scrollDisplayLeft() Me.command(cnstCursorShift Or cnstDisplayMove Or cnstMoverLeft) End Sub Public Sub scrollDisplayRight() Me.command(cnstCursorShift Or cnstDisplayMove Or cnstMoveRight) End Sub Public Sub leftToRight() Me._displaymode = CByte(Me._displaymode Or cnstEntryLeft) Me.command(CByte(cnstEntryModeSet Or Me._displaymode)) End Sub Public Sub rightToLeft() Dim entry As Byte = cnstEntryLeft Me._displaymode = _displaymode And CByte(Not entry) Me.command(CByte(cnstEntryModeSet Or Me._displaymode)) End Sub Public Sub noBacklight() Me._backlightval = cnstNoBackLight expanderWrite(0) End Sub Public Sub backlight() Me._backlightval = cnstBackLight expanderWrite(0) End Sub Public Sub autoscroll() Me._displaymode = CByte(Me._displaymode Or cnstEntryShiftIncrement) Me.command(CByte(cnstEntryModeSet Or Me._displaymode)) End Sub Public Sub noAutoscroll() Dim entry As Byte = cnstEntryShiftIncrement Me._displaymode = Me._displaymode And CByte(Not entry) Me.command(CByte(cnstEntryModeSet Or Me._displaymode)) End Sub#End Region#Region "Charaters and writing" ''' <summary> ''' Allows us to fill the first 8 CGRAM locations with custom characters ''' </summary> ''' <param name="location"> 0-7 locations</param> ''' <param name="charmap"> byte[8] containg charater map</param> Public Sub createChar(ByVal location As Byte, ByVal charmap As Byte()) 'SyncLock LCDLock location = CByte(location And &H7) ' we only have 8 locations 0-7 Me.command(CByte(cnstSETCGRAMADDR Or (CLng(location * 2 ^ 3)))) For i As Integer = 0 To 7 Me.write(charmap(i)) Next 'End SyncLock End Sub Public Sub setCursor(ByVal col As Byte, ByVal row As Byte) Dim row_offsets As Integer() = {&H0, &H40, &H14, &H54} If row > Me._numlines Then ' we count rows starting w/0 row = CByte(Me._numlines - 1) End If Me.command(CByte(cnstSETDDRAMADDR Or (col + row_offsets(row)))) End Sub Public Sub write(ByVal value As Byte()) For position As Integer = 0 To value.Length - 1 Me.write(value(position)) Next End Sub Public Sub write(ByVal value As String) Dim writeVal As Byte() = Encoding.UTF8.GetBytes(value) For position As Integer = 0 To value.Length - 1 Me.write(writeVal(position)) Next End Sub Public Sub write(ByVal value As Byte) Me.send(value, &H1) End Sub Public ReadOnly Property Rows As Integer Get Return Me._rows End Get End Property Public ReadOnly Property Cols As Integer Get Return Me._cols End Get End Property#End Region#Region "Mid level commands" '********** mid level commands, for sending data/cmds Private Sub command(ByVal value As Byte, ByVal vv As Byte) Me.send(value, vv) End Sub Private Sub command(ByVal value As Byte) Me.send(value, 0) End Sub '''/compatibility API function aliases Public Sub blink_on() Me.blink() End Sub Public Sub blink_off() Me.noBlink() End Sub Public Sub cursor_on() Me.cursor() End Sub Public Sub cursor_off() Me.noCursor() End Sub Public Sub setBacklight(ByVal new_val As Boolean) If new_val Then Me.backlight() Else Me.noBacklight() End If End Sub Public Sub load_custom_character(ByVal char_num As Byte, ByVal charMap As Byte()) Me.createChar(char_num, charMap) End Sub#End Region#Region "Low Level commands" ''' <summary> ''' write either command or data to the devide ''' </summary> ''' <param name="value">byte to send</param> ''' <param name="mode">0 = command, 1 = data</param> Private Sub send(ByVal value As Byte, ByVal mode As Byte) Dim highnib As Byte = CByte(value And &HF0) Dim lownib As Byte = CByte((CLng(value * 2 ^ 4)) And &HF0) Me.write4bits(CByte((highnib) Or mode)) Me.write4bits(CByte((lownib) Or mode)) End Sub Private Sub write4bits(ByVal value As Byte) expanderWrite(value) pulseEnable(value) End Sub ''' <summary> ''' Lowest level command to send data to the I2C port ''' </summary> ''' <param name="_data"></param> Private Sub expanderWrite(ByVal data As Byte) Me._I2C.Write(New Byte() {CByte(data Or Me._backlightval)}) End Sub Private Sub pulseEnable(ByVal data As Byte) expanderWrite(CByte(data Or &H4)) ' En high 'Thread.Sleep(1); // enable pulse must be >450ns Me.expanderWrite(CByte(data And Not &H4)) ' En low 'Thread.Sleep(50); // commands need > 37us to settle End Sub#End RegionEnd Class
- carb likes this
#28
Posted 22 September 2013 - 12:05 AM
Thanks for sharing this AxelG. Your library works great!
#29
Posted 13 October 2013 - 07:23 PM
After some digging online regarding implimenting protected constructors, I am able to get it to compile now but I have my doubts I'm calling the methods correctly. I'm not getting anything (not even a flicker) on the LCD. I'm not getting any runtime errors either so I'm assuming it is 'sensing' the screen. Or do I2C ports fail quietly?
public class Display : LiquidCrystal_I2C { public Display(byte address, byte cols, byte rows) : base(address, cols, rows) { } public void writeValue(string s) { this.setCursor(0, 0); this.blink(); this.write(Tools.GetBytes(s)); }
Matthew,
I found that i had nearly identical code as you did, with the same outcome. No exceptions, no worky. If you still are having issues with this / anyone googling this post is, i changed my i2c address back to 0x27 and it worked.
#30
Posted 15 October 2013 - 07:12 PM
I have an example project, now is communication working without exceptions,
but still is not working 100%.
Text is not still displayed...only backlight is working. Bellow is my testing implementation :
Declaration class :
public class HD44780_I2C_Driver : LiquidCrystal_I2C { public HD44780_I2C_Driver(byte address, byte cols, byte rows) : base(address, cols, rows) { } public void WriteString(string s) { this.setCursor(0, 0); this.blink(); byte[] byteArray = Encoding.UTF8.GetBytes(s); this.write(byteArray); } }
program class :
public class Program { private static HD44780_I2C_Driver myLCD = new HD44780_I2C_Driver(0x27, 20, 4); private static OutputPort DA_Led = new OutputPort(Pins.ONBOARD_LED, false); private static bool ledStatus = false; public static void Main() { while (true) { myLCD.setBacklight(true); ledStatus = !ledStatus; DA_Led.Write(ledStatus); myLCD.WriteString("FIRST MESSAGE"); Thread.Sleep(1000); myLCD.WriteString("SECOND MESSAGE"); Thread.Sleep(1000); myLCD.setBacklight(false); Thread.Sleep(1000); } } }
#31
Posted 20 October 2013 - 02:16 PM
After some digging online regarding implimenting protected constructors, I am able to get it to compile now but I have my doubts I'm calling the methods correctly. I'm not getting anything (not even a flicker) on the LCD. I'm not getting any runtime errors either so I'm assuming it is 'sensing' the screen. Or do I2C ports fail quietly?
public class Display : LiquidCrystal_I2C { public Display(byte address, byte cols, byte rows) : base(address, cols, rows) { } public void writeValue(string s) { this.setCursor(0, 0); this.blink(); this.write(Tools.GetBytes(s)); }
Hello,
i have same issue (with one advantage - backlight is working) ... did you get sollution.?
#32
Posted 22 October 2013 - 04:15 PM
This is still working great for me on my N+2 but can anyone clue me in on how to get a degree symbol to show up?
#33
Posted 22 October 2013 - 04:33 PM
This has a character map on it, but I do not know how to get that to display via C# code.
http://forum.arduino...38699#msg138699
printing this: LCD.write("x00A1", 19, 0); ("x00A1" is a string) gives me 1010001 on the map, and with x00D9 I get 3 over and 8 down, so I'm in the right "Column" but I can't figure out how to get below the 10th (0+9) "row"...
#34
Posted 22 October 2013 - 04:43 PM
Silly me. Convert binary (11011111) to Hex (DF) and print that out:
LCD.write("x00DF", 19, 0);
#35
Posted 30 July 2014 - 04:15 PM
Howdy, quick question please:
I am getting errors in deployment with AxelG code at initial post and I think it is because my Netduino *classic* firmware is 4.1. (I've upgraded NETMF to 4.2 already, didn't help).
Must I upgrade the netduino firmware to deploy? upgrading looks daunting to me and I'm worried about it breaking my other functioning projects. I have thought i might just purchase a new Netduino to get the upgraded firmware etc.
thanks much!
#36
Posted 10 September 2014 - 09:55 PM
I am having trouble getting the code in the first post working with my LCD (same sainsmart 2004 as linked in the first post). I have added 1.8k resistors to both the sda and scl lines. When my project start, I see "blocks" in lines 1 and 3 and never get text on the LCD.
I am using a Netduino Plus 2.
#37
Posted 02 June 2015 - 07:47 PM
I attached the driver code to the first post.
Can you post some sample code that uses your driver?
I can't seem to get it to work or initialize the device.
Also tagged with one or more of these keywords: LCD I2C, HD4478, LCD, I2C
General →
Project Showcase →
Adafruit RGB LCD ShieldStarted by giawa, 19 Jul 2015 adafruit, rgb, lcd, shield |
|
|||
General →
General Discussion →
Does Netduino 4.3 Support Clock Stretching by I2C Slave Devices?Started by gismo, 09 Jul 2015 i2c |
|
|||
General →
General Discussion →
Melexis MLX90614 and I2C missing repeated start bitStarted by NameOfTheDragon, 02 Jul 2015 I2C, Plus2, MLX90614 and 1 more... |
|
|||
General →
General Discussion →
Writing a better class to Manage EEPROM Chip - Guidance/Advice WantedStarted by gismo, 30 Jun 2015 eeprom, i2c, class-design and 1 more... |
|
|||
General →
General Discussion →
Talking to Multiple I2C DevicesStarted by Nevyn, 23 May 2015 I2C, Exception |
|
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users