variabele op hd44780 display

trix

Golden Member

hallo,

ik heb ergens in een topic van mij, zijdelings deze vraag ook gesteld, waar beperkte reacties op kwamen.
dus vandaar een nieuw topic.

ik wil op mijn display (4x20) met hd44780, variabele (int & long) laten zien, eigenlijk alleen voor in de test fase. probleem is dat je naar het display alleen "harde" karakters kan sturen.
hoe doe je dit het best/eenvoudigst in C ?
is daar b.v. een aangewezen methode voor ?

tnx.

eigenwijs = ook wijs
buckfast_beekeeper

Golden Member

Wat bedoel je met 'harde' karakters?

Welke librarie gebruik je?

Van Lambiek wordt goede geuze gemaakt.

voor int : itoa()
voor long : ltoa()

Als in:

code:


   char Buffer[20];

   int x = 5;
   itoa(x, Buffer, 10);

   long y = 1000;
   ltoa(y, Buffer, 10);

Dat levert een ASCII string in Buffer die je naar je display kunt sturen.

buckfast_beekeeper

Golden Member

Een goed librarie heeft iets in de richting van putInt en putLng.

Als je wat info zoekt over itoa en ltoa dan kom je vaak dit tegen.

This is a non-standard function. Even though the prototype given is commonly used by compilers on other platforms, there is no guarantee that this function will behave the same on all platforms, in all cases. You can use this function to help port applications from other platforms, but you should avoid using it when writing new applications, in order to ensure maximum portability.

Van Lambiek wordt goede geuze gemaakt.
trix

Golden Member

Op 29 juni 2020 17:50:35 schreef buckfast_beekeeper:
Wat bedoel je met 'harde' karakters?

Welke librarie gebruik je?

harde karakters, tsja,...ik bedoelde eigenlijk dat je alleen letters & cijfers kunt sturen naar het display,.....het is slecht verwoord door mij

ik gebruik een libary gedownload van electrosome.com, moet even zoeken.

komt van deze pagina:
https://electrosome.com/lcd-pic-mplab-xc8/

eigenwijs = ook wijs
Arco

Special Member

harde karakters, tsja,...ik bedoelde eigenlijk dat je alleen letters & cijfers kunt sturen naar het display,.....het is slecht verwoord door mij

Dat is niet waar: je kunt ook custom characters aanmaken...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
trix

Golden Member

klopt, dat wist ik wel :) ....slecht verwoord.

eigenwijs = ook wijs
buckfast_beekeeper

Golden Member

@trix: lees de door je geposte pagina een keer goed. Ik denk dat het antwoord gewoon op de website staat.

sprintf() to Format Outputs

sprintf() can be used to write formatted string to a variable. It can be used with this LCD library to format displayed texts. This enables us to display integers and floating point numbers on the LCD very easily. You should include the header file stdio.h for using sprintf().

Alles rond het gebruik van sprintf kan je hier lezen.

Als je de datasheet van je display er op na slaat, dan staat daar meer dan waarschijnlijk ook de ganse karakter lijst in. Door de juiste waarde naar je display te sturen kan je die ook tevoorschijn toveren.

En zoals Arco ook al zegt, je kan 8 eigen karakters aanmaken. Die kan je opslaan van adres 0 tot 7. Let wel dit is RAM en geen ROM. Elk karakter dien je dan zelf te definiëren. Maar ook daarvan staat een voorbeeld in de datasheet.

Van Lambiek wordt goede geuze gemaakt.

Die display leeft inderdaad alleen een ASCII interface.
En dan kun je sprintf() gebruiken om de strings aan te maken:

code:



   char Buffer[20];

   int a = 12;
   sprintf(Buffer, "Integer = %d", a);
   Lcd_Set_Cursor(2,1);
   Lcd_Write_String(Buffer);

Maar dat is nogal in-efficient want dan komt de string ook in SRam.
Die kun je beter in flash plaatsen met sprintf_P():

code:



   char Buffer[20];

   int a = 12;
   sprintf_P(Buffer, PSTR("Integer = %d"), a);
   Lcd_Set_Cursor(2,1);
   Lcd_Write_String(Buffer);

Zoals gedefinieerd in:

code:


   #include <stdio.h>
   #include <avr/pgmspace.h>

Alles rond het gebruik van sprintf kan je hier lezen.

Nou, alles? Voor Avr-gcc zijn er nog wel een paar extra puntjes van belang die daar niet vermeld staan.

Zie avr-libc-user-manual.pdf
Die komt mee met elke install. Ook met atmet studio, al zit hij wel diep verstopt in de toolchain directory:

"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\doc"

trix

Golden Member

even op me in laten werken en inderdaad nog eens goed lezen.

eigenwijs = ook wijs
Arco

Special Member

Ik gebruik de custom characters altijd voor batterij symbooltjes... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
mel

Golden Member

Ik heb eens een treintje over het display laten rijden :)

u=ir betekent niet :U bent ingenieur..

Als je een print-teken functie hebt, die een enkel teken op je display zet (en ervoor zorgt dat het volgende teken erachter komt) dan kun je vrij eenvoudig printf() gebruiken:

c code:


void print_char(char c)
{
  // do display stuff
}
FILE display_stream = FDEV_SETUP_STREAM(printchar, NULL, _FDEV_SETUP_WRITE);
stdout = &display_stream;

En dan kun je overal printf() gebruiken.

trix

Golden Member

ik ben nu aan het testen om een variabele op het scherm te krijgen, en dat lukt ook wel. maar ik had toch nog wat vraagjes:
volgens het voorbeeld op:
https://electrosome.com/lcd-pic-mplab-xc8/
(jemoet naar beneden scrollen naar: sprintf() to Format Outputs)

c code:


int a = 56;
char s[20];

sprintf(s, "Integer = %d", a);
Lcd4_Set_Cursor(2,1);
Lcd4_Write_String(s);

krijg ik keurig 56 op het display.

vraag: wat doet die char s[20]; daar eigenlijk, dat is toch een array ?
eigenlijk is mij die hele syntax niet erg duidelijk.

ik heb nu dus mooi die 56 op het display, maar eigenlijk wil ik die binair op het display. hoe doe ik dat het best ?

eigenwijs = ook wijs
buckfast_beekeeper

Golden Member

char s[20] is inderdaad een array. Met sprintf(s, "Integer = %d", a) steek je "Integer = %d" in het array waar %d een signed integer moet voorstellen en a is de variabele die je op %d gaat weergeven.

Set cursor zal wel duidelijk zijn.

Met Lcd4_Write_String(s) zet je de string die je aangemaakt hebt met sprintf op het scherm.

edit: voor een binair formaat zal je zelf wat moeten schrijven in een loop waar je de char array zelf vult vermoed ik.

edit 2: voorbeeld code.

[Bericht gewijzigd door buckfast_beekeeper op zondag 5 juli 2020 10:06:47 (10%)

Van Lambiek wordt goede geuze gemaakt.
trix

Golden Member

die array heeft dan 20 plaatsen, waarom 20 ? is dat zomaar een voorbeeld ?
waarom moet je die uberhaupt in en array stoppen ?

edit: dat omrekenen ga ik bekijken, tnx

[Bericht gewijzigd door trix op zondag 5 juli 2020 10:11:38 (15%)

eigenwijs = ook wijs
buckfast_beekeeper

Golden Member

20 is meer dan waarschijnlijk gekozen omdat heel veel displays 20 tekens lang zijn. Uiteraard kan je dat aanpassen aan je behoefte. Elk karakter 'te veel' is verspilde ruimte.

Een string is een array van karakters. Stuur je "Integer = 56" naar je display stuur je eigenlijk een array met de I op plaats 0, n op plaats 1 en zo verder.

edit: Bij HD44780 displays er op letten dat op een display van 2*20 het 21ste teken niet op de 2de regel zal verschijnen. Karakter 21 zie je wel op een 4*20 karakter display op regel 3. Regel 2 begint standaard op 0x40.

[Bericht gewijzigd door buckfast_beekeeper op zondag 5 juli 2020 11:05:59 (26%)

Van Lambiek wordt goede geuze gemaakt.
pa3gws

Golden Member

Op 30 juni 2020 08:04:06 schreef mel:
Ik heb eens een treintje over het display laten rijden :)

En is het display heel gebleven. :-p (sorry kon het niet laten)

Ik ben gestopt met roken nu mijn schakelingen nog.
EricP

mét CE

Je denkt veel te moeilijk - komt vaker voor bij mensen die nooit fatsoenlijk assembly geleerd hebben.

Goed, je hebt een stuk text en daar wil je wat mee. In dit geval naar het display sturen. Kort door de bocht zijn er 2 mogelijkheden: je houdt bij hoe lang het is en waar het begint (zo doet pascal het). Of je houdt bij waar het begint en gebruikt een 'special character' wat anders nooit voor zal komen als terminator (zo doet C het).

Voor beide methoden is wat te zeggen. Bij de eerste is de lengte beperkt (immers, in Pascal is de 'length' een byte, en daarmee je string beperkt tot 255 characters). Bij de 2de is de soort van data die je erin kunt douwen beperkt (nl. een 0 als waarde is 'einde', dus die kun je nooit opslaan). Voor dingen die weergegeven moeten worden, is dat prima. Immers, ASCII 0 is niets zichtbaars.

Als je dus (in C) een array van 20 elementen declareert, dan kun je er dus 19 characters en 1 terminator in kwijt (ja, die fout wordt vaak gemaakt).

Wat ZOU KUNNEN (en dat hoeft dus zeer zeker niet zo te zijn), is dat de maker van de lib eea. 1-op-1 op het display laat matchen. Dat zou die 20 characters verklaren. Erg onhandig, want als je een strcpy zou gebruiken met 20 chars, dan schrijf je dus 1 byte te ver - en dus over wat anders heen. Dit is dus de manier om stack plat te schrijven en op een PC je eigen code uit te voeren.

Waarom het een array is? Welnu, ik denk dat dat gewoon makkelijk uit kwam in de syntax.
Daarnaast zit C redelijk dicht tegen assembly aan. In assembly moet je ook gewoon 20 bytes declareren en zelf bepalen welk mechanisme je gebruikt. Dat zit in je library functions, niet direct in je taal. Dit is de 1-op-1 vertaling ervan.

[Bericht gewijzigd door EricP op zondag 5 juli 2020 11:12:51 (13%)

mel

Golden Member

;)

Op 5 juli 2020 11:01:22 schreef pa3gws:
[...]
En is het display heel gebleven. :-p (sorry kon het niet laten)

;) :P

u=ir betekent niet :U bent ingenieur..
trix

Golden Member

Op 5 juli 2020 11:04:55 schreef EricP:
Je denkt veel te moeilijk

heb ik heel mijn leven al last van :)
het word al wat duidelijker, tnx

edit: ik heb trouwens een 4x20 (hd44780)

[Bericht gewijzigd door trix op zondag 5 juli 2020 11:45:47 (10%)

eigenwijs = ook wijs
EricP

mét CE

Je moet met die sprintf dus erg oppassen dat je resultaat niet te lang wordt. Dan ga je over ander memory heen schrijven.
Kijk evt. ook eens naar snprintf.

Verder: Ik ken de lib die je gebruikt niet. In de documentatie daarvan zou moeten staan hoe die de data verwacht.

trix

Golden Member

over dat te lang, moet ik nog even over nadenken. dat zou wel heel vage errors kunnen geven in je code.

ik begrijp natuurlijk wel dat het resultaat niet langer mag zijn dan wat in de array past.

[Bericht gewijzigd door trix op zondag 5 juli 2020 12:00:13 (31%)

eigenwijs = ook wijs
EricP

mét CE

Ja. Je weet niet wat daarachter staat. Verdiep je in stack en heap in C.
Het algemene gebruik als aanvalsvector (dat zal voor een controller in deze context wel loslopen hoor):

  • Zoek iets wat een crash veroorzaakt
  • Kijk naar de code en analyseer waarom het struikelt
  • Kijk of je bij een return address op de stack kunt komen zodat je dat kunt modificeren
  • Zet je eigen code neer en laat op de return daarheen springen.

Wat er feitelijk gebeurt als je een CALL doet is dat op de stack het return address gezet wordt - waar moet de instruction pointer heen als je een RET doet? Daarna worden locals geallocceerd. Stack groeit van boven naar beneden, dus als je in een local teveel schrijft, dan schrijf je eerst de volgende local plat en uiteindelijk je return address. En ja, dat kan hele rare bijeffecten geven.