Vreemd gedrag OLED display

benleentje

Golden Member

I2C is maximaal 400Khz maar meestal op 100kHz. De Spi klok is enkele Mhz. Dus ja I2C is veel trager

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.
Arco

Special Member

Standaard I2C is 100kHz (max 5+ MHz voor ultrafast i2c), SPI kan tot 50+ MHz: dus tot ruim 500 keer sneller.
I2C is voor grafische displays meestal geen goede keuze...

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

Golden Member

Weer wat geleerd. Ik dacht ergens gelezen dat via een arduine er max 400kHz I2C kan ingesteld worden maar dat het een stuk hoger kan blijkt nu wel.

Op mijn arduino kreeg is 200kHz nog wel aan de praat maar 400kHz gaf al problemen. Ik had al wel de weerstanden in waarde verlaagt maar misschien nog niet genoeg. Voor mijn toepassing schrijven naar een karakter display merkte ik het verschil tussen 100 en 200kHz ook niet eens.

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.
Bavelt

Golden Member

En weer wat: (past bij het topic).

Een oud probleem dat ik vroeger ook had: een OLED 0,96" - I2C slaat steeds een 'rij' over.
Het lijkt net of het ding 128 * 32 is ipv 132 * 64.

Ik kan echter in de datasheet niet ontdekken of dat instelbaar is.
Ik heb hier nog een exemplaar met gele ledjes erin liggen, die toont wél alle pixels.

Dit probleem wordt af ten toe gemeld op internet, maar vrijwel iedereen is dan met 'Adafruits' libraries in de weer.

Ik hou het wat dichter bij huis:

Dit gaat goed:

pic basic code:

I2C1_Start()
  I2C1_Wr(0x78)
  I2C1_Wr(0x40)
  I2C1_Wr(%10101010)
  Delay_ms(1)
  I2C1_Stop()

Op deze wordt niks getoond:

pic basic code:

I2C1_Start()
  I2C1_Wr(0x78)
  I2C1_Wr(0x40)
  I2C1_Wr(%01010101)
  Delay_ms(1)
  I2C1_Stop()

oneven bits werken dus niet. Bij twee Oled-displays niet, bij een derde exemplaar met gele ledjes dus wel

Rara (of gewoon stuk...)

Fouten zijn het bewijs dat je het probeert..
benleentje

Golden Member

Je heb een oled
0,96 inc 128 x 64 maar ook een
0,91 inc 128 x 32

Weet je eker dat je de goede hebt?

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

Ik zag een breadbord hoe gedraagt de schakeling zich gesoldeerd op een experimenteerprint. Ik heb de ervaring dat de overgangsweerstand nog wel eens wil verschillen.

Misschien krijg je daar een storing door. Gnd opgetild oid.

Bavelt

Golden Member

Op 21 januari 2023 01:45:04 schreef benleentje:
Je heb een oled
0,96 inc 128 x 64 maar ook een
0,91 inc 128 x 32

Weet je eker dat je de goede hebt?

Ja hoor, het is een 0.96"
Dit is het exemplaar dat steeds een rij overslaat. Bij inzoomen is dat goed te zien.

En deze (kleur geel) doet het wel goed met hetzelfde programma en in dezelfde opstelling:

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 21 januari 2023 10:44:00 schreef tuxie:
Ik zag een breadbord hoe gedraagt de schakeling zich gesoldeerd op een experimenteerprint. Ik heb de ervaring dat de overgangsweerstand nog wel eens wil verschillen.

Misschien krijg je daar een storing door. Gnd opgetild oid.

Daarom heb ik ook een proef genomen en de GND in een ster aangesloten.
Het relais gedeelte voorzien van een eigen LM7805.

Maar het schakelen van het relais levert nog teveel storing op voor het displaytje. (De processor heeft er geen last van en werkt keurig door).

Ik overweeg nu om toch het relais met zijn spoel en mechanische contacten te vervangen door een (soort SSR), met een opto coupler en Triac BT136

Vwb De Triac heb ik gezien dat er vele soorten en maten zijn.

Zo zijn er 'snubberless' Triacs voor vrijwel hetzelfde geld.

Zoals de BTA16-600BW of de BTB06. Dat zou een snubber-netwerkje schelen. Alhoewel ik me afvraag of bij het schakelen van een inductiebelasting zoals een motor, er toch niet een RC netwerkje moet worden gebruikt.

Tips en suggesties welkom!

Fouten zijn het bewijs dat je het probeert..

Wat als je de cpu print en de relais scheid door een opto bijvoorbeeld de pc817 oid.
De cpu print krijgt zijn eigen adapter en de relais krijt zijn eigen adapter.
Het is niet handig voor in de praktijk maar voor debuggen kan het veel duidelijk maken.

Doen de problemen zich dan nog steeds voor.

Is het "vastlopen" van de displays betrouwbaar te reproduceren?

Op 20 januari 2023 20:25:19 schreef benleentje:
Weer wat geleerd. Ik dacht ergens gelezen dat via een arduine er max 400kHz I2C kan ingesteld worden maar dat het een stuk hoger kan blijkt nu wel.

Je kan er bij I2C niet zomaar vanuit gaan dat het "kan".

Voor 400kHz was geloof ik weinig meer nodig dan het verzwaren van de pullup weerstandjes. Voor 1MHz moet je al een "sterke output driver" hebben op de stuursignalen (dus SDA+SCL op de master, SDA op de slaves).

Dat van "nog eens sneller" kennelijk naar 5MHz, zal je echt eea precies goed moeten doen. Dat is interessant voor bedrijven die allerlei dingen hebben gemaakt, maar waar de software-engineer met pensioen is terwijl ze nog wel hardware engineers in dienst hebben. Dus overstappen op ander protocol gaat niet, maar nieuwe hardware ontwikkelen wel.

I2C is eigenlijk niet geschikt om snel te zijn. Het is gemaakt om "klant selecteert nederland 2"(*) door te geven van de IR ontvangst chip naar de tuner chip.

(*) Ik typte eerste "nederland 3" maar dat bestond nog niet toen het gemaakt werd. :-)

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Bavelt

Golden Member

Op 22 januari 2023 01:28:49 schreef tuxie:
Wat als je de cpu print en de relais scheid door een opto bijvoorbeeld de pc817 oid.
De cpu print krijgt zijn eigen adapter en de relais krijt zijn eigen adapter.
Het is niet handig voor in de praktijk maar voor debuggen kan het veel duidelijk maken.

Doen de problemen zich dan nog steeds voor.

Is het "vastlopen" van de displays betrouwbaar te reproduceren?

Het vastlopen van het display is niet steeds op hetzelfde punt. Maar het is wel enigszins reproduceerbaar door het relais met twee draadjes aan te voeding te laten 'denderen'. Het relais 'klikt' er dan vrolijk op los, en op een gegeven moment zie je het display in de stress springen: regels die 4 lijnen opschrijven, rommel in het scherm, tot compleet hangen etc. Dan worden er weer wat bitjes aan of uitgezet in de display door de piek(en) op de voedingsspanning.

Op dit moment heb ik het 'opgelost' door de reset-functie met een vast tijdsinterval te starten (bijvoorbeeld iedere 30 seconden).
Regelrechte symptoombestrijding. :> Maar het werkt wel...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik heb me nog wat verder verdiept in dit displaytje (0,96", I2C)

Ik heb een routine gemaakt om het scherm te vullen en vervolgens weer schoon te maken.

pic basic code:


While true
 
 For y1 = 0 To 7
    I2C1_Start()
    I2C1_Wr(0x78)     'slave address
    I2C1_Wr(0x80)     'command
    I2C1_Wr(0xB0 + y1)'page
    I2C1_Wr(0x40)     'data

    For x1 = 0 To 127
       I2C1_Wr(0xFF)
    Next x1
    
    I2C1_Stop()
    Delay_ms(10)
  Next y1
  
  Delay_Ms(1000)
 
  For y1 = 0 To 7
     I2C1_Start()
     I2C1_Wr(0x78)     'slave address
     I2C1_Wr(0x80)     'command
     I2C1_Wr(0xB0 + y1)'page
     I2C1_Wr(0x40)     'data

     For x1 = 0 To 127
        I2C1_Wr(0x00)
     Next x1

     I2C1_Stop()
     Next y1
     
     Delay_Ms(1000)
     
Wend

Dit werkt. Maar waarom moet tussen elke 'page' een I2C_Stop() en daarna weer I2C start?

Ik had gedacht ik doe de start aan het begin en de stop aan het einde van alles.
Je gaat toch immers gewoon door met de commando's en data?

Fouten zijn het bewijs dat je het probeert..
benleentje

Golden Member

IK zou denken dat je niet 2x chter elkaar een start commando kan geven eens gestart dan kan je niet nog een keer start doen. Er zijn denk ik 2 opties de start buiten de lus of loop houden of restart gebruiken.

pic basic code:



 I2C1_Start()
 For y1 = 0 To 7
    //Met eventueel een restart hier
    I2C1_Wr(0x78)     'slave address
    I2C1_Wr(0x80)     'command
    I2C1_Wr(0xB0 + y1)'page
    I2C1_Wr(0x40)     'data

    For x1 = 0 To 127
       I2C1_Wr(0xFF)
    Next x1
    
    I2C1_Stop()
    Delay_ms(10)
  Next y1
I2C1_Stop() 

Dat van "nog eens sneller" kennelijk naar 5MHz, zal je echt eea precies goed moeten doen.

Mooie helder uitleg. Die 5Mhz zal wel zijn als 2 chips bijna tegen elkaar op een PCB zitten met een hele goede routing en PCB layout.

[Bericht gewijzigd door benleentje op maandag 23 januari 2023 00:13:24 (18%)

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.
Bavelt

Golden Member

Op 23 januari 2023 00:09:14 schreef benleentje:
IK zou denken dat je niet 2x chter elkaar een start commando kan geven eens gestart dan kan je niet nog een keer start doen. Er zijn denk ik 2 opties de start buiten de lus of loop houden of restart gebruiken.

pic basic code:



 I2C1_Start()
 For y1 = 0 To 7
    //Met eventueel een restart hier
    I2C1_Wr(0x78)     'slave address
    I2C1_Wr(0x80)     'command
    I2C1_Wr(0xB0 + y1)'page
    I2C1_Wr(0x40)     'data

    For x1 = 0 To 127
       I2C1_Wr(0xFF)
    Next x1


    
    I2C1_Stop()
    Delay_ms(10)
  Next y1
I2C1_Stop() 

[...]Mooie helder uitleg. Die 5Mhz zal wel zijn als 2 chips bijna tegen elkaar op een PCB zitten met een hele goede routing en PCB layout.

Er zit een Stop tussen (aan het einde van de eerste loop)

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Iets eenvoudiger gemaakt:

Dit werkt wel:

pic basic code:


I2C1_Start()
 I2C1_Wr(0x78)     'slave address
 I2C1_Wr(0x80)     'command
 I2C1_Wr(0xB0)     'page 0
 I2C1_Wr(0x40)     'data

 For x1 = 0 To 127
    I2C1_Wr(0xFF)
 Next x1
 I2C1_Stop()

 I2C1_Start()
 I2C1_Wr(0x78)     'slave address
 I2C1_Wr(0x80)     'command
 I2C1_Wr(0xB3)     'page 3
 I2C1_Wr(0x40)     'data

 For x1 = 0 To 127
    I2C1_Wr(0xFF)
 Next x1
 I2C1_Stop()

Maar dit werkt niet:

pic basic code:


I2C1_Start()
 I2C1_Wr(0x78)     'slave address
 I2C1_Wr(0x80)     'command
 I2C1_Wr(0xB0)     'page 0
 I2C1_Wr(0x40)     'data

 For x1 = 0 To 127
    I2C1_Wr(0xFF)
 Next x1

 I2C1_Wr(0x78)     'slave address
 I2C1_Wr(0x80)     'command
 I2C1_Wr(0xB3)     'page 3
 I2C1_Wr(0x40)     'data

 For x1 = 0 To 127
    I2C1_Wr(0xFF)
 Next x1
 I2C1_Stop()

Hij wil persé een stop-start tussen iedere page...

Fouten zijn het bewijs dat je het probeert..
benleentje

Golden Member

Er zit een Stop tussen (aan het einde van de eerste loop)

Die moet daar weg heb ik verkeerd verandert.

Maar ik dacht als je een slave eenmaal geselecteerd hebt dat je dan niet nog een keer zijn adres mag sturen. Alleen na een start of restart mag ereen adres volgens voor zover ik weet.
In principe zou je dan als de ene page vol is direct de volgende pagina kunnen selecteren door commando en Page 3 op de bus te zetten.

Het kan wel zijn dat je soms een restart op de bus moet zetten. IK zou dat toch even nalezen met als eerste de data sheet van slave zelf. Misschien kan je ook maar 1 pagina tegelijk doen, maar dat staat dat er vast wel in.

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.
Bavelt

Golden Member

Ik heb inderdaad al lopen grasduinen in de datasheet van de SSD1306. Maar kan daar eigenlijk niet vinden dat na het verwerken van een 'page' je opnieuw een IC2 stop/start moet geven.
Ik lees daar dat je de cyclus command en/of data gevolgd door een bit zou kunnen voortzetten tot je voldoende hebt geschreven.

Nu lees je daar wel gauw overheen, de datasheet is niet echt makkelijk opgezet vind ik.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Maar ik dacht als je een slave eenmaal geselecteerd hebt dat je dan niet nog een keer zijn adres mag sturen.

Daarvoor hebben ze ook het restart commando uitgevonden... ;) (combinatie van een stop en start)

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

Golden Member

Ik ben een stuk verder gekomen en ben bijna bij de oplossing denk ik..
Bijna..

Het heeft niet zozeer te maken met een Start/Stop tussen de pages, dat zou helemaal niet hoeven.

Maar het gaat fout bij:

Als ik de data (0xFF) heb geschreven op Page 3 wil ik het laten volgen door een Command (zoals 0xB5 naar page 5).

Maar hij ziet het commando-bit (0x80) en het daarop volgende bit (0xB5) gewoon als data!
En schrijft dan lekker verder op het display. Daar gaat het mis.

pic basic code:


I2C1_Start()
 I2C1_Wr(0x78)     'slave address

 I2C1_Wr(0x80)     'command
 I2C1_Wr(0xB3)     'page
 I2C1_Wr(0x40)     'data

 I2C1_Wr(0xFF)     'data FF

 I2C1_Wr(0x80)     'command   <--- maar hij ziet dit als Data!
 I2C1_Wr(0xB5)     'page
 I2C1_Wr(0x40)     'data
'
 I2C1_Wr(0xFF)

 I2C1_Stop()

De vraag is dan hoe maak je de overgang van data naar command? Ik dacht door 0x80 maar dat is niet zo.

Wellicht iets met het Co-bit?

Fouten zijn het bewijs dat je het probeert..

Het commando is het eerste byte na een START (en een adres).

Ik zou van je library verwachten dat als je een "start" doet zonder stop daarvoor dat ie dan een zogenaamde "restart" doet.

Maar als je 1 op de 128 bytes een stop/start moet doen, dan is dat ongeveer 1 of 2 op duizend bitjes. Dus een overhead van 0.2% max. Ik zou me geen zorgen maken.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Arco

Special Member

Als er eenmaal data verstuurd wordt, kun je nooit commando's versturen zonder een restart. (hoe zou 'ie moeten weten dat het een commando is??? )

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

Golden Member

Op 23 januari 2023 14:39:11 schreef rew:
Het commando is het eerste byte na een START (en een adres).

Ik zou van je library verwachten dat als je een "start" doet zonder stop daarvoor dat ie dan een zogenaamde "restart" doet.

Maar als je 1 op de 128 bytes een stop/start moet doen, dan is dat ongeveer 1 of 2 op duizend bitjes. Dus een overhead van 0.2% max. Ik zou me geen zorgen maken.

Jawel, maar je moet dan blijkbaar na iedere 'page' een I2C_Stop en voor de volgende page weer een I2C-Start doen.

Ik vermoed (kan dat nog niet uit de datasheet halen) dat je in "Page Adressing mode" maar één page kunt benaderen tijdens de sessie.

Wil je meer pages, dan is de Start-Stop onontkoombaar lijkt het, tenzij geen gebruik wordt gemaakt dan de Page Adressing Mode. Dat moet ik nog uitzoeken.

Ik weet niet zeker of ik hiermee op het goede spoor zit.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 23 januari 2023 14:50:33 schreef Arco:
Als er eenmaal data verstuurd wordt, kun je nooit commando's versturen zonder een restart. (hoe zou 'ie moeten weten dat het een commando is??? )

Ik dacht dus door 0x80...Maar inderdaad, stel je wilt 0x80 als echte data verzenden, dan zou dat niet kunnen...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Maar ook wel een beetje hierdoor:

For the rest of this article I will focus on the serial interface, I2C. How do you send commands and data? Simple. When you start a transaction you send a control byte which tells the controller what to expect next. There are four legal control bytes.

0b10000000 = 0x80 = multiple commands
0b00000000 = 0x00 = one command
0b11000000 = 0xC0 = multiple data
0b01000000 = 0x40 = one data byte

Dat doet suggereren dat als je 0x40 hebt gedaan er slecht één bitje data komt. (en daarna bv weer een command).

Maar dat is niet zo.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Het staat in de i2c specs...

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