Forum: Mikrocontroller und Digitale Elektronik Probleme mit MPU6050 Lib. Am UART kommt nur Müll raus


von Mike (Gast)


Lesenswert?

Hi!

Folgendes Setup steht bei mir auf dem Schreibtisch:

- Arduino UNO mit ATMega328p
- AVR ISP mkii, programmiert wird in C mit AtmelStudio
- MPU6050 mit Breakout Board auf Steckbrett. GND an GND, VCC an die 3,3V 
vom Arduino, SCL an SCL, SCA an SCA.
- Stromversorgung über USB


Zur Software:
Ich möchte folgende Library benutzen:

http://davidegironi.blogspot.de/2013/02/avr-atmega-mpu6050-gyroscope-and.html

Diese entpacke ich. Dann neues Projekt in AtmelStudio erstellen. Den 
Inhalt der main.c aus der Lib kopieren ich in meine projektname.c, die 
ich mit AtmelStudio erstellt habe.

Dort ändere ich die Baudrate auf 9600:
1
 #define UART_BAUD_RATE 9600
Ausserdem wird noch die CPU Taktfrequenz definiert:
1
#define F_CPU 16000000UL

Mit einem Rechtsklick auf "Projektname" im Solution Explorer => Add => 
Existing Item füge ich die Dateien
1
i2cmaster.h
2
mpu6050.h
3
mpu6050.c
4
mpu6050dmp6.c
5
mpu6050registers.h
6
twimastertimeout.c
7
uart.c
8
uart.h
hinzu.

In der mpu6050.h muss ich dann noch die Zeile
1
#include MPU6050_I2CFLEURYPATH
in
1
#include "i2cmaster.h"
ändern.

Anschließend bekomme ich noch einen Fehler bei:
1
#include "mpu6050/mpu6050.h"
2
#include "uart/uart.h"
Was bewirkt diese Schreibweise? Hab das ehrlich gesagt noch nie gesehen.
Mein Workaround:
1
#include "mpu6050.h"
2
#include "uart.h"

Dann läuft das Programm. Wenn ich mir den Output aber mit HTerm anschaue 
(8Databits, 1Stopbit, Parity None, 9600Baud) kommt nur Müll an.

Das Meisste sind Quadrate (Wahrscheinlich nicht darstellbare Symbole).

Kann mir irgendeiner sagen, wo denn mein Fehler liegt? Wäre euch 
wirklich sehr dankbar!

Grüße!

von Mike (Gast)


Lesenswert?

Sorry für den Doppelpost, aber ich hab was vergessen:

Der häufige Fehler, dass mit den UART Einstellungen was nicht passt, 
kann man denke ich ausschließen. F_CPU und die Baudrate sind richtig 
definiert, den Rest macht die Lib von Peter Fleury zum Glück alleine.

Grüße!

von holger (Gast)


Lesenswert?

>Der häufige Fehler, dass mit den UART Einstellungen was nicht passt,
>kann man denke ich ausschließen. F_CPU und die Baudrate sind richtig
>definiert, den Rest macht die Lib von Peter Fleury zum Glück alleine.

Dummerweise reicht es aber nicht die im Quellcode zu definieren.
Die Fuses müssen auch dazu passen.

Ansonsten liegt der Fehler wohl in einem Codeteil den keiner
sehen kann.

von Mike (Gast)


Lesenswert?

Hi!

holger schrieb:
> Dummerweise reicht es aber nicht die im Quellcode zu definieren.
> Die Fuses müssen auch dazu passen.

Daran sollte es eigentlich nicht liegen. Ich habe Heute morgen das 
Beispiel der Fleury Lib ausprobiert. Dies hat problemlos funktioniert. 
Seitdem hab ich die Fuses nicht mehr angepackt.

Fuses:
BODLEVEL = 2V7
RSTDISBL = [ ]
DWEN = [ ]
SPIEN = [X]
WDTON = [ ]
EESAVE = [ ]
BOOTSZ = 256W_3F00
BOOTRST = [X]
CKDIV8 = [ ]
CKOUT = [ ]
SUT_CKSEL = EXTFSXTAL_16KCK_14CK_65MS

EXTENDED = 0xFD (valid)
HIGH = 0xDE (valid)
LOW = 0xF7 (valid)

Sollte doch soweit passen?
Evtl. kann ja jemand das oben beschriebene Verfahren nachvollziehen...

Grüße!

von Mike (Gast)


Lesenswert?

Hi!

hab jetzt das Problem mit dem UART selber lösen können. Woran es lag, 
weiss ich ehrlich gesagt nicht, aber die Funktionen, die in der main() 
die Daten ausgeben sollten, haben nicht funktioniert.

Ich habe nun selber etwas Code:
1
#define F_CPU 16000000UL
2
#define UART_BAUD_RATE 9600
3
4
#include <stdlib.h>
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
#include <avr/pgmspace.h>
8
#include <util/delay.h>
9
#include <math.h>
10
#include "mpu6050.h"
11
#include "uart.h"
12
13
int main(void)
14
{
15
  int16_t ax = 0;
16
  int16_t ay = 0;
17
  int16_t az = 0;
18
  int16_t gx = 0;
19
  int16_t gy = 0;
20
  int16_t gz = 0;
21
  
22
  char buffer[10];
23
  
24
  //init uart
25
  uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
26
27
  //init interrupt
28
  sei();
29
  
30
  //Testen ob alle Einstellungen des UART korrekt sind
31
  uart_puts("UART Läuft!\n");
32
33
  //init mpu6050
34
  mpu6050_init();
35
  
36
  while(1)
37
  {
38
    mpu6050_getRawData(&ax, &ay, &az, &gx, &gy, &gz);
39
40
    itoa(ax, buffer, 10);
41
    uart_puts("AccelX: "); uart_puts(buffer); uart_puts("  ");
42
    
43
    itoa(ay, buffer, 10);
44
    uart_puts("AccelY: "); uart_puts(buffer); uart_puts("  ");
45
    
46
    itoa(az, buffer, 10);
47
    uart_puts("AccelZ: "); uart_puts(buffer); uart_puts("\n");
48
    _delay_ms(500);
49
  }
50
}

zusammengeschrieben. Dieser verwendet weiterhin die Routinen der 
Library:

Die mpu6050_getRawData() sieht so aus:
1
void mpu6050_getRawData(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz) {
2
  mpu6050_readBytes(MPU6050_RA_ACCEL_XOUT_H, 14, (uint8_t *)buffer);
3
4
    *ax = (((int16_t)buffer[0]) << 8) | buffer[1];
5
    *ay = (((int16_t)buffer[2]) << 8) | buffer[3];
6
    *az = (((int16_t)buffer[4]) << 8) | buffer[5];
7
    *gx = (((int16_t)buffer[8]) << 8) | buffer[9];
8
    *gy = (((int16_t)buffer[10]) << 8) | buffer[11];
9
    *gz = (((int16_t)buffer[12]) << 8) | buffer[13];
10
}

Die mpu6050_readBytes() sieht so aus:
1
int8_t mpu6050_readBytes(uint8_t regAddr, uint8_t length, uint8_t *data) {
2
  uint8_t i = 0;
3
  int8_t count = 0;
4
  if(length > 0) {
5
    //request register
6
    i2c_start(MPU6050_ADDR | I2C_WRITE);
7
    i2c_write(regAddr);
8
    _delay_us(10);
9
    //read data
10
    i2c_start(MPU6050_ADDR | I2C_READ);
11
    for(i=0; i<length; i++) {
12
      count++;
13
      if(i==length-1)
14
        data[i] = i2c_readNak();
15
      else
16
        data[i] = i2c_readAck();
17
    }
18
    i2c_stop();
19
  }
20
  return count;
21
}
Die letzten beiden Codeschnipsel sind von 
http://davidegironi.blogspot.de/2013/02/avr-atmega-mpu6050-gyroscope-and.html, 
danke dafür!


Problem ist nun folgendes:
Nach ungefähr 21 Ausgabezeilen, die korrekt ausgegeben werden, gibt der 
UART nur noch -1 für die Werte aus.

Output in HTerm sieht so aus:
1
UART L?uft!<\n>
2
AccelX: -1214  AccelY: -930  AccelZ: 15758<\n>
3
AccelX: -1166  AccelY: -964  AccelZ: 15710<\n>
4
[17 Zeilen ausgelassen...]
5
AccelX: -1224  AccelY: -954  AccelZ: 15738<\n>
6
AccelX: -1172  AccelY: -982  AccelZ: 15724<\n>
7
AccelX: -1  AccelY: -1  AccelZ: -1<\n>
8
AccelX: -1  AccelY: -1  AccelZ: -1<\n>
9
[...]

Ein Problem mit dem UART kann ich dabei ausschließen, denn wenn ich in 
der main() eine Variable hochzählen lasse, und diese in ax, ay und az 
schreibe und das anschließend wie gewohnt ausgeben lasse, sind auch 200 
und mehr ausgegebene Zeilen kein Problem.

Ich bin mal wieder ratlos. Irgendjemand eine Idee, an was das liegen 
könnte?

Grüße - Ich hoffe ich darf den teilweisen Inhalt der Lib hier so 
reinkopieren, Quellenangabe ist ja dabei...

von Mike (Gast)


Lesenswert?

Hi!

Hab nochmal ein wenig rumprobiert, dabei ist mir folgendes aufgefallen:
Obs funktioniert ist von der Zeit des Delays abhängig. Bei 500ms zickt 
das Teil rum.
Gerade läufts mit 100ms Delay, da funktioniert alles bestens.
Bei 50ms Delay gibts nach wenigen Zeilen nur noch -1 als 
Beschleunigungswert, ebenso bei 80ms und 150ms.

Warum bekomme ich nur bei 100ms Delay reproduzierbare Werte heraus?

Mir erscheint das ganze mehr als komisch. Hat irgendjemand noch eine 
Idee, an was das liegen könnte? Ich bin mit meinem Latein am Ende.

Grüße!

von Mike (Gast)


Lesenswert?

Hi!

Hat keiner von euch eine Idee? Braucht ihr mehr Infos?

Fürchte ich kann das Problem leider nicht alleine lösen :-(

Grüße!

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.