EV3Basic: allgemeine Kommunikation mit I2C Geräten

NXC, C/C++, Lejos, pbLua, RobotC...

Moderator: Moderatoren

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 22. Sep 2015 18:54

hallo,
auf der Suche nach I2C Kommandos habe ich schon einmal einige Examples von Github gesammelt
(viewtopic.php?f=25&p=67569#p67569),
fündig geworden nach I2C Kommandos bin ich aber nicht.

Wie schreibt man allgemein I2C Read- und Write Befehle mit EV3Basic?
Analog zu den X3-Befehlen hier auf der Dexter-Seite?

http://www.dexterindustries.com/howto/c ... 3-arduino/

Die Dexter-X3-Blöcke unterstützen nur Messages von 1 oder 8 Bytes, die Lego-Firmware aber tatsächlich bis 32 Bytes Länge (Inkl. Device- und Registeradresse, also "netto" nur 30).
Soll aber erst mal nur ums Prinzip in EV3Basic gehen, egal wie lang die msgs sind. Mit 8 kann man ja erstmal anfangen.
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 23. Sep 2015 23:03

Für die Kommunikation über I2C bietet EV3Basic genau einen einzigen Befehl:

Code: Alles auswählen

Sensor.CommunicateI2C (port, address, writebytes, readbytes, writedata


Dieser kann in einem einzigen Aufruf ein Datenpaket zu einem Slave schicken und ein anderes Datenpaket abholen.
Kurze Erklärung der Parameter ist im - inzwischen viersprachigen - Handbuch zu finden.
Ein Beispiel ist in den examples.zip leider nicht dabei, aber im Prinzip würde das etwa so aussehen (achtung code nicht getestet!).

Code: Alles auswählen

'  ... create data to be sent to I2C slave
OUTGOING[0] = 55
OUTGOING[1] = 22
OUTGOING[2] = 44
OUTGOING[3] = 11
OUTGOING[4] = 99
INCOMMING = Sensor.CommunicateI2C(1,47, 5,5,  OUTGOING)
 ' ... do some action with the INCOMMING data

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 24. Sep 2015 08:36

danke für deine Antwort!

Code: Alles auswählen

Sensor.CommunicateI2C (port, address, writebytes, readbytes, writedata


wie definiere ich die Arraygröße als Variable?
in C würde man schreiben
byte OUTGOING[32];

wie geht das in Basic? Ich will ja keine Floats speichern und keine Ints, sondern nur Bytes!

Die ersten beiden Parameter sind klar, aber was sind die letzten 3?
was genau steckt hinter
writebytes, readbytes, writedata ?

ich hätte
byte OUTGOING[32]; // bzw. sendmsg[32]
byte INCOMING[32]; // bzw. recvmsg[32]

was sind Arrays, was sind Skalare (Größenangaben, Einzel-Bytes)?
was davon entspricht OUTGOING[32], was INCOMING[32]? was ist der 3. Parameter?
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 24. Sep 2015 10:29

Alle diese Sachen mit den Datentypen ist in Small Basic ja stark reduziert. Es gibt im Prinzip nur floats für Zahlen.
Arraygrößen brauchst du normalerweise auch gar nicht deklarieren, das Array kann zu jedem Index einen Wert aufnehmen und legt bei Bedarf Speicher an. Deswegen ist das Konzept der Arraygröße auch gar nicht wirklich vorhanden.

Wenn du aber den Code gerne ein bisschen traditioneller ausehen lassen willst, dann kannst du am Anfang schreiben

Code: Alles auswählen

OUTGOING = Vector.Init(32, 0)
INCOMMING = Vector.Init(32, 0)

Damit erzeugst du gleich mal zwei Arrays die jeweils eine 0 an den Indizes 0 -31 haben.

Noch zu den Parametern:
- writebytes ist die Anzahl der Bytes, die gesendet werden sollen.
- readbytes ist die Anzahl der Bytes, die empfangen werden soll (die werden in das Array gespeichert das die Zuweisung empfängt - in meinem Beispiel INCOMMING)
- bei writedata übergibst du das Array von dem die gesendeten Bytes genommen werden sollen.

Wenn ich sage "Bytes", dann betrifft das nur die I2C - Kommunikation. Im Basic intern ist immer alles float und wird immer entsprechend konvertiert. Wenn du also Zahlen jenseits von 0-255 oder Kommazahlen übergibst, werden die Werte entsprechend abgeschnitten/gerundet.

Noch was zu der Verwendung von floats und der Performance: Es ist für die Geschwindigkeit praktisch egal, dass die VM mit floats rechnet und nicht mit integer-Typen. Die ganze Performance geht sowieso dafür drauf, dass es überhaupt eine VM gibt, die jede VM-Instruktion einzeln interpretieren muss. Und wegen dem Speicher hat man damit normalerweise auch kein Problem, weil der EV3 ziemlich viel RAM hat

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 24. Sep 2015 10:35

ich habe mir sagen lassen, dass die Arraylänge bei lms2012 max. 32 ist, aber INKLUSIVE Adress- und Registeradresse.

Muss dann
OUTGOING = Vector.Init(32, 0)
INCOMMING = Vector.Init(32, 0)

oder mit
OUTGOING = Vector.Init(30, 0)
INCOMMING = Vector.Init(30, 0)

initialisiert werden?

- und sind dann writebytes und readbytes beide 32 oder 30 ?

- und stehen dann die gesendeten Daten in OUTGOING ab 3.Position (2) und in INCOMING ab 1. Position (0) ?

- BTW: man braucht doch 2 Arrays - warum ist da im Aufruf nur 1 Array definiert (writedata ist wohl dann der Array OUTGOING ) ?
Wo ist readdata (INCOMING) ?

Code: Alles auswählen

Sensor.CommunicateI2C (port, address, writebytes, readbytes, writedata
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 24. Sep 2015 22:10

Die maximalen Längen für die I2C-Pakete sind beim Schreiben zum Slave 31 Byte, beim Lesen vom Slave 32 Byte.
Wie das in den Tiefen des lms2012 genau zustandekommt, weiß ich auch nicht genau, aber ich hab es ausprobiert und so viel geht.

Das mit den Arrays ist in Small Basic natürlich alles ein bisschen ungewohnt für einen C-Programmierer. Eigentlich braucht man die Initialisierung von INCOMMING gar nicht, weil dieses Array bei jeder Zuweisung in Größe und Inhalt angepasst wird. Und explizite Variablendeklarationen gibt es sowieso keine.
Das OUTGOING-Array muss mit so vielen Zahlen befüllt sein, wie man nach schicken will. Wenn das Array größer ist, macht es auch nichts. Es werden halt nur die ersten n Zahlen genommen. Falls das Array zu wenig Daten enthält, verschickt das Kommando dann 0-Bytes an deren Stelle. Insgesamt ist EV3Basic recht fehlertoleant.

Nochmal ein Beispiel mit Erklärung (ungetestet!):

Code: Alles auswählen

     X = Vector.Init(10)             ' erzeugt mal ein Array mit 0-en an den Indizes 0..9
     X[2] = 55
     X[3] = 66
     X[4] = 88
     Y = Sensor.CommunicateI2C(1, 47, 5, 8, X)


Die ersten drei Zeilen initialisieren das Array X so, dass es 10 Zahlen (bei Index 0..9) enthält, an 2., 3. und 4. Stelle jeweils 55,66,88.
Die allererste Zeile ist eigentlich nur eine Optimierung. Arrays in Small Basic wachsen nämlich nach Bedarf und durch die drei Zuweisungen würden sowieso die Zellen 2, 3 und 4 ihre Werte bekommen. Die davor liegenden Zellen werden mit 0 aufgefüllt. Allerdings müsste dann das Array zweimal wachsen, was für die Laufzeit recht aufwändig ist. Wenn ich das Array gleich zuerst groß genug mache, entfällt das.

Die letzte Zeile macht dann die Kommunikation und schreibt die empfangenen Daten ins Array Y (das durch diese Anweisung sogar erst deklariert wird). Die Länge von Y wird dann intern auf 8 gesetzt und die Zellen 0..7 mit den 8 angeforderten Bytes vom Slave gefüllt. Falls der Slave weniger zurückschickt, dann wird das hinten mit 0en aufgefüllt (glaube ich jetzt mal).

Weil Small Basic solche Konzepte wie Zeiger,Referenzen und andere Arten, Daten aus Funktionen herauszuleiten, nicht kennt, muss alles über den Rückgabewert der Befehle gemacht werden. In diesem Fall ist der Rückgabewert eben ein ganzes Array das den vorigen Wert von Y komplett überschreibt. Deswegen gibt es auch keinen 'readdata' Parameter. Aufrufparameter können Information immer nur in den Befehl hineinschicken.

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 24. Sep 2015 22:19

Noch etwas zum besseren Verständnis: In obigem Beispiel werden die 5 Bytes 0,0,2,3,4 über den Sensor-Port 1 an den Slave mit der Adresse 47 geschickt, und dann 8 Bytes vom selben Slave angefordert.

Ein Detail am Rande:
Aus mysteriösen Gründen (wohl in Bug in der VM), kann man zwar 0 Bytes schicken (der Slave kriegt dann gar kein Paket), aber man muss jedesmal zumindest 1 Byte holen, weil da sonst irgendwie alles durcheinander kommt. Das macht EV3Basic selbstständig, sodass es immer zumindest auch 1 Byte abholt. Irgendwie ist das ein bisschen lästig, weil das I2C-Protokoll ja bei jedem Sende- und bei jedem Empfangsvorgang die Slave-Addresse schicken muss. Wenn man also gar nichts emfangen möchte, es aber wegen den Bug trotzdem muss, dann dauert der Sende-Request gleich mal ca. 3 ms länger.

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 25. Sep 2015 07:35

aha, danke, der vermisste readdata array ist also der Rückgabewert der Funktion!
Das ist dann klar soweit.

Code: Alles auswählen

readdata = Sensor.CommunicateI2C (port, address, writebytes, readbytes, writedata)

port == EV3-Sensorport (gezählt ab 1...(?) )
address == I2c Slave-Device Adresse (8-bit-kodiert (?) )
writebytes == Anzahl geschriebene Daten-Bytes
readbytes == Anzahl gelesene Daten-Bytes,
writedata == gesendeter reiner Daten-Array ohne Adress-Bytes etc.
readdata == Rückgabewert == gelesene Daten (einzelnes byte oder array)

Generell zu I2C:
Register am Slave kann man dann also nicht direkt adressieren zum Lesen oder schreiben...?
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 25. Sep 2015 09:51

Stimmt im wesentlichen. Ein paar Details aber:
writebytes = Anzahl der zu schreibenden Bytes (wieviele der Slave dann davon wirklich annimmt, kann man leider nicht herausfinden)
readbytes = Anzahl der Bytes, die man lesen will (wiederum hängt das von Slave ab, wieviele man wirklich kriegt)
readdata = Array mit sovielen Zahlen wie man bei readbytes angegeben hat (falls der Slave weniger schickt, sind dann hinten 0en dran). Und es ist immer ein Array - auch wenn man nur ein Byte holt.

Wegen Frage zu den Registern am Slave: Das I2C-Protokoll selbst ist zur Datenübertragung definiert und macht noch keine Aussage über die Bedeutung der Daten und ob das dann dazu führt, dass der Slave irgendwelche Register verwaltet.
Aber natürlich gibt es bereits einen Standard für diese Verwendung von I2C und das läuft dann meistens nach diesem Schema ab:

- Bei einem Sendepaket ist das erste Byte immer die Register-Addresse mit der im Slave der Register-Zeiger gesetzt wird. Die nachfolgenden Bytes im selben Paket werden dann beginnend bei dieser Adresse in die Register geschrieben.
- Bei einem Empfangspaket schickt der Slave beginnend von der aktuellen Position des Register-Zeigers die Inhalte dieser Register.

Um also z.B. Register 3 auf den Wert 6 zu setzen, muss man die Bytes 3,6 schicken.
Um z.B. das Register 5 zu lesen, muss man zuerst mal ein das einzelne Byte 5 schicken, und dann ein Byte abholen (geht mit EV3Basic in einem Aufruf). Man kann auch mehrere Register auf einmal lesen oder schreiben, allerdings nur welche mit hintereinanderliegenden Addressen.

Nochmal zur Klarstellung: Wenn du I2C auf einem Arduino selbst programmierst, dann ist da von Haus aus gar nichts bezüglich Registern vorhanden. Muss man alles selbst programmieren (ist aber mit der Wire - Library recht einfach).

Nochmal ein Beispiel in EV3Basic für einen I2C-Slave mit Registern

Code: Alles auswählen

   ' Setzt im Slave mit Addresse 47 an Port 1 das Register 11 auf den Wert 55
   x[0] = 11
   x[1] = 55
   Sensor.CommunicateI2C (1, 47, 2,0, x)
   
   ' Liest vom selben Slave das Register 14 aus
   x[0] = 14
   y = Sensor.CommunicateI2C (1, 47, 1,1, x)
   ' wert ist dann int y[0]


Ich muss noch dazu sagen, dass beim ersten Aufruf zwar eine 0 als readbytes angegeben wird (man will in dem Fall ja gar keine Daten holen), aber wegen des füher erwähnten Bugs, wird doch trotzdem ein einzelnes Byte geholt und sofort wieder verworfen. Normalerweise ändert das Holen eines Bytes von den Registern nichts am internen Zustand des Slaves. Allerdings wird der Registerzeiger einmal weitergesetzt. Solange man aber sowieso jedesmal die Registeradresse mitschickt (erstes Byte in einem Sendepaket), spielt das keine Rolle.

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 25. Sep 2015 10:02

ja, danke, auf dem Arduino ist das klar, meine Frage war generell zu I2C ("allgemeine Kommunikation mit I2C Geräten"), da kann man ja z.B. in einzelne Register schreiben zum Konfigurieren des Geräts (z.B. Compass calibration) oder Auslesen einzelner Werte (z.B. Acc X in Registern 12+13 oder Roll angle in Reg. 26+27), wenn man die ganzen anderen momentan gar nicht braucht, wie z.B. hier:

Code: Alles auswählen

Register     Function
0       Command register (write) / Software version (read)
1       Compass Bearing 8 bit, i.e. 0-255 for a full circle
2,3     Compass Bearing 16 bit, i.e. 0-3599, representing 0-359.9 degrees. register 2 being the high byte
4       Pitch angle - signed byte giving angle in degrees from the horizontal plane, Kalman filtered with Gyro
5       Roll angle - signed byte giving angle in degrees from the horizontal plane, Kalman filtered with Gyro
6,7     Magnetometer X axis raw output, 16 bit signed integer with register 6 being the upper 8 bits
8,9     Magnetometer Y axis raw output, 16 bit signed integer with register 8 being the upper 8 bits
10,11   Magnetometer Z axis raw output, 16 bit signed integer with register 10 being the upper 8 bits
12,13   Accelerometer  X axis raw output, 16 bit signed integer with register 12 being the upper 8 bits
14,15   Accelerometer  Y axis raw output, 16 bit signed integer with register 14 being the upper 8 bits
16,17   Accelerometer  Z axis raw output, 16 bit signed integer with register 16 being the upper 8 bits
18,19   Gyro X axis raw output, 16 bit signed integer with register 18 being the upper 8 bits
20,21   Gyro  Y axis raw output, 16 bit signed integer with register 20 being the upper 8 bits
22,23   Gyro Z axis raw output, 16 bit signed integer with register 22 being the upper 8 bits
24,25   Temperature raw output, 16 bit signed integer with register 24 being the upper 8 bits
26      Pitch angle - signed byte giving angle in degrees from the horizontal plane (no Kalman filter)
27      Roll angle - signed byte giving angle in degrees from the horizontal plane (no Kalman filter)
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 25. Sep 2015 10:08

halt, stopp:

Bei einem Sendepaket ist das erste Byte immer die Register-Addresse mit der im Slave der Register-Zeiger gesetzt wird.


wo ist dann die Device-Adresse ?

irgendwie ist das ganz schön komisch verquer...

edit: ach so, die Device-Adresse ist das 2. Byte im Funktionsaufruf....
trotzdem sehr seltsam die Syntax beim EV3, so ganz verstehe ich das ehrlich gesagt doch noch nicht...

Könnte man für EV3Basic die Syntax evtl umstricken?

Code: Alles auswählen

Sensor.I2CWrite(port, devaddr, regaddr, count, sendarray)

Sensor.I2CRead(port, devaddr, regaddr, count, recvarray)
'// oder
recvarray = Sensor.I2CRead(port, devaddr, regaddr, count) 
?

(ich glaube, ich denke sehr C-isch und Arduino-isch ... :-/ )
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 25. Sep 2015 17:34

habs jetzt nochmal durchgelesen und jetzt so verstanden:
man hat immer max einen byte msg-array mit Länge [32] als Obergrenze

man darf aber nur max [31] zum Senden deklarieren weil die dev addr immer zusätzlich mitbenutzt wird
man muss zum Senden immer in seiner msg an 1. Stelle (array[0] ) eine Reg-Adr. übergeben (meist wohl eine Null, zumindest zum Senden an Arduinos)
man kann aber dann nur effektiv [30] für seine eigentliche msg zum Senden nutzen...
und muss aber trotzdem als Sende-Länge 31 angeben, aber 32 werden dann tatsächlich benutzt... uff... :uff:

Was kommt dann aber für ein Array beim Arduino an?
Hat dann die Stelle [0] die Registeradresse? Oder das erste richtige msg- Byte?
Empfängt der Arduino als Msg dann insgesamt 30 oder 31 ? Das muss man ja mit Wire.available() abfragen,

Code: Alles auswählen

while(Wire.available()<32) ; // wait for 32 ???? 31 ???? 30 ???? bytes to complete

damit man die Vollständigkeit überprüfen kann... :heul:

was aber dann beim Empfang als Rückgabewert? Dann die vollen 32 ? :idee:

oh Herre, diese Lego-Firmware-Programmierer... also neee...
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 25. Sep 2015 19:22

Ich glaube, du verstehst noch immer nicht, was es mit diesen "Registern" auf sich hat. Wenn du selbst deinen Arduino programmierst, dann gibt es da ganz einfach keine Register. Die Wire-Library am Arduino kennt das gar nicht. Du kriegst dort einfach ein Paket Bytes und musst auf Bedarf ein Paket Bytes schicken. Diese Bytes sind exakt die Bytes, die vom EV3 in den Arrays übergeben / empfangen werden. Die Slave-Adresse ist extra, weil der Slave die Addresse dann auch nicht in den User-Code weitergibt (die kommt zwar natürlich auf der Leitung daher, wird aber von der Wire-Library entfernt, weil das für den Arduino-Code ja nutzlos wäre, die eigene Adresse in den Daten zu kriegen).

Dieses Konzept der Register existiert nur, wenn das Programm am Slave eben diese Art Protokoll implementiert. Viele Bauteile arbeiten so und deswegen hat sich das so als Standard für viele Anwendungen etabliert.
Aber solange du selbst den Arduino programmierst, bist du da komplett frei. Du kannst also die vollen 31 Bytes hinschicken und sogar 32 Bytes vom Arduino zurückverlangen.

Benutzeravatar
c0pperdragon
Schreibt viel
Schreibt viel
Beiträge: 231
Registriert: 9. Feb 2015 00:29

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon c0pperdragon » 25. Sep 2015 19:31

Wegen dem Vorschlag, den I2C-Kommunikationsbefehl in zwei Teile zu spalten (einmal zum Senden, einmal zum Empfangen):
Das wollte ich ursprünglich machen, aber wegen dieses seltsamen Fehlers in der EV3-Firmware, ist es einfach nicht möglich, ein Paket zu senden, ohne auch zumindest eines der Länge 1 anzufordern. Für den Anwendungsfall Senden & Empfangen müsste man dann beim einzelnen Sende-Aufruf akzeptieren, dass ein nutzloses Byte geholt wird (dauert 3ms), obwohl ja sowieso gleich noch ein Empfangs-Aufruf folgt.
Deswegen (und um die API klein zu halten), aber ich das in einen Befehl kombiniert (wenn man nichts senden will, funkioniert der Wert 0 für writebytes).

Benutzeravatar
HaWe
Administrator
Administrator
Beiträge: 5288
Registriert: 11. Jan 2006 21:01
Wohnort: ein kleiner Planet in der Nähe von Beteigeuze

Re: EV3Basic: allgemeine Kommunikation mit I2C Geräten

Beitragvon HaWe » 25. Sep 2015 20:02

doch ich verstehe das mit den Registern schon, aber eben so, wie man es bei Arduinos macht, wenn man slaves pollt oder auch wenn man ihn selber als slave konfiguriert.

Das Senden und Empfangen könnte man doch verbinden, denn ich will ja beides:
ca. 32 Bytes senden und dann andere 32 Bytes vom Arduino zurückschicken.
Hast du dir meinen Arduino Code angeschaut?

Wenn ich aber 30-32 Bytes vom EV3 aus sende, schriebst du ja, muss in den sende-Array immer das 1. byte ein Registerbyte sein, und das kann ja für den Arduino nur das an 1.Stelle, also [0] sein. der Rest ab Stelle [1] enthält dann z.B. die Sensor-Daten, die an den Arduino rüber sollen.

Der Arduino wiederum hat 2 Events, einmal Receive Event und einmal Request Event.

Beim ersten liest er die geschickten Daten, und wenn der EV3 jetzt einen Request sendet, kriegt er halt den vom Arduino inzwischen bereit gestellten Daten-Array zurück (mit DESSEN Sensor Daten oder was auch immer).

Wäre doch geradezu perfekt.

Jetzt geht es nur darum: wie baut der EV3 seinen Sende-Array zusammen, und was wird davon wie vom Arduino gelesen.
Ich vermute, dass devaddr und regaddr beim msg senden dort nicht als Teil der msg ankommen, aber das muss man ntl genau wissen.

Hier ist der Arduino-Code - statt 32 muss es jetzt nur wschl 31 oder 30 heißen::

viewtopic.php?f=25&t=8673&p=67598#p67557

Diese spezielle Kommunikation sollte man aber drüben im anderen Thread besprechen.
Gruß,
HaWe
±·≠≈²³αβγδε∂ζλμνπξφωΔΦ≡ΠΣΨΩ∫√∀∃∈∉∧∨¬⊂⊄∩∪∅∞®
NXT NXC SCHACHROBOTER: https://www.youtube.com/watch?v=Cv-yzuebC7E


Zurück zu „textbasierte Programmiersoftware“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 19 Gäste

Lego Mindstorms EV3, NXT und RCX Forum : Haftungsauschluss