Go Down

Topic: I2C - Beeinflussung der Daten (Read 262 times) previous topic - next topic

hawo1997



Hallo an alle

Ich stelle mich gleich mal kurz vor:

Mein Name ist Hannes, ich bin 19 und habe dann auch endlich mal die Vorzüge des Arduino entdeckt. :D

Ich habe nun folgendes Problem (habe schon im Mikrocontroller.net Forum gefragt, da bekam ich bis jetzt aber noch nicht wirklich ne passende Antwort, habe den Text von dort Kopiert):

Probiere mich zur Zeit mit Arduino aus und muss für ein Projekt
Beschleunigungen messen. Dazu benutze ich 2 ADXL345 Breakout boards von
Adafruit. Die Kommunikation läuft über I2C. Einen einzelen Sensor
anzusteuern und auszulesen ist kein Problem, soweit habe ich das auch
hinbekommen. nun Versuche ich den zweiten Sensor mit in das System zu
integrieren. Dabei hat der eine Sensor die Adresse 0x53 und der Andere
die Adresse 0x1D (hängt von der Belegung von SDO ab).

Zuerst habe ich dabei versucht die Umsetzung mit der von Adafruit
mitgelieferten Bibliothek zu machen, jedoch verstehe ich dort das System
mit dem ansprechen über die Adressen nicht. Daher hab ich zum Test
einmal die Anleitung auf folgender Seite benutzt:

http://codeyoung.blogspot.de/2013/06/connecting-tw...

Code: [Select]

#include <Wire.h>

#define ACC_A (0x1D)
#define ACC_B (0x53)
#define READING (6)

byte buff[READING];
char str[512];

int regAddress = 0x32;      //first axis-acceleration-data register on the ADXL345
int xa = 0, ya = 0, za = 0; 
int xb = 0, yb = 0, zb = 0;

void setup() {
  // put your setup code here, to run once:

  Wire.begin();
  Serial.begin(9600);

  //Turn on devices
  writeTo(ACC_A, 0x2D, 24);
  writeTo(ACC_B, 0x2D, 24);

}

void writeTo(int device, byte address, byte val) {
   Wire.beginTransmission(device); //start transmission to device
   Wire.write(address);        // send register address
   Wire.write(val);        // send value to write
   Wire.endTransmission(); //end transmission
}

void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission
 
  Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device
 
  int i = 0;
  while(Wire.available())    //device may send less than requested (abnormal)
  {
    buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}

void loop()

  readFrom(ACC_A, regAddress, READING, buff); //read the acceleration data from the ADXL345 
   //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
   //thus we are converting both bytes in to one int
  xa = (((int)buff[1]) << 8) | buff[0];   
  ya = (((int)buff[3])<< 8) | buff[2];
  za = (((int)buff[5]) << 8) | buff[4];
 
  readFrom(ACC_B, regAddress, READING, buff); //read the acceleration data from the second ADXL345
  xb = (((int)buff[1]) << 8) | buff[0];   
  yb = (((int)buff[3])<< 8) | buff[2];
  zb = (((int)buff[5]) << 8) | buff[4];
 
  //we send the x y z values as a string to the serial port
  sprintf(str, "%d %d %d %d %d %d", xa, ya, za, xb, yb, zb);
  Serial.print(str);
  Serial.write(15);
 
  //It appears that delay is needed in order not to clog the port
  delay(150);
}



habe den Code dabei 1:1 übernommen, Übertragung ansich funktioniert auch
vom Sensor zum Arduino, die vom Arduino zum Computer auch plus Ausgabe
im Format "xa, ya, za, xb, yb, zb" wobei die a- Werte für den einen und
die b- Werte vom anderen Sensor sind. Soweit zum Stand.

Nun habe ich folgendes Problem:

Halte ich beide Sensoren gerade so sieht die Ausgabe ca. folgendermaßen
aus von den Werten her:

Diese Werte nach oben genanntem Muster bekomme ich wenn ich beide
Sensoren flach vor mich hin lege (Z- Achse zeigt nach oben, x und y
Achse sind waagrecht)
"1 1 251 1 2 255"

So sieht das Bild aus wenn ich den Sensor mit der Adresse 0x53 um 90
grad drehe (x Achse zeigt nach oben, y und z waagerecht)
"0 0 52 2 0 52"

So sieht das Bild aus wenn ich den Sensor mit der Adresse 0x1D um 90
grad drehe (x Achse zeigt nach oben, y und z waagerecht)
"195 0 508 195 0 509"

Ich habe die Sensoren wie auf der verlinkten Seite nach dem "Super"
Schaltplan angeschlossen. Jedoch scheint es so als ob die Sensoren sich
bei der Datenübertragung beeinflussen.

Hat vielleicht einer eine Idee was das Problem der Beeinflussung ist?

Mit freundlichen Grüßen

Hannes.

 :)

HotSystems

Hallo Hannes,

ich kenne die Module nicht, kann daher leider nichts dazu sagen, aber

Welchen Arduino verwendest du ?

Hast du evtl. für I2C Levelshifter eingesetzt ?

Hast du am I2C Pullup-Widerstände eingesetzt ?

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

hawo1997

Hallo ich benutze zur Zeit einen Uno R3 für das Projekt.

Pullups sind Dranne 5k jeweils auf SDA und SCK von VCC aus.

Wenn du mit Levelshifter jetzt einen Spannungswandler meinst dann nein habe die beiden Module an 3.3V laufen.


HotSystems

#3
Mar 19, 2017, 11:32 pm Last Edit: Mar 19, 2017, 11:33 pm by HotSystems
Wenn du mit Levelshifter jetzt einen Spannungswandler meinst dann nein habe die beiden Module an 3.3V laufen.
Dann lies dir mal das Datenblatt durch, die Sensoren I2C brauchen einen Levelshifter (Converter) für I2C, die arbeiten nicht mit 5Volt an I2C.

Steht hier etwas weiter unten.
I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

DrDiettrich

#4
Mar 20, 2017, 11:26 pm Last Edit: Mar 20, 2017, 11:30 pm by DrDiettrich
Vermutlich liefert der zweite Sensor keine Daten, und Du gibst den alten Pufferinhalt zweimal aus.

Lösche buf zwischendrin, dann müßten für xb usw. Nullen kommen.

Liefert Wire.requestFrom() nicht die Anzahl der gelesenen Bytes zurück?

Serenifly

#5
Mar 21, 2017, 12:05 am Last Edit: Mar 21, 2017, 12:08 am by Serenifly
readFrom() ist falsch implementiert.

beginTransmission() und endTransmission() sind nur für das Senden. Nicht für den Empfang. Nach dem Setzen der Start-Adresse von der gelesen werden soll (an der Stelle ist begin/end korrekt) kommt nur requestFrom() und danach x-mal read(). Mehr nicht

FlyingEagle

Also ich lese so erfolgreich von einem MCP23017 die Registerdaten aus.

Code: [Select]
uint8_t ic2_mcp_read (int adr, const uint8_t reg)
{
Wire.beginTransmission (adr);
Wire.write (reg);
Wire.endTransmission (true);
Wire.requestFrom (adr, 1, 1);
return Wire.read();
}


Das Abfragen ist hier aber gepollt. Der MCP schickt nichts selbständig, wenn man vonm IRQ absieht. Der triggert aber dann das manuelle Lesen erst.

Go Up