News:

Let's find out together what makes a PIC Tick!

Main Menu

I2C LCD1602 RGB Module Problems

Started by Wimax, Apr 10, 2022, 09:51 AM

Previous topic - Next topic

Wimax

Hi folks !

I have a problem with a LCD1602 RGB Module display from Waveshare ( https://www.waveshare.com/wiki/LCD1602_RGB_Module ).
I can't get it to work using a 33FJ12GP202 PIC, the module can theoretically be powered at 3.3V or 5V and I'm using the first mode.
Since it seems that in this world you have to use Arduino, Raspberry and similar platforms to use peripherals I wasted some time translating some Python code in Basic to try to use it (the datasheet is quite poor).
Before returning it I want to make sure I didn't make any mistakes, I tried with an "old" BasicAtom (8 bit, 5V) and I could only turn on the backlight and change the colors, but the display doesn't initialize.
Switching to the 33FJ12GP202 the situation got even worse and I just can't get it to work.
This is the code:

Device=33FJ12GP202
Declare Xtal= 7.3728
 
Symbol LCD_ADD = ($0x7c) ' Target LCD
Symbol RGB_ADD = ($0xc0) ' Target RGB
Symbol SDA_Pin = PORTB.2 ' Alias the SDA (Data) pin     IO5
Symbol SCL_Pin = PORTB.3 ' Alias the SSL (Clock) pin    I06
Symbol LED = PORTB.15 ' Alias the LED
Low LED
DelayMS 1000

I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x20|$0x00|$0x00]
DelayMS 50
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x20|$0x00|$0x00]
DelayMS 50
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x20|$0x00|$0x00]
DelayMS 50

I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x04|$0x00|$0x00]
DelayUS 150
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x08|$0x04]
DelayUS 150
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x01]
DelayUS 150
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,$0x04|$0x02|$0x00]
DelayUS 150


I2COut SDA_Pin, SCL_Pin, RGB_ADD,[$0x0,$0x0]
DelayUS 200
I2COut SDA_Pin, SCL_Pin, RGB_ADD,[$0x01,$0x20]
DelayUS 200
I2COut SDA_Pin, SCL_Pin, RGB_ADD,[$0x08,$0xFF]
DelayUS 200

I2COut SDA_Pin, SCL_Pin, RGB_ADD,[$0x04,$0xFF]
DelayUS 200
I2COut SDA_Pin, SCL_Pin, RGB_ADD,[$0x03,$0xFF]
DelayUS 200
I2COut SDA_Pin, SCL_Pin, RGB_ADD,[$0x02,$0xFF]

High LED

the repetition of some commands I inherited from python code, actually it shouldn't be necessary.

Wimax

A "perfect storm" occurred  :o .

  • Probable bug in the I2Cout command of the old 8-bit micro, discovered thanks to the logic state analyzer
  • Problem on PORTB.3 port of 33FJ12GP202, I don't know why the clock signal was not generated
  • Incorrect initialization sequence described in the software for Arduino & Co. supplied with the module


After wasting a lot of time trying to make the module work according to the Python software, I found the datasheet of the AiP31068 integrated circuit that controls the display. Once powered up and waiting for a reasonable time during which an internal initialization routine is executed, it is necessary to send the following sequence:

I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,%00101000]       
DelayMS 50
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,%00001100]       
DelayMS 50
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x80,%00000001]       
DelayMS 50

and...that's all !

I changed the CLK port from PORTB.3 to PORTB.6 because I didn't have the CLK signal and I don't know why.

top204

#2
Glad you got it sorted. I was working an an I2C LCD a few years ago that used a PCF8574 chip for its interace, and it worked well using the I2C commands.

With the PIC and PIC24 and dsPIC microcontrollers, pins are often multiplexed with other peripherals, and for some reason, Microchip have a habit of defaulting with the peripherals enabled. So an I/O pin will not operate as a digital pin until the peripheral is disabled and the pin set to digital mode.

The compilers try to disable the peripherals it can, but it does sometimes miss one because Microchip keep moving things around, and the "If" statements in the .ppi creator program are already huge for all the differences, and I do not have the logistical time to go though every single item in every single device's data sheet. LOL

The I2CIn and I2Cout commands use a software method of operation, named bit-bashing and have not changed from day one of them being added to the compilers, so it will be a multiplexed peripheral that is causing a problem somewhere in the device. The bit-bashed comamnds are much better because they are not "device dependant", because Microchip change the way peripherals operate from device to device now, and standards do not seem to exist with them anymore. :-(

Wimax

Nice to hear from you again Les ! :)

Thanks for the suggestions, I will try to unlock the pin.
I'm now struggling to find an efficient way to pass a string (of undefined length a priori) to a procedure so that I can then send it as a write to the module.
I'm trying to send a series of numbers, but when I use this code:
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x40, "100" ] 
DelayMS 100
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x40, "200" ] 
DelayMS 100
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x40, "300" ] 
DelayMS 100

The display shows 100200300 as it must do. When I switch to a For/Next cycle as (A is a Word variable):
For A=100 To 300 Step 100

I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x40, Dec A ] 
DelayMS 100

Next
it writes 100300 ?! Why one number is lost ? :'(

top204

#4
Quoteit writes 100300 ?! Why one number is lost ?

That seems to be something to do with the LCD's timing, because the variable "A" will hold the value of 200 at one point within its loop, and if the LCD received and displayed "100" then "300", maybe the timing is too short for the middle one to be received by it. Try it with smaller steps and with different delays between them. Also send the clear display and home command, so you see the individual texts on the LCD more clearly.

You are better off using a String variable to pass the text to the LCD, then either use the String as a parameter of a procedure, or load the String before sending it via the I2Cout command.

Wimax

Ok! Now I'm using a string, but I'm trying to limit the number of characters to display because a Null is also transmitted and generates an unwanted extra character. Positron does not allow me to use a variable for the number of characters that can be displayed via Str
For A=10 To 30 Step 10
Cifre=Str$(Dec A)
L=Len (A) -1
I2COut SDA_Pin, SCL_Pin, LCD_ADD,[$0x40, Cifre\L ] 
DelayMS 1000

Next