Forum: Mikrocontroller und Digitale Elektronik I2C Slave -> UART im AVR


von Marvin G. (margau)


Lesenswert?

Hallo!
Wir haben in einer schulischen Robotik-AG das folgende Problem:
Um unsere Robotersteuerung für ein Industrieprojekt, bestehend aus 
Fischertechnik-TX-Controllern, in ein Netzwerk einbinden zu können und 
mit mehr Intelligenz zu versehen, müssen wir diese per I2C mit einem 
CHIP (https://getchip.com) kommunizieren lassen.

I2C ist leider die einzige Verfügbare offene Schnittstelle an den 
Controllern,
und die CHIP's müssen wir nehmen, da wir in unserer API entsprechende 
Leistung brauchen, sodass ein AVR mit Netzwerkadapter leider nicht 
reicht. Die CHIP's (oder als alternative Raspberry Pi's) unterstützen 
nach unseren Recherchen leider kein I2C-Slave-Mode, und die 
Fischertechnik-Controller können nur Master sein, sodass wir gezwungen 
sind, hier eine Brücke zu finden.

Der derzeit geplante Signalfluss sieht folgendermaßen aus:

TX-Controller (I2C Master) =I2C=> AVR als Brücke <=UART=> CHIP <=> 
Netzwerk

Leider müssen wir den AVR zur Signalkonvertierung als I2C-Slave 
betreiben, sodass wir im I2C-Interrupt stecken bleiben und keine Daten 
per UART, was ja auch Interrupt-basiert läuft, abholen können.
Gibt es für solche Fälle irgendeine sinnvolle Lösung?

Bereits jetzt danke für Anregungen, Ideen etc.

Viele Grüße!
margau

von Wilhelm M. (wimalopaan)


Lesenswert?

Der I2C-Slave stellt alle empfangenen Daten in eine Queue, in einer 
Event-Loop werden Daten aus der Queue entnommen und in den UART gegeben.

von Marvin G. (margau)


Lesenswert?

Hallo!

Danke für die Antwort, aber wir haben leider das Problem, das wir auch 
Daten zurücksenden müssen - der Master macht einen Request mit ein paar 
Daten, und diese werden per UART übergeben und die Antwort dann an den 
Master zurückgesendet, was wegen den Interrupts nicht geht.

Viele Grüße!
margau

von Wilhelm M. (wimalopaan)


Lesenswert?

Klar doch, geht genauso auch in die andere Richtung.

Die Interrupts transferieren die Daten nur in / von den Device-Queues. 
Alles andere macht man ausserhalb der ISRs in einer (Event)-Loop.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Marvin G. schrieb:
> Leider müssen wir den AVR zur Signalkonvertierung als I2C-Slave
> betreiben, sodass wir im I2C-Interrupt stecken bleiben und keine Daten
> per UART, was ja auch Interrupt-basiert läuft, abholen können.
> Gibt es für solche Fälle irgendeine sinnvolle Lösung?

 Muss es ein AVR sein ?
 Ein billiger STMF103 würde so etwas machen, ohne sich anzustrengen
 oder es überhaupt zu merken, wenn es per DMA läuft...

von H.Joachim S. (crazyhorse)


Lesenswert?

Wäre nicht ein I2C-UART wie z.B. SC16IS750 die einfachste Lösung?

von Jim M. (turboj)


Lesenswert?

H.Joachim S. schrieb:
> Wäre nicht ein I2C-UART wie z.B. SC16IS750 die einfachste Lösung?

Kann der Slave Mode? Die meisten dieser Chips können nur Master Mode, 
denn da haben sie selber das Timing im Griff.

Marvin G. schrieb:
> Danke für die Antwort, aber wir haben leider das Problem, das wir auch
> Daten zurücksenden müssen - der Master macht einen Request mit ein paar
> Daten, und diese werden per UART übergeben und die Antwort dann an den
> Master zurückgesendet, was wegen den Interrupts nicht geht.

Das geht - aber in der Praxis nur dann wenn der Master I2C Clock 
Stetching versteht und das ein Erwachsener programmiert. Denn hier 
muss geschickt mit Stahe Machines gearbeitet werden, so dass man eben 
nicht im Interrupt blockiert. Das übersteigt übliches Arduino Niveau 
deutlich.

Übrigens kann man die Antwort bei I²C nicht in derselben Transaktion 
zurück senden, da ist mindestens ein Repeated-Start nebst Addressbyte 
erforderlich. Und da könnte man auch mal ein NACK senden, wenn man die 
Antwort noch nicht fertisch hat.

von (prx) A. K. (prx)


Lesenswert?

Hab das auch mal gebraucht, um einen RasPi mit Log-Daten zu versorgen, 
die aus einer bestehenden Anlage per I2C raus kamen. Vorrangig diese 
Richtung, die andere war weniger wichtig. ATtiny841, mit UART und I2C 
per Interupt.

Da das I2C Protokoll kein Datenstrom war, sondern auf Frames begrenzter 
Länge basierte, kam hinzu, dass es dem RasPi möglich sein musste, den 
UART Datenstrom wieder in Frames zu zerlegen.

: Bearbeitet durch User
von Jobst M. (jobstens-de)


Lesenswert?

Clock stretching.

Der Master schickt an deinen AVR eine Anfrage per I²C. Dieser hält die 
Clockleitung auf L, sendet seine Anfrage per UART weg, wartet auf die 
Antwort, lässt die Leitung wieder los und schickt die Antwort damit über 
I²C zum Master.

Anders funktioniert es nicht. Und ob es so funktioniert, ist auch 
fraglich.

Sonst geht es nur mit einem Flux-Kompensator, damit der AVR die Antwort 
über UART bekommt, bevor der I²C-Master die Frage gestellt hat.


Gruß
Jobst

von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

Code zu oben. Getestet, aber nicht produktiv.

Mangels Handshake zwischen dem I2C Master und dem RasPi ist das nicht 
failsafe. Wenn zu langsam, dann gehen Daten verloren. Das wird dann aber 
signalisiert.

: Bearbeitet durch User
von Marvin G. (margau)


Lesenswert?

Hallo,

Jim M. schrieb:
> Das geht - aber in der Praxis nur dann wenn der Master I2C Clock
> Stetching versteht und das ein Erwachsener programmiert. Denn hier
> muss geschickt mit Stahe Machines gearbeitet werden, so dass man eben
> nicht im Interrupt blockiert. Das übersteigt übliches Arduino Niveau
> deutlich.

das dürften wir hinbekommen, einige von uns sind kurz vor dem 
Informatik- bzw. Elektrotechnikstudium.

Jobst M. schrieb:
> Clock stretching.
>
> Der Master schickt an deinen AVR eine Anfrage per I²C. Dieser hält die
> Clockleitung auf L, sendet seine Anfrage per UART weg, wartet auf die
> Antwort, lässt die Leitung wieder los und schickt die Antwort damit über
> I²C zum Master.

Danke für die Ideen! Ein Versuch ist es wert, allerdings haben wir auf 
demselben Bus leider noch eher zeitkritische Motoren,
vielleicht können wir aber irgendwas aus entsprechenden Puffern und 
getrennten Anfragen / NAK's basteln.

Die SC16IS750-Lösung klingt zwar gut, jedoch haben wir keine gut 
Möglichkeit zum SMD-Löten.

Danke und Viele Grüße!
margau

von H.Joachim S. (crazyhorse)


Lesenswert?

Jim M. schrieb:
> Kann der Slave Mode? Die meisten dieser Chips können nur Master Mode,
> denn da haben sie selber das Timing im Griff.

Soweit ich weiss nur slave, lange her, dass ich den benutzt habe.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Marvin G. schrieb:
> Jobst M. schrieb:
>> Clock stretching.
>>
>> Der Master schickt an deinen AVR eine Anfrage per I²C. Dieser hält die
>> Clockleitung auf L, sendet seine Anfrage per UART weg, wartet auf die
>> Antwort, lässt die Leitung wieder los und schickt die Antwort damit über
>> I²C zum Master.
>
> Danke für die Ideen! Ein Versuch ist es wert, allerdings haben wir auf
> demselben Bus leider noch eher zeitkritische Motoren,

 Aha.
 Nur unterstützt der AVR clock stretching nicht und es ist fraglich ob
 der TX-Controller das auch kann.
 Als Slave hat der AVR sein SCL als Eingang definiert, da müsste der TO
 mit DDR und I2C Registern rumhantieren.
 Ausserdem wird dadurch der I2C Bus lahmgelegt.
 Wie lange dauert die Anfrage und Antwort per UART ?
 Was ist wenn die Antwort auf sich warten lässt ?

 Lass es sein, so etwas macht man (wenn überhaupt) mit SDA und NACK.

 Und meine Frage steht immer noch:
 Warum kein STMF103 für 1,25 Euro, anstatt der ganzen Fummelei ?

von Marvin G. (margau)


Lesenswert?

Hallo,

Marc V. schrieb:
> Wie lange dauert die Anfrage und Antwort per UART ?
> Was ist wenn die Antwort auf sich warten lässt ?

das kann leider schon etwas dauern, da dort noch eine API mit dran 
hängt.

Zurzeit überlege ich, die Antwort nach einer gewissen Zeit seperat 
abzuholen, oder eben in die Nachricht eingebettet ein "Antwort ist noch 
nicht da" zu senden. Dann muss der Mikrocontroller das halt Puffern.

Marc V. schrieb:
> Warum kein STMF103 für 1,25 Euro, anstatt der ganzen Fummelei ?

Ein kleiner AVR ist für uns aufgrund der DIP-Bauform einfacher zu 
verarbeiten, für SMD müssten wir extra Platinen ätzen lassen und ein 
Board mit nem STM32 frisst sehr viel Platz für die eigentlich benötigten 
4 Datenpins.

Viele Grüße!
margau

von (prx) A. K. (prx)


Lesenswert?

Marc V. schrieb:
>  Nur unterstützt der AVR clock stretching nicht

Doch, das tut er, wenn man es einschaltet. Als Master und als Slave. 
Sowohl die Megas, als auch die Tinys mit USI und ebenso obiger 
Slave-only Tiny841. Einen Tiny mit USI statt vollem I2C-Slave würde ich 
allerdings vermeiden, wenn möglich (BTDT).

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Marvin G. schrieb:
> Board mit nem STM32 frisst sehr viel Platz für die eigentlich benötigten
> 4 Datenpins.

LPC810. DIP8 mit UART und I2C. Die ATtinys in DIP haben nur USI. Ich 
habe beim Tiny841 ein kleines Konverterplatinchen verwendet, das frisst 
auch nicht viel Platz.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.