Arduino I2C kijelző helyett mit?

 ( Toomi | 2019. szeptember 6., péntek - 7:36 )

Sziasztok!

Az Arduinotól (Mega) kb. 3 méterre kellene elhelyeznem egy kijelzőt. Sajnos a megszokott/ismert I2C interfészes 1602 LCD nem használható hosszútávon, összeszedi a zavart és emiatt lefagy az Arduino. Az LiquidCrystal_I2C library segítségével van megoldva a kijelző kezelése, így nem biztos, hogy 0-ról szeretném ezt a részt újból megcsinálni.

Szerintetek mivel lehetne ezt a legkevesebb munkával kiváltani? Ki mit javasol?

Ez a 2x16 karakter elegendő, de használok egyedi karaktereket is. Egyéb elvárás nincs, a mikrokontrolleren van még gazdagon szabad ki és bemenet.

Köszi a segítséget.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Nem lehet az arduinot is oda tenni és az egyéb részeket összedrótozni velel messzebbről?

feliratkozás
> Sol omnibus lucet.

Odateszel a kijelző mellé egy kis MCU-t, ami I2C-n kommunikál a kijelzővel, a mostani eszközzel pedig RS485-ön.

Na végre valaki felismerte, hogy mitől döglik a légy.

Az I2C szabvány felhúzó ellenállása 5k. 3m-es kábel mellett az képes némi zavart összeszedni.

Azért linkelhetnéd azt I2C szabványt, ahol ezt olvastad. :-D
Aztán összeszedett zavarról sincsen szó, hacsak a hibás működést nem hívjuk annak.
Ha a felhúzó ellenállás túl nagy, akkor nem tudja időben feltölteni a kábel + a ki- és bemenetek kapacitását. Erre szuperponálódik a tápegység zaja, amitől a H szint olybá tűnhet az avatatlan szemlélő számára, hogy hol H, hol meg nemigen. ;)

A felhúzó ellenállás méretezéséhez egy segédlet:
http://www.ti.com/lit/an/slva689/slva689.pdf

Minél kisebb a felhúzó, annál lassabban megy.

Az SPI-n a 0 és az 1 is tranzisztoros kimenet, nem is jelent 15m sem problémát. És gyorsabb is.

Az I2C nem való szerintem zajos, sok hosszú kábeles rendszerekhez.

Az ellenállás és a sebesség "talán" épp fordítva viselkedik. :)
3 m még abszolút nem téma, használtuk mi ~10 méteren is.
Simán megoldható! Ha tényleg nagy a zavar, akkor árnyékolt kábelt érdemes kell használni. Ha a táp és az adat egy kábelen megy, akkor kevésbé érzékeny, ekkor még egy-egy ferrit gyűrűvel lehet javítani, bár I2C frekvencián sokat nem ér.

Amire figyelni: szoftveresen normálisan kell kezelni! Ehhez az arduino könyvtárak nem biztos hogy a legjobb alapot adják. Van az I2C valóban "deadlock" módja, amikor a két eszköz egymásra vár. Ebből néhány órajel-impulzussal ki lehet hozni.

Ebből néhány órajel-impulzussal ki lehet hozni.

Sajnos ennél sokkal rosszabb a helyzet. A több bájtos parancsoknál a néhány órajel csak az adott bájtot teszi rendbe. Pl. egy vagy több cím bájt esetén (eeprom címzés, modbus) az eszköz nem mindig felejti el a "kályhát". Ilyenkor marad a valódi reset, vagy a sérült protokoll befejezése és eldobása - ami bonyolítja a helyzetet.
A másik eset, amikor az eszköz eleve nem válaszol egy ideig, pl. eeprom írás.

Ezeket ez eseteket elsősorban az adatlapon leírtak pontos megvalósításával lehet megoldani. Az általános szoftveres megoldás nem minden esetben elegendő. Ilyenkor a busz művelet elemeit - akár a szabványtól eltérő módon - egyedileg kell meghatározni.

Jó példa az AM2320. Ez egy i2c + modbus eszköz, de tartalmaz két olyan időzítést, ami nem szerepel a szabványban. Az rpi-re megírt lib alapú driver kiválóan működik. Az rpi más órajelű verzójával meg kiakad. Nyugodtan állíthatjuk, hogy az első eset hibátlan működése csak véletlen volt. ;)

Ja persze, magasabb szinten még ezer dolog romolhat el.
Épp ilyen i2c kijelzőkkel akadt nekem olyan, hogy teljesen leakasztotta a buszt, pedig nem 3 m, hanem csak néhány cm kötötte őket össze.

Ugyanis ha egy slave megfogja az adatvonalat, azzal a master nem sokat tud tenni sajnos. Elvileg az órajellel is megteheti ezt, de ott kevésbé szokott probléma lenni, mert a clock stretching valamikor "véget szokott érni", ha a slave elvégezte a dolgát.

Viszont ha a slave-nél kimarad egy órajel, akkor a master elveszítheti az arbitrációt, erre gondoltam. Nem is kezdeményezhet akkor kommunikációt.

Láttam olyat is, ahol ezt úgy "oldották meg", hogy sw i2c-t írtak, de a clock stretching-et kidobták belőle :D

Bár én pont az ellenkezőjét írom. ;)
A slave megfogja az adatvonalat csak annyit jelenthet, hogy nem olvastad el pontosan az adatlapot.

A clock stretching és az arbitráció kifejezetten multi master opció. Az előbbi esetleg előfordulhat lassú slave esetén, bár manapság elég szegényes az a hardver, amelyikben egy shift regiszter sincsen. Az utóbbi meg nem arbitráció, hanem egyszerű leakadás, mert szarul van megcsinálva.

Az elégséges i2c működéshez ott a szabvány, ahol van Mandatory meg Optional elem is. A clock stretching (avagy szinkronizáció) csak opció, amivel egy hétköznapi (slave) hardvernél nem fogsz találkozni. A slave ack nyújtása inkább előfordulhat, amit elvileg tetszőlegesen lehet nyújtani, mert az i2c 0Hz-től megy felfelé.

Amikor Arduino Arduinoval kommunikál I2C-n, ott van clock stretching.

Elküld 8 bitet az egyik arduino, a másik arduinonak idő feldolgozni, amíg az ack jelet elküldi, addig clock strectching van.

Gondolom az I2C EEPROM írásnál is komolyan elnyújtott órajelek vannak. Szerintem kevés olyan slave van, ami csettintésre megcsinál mindent.

Pontosan erről van szó, ha a master-ben és a slave-ben eltér az órajel (pl. a slave elmaradt, vagy inkább összeszedett +1-et), akkor az adat irányában sem fognak megegyezni, és ezért fog a master arbitrációt veszíteni a slave-el szemben.
Pontosabban: arbitrációs hibát fog érzékelni (nem az van kint, amit ő ad), és ezért fogja "elengedni" a buszt. A slave meg ottmarad a meghúzott adatvonallal.

Ez egy könnyen előforduló hiba, és illik rá felkészülni. Ezen segít az, ha ilyenkor órajel impulzusokat adunk a slave-nek.

BTW ahogy írod, a clock stretching nem (elsősorban) azért kell, mert a biteket nem tudja előállítani a slave, hanem mert esetleg ennél egy komplexebb műveletet kell elvégeznie (pl. AD konverter), és maga az adat nem áll rendelkezésre.
Aki programozott i2c slave-et, az tudja miről beszélek. Pl. PIC18 i2c slave automatikusan clock stretch-el (az ACK-nál), ha olvassák. Ekkor kell beletölteni az adatot a TX bufferbe, ami a slave részéről akármeddig is eltarthat.

Nem értem, a slave-nek nincs órajele. A master adja az órajelet, hozzá igazodik mindenki. Nem térhet el a master/slave órajel egymástól, mert nincs slave órajel.

Lásd: clock sychronization, clock stretching.

Ez igaz, de zavar miatt megeshet hogy a slave nem annyi órajelnél tart, mint a master. Erről írtam.

Gondolom az I2C EEPROM írásnál is komolyan elnyújtott órajelek vannak. Szerintem kevés olyan slave van, ami csettintésre megcsinál mindent.

Teljes sebességgel lehet írni és olvasni - a hivatkozott M24512 1MHz-es eszköz. Viszont bármilyen flash eszköz írásakor időbe telik az írás, - itt 128B lap írás - konkrétan max. 5ms, amely időtartam alatt nem válaszol. Ez egy nem szabványos busz ciklus: start - cím - nincs válasz, és ez nem azonos a "nincs ack" helyzettel. Tehát a stop helyett loop kell az adatlap szerint. Persze csak akkor, ha tudod, hogy írtál.

Tehát kilépve az ardunio világból, a többi eszköz nem használja az opcionális clock strectching funkciót. Mégpedig azért nem, mert a feladatnak megfelelő hardver áll a protokoll mögött. Pl. a bus collision detektálását is hardver + interrupt végzi, így nem kell pollingolni.

A clock stretching az ack előtt is opcionális. Az Arduino Arduinoval kommunikál olyan eset lehet, amikor a két szerkezet megbeszélte (a lib írója önmagával), hogy így fognak kommunikálni. Normál esetben nincs ilyenre szükség, mert az interrupt és az adat kezelése gyorsan elvégezhető. Ha én írom. ;) Tehát ilyen funkció van egy pic-en is, de külön engedélyezni kell.

Nekem eszembe nem jutna I2C-t flow control nélkül használni.

Ha nincs clock stretching, akkor inkább értelmesebb protokollokat használok. Az I2C azért praktikus, mert képes szabályozásra.

Igazából SPI vonalon 8 MHz-en darálom át DMA-n az adatokat, nem értem minek kellene az I2C clock stretching nélkül? Lassú, macerás, körülményes, rossz zajszűrés, rövid kábel,... Értelmes paraméterei nincsenek. Max annyi, hogy kevesebb kábellel megy. Nofene.

Van valami, ahol a clock stretching nélküli I2C jobb mint egy shift regiszter, vagy RS-485?

Nekem eszembe nem jutna I2C-t flow control nélkül használni.
A gyártók erről sajnos nem tudnak. ;)
A szabvány szerint meg opcionális.
Meg nem is flow controlnak hívják, mert az más.
Lehetne hívni wait state-nek, de hát az sem.

Igazából SPI vonalon 8 MHz-en darálom át DMA-n az adatokat
Ez nyilvánvalóan hasznos lehet egy hőmérőnél. ;)

RS-485 does not define a communication protocol; merely an electrical interface.
Feltételezem, tán egy shift regiszterre sem definiált a kommunikációs protokoll. ;)
Az egyik szinkron, a másik aszinkron.
Az egyik rövid távolságokra való, a másik meg nagy távolságokra.

Aztán, ha az i2c protokollt el akarod vinni nagy távolságra, akkor megteheted akár rs485 interfészen vagy di2c interfészen keresztül is. (stb., stb.)

Nagy zavart érzek az Erőben!

Nem kell zavart érezni az erőben, tök mindegy, hogy mit írnak a gyártók, nem muszáj megvenni a termékeiket.
Flow control nélkül semmi értelme az I2C-nek, mert a többi protokoll sokkal jobb megoldást kínál erre.

Az I2C nagyon sok tekintetben nem optimális, ami tök jó, hogy vissza tud szólni, ha még nem fejezte be a feldolgozást.

AVR alatt megpróbáltam a multimaster-es módot is interrupt kezelésre, de a chip erre alkalmatlan 4-5 hardverhiba miatt. Valszeg azért lett TWI, mert idő hiányában piacra dobtak valami szart I2C helyett.
- egyszerre küldött start jelnél kiakadhat mindkét mester
- néha elveszíti a biteket és kifagy a CLK vonal
- a STOP-ot rosszul kezeli, ha gyorsan küldenek a masterek és a kódod lassú, könnyen NACK jön vissza
- nem tartja be az I2C "bus free time"-ot a specifikációból

Protokoll hibák:
- a felhúzó ellenállások miatt zajra érzékeny
- hosszú kábelnek nagy a kapacitása, miközben egy SPI/UART a HI szintet beleveri 40mA-rel, addig az I2C 5kohm felhúzó esetén 1mA-rel tölt
- őrülten lassú, a 100kHz az semmi, már egy 128x256-os LCD-hez is kevés.

Mivel helyettesítettem idáig az I2C-t?
- SPI a leginkább kézenfekvő, egy 320x200-as színes LCD-hez már 10 MHz-cel DMA-val tolom az adatokat
- WiFi (ESP8266+ESP32 egy I2C-hez képest elképesztő sebességekre képes)
- UART (mehet több résztvevő között is, multiplexinggel)
- CAN busz is lehet, nem véletlenül ezt használják a kocsikban és nem I2C-t

Hőmérőt meg vehetsz SPI-set is, meg OneWire-t is ha szívatni akarod magadat. Én a Microchip-től SPI-s cuccokat szoktam venni, mert az I2C-vel kapcsolatban fenntartásaim vannak.

A gyártók nem írnak, hanem gyártják a termékeiket. A zemberek meg megveszik és használják.

Olyan nincs, hogy nem optimális. Legfeljebb valamilyen feladatra nem optimális, de azt inkább tervezési hibának hívom. De lehet más szempont is. Pl. egy termék tervezésénél megnézem, hogy egy alkatrészből i2c vagy spi interfésszel rendelkezőből árulnak-e többet és milyen gyártóktól. Ilyenkor általában nem az spi győz. Ha sokféle eszközt kell alkalmazni egy áramkörben, akkor megint az i2c győz. Ha a feladatra alkalmas valami, akkor tökmindegy, hogy létezik-e valami egészen más, ami akár elképesztő sebességet is tud, bár nincs rá szükség.

A problémádat inkább abban látom, hogy alkalmatlan hardveren, alkalmatlan szoftverrel sikertelen voltál. Ezt még tetézi az 5kOhm-os tévhited, ami könnyel leküzdhető lenne egy adatlap, vagy méretezési példa elolvasásával. A méretezés nem azonos az össze-vissza megvásárolt modulok ötletszerű összedugásával. ;)

Meg az I2C mellőzésével is megoldható a probléma. A Microchip mindegyikből gyárt SPI-t és I2C-t is. Bocs, de jobb szeretem 10MHz-en küldeni az adatokat, mert még az is rohadt lassú.

A 320x200-as színes LCD kijelzőm 192000 bitből áll, 25FPS-hez 4800000 bit kell, ami minimum 5 MHz órajel mellett lehetséges. Küldeném én 36MHz-en is, de a kijelzőknek az már sok.

LCD-ből I2C-t nem szabad venni, mikroprocesszorból meg kizárólag olyat érdemes használni, amelyik képes DMA-zni.

Azért hidd el, durva ahogy LCD-n realtime mutatja az oszcilloszkóp az adatokat, eközben meg USB-n tovább is tudja küldeni 800 kbyte/s mellett. Aztán ugyanúgy 2$ a blue pill is (STM32F103C8T6), mint az Arduino.

Attól még hogy "lassú" az I2C, vagy nem a legalkalmasabb grafikus LCD-khez, még nem lesz rossz interfész.
Most komolyan... 20 éve ennél jóval lassabb kapcsolatokon interneteztünk.
A CAN sem gyosabb, egy kicsit sem, ha a nagyobb protokoll overhead-et beleveszed. [ferdítés on]Elektromosan meg épp azt tudja mint az I2C [ferdítés off]. Ráadásul órajelet sem visz, ott kapásból úgy kezdődne minden node, hogy akassz rá egy kvarcot, vagy horror áron beleintegrálnak egy hőmérsékletkompenzált oszcillátort.

Persze, LCD-hez van millió interfész, legelterjedtebb talán a párhuzamos. Ha viszont van egy I2C-m, arra "akárhány" eszközt felfűzhetek. Dolgoztam olyan helyen, ahol ipari gépek belső kommunikációja I2C-n volt megvalósítva (összetákolva), hosszú, több méter kábelezéssel, leágazásokkal, jelterjedési szempontból egy horror, de mégsem az I2C-vel volt baj, soha.

Hőmérőnek, RTC-nek, EEPROM-nak, lassú AD-knek tökéletes, nem is kell több. Eszembe nem jutna ezeket SPI-al megcsinálni.

+1

A linkben a legjobb a "no-longer-manufactured". ;)
Nem, nem ilyenre fejlesztette ki. Ezek a meghajtók a normál 2-3mA és 400pF maximális busz terhelés ellenében a 30mA és 4000pF terhelésre készültek.
A 3m kábel kb. 230..300pF terhelést jelent, ezért felesleges ilyet használni.

> A linkben a legjobb a "no-longer-manufactured". ;)
Természetesen lehet közvetlenül a gyártótól is vásárolni termékeket, de azért mégis az a gyakoribb, hogy nem tőle, hanem alkatrészforgalmazótól vásárolsz, azok meg még árulnak ilyen tudású IC-t.

> felesleges ilyet használni
Viszont lehet, nem drága (3-4$-ért kapsz 10 darabot), és megoldás a problémára.

Ok, a link az csak trollkodás volt - bár célszerűbb lett volna egy "itt kapható" linket betenni.

Lehet bármit is használni, de akkor sem úszod meg a busz méretezését. Ha meg nekiállsz a számolásnak, akkor kijön, hogy felesleges. Vigyázni kell a kétirányú I2C meghajtókkal, mert a két oldalán eltérő sebesség esetén visszapofázik. És akkor mégsem oldottál meg semmit, viszont mégis számolni kell. ;)

Öt linket tettem be, ebből az első kettő egy-egy gyártói adatlap volt (NXP /korábban Philips/ és TI), a maradék három meg "itt kapható" típusú...

Ne szívd már mellre! :)
Inkább a második bekezdést értelmezd, mert az olyan, tapasztalaton alapuló információt próbál átadni, amit a breadboardos rajzokból nem fogsz kitalálni.

P82B715P
Ezt használom én is arduino-k között több méteren (8m). Még sima telefon kábelen is ment 5 métert ideiglenesen.
https://a.allegroimg.com/original/0cfd6c/013278aa48c5897b720ec4c216e5

"összeszedi a zavart és emiatt lefagy az Arduino"

Egyrészt ezt mérted vagy csak saccolod? Másrészt milyen fizikai zavarvédelmet használtál?

--
https://iotguru.live

Szia!

Jórészt saccolom, "sajnos" gépészmérnök vagyok, az elektronbubusgatás csak hobbi. A kijelzőn látszik, hogy elkezdi összeszemetelni a karaktereket, így még megy egy darabig, frissülget, de aztán megáll. Valójában, fórumozgatás alapján valószínűleg nem lefagy, hanem vár valamire és végtelen ciklusba kerül ott, amiből nem tud kilábalni. A kijelzőt kigyomlálva a kódból, napokig tud futni, megállás nélkül.
Egy árnyákolt kb. 15 eres vezetékkel van összekötve, ebben megy +5V, GND mellette, egy ledsornak a DATA lába, illetve 6 egyszerű nyomógomb.

Ilyenkor kellene ráakasztani egy oszcilloszkópot vagy logikai analizátort (én például őket javaslom: https://www.saleae.com/), mert mérés nélkül csak vaktában fogsz próbálkozni, amíg véletlenül jó nem lesz. Egyrészt jelalakot kellene mérni, másrészt a Saleae tud protokollokat is elemezni, mutatja a kommunikációs hibákat.

--
https://iotguru.live

+1

Másrészt viszont ha a kommunikáció hibája miatt le tud fagyni a rendszer, akkor ott a program is hibás. Kommunikációs hiba esetén újra kellene indítani a megfelelő alrendszert, és működő állapotba hozni.

Az más kérdés, hogy ezt jól megcsinálni egy nagyságrenddel nehezebb feladat, mint amit a tipikus Arduino-s könyvtárak megtesznek: épphogy működik, akkor mehet a release és soha többé rá sem nézünk a projektre. Nyilván feladatja válogatja, hogy érdemes-e ezt a plusz munkát beletenni. Nekem is van egy hasonló kijelzős projektem, ami kb egy év működés alatt egyszer lefagyott. Újraindítottam és kész, nem fogom kidebuggolni...

Plusz előfordul, amikor a kliens hardver megy egy hibás belső állapotba és csak HW reset segít rajta. Még az is lehet, hogy nem is az I2C a probléma, hanem pl a túl hosszú kábel miatt instabil a táp. Az ilyen lehetőségek okán sem ártana jól rámérni egy szkóppal a cuccra.

Sajnos a szkópra most nincs lehetőség. Én ezt az esetet gyanítom mögötte, egyébként:
https://forum.arduino.cc/index.php?topic=66353.msg488093#msg488093

Igen, szép kis gagyi megoldás, ami még hobbista célból is kb használhatatlanná teszi az Arduino I2C alrendszerét. Volt nekem is ilyen I2C-s cuccom, ami időnként lefagyott. A legjobb benne, hogy a tipikus user előítélet jött ettől elő bennem: az I2C szar. Ahelyett, hogy azt vezettem volna le, hogy az Arduino libek szarok.

Meg a hardver is szar.

Arduino alatt van egy mastered, amelyik időnként küldhet üzenetet, amit a slave-ek fogadnak. Ebben a felállásban még működni is szokott, ha két kérés között tartasz némi delay-t.

Delay nélkül az idóta hardver képes a stop és a start jel között arra, hogy 1V-ig beemeli a feszültséget 5V helyett, majd azonnal visszahúzza. Nanosec delayt tart a start és stop között, amit az I2C slave-ek fele nem fog tudni start-ként felismerni.

I2C kérés indul, I2C stop, delay

Ha pedig több mastert szeretnél és arbitrációt, az Arduino-t elfelejtheted. Az csak a PDF dokumentációban van, hogy képes multimaster módban működni, de megbízható adatátvitelt nem fogsz vele elérni. Kifagy, failel, ...

Az Arduino platform egy rakás fajta hardvert lefed. Konkrétan az ATMega328 csipre gondolsz, hogy annak szar az I2C megvalósítása? Annyira, hogy szoftveresen sem lehet korrigálni?

Atmega328P. A normál master slave I2C megy szoftver korrigálással. Az arbitráció sosem fog menni, amikor egyszerre két mester ad, az olyan versenyhelyzeteket eredményezhet, hogy vacak hardveren megoldhatatlan.

Persze a Due más kategória, azon mehet, gondolom az ARM chipek jobbak.

Igazából a doksi TWI-nek hívja, mert gondolom nem teljesíti az I2C szabvány előírásait.

Azért TWI, mert az I2C névért és kompatibilitási bizonyítványért fizetni kell.

Ezt a buszarbitráció problémát elmagyarázhatnád, vagy linekelhetnéd, szívesen tanulnék belőle.

I2C-bus specification and user manual Rev. 6 — 4 April 2014

Megnézheted még a "clock stretching" opciót is. Ezt használva pl. programot flashelek két PIC mcu között, csak úgy "röptében". A slave az I2C ACK-ban adja vissza a blokk írás sikerességét.
Érdekességként itt egy I2C EEPROM. Hogyan valósítod meg a Figure 9. tetején levő csonka buszciklust? (start, address+w, nack -> start ... - azaz nincs stop condition)

A specifikációból kiindulva, a TWI nem tudja a Table 2. szerinti összes funkciót, de az I2C standard sebességeit sem. Ennek ellenére a szabvány ütközés miatt adott más név is igaz, és a működése az esetek többségében kompatibilis.

Az I2C lehetővé teszi, hogy ne legyen master a buszon, hanem mindenki slave. Nincs kitüntetett master, a slave-ek arbitráció útján döntik el, hogy ki fog adni.

Mi van akkor, ha egyszerre ketten akarnak adni?

A hardver észleli, hogy ő 1-et akart küldeni, de a buszon 0 van kinn, tehát másvalaki húzta le a jelet 0-ra. Ez akkor fordul elő, ha mindketten egyszerre adtuk ki a start jelet, mindketten elkezdtünk adni, az ő üzenete még egészséges, az enyém már nem, mert tönkretette azzal, hogy 0-ra húzta a vonalat. Ebben az esetben az arbitrációs logika visszavált slave módba, elvesztettem az arbitrációt, ha viszont engem címzett a másik, slave-ként meg fogom kapni az ő üzenetét, amit velem egyszerre nekem akart küldeni.

Nálam a buszarbitráció az interrupt miatt kellett volna. A slave átveszi az irányítást a buszon és értesíti a mastert, hogy megszakításos esemény történt.

Működött is, de megbízhatatlanul a versenyhelyzetek miatt. Állandó üzenetvesztés, fagyás, belebeszélés,...

Én úgy tudom az arbitráció épp a multi-master esetben kell. A multi-slave (azonos címen lévő slave-ek) az az ördög műve, nem javaslom használni, de master mindig kell, mert kommunikációt csak master kezdeményezhet.

Pedig a doksi egyértelmű. Sajnálom, hogy nem sikerült nekik hardver szinten megvalósítani.
I2C-n lehet multi slave, csak mindegyiknek más címet kell adni.

An algorithm must be implemented allowing only one of the masters to complete the transmission. All other masters
should cease transmission when they discover that they have lost the selection process. This selection process is
called arbitration. When a contending master discovers that it has lost the arbitration process, it should immediately
switch to slave mode to check whether it is being addressed by the winning master.
The fact that multiple masters
have started transmission at the same time should not be detectable to the slaves, i.e. the data being transferred on
the bus must not be corrupted.

Így érzésre, ha két master egyszerre kezd el adni, akkor előfordulhat olyan, hogy a jelalak éppen határeset lesz, amit ketten másképpen értelmeznek. Nem fordulhat ilyen elő?

Nem, ha értelmesen csinálták meg a hardvert. Mondjuk Atmega328P-re ne építs.

Amint a master lehúzza alacsonyra a jelet, a slave szintén lehúzza. Tartja a vonalat. Amint feldolgozta, akkor visszaengedi.

Master az órajelet hogy adja:
- CLK HI->LO, DATA beállít (utána CLK LO->HI)

- slave/másik-master a CLK-LO-ra CLK-LO-val válaszol => megfogja az órajelet, nem engedi, hogy a master visszaengedje HI-re

- master küldené a következő bitet, de nem tudja, mert annak ellenére, hogy saját magánál CLK->HI-re váltott, a slave CLK-LO-val fogja a vonalat. A CLK nem megy vissza HI-re.

- slave befejezte, már nincs kedve tetvészkedni, visszaengedi a CLK vonalat LO-ról, nem fogja már senki a vonalat, ezért a felhúzókkal átvált HI-re.

- a master látja, a CLK HI-n van, ezért elkezdi feldolgozni a következő bitet. A slave tetszőleges ideig tetvészkedhet.

Ha átment volna az Atmega328P az I2C szabványon, akkor nem szabadna problémát okoznia. A gond az, hogy nem tartja a szabványt, ezzel mindenbe belezavar.

Ha ennyire érdekel, itt a hardware bug részletes leírása (nem csak multimasternél jön elő).
A START / STOP között nem tartja az I2C által megállapított minimális időt.

https://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html

Itt a probléma az, hogy IT rutinból kell továbbterelni a busz állapotát, különben nem követi a valóságot, viszont a szerző által írt rutin nem elég gyors ahhoz, hogy időben lekezelje az állapotátmenetet. Ha kellően gyors volna az IT rutinja, az megoldás lenne.

16-20MHz csip órajelet feltételezve kb 2000 órajele van lekezelni az interruptot. (Jól számoltam? A busz és a csip órajelének függvénye is ez!) Le is írja a cikkben, hogy nem csak annyi van az IT rutinban, hogy beteszi a kapott bájtot egy pufferbe, hanem konkrétan csinál is vele valamit. Illetve nem tudja a regiszter mentéseket kispórolni az IT rutinból, mert túl sok változót használ, vagy van belül függvény továbbhívása.

Szerintem ezt a problémát meg lehet oldani ASM-ben írt IT rutinnal, vagy "NAKED" ISR rutinnal, ami az állapotátbillentést megcsinálja regiszter mentés nélkül, majd újraengedélyezi az IT-t, és a hosszú idejű feldolgozást már IT engedélyezés mellett hajtja végre. (Vagy csak beteszi az adatot egy round-robin pufferbe, és a fő szálról dolgozza fel, nem IT alól.) Szerk.: Emiatt számomra nem egyértelmű, hogy ezt hardware bugnak kell tekinteni, vehetjük úgy is, hogy egy nagyon szigorú IT sebesség korlátozás.

Ez egy piszkos trükk, hogy az IT rutin kontextusából, de engedélyezett IT mellett dolgozzuk fel a bejövő adatot. Lehetővé teszi az egymásba ágyazott IT-ket, ezért különösen észnél kell lenni az időzítésekkel, nehogy stack overflow legyen a vége, de jól csinálva működik.

Plusz arra is figyelni kell, hogy nem csak ez az egy IT rutin van a rendszerben, és worst case is benne kell maradni az időkeretben. Ez a többi IT rutin, plusz az IT disable blokkok kényszerű lerövidítését is jelenti. És még jó sokat kell számolgatni is. Szóval végsősoron tényleg sokkal jobb lenne, ha a hardver másképpen lenne megvalósítva, ahogy a cikk szerzője javasolja.

Rengeteg bug van hardver szinten, itt két bugról van szó:
- ha nem kezeled le időben a STOP jelet, a chip bennragad és nem fogja elkapni a következő start-ot, NACK-ot küld helyette. A gond az, hogy a STOP-ot nem tudod CLK-LO-val tartani, a chip meg nincs olyan állapotban, hogy új ACK-ot küldhessen ha címzik. Szoftveresen úgy orvosolható, hogy ISR naked, a legelső dolog, amit csinálsz, hogy STOP-nál elengeded a hardvert. Ezzel a bug letudva.

- van egy másik bug is, ami sokkal rosszabb, az a hardware bug

Megtörténik a STOP, CLK HI, DATA HI. Amint a Data magasba megy (2V) a másik master azonnal kiadja a start jelet. Az oszcilloszkópon annyit látsz, hogy a DATA 0V-ról 2V-ra megy, majd 0-ra tér vissza ns időintervallum alatt. Nem tud a DATA vonal rendesen stabilizálódni, nem is éri el a 3.3V vagy 5V jelszinteket. Egy halvány villanás lesz az egész, amit a Slave-ek fele START-nak érzékel, a másik fele semminek. Nézd meg az ábrán, hogy összecsúszik.

Itt a doksi,

https://www.analog.com/en/technical-articles/i2c-timing-definition-and-specification-guide-part-2.html

Olvasd el a tBUF részt: "bus free time between a STOP and START condition", 4.7 us.

A probléma, hogy a hardver nem tartja ezt az időt.

https://www.avrfreaks.net/forum/twii2c-bus-free-time

I agreed TWI is free to deviate from the I2C spec, but they have copied the
I2C timing specs to the AVR-TWI timing specs:

tBuf = 4.7uS < 100 kHz
tBuf = 1.3uS > 100 kHz

but this is not the case! so they deviate from their own specs as well. And if we think of our goal it is to have a common communication method. I think their is no doubt.

but I'm just wondering how i can solve this problems...

Ez a 2000 órajel egy sakkprogramra is elég. :-D
Lemértem egy eeprom olvasását - 12MHz-es órajelekben:
előkészítés=281,
restart: 38
read: 40
data read: 186
Ez a teljes interrupt ideje, még a return is benne van.
A csalás csak annyi, hogy ez high priority interrupt, tehát 8 órajelet megspórolok. Van ebben is ugrótábla 12 órajel.
Bár van olyan, aki nem ért velem egyet, de az interrupt alatt illik elvégezni a feldolgozást is. Az elrakom-előveszem általában időigényesebb.
Igaz, ez egy pic18 és asm. Ennek ellenére nem hinném, hogy a C, a más utasításkészlet és hardver tizes szorzót eredményezne. Vagy a bus collision detektálása emésztené fel a különbséget. Ezzel 8% az overhead és 10kB/s az olvasási sebesség, miközben interrupton kívül nem kell mást csinálni. A szerkezet azért kezeli az usb, timer, adc, nyomógomb interruptokat. Az 1kHz-es adc eredményét szorozza (csak 8x8 szorzó van) és számol egy 32 TAP-os FIR filtert is. Végül az eredményt aes256 kódolva az eepromba írja. ;)

Én multi-slave alatt az azonos címen lévő slave-ekre gondoltam, oda is írtam. Nyilván több slave-el elmegy az I2C.
Az összes atmega amivel találkoztam az támogatta a multi-mastert, hogy mi került át az arduino-ba ebből, azt persze nem tudom.

Ezt nem arról szól, hogy nincs master, hanem arról, hogy többen akarnak masterek lenni, az arbitráció eldönti, hogy ki lesz az egyetlen master, a többinek, aki veszített pedig slave módba kell váltania.

Hát, nincs is kitüntetett master. Innentől felfogás kérdése a probléma, én úgy értelmezem a dolgot, hogy mindenki slave és ha valaki master akar lenni, azt arbitráció útján érheti el.

De úgy is fel lehet fogni, hogy mindenki master csak slave-ként kell viselkednie ha más szerezte meg a vonalat.

Szerintem amikor nem adsz, hanem a vonalat hallgatod, akkor te nem master vagy, hanem slave.

A két szerkezetet kösd össze UTP kábellel a következő módon:

1. érpár
SDA
GND

2. érpár
SCL
GND

3. érpár
VCC
GND

4. érpár
VCC
GND

Az I2C adapter VCC és GND csatlakozó lábai közé forrassz 2,2..4,7uF/16V 0805 X7R MLCC kondenzátort.
Az I2C órajelet csökkentheted a 100kHz-es értékről egészen addig, amíg a megjelenítés nem lesz csúnya.

Meg ezt is elolvashatod: I2C Bus Pullup Resistor Calculation

Aminek alapján az SDA és SCL felhúzó ellenállások értékeit csökkentheted akár 1,8kOhm értékig.

+1

Én az órajel csökkentéssel kezdeném. A 2x16 karakterhez nem kell sok órajel, és ha ezt kellően lecsökkentjük, akkor sokkal biztosabb lesz az egész.

Arduino-n hardveres I2Ct használva az órajelet valami regiszterek beállításával kell kezelni. Valószínűleg bele kell nézni a libek kódjába hozzá, vagy akár bele is kell szerkeszteni. Alternatíva lehet, hogy a lib inicializálása utána a saját programból felülvágjuk a megfelelő HW regiszterbe tett értéket.

Szerk: rákerestem, elvileg van rá Arduino API, csak erősen HW függő, hogy milyen értékeket támogat: https://www.arduino.cc/en/Reference/WireSetClock

Köszi! Ez eddig mindenképpen gyors. Kezdetnek megteszi.

Az SPI szerintem alapjáraton elmegy 3 méterre.

Két Arduino simán eldumál egymással SPI-n. A közeli Arduino I2C-n vezérli az LCD-t, míg a távoli központtal SPI-n kommunikál.

Az Arduino mikrovezérlő egy kis szar. Akkor tudsz vele értelmes cuccokat készíteni, elfelejted az 1 feladat 1 processzor elvet. Ha nem elég 1 arduino, akkor benyomsz 2-t, azok meg eldumálnak egymással.

Ha nem fullhd-s videókat akarsz kitolni realtime-ban, hanem kisebb adatokat, akkor a kijelző mögé betolsz valami kisebb arduinot, pl nano-t, mellébekötsz egy hc-05-ös bluetooth modult, az "anya" arduino mögé szintén és mehet neki bluetooth-on az adat :)

Ugyanez akár rádiójeles modulokon ha a bluetooth nem tetszik.

De persze csak akkor játszik ha nem nagy adatmennyiséget küldenél, és persze meg kell oldani a két eszköz párosítását is.

3 méterre? 1602 LCD-hez?

A 2db Core i7 kimaradt. ;)

valami jó kis pitonos támogatással...

Ebay-ról rendelve pár ezer Ft-ból kihozható. Lehet kicsit sok hűhónak tűnik, viszont a 3m nem okoz többet gondot, több is lehet és nincs kábel.
Nem értem az i7-es fikázást ezzel kapcs.

Úgy tűnik, a kérdést nem olvastad el...

"Ha nem fullhd-s videókat akarsz kitolni realtime-ban"
"csak akkor játszik ha nem nagy adatmennyiséget küldenél"

Ezt úgy mondják nem informatikai nyelvezeten: Ágyúval verébre. ;)

Mindössze arról van szó, hogy
- ott a kábel
- rosszul van illesztve
- legfeljebb 50Ft költséggel megoldható.

A feladat egy 1602 LCD meghajtása, amin 32 betű van. Elég lomha jószág. A vezérlő jeleket is figyelembe véve, legfeljebb 64 betű/másodperc a legnagyobb sávszélesség. De az már elmosódott mozinak látszik ;), szóval ennél lényegesen kevesebb. És az is csak ritkán.

A megoldást pontosan leírtam. Ezen felül minden egyéb felselegesen bonyolítja és drágítja.

Kérdezz nyugodtan, ha valami nem lenne világos!

Mint téma iránt érdeklődő, kezdő, csendesen javaslom, hogy mint elméleti megoldás akár, vegyél 2 ilyet, közé UTP kábelt, és kész:

UTP kábel - Rj45 - I2C átalakító :)

https://www.youtube.com/watch?v=Km-XAFcmP6c

SparkFun Differential I2C Breakout - PCA9615 (Qwiic)
https://www.sparkfun.com/products/14589

És ott lent találsz hozzá még átalakítókat, kábeleket, stb, hogy könnyebb legyen összerakni.

Hamarosan tesztelni fogom, nekem szenzor adatok átvitelére kell.

Sakk-matt,
KaTT :)

Talán valami ilyesmivel toldanám ki P82B715

* Én egy indián vagyok. Minden indián hazudik.

Én meg először elolvasnám, amit bucko írt. ;)
Rossz esetben a 30-40m-es meghajtó sem oldja meg a hibát, jobb esetben meg pénzkidobás.
A hiba oka az, hogy az i2c modul felhúzóellenállása 20-50cm kábelre van méretezve. Itt a modul a kezemben, látom. A modul szűrése is valószínűleg elégtelen és nem is a kábel végén van. Azaz a modul nem szűrésssel kezdődik, mint ahogyan illene.

Igazad van, nem vagyok formában.

* Én egy indián vagyok. Minden indián hazudik.

Volt beszélgetés az I2C rendszerek problémáiról, a terepasztalon valószínűleg USART-ra fogom cserélni. Maga a terepasztal úgy megy, hogy van egy központi hálózat, az leadja a vonatok jeleit, a sorompó vezérlő, jelző vezérlő, meg miegymás ennek megfelelően állítja a fényeket, sorompókat.

Teljesen elosztott mikrovezérlős rendszer, ahol broadcast üzenetekkel értesülnek az egyes elemek, hogy mi a helyzet. Van egy központi mester, az tolja az üzeneteket.

Az architektúra durván így nézne ki:
https://people.ece.cornell.edu/land/courses/ece4760/PIC32/uart/multiple_drop_diode.PNG

Half-duplex vonal lenne, a diódák miatt kb. open collectorosan működne, bár működhetne push-pull módon is. Egy dolog hiányzik belőle: az interrupt, amikor egy eszköz jelezni akar, hogy üzenete van. Ezt egy másik open collectoros vezetéken oldanám meg, amikor van üzenet, lehúzza a vonalat, a mester meg körbekérdez mindenkit, hogy mi történt.

Erre az I2C rendszer is jó lenne, akkor mi a baj vele:
- körülményes. Miközben az USART-on kiadom, hogy ezt a puffert DMA-val told át, vagy olvasd be, addig I2C alatt semmi nem megy tapsra. Nem lehet egy rendes DMA-t ráállítani. Ezer dolog történhet az I2C buszon, nem úgy megy, hogy itt egy puffer, küldd át, vagy töltsd fel.
- gyorsabb: még open collectorosan is 2X sebességgel megy (kevesebb szintátmenet), push-pull módban 20X is lehetne
- ha push-pull módban megy, akkor kevésbé zavarérzékeny
- az USART egyszerűbb hardver, sem az Atmel, sem az STM32 nem bug mentes. Lehetnek versenyhelyzetek, néha a chip is kiakad.
- a slave nem tudja jelezni, hogy vége az üzenetnek. Max az lehet, hogy az első bájt az üzenetból elmondja, hogy milyen hosszú lesz.
- az I2C előnye, hogy képes késleltetni a mestert, de ez egyben hátrány is, mert miközben vár, mást is csinálhatna a buszon.