PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RP6 und Arduino: I2C funktioniert nicht



BattleBot
09.02.2014, 00:56
Hallo Liebe Roboter-Community,
ich arbeite an einer I2C-Kommunikation zwischen Arduino als Master und RP6-Base als Slave. Da dies für meine Ultraschall/Servo-Anwendung nicht funktioniert, habe ich zwei sehr einfache Programme für den Arduino und den RP6 geschrieben um mit dem Debuggen anzufangen.
Die vereinfachte Anwendung ist wie folgt:
1. Arduino generiert variable x
2. Arduino schreibt sie über I2C in einem RP6-Register
3. RP6 liest Register und kommuniziert diese Variable über USB zum PC-Display
4. Variable wird im Arduino inkrementiert und alles fängt von vorne wieder an.
Leider ist es so, dass den RP6 immer nur die initialisierte Variable wiedergibt (in diesem Fall = 0), so dass ich davon ausgehe, dass der Arduino entweder gar nichts oder an die falsche Stelle im RP6 schreibt. Es ist mir schon klar, dass ich nicht unbeding eine Serie {1, 2, 3, 4, 5, ...} auf dem PC-Dsiplay aufgrund der eingestellten Delays haben werde, aber wenn die Kommunikation funktionieren würde, würde sich die Variable x_arduino auf dem PC-Display zumdindest ändern!
Ich habe mal den Arduino-Sketch und den RP6-C-Code beigefügt. Wenn Ihr irgendeine Idee habt, weshalb das nicht funktioniert, dann wäre ich Euch sehr dankbar!!! (Als RP6-Adresse habe ich 10 verwendet und da Arduino mit dem 7-Bit-Format arbeitet, habe ich dort die Adresse 5 angegeben).

RP6-slave:
#include "RP6RobotBaseLib.h"
#include "RP6I2CslaveTWI.h" // I2C Library Datei einbinden (!!!)
// ACHTUNG: Das muss auch im Makefile eingetragen werden (!!!)


int main(void)
{
initRobotBase();
I2CTWI_initSlave(10); // TWI initialisieren und Adresse 10 einstellen
uint8_t x_arduino = 0;
powerON();
while(true)
{
// irgendein Kommando empfangen und KEIN Schreibzugriff aktiv?
if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy)
{
// Register speichern:
x_arduino = I2CTWI_writeRegisters[0];
mSleep(150);
}
writeString("x_arduino = ");
writeInteger(x_arduino, DEC);
writeChar('\n');
mSleep(150);}
return 0;
}

Arduino Master:
#include <Wire.h>


void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}


byte x = 0;


void loop()
{
Wire.beginTransmission(5); // transmit to device #5 in 7Bit-Format, #10 in 8Bit-Format
Wire.write(x); // sends one byte
Wire.endTransmission(); // stop transmitting


x++;
delay(50);
}

shedepe
09.02.2014, 03:28
Mhh, ich sehe z.B. erst mal nicht an welcher Stelle du dem master sagst, dass dein Slave die Adresse 10 hat.
Weiterhin solltest du dir noch mal anschauen nach welchem Prinzip der RP6 in seine I2C Buffer schreiben lässt, wenn man die Standardimplementierung verwendet. Das beachtest du an dieser Stelle nämlich meiner Ansicht nach nicht.

BattleBot
09.02.2014, 09:51
Hallo Shedepe,
1) an welcher Stelle du dem master sagst, dass dein Slave die Adresse 10 hat -> im Arduino-Sketch:"Wire.beginTransmission(5); ", da 10dec >>1 = 5dec
2) nach welchem Prinzip der RP6 in seine I2C Buffer schreiben lässt: was meinst Du damit? meine Meinung nach ist der I2C-Protokoll in den Arduino und RP6-Libs so implementiert worden, dass man keine "Protokoll"-Fehler machen kann.
Gruß
BattleBot

Dirk
09.02.2014, 10:09
Hi BattleBot,
vom Arduino-Sketch habe ich keine Ahnung. Sieht aber erstmal gut aus. Wenn delay(50) bedeutet, dass in 50ms Abstand gesendet wird, dann würde ich das mal auf delay(1000) einstellen.

1. Beim RP6-Slave must du NACH dem Register speichern (also nach: x_arduino = I2CTWI_writeRegisters[0]; ) noch Reg. 0 wieder löschen:
I2CTWI_writeRegisters[0] = 0;

2. Die Pausen (zweimal mSleep(150); ) müssen aus der Hauptschleife raus (Der Master bestimmt sowieso die Frequenz der Sendungen über den I2C-Bus).

3. Die Anzeige (writeString("x_arduino = ") usw.) muss in die if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy) Klammer mit rein.

BattleBot
15.02.2014, 18:07
Hallo Dirk,
vielen Dank für dein Feedback. Ich habe alles so geändert und verstehe auch warum das so sein muss.
Leider funktioniert es immer noch nicht. Wenn RP6 eine 8-Bit-I2C-Adresse benutzt, dann kann es auch nicht an der Adresse liegen.
Langsam vermute ich einen HW-Problem. Widerstand zwischen VDD und SDA bzw. SCL habe ich gemessen und ist 4,5k, also das passt. Wiring wurde mit Widerstandsmessung ebenso überprüft und passt. Kann es sein, dass die I2C-Pins vom RP6-Micro hin sind?
Gibt es noch andere Pins die man dafür ohne großen Aufwand verwenden kann?
Falls Du eine Idee hast, was ich da noch machen kann, würde ich mich freuen.
Viele Grüße
BattleBot

Dirk
15.02.2014, 20:53
Hi,

Kann es sein, dass die I2C-Pins vom RP6-Micro hin sind?
Am besten testen:
LED mit Vorwiderstand an SCL und SDA und mit einem kurzen Programm blinken lassen (... etwa wie hier ... (https://www.roboternetz.de/community/threads/33721-LEDs-an-XBUS-USRBUS))


Gibt es noch andere Pins die man dafür ohne großen Aufwand verwenden kann?
Nein, wenn man Hardware-I2C (also die I2C-Libs des RP6) nutzen will.


Falls Du eine Idee hast, was ich da noch machen kann, würde ich mich freuen.
Nicht wirklich. Hast du GND des RP6 und des Arduino auch verbunden?

BattleBot
16.02.2014, 15:41
Hallo,
die GNDs sind miteinander verbunden. Habe den oben genannten Test mit den LEDs jetzt durchgeführt und der µC vom RP6 kann die SDA und SCL anscheinend problemlos steuern.
Das Problem verstehe ich wirklich nicht. Werde mal im Arduino-Forum nachfragen, ob es vielleicht am Arduino-sketch liegt.
Danke für deine Unterstützung.
BattleBot

SlyD
16.02.2014, 16:35
Hallo,

das Senden läuft bei der RP6Lib immer so:
Bus Adresse
Register Adresse (0 = Kommandoregister, alle folgenden sind Daten/Parameter)
Daten

Du sendest aber nur
Bus Adresse
Daten


MfG,
SlyD