Tack för svaren.
Displayen har en lödd kontakt med 8cm långa sladdar med stiftpinnar i andra änden.
(Såna där sladdar som säljs i en bunt med olika färger och svarta pinnar, just för labplattor.)
Dessa sitter anslutna så nära portexpander-IC'n som det bara är möjligt.
Mindre härva än så här kan man inte få med en display ansluten till en labplatta.
Från portexpander-IC'n så går en 10cm lång flatkabel med IDC-kontakt till Raspberry Pi'ens I2C-anslutningar.
Matningspänning för display och portexpander kommer från ett bra köpt labaggregat.
(Labaggregatet och Raspberryn har sina GND ihopkopplade till en punkt på labplattan.)
Det är allt.
Jag håller med om att det verkar som timingproblem eller att något hamnar "snett",
t.ex att sista nibblen uteblir på något ställe.
Men jag kan inte låta bli att fundera på en sak:
Hur skulle det kunna vara ett fel med hårdvaran eller mjukvaran (glitchar, timingproblem, fel i rutiner, osv)
när jag kan göra allt utom att göra egna tecken? Dvs:
Att initieringsrutinen körs korrekt bevisas av att jag kan skriva text/siffror på displayen.
Att jag kan skriva text/siffror, flytta markören (med flit) visar ju att rutinerna fungerar
och att det inte är glitchar eller timingproblem.
Eller ligger CGRAM möjligen på en separat minneskrets som skiljer sig mellan DDRAM,
eller är det något annat i displayens hårdvara som skiljer dem åt rent elektroniskt
och därmed gör att just enbart CGRAM drabbas av vad som nu orsakar problemen?
Om jag går igenom portexpanderns utgångar:
Eftersom jag kör med 4bit så används bit 7-4 till allt som ska ut på skärmen.
De används alltså flitigt. Och det har aldrig blivit något som helst tecken till problem.
Bit 3 använder jag inte.
Bit 1 och 2 styr E. Utan dem hade jag inte kunnat få ut något livstecken alls på displayen.
Bit 0 styr RS. RS ska vara 0 när man initierar. Jag kan initiera.
RS ska vara 1 för att kunna skriva text på displayen. Jag kan skriva text på displayen.
Jag förstår inte hur ovanstående skulle kunna ha varit möjligt om det var något med
hårdvara, glitchar, egenheter i portexpandern, fel i mina rutiner, och liknande.
För visst måste ni hålla med om att det vore ytterst märkligt om portexpandern
skulle uppföra sig annorlunda när jag t.ex vill skriva till CGRAM jämfört med om jag vill skriva till DDRAM.

Den har ju inte en aning om vad det är.
Om det var någon enstaka eller ett par bitar i kommunikationen som uppförde sig konstigt
så skulle det ju märkas även när jag använder samma bitar till andra saker.
Upplys mig gärna ifall det är något i mitt resonemang som jag missar.
"Hur latchar portexpandern data till pinnarna? Kan det vara så illa att denna är utförd så utgångarna fladdrar när data skiftas in eller på något sätt släpper ifrån sig glitchar? I så fall kan det uppstå vilka magiska fenomen som helst."
Jag bifigade några bilder på loggning av den data som displayen får samt datablad till portexpandern.
Se slutet av inlägget.
När jag loggade signalerna så samplade jag bara med 10MHz eftersom minnet inte räcker annars,
men så långt ser jag inga fel iallafall.
Men jag kan ju göra allt som står i databladet felfritt, varje gång - förutom att skriva till CGRAM.
Det borde väl inte vara möjligt om felet beror på det du beskriver?
Den här portexpandern (MCP23017-E/SP) är förresten en mycket vanlig komponent
bland de som kopplar en display till sin Raspberry Pi.
Jag skriver till OLAT. I databladet för portexpandern står det:
"The OLAT register provides access to the output
latches. A read from this register results in a read of the
OLAT and not the port itself. A write to this register
modifies the output latches that modifies the pins
configured as outputs."
Marta:
"Du *måste* skicka hela CGRAM-instruktionen, fungerar inte detta är något mycket trasigt och skall absolut åtgärdas."
Jag har korrigerat så att jag nu skickar hela CGRAM-instruktionen.
Jag är medveten om att jag inte har visat programmet,
men har du något förslag på vad som skulle kunna vara trasigt
utan att något annat (t.ex allt som har med DDRAM att göra) skulle påverkas av det trasiga?
Det enda jag kan komma på är om jag adresserar CGRAM på fel sätt.
Jag har inte hittat någon information om vilka displaykretsar som sitter på displayen
och det finns ju de "HD44780-kompatibla" kretsar som inte är 100% kompatibla.
Tyvärr har jag ingen erfarenhet av på vilket sätt de brukar skilja sig från riktiga HD44780-kretsar
och jag har inte hittat något på nätet om detta.
edit:
Jag testade nu med en 4x20 LCD med en synlig HD44780-krets och den uppför sig exakt likadant.
Då kan jag stryka min tanke med att jag adresserar CGRAM på fel sätt.
"Kan Du koppla E direkt till processorn så Du med absolut såkerhet *vet* vad som skickas till denna pinne?"
Jag får bygga om en del då och skaffa en annan kontakt, men det är förstås möjligt att ordna.
Nu kanske det verkar som att jag resonerar "näää, men *det* är det iallafall inte fel på, och så kollar jag inte det".
Men det stämmer naturligtvis inte. Jag utesluter ingenting.
Att "ifrågasätta" är ju bara en naturlig del av lärandeprocessen och felsökningen.
Jag ville bara berätta vilka tankar som väcktes när jag läste era senaste inlägg.
Jag plockade som sagt fram min logik-analysator.
(Jag har tidigare använt den för att hitta små fel i bl.a MIDI-data, I2C-kommunikation mm.)
I bilderna nedan så har jag inga filter eller något på signalerna. Allt är vad displayen får.
Såhär ser första delen av initieringen ut:

(Klicka för att se full storlek.)
Följande bild: Hela initieringen och texten "Hej! 26,5C" :
(Detta utförs enbart av mina rutiner.)

(Klicka för att se full storlek.)
Bilden nedan visar signalerna som följande kod genererar,
och som resulterar i att markören bara går ner till rad 2 kolumn 1.
Notera att bus.write_byte_data() skriver direkt till portexpandern via I2C och Python's standard-library för I2C.
*Ingen* av mina rutiner är inblandade här.
Kod: Markera allt
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # RS 0
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01000000) # CGRAM
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01000110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b01000000) # E off
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # CGRAM L
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000110) # E on
sleep(0.1)
bus.write_byte_data(DEVICE, OLATA, 0b00000000) # E off
sleep(0.1)
exit()

(Klicka för att se full storlek.)
Mer om portexpandern MCP23017-E/SP:
Databladet:
http://ww1.microchip.com/downloads/en/D ... 21952b.pdf
Min initiering av portexpandern:
Kod: Markera allt
# - - - - - -
# Definiera adresser
DEVICE = 0x22 # Adressen till min krets
# A
IODIRA = 0x00 # Register for pin direction. In or Out
OLATA = 0x0A # Register for outputs (When IOCON.BANK=1)
GPIOA = 0x09 # Register for inputs (When IOCON.BANK=1)
# B
IODIRB = 0x10
OLATB = 0x1A
GPIOB = 0x19
#
IOCON = 0x04
GPPUA = 0x06
GPPUB = 0x16
# - - - - - -
bus = smbus.SMBus(1) # I2C-bussen och vilken kanal.
#Bank 1. No mirror in INT. Sequential operation enabled.
bus.write_byte_data(DEVICE, IOCON, 0b10000000)
# Pull-up disabled for inputs
bus.write_byte_data(DEVICE, GPPUA, 0b00000000)
bus.write_byte_data(DEVICE, GPPUB, 0b00000000)
# Set all GPA and GPB pins as outputs by setting
# all bits of IODIRA and IODIRB register to 0
bus.write_byte_data(DEVICE,IODIRA, 0x00)
bus.write_byte_data(DEVICE,IODIRB, 0x00)
# Set output all 7 output bits to 0 on GPA and GPB
bus.write_byte_data(DEVICE,OLATA, 0)
bus.write_byte_data(DEVICE,OLATA, 0)
Nu är inlägget väldigt långt, så jag stoppar här för tillfället och inväntar era tankar.
Under tiden ska jag fortsätta som jag gjort med att läsa, fundera, mäta och prova.