I2C is maximaal 400Khz maar meestal op 100kHz. De Spi klok is enkele Mhz. Dus ja I2C is veel trager
I2C is maximaal 400Khz maar meestal op 100kHz. De Spi klok is enkele Mhz. Dus ja I2C is veel trager
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...
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.
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...)
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?
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.
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 32Weet 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:
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!
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.
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...
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?
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 23 januari 2023 00:13:24 (18%)
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)
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...
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.
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.
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)
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?
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.
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??? )
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.
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...
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.