Das erste Wire.endTransmission(); trennt den vorangehenden i2c-write Befehl (um den Slave und seine Register zu adressieren und das Lesen vorzubereiten) von dem darauffolgenden i2c-read.
Hier auf Fehler zu testen, ist tatsächlich sinnvoll, wenn Verbindungsprobleme bestehen sollten. Dann kann man die Schleife vorzeitig verlassen (Fehlermeldung an Serial.print()!).
per Wire() zu versuchen, eine bestimmte Anzahl Bytes zu lesen ohne dass sie im Puffer zur Verfügung stehen gibt tatsächlich aber meistens Mist - das wegzulassen ist die schlechteste aller Lösungen: es sollte so stehen bleiben.
Ein Timeout in die while Schleife einzubauen, ist nicht verkehrt, ist aber bei Arduino Wire() üblicherweise nicht nötig, alle Arduino Beispiel Codes verzichten darauf: wenn 4 Bytes angefordert werden, dann ist damit zu rechnen, dass sie auch umgehend kommen (wenn das vorrangehende endTransmission fehlerfrei war) , es führt nur leider oft zu Fehlern wenn man zu früh anfängt mit dem Wire.read (also wenn, wie gesagt, der Puffer ausgelesen wird, er aber noch nicht mit den erforderlichen Bytes gefüllt ist).
Bei zickigen Master-Slave-Kombinationen (z.B. anderen MCU devices, die bitbang-i2c verwenden oder vlt auch übermäßiges clock-stretching) kann das zugegebenermaßen vielleicht sinnvoll sein. Das betrifft dann aber meist andere Master, nicht Arduino-Master (z.B. Raspis oder Lego EV3 als Master ), der Arduino ist da geduldig und der cmps10/11 als Slave gehört auch nicht zu den Zicken (hab ich selber, läuft bei 100-400kHz und 1m Kabel dazwischen ohne Probleme, und zwar sowohl am Arduino als auch am Raspi.)
http://www.mindstormsforum.de/viewto...tart=60#p69275
Wer mag, kann ja die beiden Codes mal gegenseitig vergleichen.
Ein delay ist in der while Schleife ebenfalls nicht nötig, Arduino-Standard-Beispiele fügen hier nie delays ein (ich wäre nicht überrascht, wenn die in der Funktion Wire.available() sowie so schon enthalten wären), daher kann man nach while() direkt die Nullanweisung ";" hinschreiben ohne irgendeinen {code} / Body/Körper.
Sprich, so wie der Code oben steht, ist es das Arduino-Standardverfahren, hier wäre der letzte Ort, wo ich dran herum spielen würde zur Fehlersuche.
ps,
Sinnvoll ist es aber immer, in den Code Serial.println() einzufügen, wobei dann verschiedenste Variablenwerte schrittweise zur Kontrolle ausgegeben werden. In diesem Fall sollte man mal das Heading zur Kontrolle anzeigen lassen, und natürlich auch den ganzen Rest zu Debug-Zwecken.
edit,
ggf bei Fehlern im i2c-auslesen: sind die verwendeten Pullups richtig?
welcher Arduino wird verwendet (manche haben ausreichende Pullups bereits intern verbaut, manche nicht) und ggf welche externen Pullups wurden gesteckt?
Lesezeichen