Forum: Mikrocontroller und Digitale Elektronik I2C Beschleunigungssensor ADXL375


von Thomas M. (pomestomi)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich bin grade dabei den ADXL375 Beschleunigungssensor mit einem 
ATMega328PU über I2C auszulesen.

Dazu hab ich mir die Dateien von Peter Fleurys Projekt I2CMaster in mein 
Atmel Solution eingebunden. Wenn ich die Verbindung mittels 
i2c_start(DEV, I2C_Write) teste, kommt eine 0 zurück, was bedeutet, dass 
die Verbindung zwischen µC und Sensor funktioniert.
Ich Debugge den Aufbau Mittels MAX232 und HTerm am PC, damit ich weis, 
was los ist.

Jetzt versuche ich das Register 0x00 des ADXL375 zu lesen, was mir aber 
nicht gelingt. Ich sollte hierbei den ID Code 0xE5 zurückbekommen, HTerm 
zeigt aber 8 bytes an ( siehe Anhang ), die keinen Sinn ergeben.

Der kurze Programmcode ist auch als Screenshot dabei. Mit integriert ist 
natürlich die RS232 und I2C initialisation.

Eine Idee von mir wäre, dass ich eventuell Datentypen miteinander 
vertausch, wie es nicht sein sollte? Wisst ihr eine Lösung?

Mit freundlichen Grüßen
Thomas

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>Den Fall hast du aber nicht. Du willst lediglich vom Baustein lesen.
>Aber auch dazu musst du die Adresse von der du lesen willst an den
>Baustein geben.
>
>d.h. der Ablauf ist
>
>  i2c_start( DEV_375 + I2C_READ );
>  i2c_write( 0x00 );    // von Adresse 0 lesen
>  data = i2c_readNAK();
>  i2c_stop();

Tut mir leid Karl Heinz, aber das ist falsch und das Programm
im Bild sieht besser aus;)

von holger (Gast)


Lesenswert?

>Eine Idee von mir wäre, dass ich eventuell Datentypen miteinander
>vertausch, wie es nicht sein sollte? Wisst ihr eine Lösung?

println() erwartet sicher einen String, du gibst aber nur ein char.
Deshalb kommt der Müll da vermutlich raus.

von Thomas M. (pomestomi)


Lesenswert?

Hallo holger,

das dacht ich mir schon fast. Es ist in der Tat so, dass ein String 
erwartet wird. Ich denk mal die Suchfunktion wird was passendes finden, 
wie ich Char in String konvertier. Ich probiers morgen mal aus und 
schau, was passiert. :)

Mit freundlichen Grüßen,
Thomas

von Thomas M. (pomestomi)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich brauch wohl doch nochmal Hilfe. Der Funktion zum Senden von Daten 
über den UART ist genau die aus diesem Forum (siehe Bild). Der char, den 
ich senden will, hat den Wert 0xE5. Dies entspricht meines Wissens nach 
einfach der Binärzahl 0b11100101. Wie kann ich jetzt nur E5 oder eben 
die Binärzahl über UART senden?

Mit freundlichen Grüßen,
Thomas

von Felix P. (fixxl)


Lesenswert?

Wenn du den gelesenen unsigned char über die UART binär ausgeben willst, 
kannst du so etwas versuchen. Das Array sollte mindestens 11 Bytes lang 
sein ('0', 'b', 8 Stellen für Bits, abschließende 0).
1
void char2binarray(uint8_t dat, char* array) {
2
  array[0] = '0';
3
  array[1] = 'b';
4
5
  for(uint8_t i=2; i<10; i++) {
6
    array[i] = (dat&0x80)?'1':'0';
7
    dat <<= 1;
8
  }
9
  array[10] = '\0';
10
}

Die Funktion rufst du direkt nach dem Einlesen mit
char2binarray(data, array) auf und danach kannst du dir die Daten via 
println(array) über UART ausgeben lassen.

Nachtrag: char als Variablenname zu verwenden, ist keine gute Idee ;-)

Nächster Nachtrag: Für Hex-Darstellung geht es so:
1
char nibble2hex(uint8_t zahl) {
2
  zahl &= 0x0F;
3
  if (zahl > 9) {
4
    return zahl - 10 + 'A';
5
  } else {
6
    return zahl + '0';
7
  }
8
}
9
10
void char2hexarray(uint8_t dat, char* array) {
11
  array[0] = '0';
12
  array[1] = 'x';
13
  array[2] = nibble2hex(dat >> 4);
14
  array[3] = nibble2hex(dat & 0x0F);
15
  array[4] = '\0';
16
}

Im Hauptprogramm char2hexarray(data, array) aufrufen und dann per 
println(array) ausgeben.

: Bearbeitet durch User
von Thomas M. (pomestomi)


Lesenswert?

Hallo Felix,

so wie ich das verstehe, soll die Funktion ein Array mit den Werten vom 
Char füllen. Das passiert mit der Zeile

array[i] = (char&0x80)?'1':'0'

wo entweder eine 1 oder eine 0 ins Array geschrieben wird. Aber was 
bedeutet die Und-Verknüpfung von char und 0x80? Bei der Definition 
uint8_t char meckert der Compiler logischerweise, weil ja zwei 
Datentypen definiert werden. Der Ansatz ist gut, ich versteh ihn nur 
noch nicht ganz.

Mit freundlichen Grüßen,
Thomas

von Karl H. (kbuchegg)


Lesenswert?

Thomas Maier schrieb:
> Hallo Felix,
>
> so wie ich das verstehe, soll die Funktion ein Array mit den Werten vom
> Char füllen. Das passiert mit der Zeile
>
> array[i] = (char&0x80)?'1':'0'
>
> wo entweder eine 1 oder eine 0 ins Array geschrieben wird. Aber was
> bedeutet die Und-Verknüpfung von char und 0x80?

Er will an dieser Stelle wissen, ob das Bit 7 in 'char' gesetzt ist oder 
nicht.
Je nachdem weißt er dann ins Array das Zeichen '1' oder das Zeichen '0' 
zu.

> Bei der Definition
> uint8_t char meckert der Compiler logischerweise, weil ja zwei
> Datentypen definiert werden. Der Ansatz ist gut, ich versteh ihn nur
> noch nicht ganz

Gehen wir von innen nach aussen.
Der Kern lässt sich auch so schreiben
1
    if( dat & 0x80 )
2
      array[i] = '1';
3
    else
4
      array[i] = '0';
( das ist nichts anderes als die Langform zu der kürzeren Variante
   array[i] = ( dat & 0x80 ) ? '1' : '0';
)

wenn also Bit 7 in value auf 1 ist, dann soll im Array an der i-ten 
Stelle das zeichen '1' eingetragen werden. Wenn nicht (dann muss das Bit 
0 sein) dann eben das Zeichen '0'.

Aber eigentlich will man ja nicht das 7-Bit, sondern nacheinander die 
Bits 7, 6, 5, 4, ... entsprechend auswerten. Wie macht man das dann?
Nun, man kann immer noch immer das 7.Bit betrachetn, wenn man dazu 
einfach nur im Gegenzug die Bits um jeweils 1 Stelle nach links 
verschiebt.
1
     dat <<= 1;
macht genau das.

Das ganze macht man 8 mal . und schon hab wir die nächste Zutat auf dem 
Weg von innen nach aussen: Eine Schleife die 8 mal durchlaufen wird. Da 
es sowieso noch eine Steuerung braucht, die dafür sorgt, dass das i in 
array[i] hochzählt, bietet es sich an, da gleich eine for-Schleife dafür 
zu benutzen.
1
  for(uint8_t i=2; i<10; i++) {
2
    array[i] = (dat&0x80)?'1':'0';
3
    dat <<= 1;
4
  }

von 2 bis 10 deshalb, weil vor den Bits ja nach der Textbestandteil "0b" 
auftauchen soll. Das sind nun mal 2 Zeichen.

von Thomas M. (pomestomi)


Lesenswert?

Hallo Leute,

> Nachtrag: char als Variablenname zu verwenden, ist keine gute Idee ;-)

Dieser Nachtrag hat den Groschen fallen lassen :). Vielen Dank dafür!
Und auch vielen Dank an Karl Heinz für den C-Crashkurs. Es läuft alles 
und ich habs kapiert!

Mit freundlichen Grüßen,
Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.