Arduino Due TWI / I2C

Gast #3734439
Lesenswert?

Hallo,

hat von euch jemand Erfahrung mit der Verwendung von TWI / I2C mit dem 
Arduino Due?

Ich benutze einen Atmega32U4 mit dieser I2C Bibliothek 
Beitrag "AVR TWI Master und Slave Funtionen in C"
und einen Arduino Due mit dem Wire-Library.
Eine von beiden verursacht bei mir Probleme, und ich vermute, dass es 
die Arduino-Library ist...

Funktioniert die von Arduino mitgelieferte Library mit einem Arduino 
Due bei euch problemlos?

Viele Grüße,
Christian
Gast #3734472
Lesenswert?

San Lue schrieb:
> Christian schrieb:
>> Funktioniert die von Arduino mitgelieferte Library mit einem Arduino
>> Due bei euch problemlos?
>
> Du solltest die Fehler erst einmal bei dir suchen, anstelle von einer
> Arduino Lib welche täglich Tausende von Menschen verwenden.

Da in der Wire-Lib für den Due aber einige Fehler bekannt sind, wollte 
ich erstmal eure Erfahrungen hören, denn die Lib, die ich für den Atmega 
verwende wird auch von vielen Leuten verwendet und ich hatte mit dieser 
auch noch nie Probleme.

 Kassiopeia schrieb:
>Die Wire library ist ziemlich buggy!
>http://forum.arduino.cc/index.php?topic=144700.0
>https://github.com/arduino/Arduino/pull/1994

Genau auf die Fehler bin ich auch schon gestoßen und habe auf die 
Arduino 1.5.9 Version gewechselt, wo der Fehler gepatcht ist.
Gast #3734485
Lesenswert?

San Lue schrieb:
> Du solltest die Fehler erst einmal bei dir suchen, anstelle von einer
> Arduino Lib welche täglich Tausende von Menschen verwenden.

Oder aber auch nicht!  Bei den AVR basierten Arduinos mag das stimmen, 
der DUE hat leider noch nicht die Verbreitung, da klemmen noch ein paar 
Dinge.

Das Problem ist wohl auch, das die Arduino-Libraries sich zunächst sehr 
an den Möglichkeiten des 328P orientiert haben, und der 
Kompatibilitätsanpruch auch hardwareseitig zu merkwürdigen Dingen führt.

Zum Beispiel werden jeweils zwei Pins des SAM3X8E einfach 
kurzgeschlossen auf jeweils einen PIN des DUE geführt:  PC29 und PA28 
auf PIN 10
PA29 und PC26 auf PIN 4

Dies nur deswegen, dass somit auf diesem Pin sowohl PWM als auch SPI-CS 
angeboten werden kann.  Keine Möglichkeit vorgesehen, eine der beiden 
Leiterbahnen wenigstens kontrolliert trennen zu können...

Wenn nun beide PINs des SAM auf Output gesetzt werden, der eine High, 
der andere Low .....

Der DUE und seine Clones, insbesondere der DigiX sind interessante 
Boards, weit leistungsfähiger als die AVRs, aber die Arduino-Libs sind 
dafür in vielen Bereichen noch bestenfalls BETA
Gast #3734492
Lesenswert?

Christian schrieb:
> Auch auf dem Arduino DUE ???

Gerade auf dem DUE, wie die Links zeigen!

Kommt jeweils drauf an, was man damit macht.  Bibliotheken, die z.B. den 
Returncode von Wire.endTransmission() nicht auswerten laufen. 
Bibliotheken, oder Programme, die das Auswerten haben Probleme.

Bei mir laufen auch einige Dinge, andere liefen erst, als ich gepatcht 
habe.
Gast #3734551
Lesenswert?

Kassiopeia schrieb:
> sorry, falsche Nachricht markiert ... ;-)
>
> Da der TO nun auf die 1.5.7 umgestiegen ist, wird er bald melden, ob es
> das war.

Ja ich bin schon vor ein paar Tagen umgestiegen. Danach war ein Problem 
behoben. Aber das war scheinbar noch nicht alles. Der Arduino beendet 
das Senden von Daten scheinbar noch immer nicht sauber. Ich erstelle im 
Laufe des nachmittags mal ein Minimalbeispiel, das auch die Codes des 
Statusregiserts zeigt. Da wird mein Problem deutlich!

Danke schonmal!
Gast #3734630
Lesenswert?

So ich konnte das Problem eingrenzen. Es passiert, wenn ich vom Arduino 
mehr als 1 Byte an den Atmega sende.

Der Arduino fordert alle 500ms ein Byte Daten vom Atmega. Der Atmega 
sendet daraufhin Decimal 36
Wenn ich nun ein Zeichen in die Arduino-Konsole eingebe, soll der 
Arduino einmalig die beiden Bytes mit den Decimalwerten 37 und 38 senden

Ausgabe des Atmegas (Slave):
1
TWSR: 0xa8 // Slave soll Daten senden
2
Sende: 36  // Slave sendet Daten
3
TWSR: 0xa8 // Slave soll Daten senden
4
Sende: 36  // Slave sendet Daten
5
(...Hier bekommt der Arduino die Aufforderung, die Daten zu senden...)
6
TWSR: 0xf8 // TWI_NO_STATE
7
TWSR: 0x60 // Slave soll Daten lesen
8
Empfange: 37 und 38 // Slave liest Daten
9
TWSR: 0xa8 // Slave soll Daten senden
10
Sende: 36  // Slave sendet Daten
11
TWSR: 0x60 // Ab hier wirds merkwürdig: Der Arduino möchte weiterhin Daten senden, obwohl er dies gar nicht soll!
12
Empfange: 37 und 74 // Arduino sendet fehlerhafte Daten (2. Byte falsch)
13
TWSR: 0xa8 // und dann gehts immer so weiter...
14
Sende: 36
15
TWSR: 0x60 
16
Empfange: 37 und 74

Der Arduino scheint irgendwie das Senden der Daten nicht korrekt zu 
beenden und sendet Byte 1 immer wieder und Byte 2 auch, aber mit einem 
falschen Wert... :-S
Wenn ich nur ein Byte sende, ist alles Prima!

Übersehe ich etwas?
Angehängte Dateien:
Gast #3734661
Lesenswert?

Okay ich bin noch einen Schritt weiter:
Das zweite "falsche" Byte ist immer das erste Byte*2. Das spricht dafür, 
dass irgendwie das Byte nach links geshiftet und nochmal gesendet wird.
Das spricht für mich irgendwie dafür, dass der Arduino das zweite Byte 
als Adresse interpretiert.
Die Adresse wird dann um 1 Bit nach links geshiftet und um 0 erweitert, 
sodass sich SLA+R (Slaveaddress und Read-Bit) ergibt.
Gast #3734691
Lesenswert?

in der Wire.cpp von Arduino hat die Funktion Wire.EndTransmission den 
parameter sendStop. Diesen kann man zwar übergeben, aber er wird 
nirgends verwendet :-S
Was ist denn das für ein Murks?
1
//
2
//  Originally, 'endTransmission' was an f(void) function.
3
//  It has been modified to take one parameter indicating
4
//  whether or not a STOP should be performed on the bus.
5
//  Calling endTransmission(false) allows a sketch to
6
//  perform a repeated start.
7
//
8
//  WARNING: Nothing in the library keeps track of whether
9
//  the bus tenure has been properly ended with a STOP. It
10
//  is very possible to leave the bus in a hung state if
11
//  no call to endTransmission(true) is made. Some I2C
12
//  devices will behave oddly if they do not see a STOP.
13
//
14
uint8_t TwoWire::endTransmission(uint8_t sendStop) {
15
  uint8_t error = 0;
16
  // transmit buffer (blocking)
17
  TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);
18
  if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT))
19
    error = 2;  // error, got NACK on address transmit
20
  
21
  if (error == 0) {
22
    uint16_t sent = 1;
23
    while (sent < txBufferLength) {
24
      TWI_WriteByte(twi, txBuffer[sent++]);
25
      if (!TWI_WaitByteSent(twi, XMIT_TIMEOUT))
26
        error = 3;  // error, got NACK during data transmmit
27
    }
28
  }
29
  
30
  if (error == 0) {
31
    TWI_Stop(twi);
32
    if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT))
33
      error = 4;  // error, finishing up
34
  }
35

36
  txBufferLength = 0;    // empty buffer
37
  status = MASTER_IDLE;
38
  return error;
39
}
Gast #3734725
Lesenswert?

Kenne mich mit I2C nur sehr flüchtig aus, hatte aber mal ein ähnliches 
Problem. Lag daran dass ich nicht bedacht hatte, dass beim ersten Byte 
das Bit 0 für R/W steht. Vielleicht hilft dir ja das irgendwie weiter... 
Vielleicht ist es auch totaler Müll was ich erzähle, aber ein versuch 
ist es wert hehe
Gast #3734744
Lesenswert?

TWI schrieb:
> Kenne mich mit I2C nur sehr flüchtig aus, hatte aber mal ein
> ähnliches
> Problem. Lag daran dass ich nicht bedacht hatte, dass beim ersten Byte
> das Bit 0 für R/W steht. Vielleicht hilft dir ja das irgendwie weiter...
> Vielleicht ist es auch totaler Müll was ich erzähle, aber ein versuch
> ist es wert hehe

Damit hast du schon recht, aber das sollte normalerweise nur bei der 
Übertragung der Adresse eine Rolle spielen.
Die anschließenden Datenbytes sind volle 8 Bit.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren