Hallo Leute,
ich möchte einen Arduino SAMD21 in einen bestehenden I2C Bus von einer
Torsteuerung integrieren.
Der Arduino soll einen I/O Expander ersetzen.
Es scheint so, als sei die Start Condition die vom Master kommt (keinen
Einfluss drauf), zu kurz und der Arduino spricht nicht an.
Test.png - Zeigt meinen Arduino mit einem RPi
Device.png zeigt meinen Arduino in der Torsteuerung.
Beide mit 100khz Clock.
Jemand eine Idee wie ich den Arduino dazu bekomme die kürzere Start
Condition zu akzeptieren?
Jens1993 schrieb:> Es scheint so, als sei die Start Condition die vom Master kommt (keinen> Einfluss drauf), zu kurz und der Arduino spricht nicht an.
Dann hat der Code im Arduino einen Bug.
I²C ist ja explizit darauf ausgelegt, dass das angesprochene Gerät den
Start so lange verzögern kann, bis es bereit ist. Dazu muss es halt die
Leitung dann selbst weiter herunter ziehen.
Dachte ich zunächst auch. Jedoch sieht das Signal am I2C Master
(Torsteuerung) genauso aus wenn kein Arduino angeschlossen ist. Das
hätte ich erwähnen sollen.
Der originale I/O Expander ist entfernt.
Der Trace sieht allerdings so aus, als würde da schlicht gar keiner
reagieren. Sicher, dass alles richtig verdrahtet ist?
In deinem Test.png wird ja die Startbedingung deutlich verlängert, im
anderen Bild gar nicht.
Also eine fehlverdrahtung kann ich ausschließen. Kabel und Pins sind
markiert.
Mittels Logic Analyzer konnte ich auch SDA und SCL auf dem Tor-Board
gegenprüfen. Die sind korrekt beschriftet.
Logic Level sind durchweg 3,3V.
Der einzige Unterschied scheint mir in der Start Condition zu liegen.
Der originale IO Expander benötigt:
2C bus free time between Stop and Start 4.7 μs
2C Start or repeated Start condition setup 4.7 μs
2C Start or repeated Start condition hold 4 μs
2C Stop condition setup 4 μs
Mein StartBit vom Tor ist 5 μs lang.
Ich denke, dass ist für den SAMD21 zu kurz.
So wie ich das verstehe, möchtest du den SAMD21 als Slave einsetzen, der
auf einen Master reagiert, wenn der Master das Gerät 0x70 anspricht.
Ich habe diverse Prozessoren auch schon mal als Slave benutzt.
Allerdings ist die Programmierung wesentlich komplexer als beim Einsatz
als Master.
Es müssten meistens Interrupts benutzt werden, dann eine Routine, wenn
das Adressebyte empfangen wurde (also mittendrin), etc. Und da kann man
viele Fehler machen.
Bist du sicher, dass du das alles richtig programmiert hast?
Vielleicht solltest du etwas Debug-Code in den Slave einbauen, um zu
erkennen, was er wirklich an Daten bekommt, und worauf er evtl nicht
reagiert.
Ich kann mir nicht vorstellen, dass es nur dieses Timing ist. Denn I2C
ist so langsam, dass die CPU doch dabei Däumchen dreht.
PittyJ schrieb:> So wie ich das verstehe, möchtest du den SAMD21 als Slave einsetzen, der> auf einen Master reagiert, wenn der Master das Gerät 0x70 anspricht.
Yes, das ist der Plan.
Ich nutze:
https://github.com/charkster/samd21-i2c_slave
Ich glaube auch nicht, dass der Controller zu langsam ist.
Ich glaube, dass die Start Condition für den SAMD21 eine bestimmte Dauer
haben muss und diese gar nicht erreicht wird.
Das ist mal meine Vermutung.
Weil sonst sind die Signale Zeitgleich.
In der .ino Datei sind receiveEvent() und requestEvent().
Hast du da mal Debugausgaben reingetan, um zu sehen, ob und was da
überhaupt ankommt?
Alternativ das Teil auch mal mit einem anderen Master (z.B. 2ter
Arduino) ansprechen, und sehen, wie das reagiert, und was für Daten dort
kommen.
Ja das habe ich gemacht.
Das Terminal bleibt stumm. Das habe ich probiert bevor ich den Logic
Analyzer angeschlossen habe.
Mit einem anderen Master klappt es. Es war ein RPi. Siehe Test.png.
Das Signal sieht vollkommen korrekt aus. Entweder, da ist ein Bug im
SAMD21 oder in der Lib.
Ist ein SAMD21 als IO-Expander eh nicht völlig oversized. Ein ATmega48
sollte doch dicke reichen.
Der SAMD21 agiert ja nur als IO Expander und soll die Daten dann über
einen BUS (welcher steht noch nicht fest) senden.
Ein ATmega48 tut es sicherlich auch, nur davon fliegt hier keiner rum.
Habe den Code mal auf einen ESP32 geladen. Funktioniert nun.
Ich werde die Tage mal ein GitHub Issue beim Arduino-Core SAMD21
aufmachen.
Ggf. ist wirklich ein Fehler in der Lib.
Die Start Condition in "Device.png" sieht für mich schon arg knapp aus.
Wenn da noch irgendwelche Leitungskapazitäten hängen, dann kann das für
den SAM21D durchaus nach "Start" - "Stop" aussehen. Da müsste man mal
mit einem echten Oszi drauf schauen oder einer besseren Auflösung.
Zwischen fallender Flanke vom SCL und der steigenden Flanke vom SDA
sollten wenigsten 300ns (Max Fall time bei 100kHz) liegen und das kann
ich an dem Bild so nicht erkennen.
Andreas M. schrieb:> Die Start Condition in "Device.png" sieht für mich schon arg knapp aus.
Naja, eigentlich nicht. Er hat da an die 5 µs Zeit, sie zu
interpretieren. Dass der Master danach SDA wieder freigibt, ist ja
normal – der SAMD21 könnte an der Stelle SDA weiter unten halten, wenn
er noch Zeit braucht (passiert wohl im anderen Trace so). Der nimmt
einfach die Startbedingung gar nicht zur Kenntnis.
Jörg W. schrieb:> Dass der Master danach SDA wieder freigibt, ist ja> normal – der SAMD21 könnte an der Stelle SDA weiter unten halten, wenn
Ich sehe das Problem eher bei der 1. Flanke SCL (fallend) und 2.Flanke
SDA (steigend) Die sind sehr eng beeinander. Ich hätte gedacht, das da
etwas mehr Abstand sein sollte. Wenn es dumm läuft, dann sieht der
SAMD21 die steigende SDA Flanke bevor er mitbekommen hat, das SCL Low
ist. Was für Ihn dann "Stop" heißen könnte. Wobei der eigentlich darauf
achten müsste, das wenigsten 4µs zwischen SDA und SCL liegen müssen
damits ein Start oder Stop ist.
Edit: Die Chinesen mit dem ESP32 scheinen es aber auch hinzubekommen :-)
Ich hab die I2C Cores der ATSAMS auch nicht in bester Erninnerung.
Andreas M. schrieb:> Ich sehe das Problem eher bei der 1. Flanke SCL (fallend) und 2.Flanke> SDA (steigend) Die sind sehr eng beeinander.
Das ist kein Problem.
Wenn man z.B. in das Datenblatt des PCF8574 schaut, dann darf tHD;DAT =
0ns kurz sein.
Mit einem Scope würde ich auch noch einmal schauen.
Statt Rechtecke bekommt man weiche Kurvenflanken, die der Logic Analyser
anders interpretiert als der Chip selber.
Oder man die 3.3V and einem 5V Chip liegen und ähnliche Effekte.
Oder ein Pullup/Down passt nicht...
Ich hab allerdings auch den Eindruck, daß viele Nachbauer des I2C zu
faul waren, die original Phillips Spezifikationen zu lesen.
Echte Männer lesen keine Anleitungen (Tool Time).
Andreas M. schrieb:> Ich sehe das Problem eher bei der 1. Flanke SCL (fallend) und 2.Flanke> SDA (steigend) Die sind sehr eng beeinander.
Das ist egal. Die Startbedingung ist ja der H->L Übergang von SDA
während SCL high ist. Die liegt lange genug an, als dass ein
Busteilnehmer, der sich erst noch putzen muss, SDA weiter unten halten
könnte, um diese Bedingung hinaus zu zögern. Wie das dann aussieht,
siehst du ja im zweiten Diagramm des Eröffnungspostings. (Auch dort wird
der Master SDA unmittelbar nach der H->L Flanke von SCL freigegeben
haben, aber der Busteilnehmer hält es länger unten.)
Jörg W. schrieb:> Das ist egal. Die Startbedingung ist ja der H->L Übergang von SDA> während SCL high ist. Die liegt lange genug an, als dass ein
Ja und wenn der SAM21 nun beim L->H Übergang von SDA direkt wieder den
Stop erkennt? Was soll es bringen SDA unten zu halten? Clock Stretching
ist auf SCL bezogen. Ich wüsste auch gar nicht, das Slave direct nach
Start am SDA rumspielen dürfte. Da hat der Master die Kontroller drüber.
Ist mir neu das man am SDA das Timing manipulieren könnte. Aber erklär
mal wie das gehen soll.
Peter D. schrieb:> Das ist kein Problem.> Wenn man z.B. in das Datenblatt des PCF8574 schaut, dann darf tHD;DAT => 0ns kurz sein.
Es geht aber nicht um tHD;DAT und schon gar nicht darum was im
Datenblatt eines I2C Slaves steht sondern darum, was im der I2C Spec
steht.
Und dort könnte man im Angesicht des Timing-Diagrams (Fig31) zu dem
Schluss kommen, das der Master nach setzten des SDA Signals tSU;DAT bis
zur Flanke SCL L->H und dann nochmal tHIGH bis zur Flanke SCL H->L
warten muss. Für mich heißt das, das nachdem der Master SDA gesetzt hat
es mindestens 4,25µs bis zur nächsten SCL H->L Flanke dauern muss.
Wetten, dass es funktionieren würde, wenn die Adresse mit "0" statt mit
"1" anfangen würde?!