PDA

View Full Version : How exactly LCDOUT statement works?



CuriousOne
- 6th August 2021, 04:39
Hello.
I'm trying to get the max out of ST9720 LCD module. It needs some custom commands to be sent, and I'm using LCDOUT for that. But what and how exactly this statement does? Manual shows only common use, without going into internals. Like just send $FE,$80 to set cursor at beginning of the 2nd line and so on.

So here are questions.

What is $FE for LCDOUT and why it is mandatory? (I tried removing it and sending next statement without it - it does not works) This is 1111 1110 in BIN, and I can understand that it might be used for display initialization, but as most display manuals say, for initialization you have to send 0000 0001. This means, this statement works in reverse? If it is not for initialization, then why LCDOUT $FE, $1 does the same?

Does this statement allows control of RW/E lines? (This is required for display module config), or we have to do it manually) If yes, then how?

CuriousOne
- 6th August 2021, 04:42
Also, it is possible to use 4 or 8 bits for controlling the LCD module. But some statements want to send bytes to DB7-DB4 ports. How this is done via 4 bit hardware connection?

richard
- 6th August 2021, 10:40
5.38 LCDOUT
LCDOUT Item{,Item...}
Display Items on an intelligent Liquid Crystal Display. PBP supports LCD modules with a Hitachi 44780 controller or equivalent. These LCDs usually have a 14- or 16-pin single- or dual-row header at one edge.
.......................


What is $FE for LCDOUT and why it is mandatory? (I tried removing it and sending next statement without it - it does not works) This is 1111 1110 in BIN, and I can understand that it might be used for display initialization, but as most display manuals say, for initialization you have to send 0000 0001. This means, this statement works in reverse? If it is not for initialization, then why LCDOUT $FE, $1 does the same


Commands are sent to the LCD by sending a $FE followed by the command. ie not data
read the manual


5.38 LCDOUT
The LCD may be connected to the PIC MCU using either a 4-bit bus or an 8-bit bus. If an 8-bit bus is used, all 8 bits must be on one port. If a 4-bit bus is used, the top 4 LCD data bits must be connected to either the bottom 4 or top 4 bits of one port.



Also, it is possible to use 4 or 8 bits for controlling the LCD module. But some statements want to send bytes to DB7-DB4 ports. How this is done via 4 bit hardware connection?

44780 or equivalent controllers Have a 4 bit i/f protocol that pbp can use to send 8 bit data or commands to the display by breaking it into nibbles for transfer

CuriousOne
- 6th August 2021, 19:38
I have read manual, and it says nothing about $FE, and why it can't be $DC, for example.

And how this breaking into nibbles is done?
Can I have an example?
I mean, how can I instruct LCDOUT to send 8 bit data command.

HenrikOlsson
- 6th August 2021, 22:44
$FE is the "signal" to the compiler that the next byte should be sent to the LCD as a command and not as data. The fact that it's $FE and not something else is most likely because $FE in the character set of the HD44780 is a white space (at least in ROM code A00) which there already is a valid ASCII code for within the character set ($20).

DEFINE LCD_BITS 8 will instruct the compiler to talk to the LCD in 8-bit mode. This IS covered in the manual, there's even setup code and schematic for 8-bit mode. The LCDOUT command itself is used exactly the same, no matter 4 or 8 bit mode. Read through the section on LCDOUT again.

CuriousOne
- 7th August 2021, 16:03
I know how to set up 8 bit connection.
I want to learn how to transfer 8 or 16 bits with 4 bit connection.
Because say

LCDOUT $FE,0,1

is NOT equal (in terms what I see on display)

to

LCDOUT $FE,0
LCDOUT $FE,1

So I guess, on each LCDOUT statement, there's something special made to display. So I'm interested exactly what happens.

HenrikOlsson
- 7th August 2021, 21:33
Again, $FE is the "signal" to the compiler that the next byte should be sent to the LCD as a command and not as data.

LCDOUT $FE, 0, 1 will send the value 0 to the instruction register and then the value 1 to the data register of the LCD controller.
LCDOUT $FE, 0, $FE, 1 will send 0 and 1, both to the instruction register.

On the LCD controller the RS-pin is what controls which register the data ends up with. $FE tells the compiler to generate code that pulls the RS-line LOW for the duration of the next byte transfer. It's as simple as that and it feels to me like your reading too much into it.

CuriousOne
- 11th August 2021, 20:35
I'm trying to deal with ST7920 controller, to enable the graphics mode.
It needs a complex initialization sequence. (like send this, then wait xx ms, then pull e high, then pull e down, then wait again, then send and so on) To make things simpler, I wanted to use LCDOUT, instead of port bitbanging, but as it seems, that is impossible.

HenrikOlsson
- 12th August 2021, 08:28
Well, LCDOUT is designed for 44780 compatible controllers. A quick look at the ST7920 datasheet seems to indicate that it's sort of compatible but with extended functionallity. It may or may not work with LCDOUT.
Do you have it connected with 4-bit or 8-bit interface?

I would let the compiler do the initial initalization, setting 4/8-bit interface etc. Then I would make two manual writes enabling graphics mode and extended function set mode, making SURE I don't change the 4/8-bit mode flag when doing so. See the note in the datasheet that you can't change DL, RE, and G at the same time, hence the multiple writes. Provided 4-bit interface is used I would try:


LCDOUT $FE, %00100100 ' Enable extended instruction set, keep 4-bit interface.
LCDOUT $FE, %00100110 ' Enable graphics mode, keep 4-bit interface and extended instruction set.

CuriousOne
- 12th August 2021, 09:01
Yes I have it connected via 4 bit interface. This is a special kind of ST7920 module, which has physical dimensions and pinout of standard 1602 LCD module, and in most cases, just works as drop-in replacement.
So far, I've figured an easy ways how to use LCDOUT to display all extended characters and features for this display. The graphic mode remains a mystery. My idea is to develop a PBP code, which will allow to use this module with existing 1602 LCD codes with as less modification, as possible.

I will try your solution today later and will write back.

CuriousOne
- 20th September 2021, 06:32
Just a note to myself or anyone else having same situation - the recommended approach works. While I have not tested it with ST7920, I do tested it with PT6314 for adjusting the VFD brightness and it does works.

mpgmike
- 21st September 2021, 00:44
This thread illustrates why I use maybe 80% of the PBP commands, but manually work with SFRs for the other 20%. I don't use LCDOUT (and several other commands), as they occasionally don't work with the PIC I'm using, or I can't get them to do what I want. If all else fails, PBP does an excellent job of enabling the programmer to manipulate SFRs manually. I create Subroutines to do what certain PBP commands are supposed to do. In fact, I don't even use ADCIN anymore after it failed on one of the PICs I worked with several years ago (forget which one).

This thread has brought forth what I consider to be valuable questions that lead to knowing what actually goes on in the background. The PBP Commands that I still use (most, actually) are ones that after discovering what they do, I like-endorse-value the PBP approach. Those I have abandoned are ones that I feel I can do an adequate job (perhaps even better for my application) than the PBP approach. Hobbyists appreciate the simplicity of the PBP Commands. Those of us that NEED absolute functionality may decide to manipulate the SFRs instead of using convenient PBP Commands. This thread has been educational.

CuriousOne
- 21st September 2021, 06:50
Well it's about knowledge.
For me it would be great if there were commands which directly work with WS2812, DHT22 and a huge list of other hardware, which is not supported right now....

Ioannis
- 21st September 2021, 07:43
... In fact, I don't even use ADCIN anymore after it failed on one of the PICs I worked with several years ago (forget which one)...

Well in contrast when I fail to use an ADC, I turn to ADCin and works first time! Taking more code space I guess and time...


Well it's about knowledge.
For me it would be great if there were commands which directly work with WS2812, DHT22 and a huge list of other hardware, which is not supported right now....

Then it would be Arduino and not PBP...

Ioannis

CuriousOne
- 21st September 2021, 11:39
lol ok, let's remove LCDOUT, OWIN, ADCIN, SEROUT and others too? :D
Instead of adding something useful like NEOPIXEL $ADDR,$BRIGHTNESS,$R,$G,$B :)

richard
- 21st September 2021, 12:20
adding something useful like NEOPIXEL $ADDR,$BRIGHTNESS,$R,$G,$B

all of my posted examples can do that easily, except for brightness as its a function of r g b so would be a totally useless input

http://www.picbasic.co.uk/forum/showthread.php?t=23399
http://www.picbasic.co.uk/forum/showthread.php?t=20973

a neopixel usercommand could be added with a few more lines of code to make the process more explicit
but its trivially easy as is.
very few have shown any interest in this code , very few have even asked a question.

large arrays of neopixels can be resource hungry and will need a midrange chip. a general purpose version is and will
remain a fantasy, the hardware must match the job

Ioannis
- 21st September 2021, 13:53
large arrays of neopixels can be resource hungry and will need a midrange chip

tell me about it... That is why I prefer APA101.

So every job needs its tool. Cannot one size fit all.

Ioannis

CuriousOne
- 21st September 2021, 15:19
But arduino does neopixel with ancient chip with ease?
and also supports brightness? (it is also supported with RGB, you know?)

The libraries and our own addons are of course great, but I'm speaking about centralized support - you just type in, it just works. No forum searching and guesswork.

HenrikOlsson
- 21st September 2021, 19:17
As far as I know (correct me if I'm wrong) Arduinos support for NeoPixels is not part of the Arduino language itself. It's an add-in library that you have to download, install and include into your code in order to use it. It's not written or maintained by "Arduino the company" but by some third party (user, company, community) and I'm pretty sure there's more than ONE version of that library to choose from as well. Which can be confusing.

The same thing goes for a lot of other stuff that "Arduino has" - it's libraries written by users and rest assured that the quality of them varies. Pretty much the same thing as "our" stuff.

The big advantage is the encapsulation that proper function calls with parameter passing, local variables and return values provides. This provides the means to "hide away" even more stuff from the user than with PBP that doesn't support function calls and/or local variables. It's not magic though.

A month or so ago I posted code for driving SK6812 RGBW LEDs. Using that particular code your example

NEOPIXEL $ADDR,$BRIGHTNESS,$R,$G,$B

Would look like:

Red[ADDR]=R : Green[ADDR]=G : Blue[ADDR]=B : GOSUB UpdateDisplay

And if you wanted you could rename the UpdateDisplay subroutine to NEOPIXEL and it would be

Red[ADDR]=R : Green[ADDR]=G : Blue[ADDR]=B : GOSUB NEOPIXEL

Not THAT much different now, is it? Granted, the "library" IS hardcoded to run at 64MHz so you won't run a 16x16pixel array on a 12F508 - for multiple reasons.

You still need to include the code and set up some variables and aliases, but you don't get away from that with Arduino either.

CuriousOne
- 21st September 2021, 20:19
Regarding this particular library, it is supported and maintained by adafruit - major arduino contributor.
To use it in your project, you just go to library manager, type in neopixel there, click download & install and that's all.
all "define"s for it are here:

#define LED_PIN 14
#define NR_OF_PIXELS 12
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}

And to use it:

strip.setBrightness(255);
strip.setPixelColor(1,10,30,40);

no "hard coding" no "tied to 64mhz oscillator" - it just runs.
I understand that from approach of older guys like myself
this might appear to be not serious, but it allows you to get
to the end result faster - you need neopixel led, you got it
no need to care about osc clocks, tight timing and which
chip can do it, and which - can't.

Of course, arduino has it's own limitations - huge board with external osc
you can't run it off tiny SOIC-8 chip, as you can do with PBP
and that dreadful programming language, not meant to be understood by normal human beings :)

Ioannis
- 21st September 2021, 20:25
But arduino does neopixel with ancient chip with ease?

How does these chips compare to the many flavors of PIC's?

You can't have it all. Too many chips, too many specs, and all do the same thing. Not possible. You have to compromise and select a powerful chip, stick on this no matter how much it costs and do your light or heavy job. Close to what a powerful ATMEL chip does on Arduino. From flashing a LED to NEOPIXEL or more.

Ioannis

CuriousOne
- 21st September 2021, 20:58
Yeah but LCDOUT and other "specific" statements like OWIN do work on both low end beauties and high end PICs too?

Ioannis
- 21st September 2021, 21:10
Sure they do. They are low on resources need!

But Neopixel? no...

Ioannis

richard
- 22nd September 2021, 02:10
But arduino does neopixel with ancient chip with ease?

the typical micro in uno etc is ATmega328P thats slightly more 'powerful' than a 18f26k22
its no pic16 clunker, the arduino chips go upwards from there in performance



no "hard coding" no "tied to 64mhz oscillator" - it just runs.

that you can see , its there , tied into a mandatory small set of fixed hardware configurations

CuriousOne
- 23rd September 2021, 18:52
And what about BMP180 pressure sensor?
I only find sample code for BMP085 on this forum, and it requires PBPL and high end chip too
but why? isn't that simple I2C interfacing?

HenrikOlsson
- 25th September 2021, 09:34
Sure, interfacing the chip is simple I2C or SPI but there's some quite heavy math involved in order to go from the raw values you get out of the chip to actual "units". Just look at the datasheet. If you can use the BME280/BMP280 instead, I've posted code for that (http://www.picbasic.co.uk/forum/content.php?r=558-BME280-Example) - but yes it requires an 18F part in order to perform the math involved.

(It might be that the code would work for the BMP180 as well, I won't investigate).

CuriousOne
- 25th September 2021, 17:32
Thanks!
So there is no PIC16 friendly barometric pressure sensor available?
I want to integrate it into my VFD clock project - I already have DHT22, DS3231, TTP223 up and running. So I wanted to add barometric pressure, to do some weather forecasting :)

(Sorry for not removing protective sheet from filter, this is quite expensive material, a gift was send by Noritake, so I'm keeping it sealed till I'll go to final design stage and incorporate it into finished product).

9079

CuriousOne
- 25th September 2021, 17:45
Say if 1% precision for me is enough, still 18F needed?

CuriousOne
- 3rd October 2021, 16:05
Got some time and tested that approach with ST7920. And it indeed works.
While PBP seems to beginning to belong to dead language category, I'll leave this simple code here anyways - maybe someone will find it useful.

ST7920 is wired as standard HD44780 in 4 bit mode. With appropriate LCD pins defined.



LCDOUT $FE,$2E 'enable graphic mode
LCDOUT $FE,$80 'set Y position to zero (Top)
LCDOUT $FE,$80 set X position to zero (Left)
LCDOUT 255 'draw a line consisting of 8 pixels in top left row

Note: X counter increases after each write by itself, but Y counter - not, so you have to do it manually.

And this simple code fills up entire screen with white:



LCDOUT $FE,$2E
for Z=0 to 32
LCDOUT $FE,$80+z
LCDOUT $FE,$80
FOR x=1 TO 18
LCDOUT 255
NEXT
next

CuriousOne
- 12th October 2021, 06:10
How to send $FE with LCDOUT ?
X=$FE
LCDOUT X

It sends statements instead of byte data :) Found this accidentally - one of my custom font letters contained $FE pixels, and when using that char, it blowed up all my code. Took me several days to figure the reason (I was thinking about faulty EEPROM, display controller, SRAM on PIC and so on)

CuriousOne
- 17th October 2021, 13:26
Any ideas?
This is very annoying and trashes whole idea of using LCDOUT statement...

HenrikOlsson
- 17th October 2021, 14:11
At the very beginning of this thread we went over how LCDOUT works, how it determines if what you give it should be sent as data or as commands, ie the $FE prefix. Now, a couple of weeks later you claim to have found this by accident and all of a sudden the LCDOUT command is at fault and doesn't work.

LCDOUT works perfectly fine for its intended purposes. You're trying to use it for something it was not designed for and because that doesn't work the way you'd like the command is flawed, is that correct?

Apart from editing the custom characters to not include $FE and/or writing your own routines to drive the display I don't have any ideas.

CuriousOne
- 17th October 2021, 14:19
Well, I have shifted letters to right edge, instead of left, and for text it indeed works, but when there is need to display the graphics...
I'm using LCDOUT due it's simplicity and low memory use.
The code below occupies less than 1k of memory (font data stored in eeprom), and allows you to have 4 lines X 18 characters text display with all custom letters on graphical display.



C=0 '0=1st line, 8=2nd line, 16=3rd line and 24=4th line
arraywrite topline, ["place text here "]
GOSUB GCODER
stop




GCODER:
FOR X=0 TO 17 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
Y=(topline[x]-65)*8
Z=(topline[x+1]-65)*8 'READ INTO VARIABLE AS TWINS
FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B
LCDOUT $FE,$80+i+c 'UPDATE Y POSITION
LCDOUT $FE,$80+x/2 'UPDATE X POSITION
if topline[x]=32 then a=0
if topline[x+1]=32 then b=0 'blanker
LCDOUT a
LCDOUT b 'WRITE TO SCREEN
'pause 10
NEXT I
NEXT X
return