Forum: Mikrocontroller und Digitale Elektronik BMA020 mit GNUBLIN dip


von IbuzaP (Gast)


Lesenswert?

Hallo,

ich versuche die Achsendaten die der BMA020 liefert unter gunblin 
auszulesen. Laut Datenblatt muss ich dafür erst ein Offset (0x02) auf 
0x70 schreiben und dann 0x71 auslesen, was mir die 6 Byte zurückgeben 
soll, die die Werte repräsentieren.

Hier mal mein Code:
1
#include <stdio.h>
2
#include <fcntl.h>
3
#include <unistd.h>
4
#include <sys/ioctl.h>
5
#include <linux/i2c-dev.h>
6
7
#define acc_10Bit(LSB, MSB)     ((int8_t)MSB << 2 | LSB >> 6)
8
9
int main(int argc, char **argv)
10
{
11
        int r;
12
        int fd;
13
14
        char buf[10] = {0};
15
        char data[6] = {0};
16
17
        char *dev = "/dev/i2c-1";
18
        int addr = 0x38;
19
20
        printf("BMA020 Test\n");
21
22
        fd = open(dev, O_RDWR);
23
        if (fd < 0)
24
        {
25
                perror("Opening i2c device node\n");
26
                return 1;
27
        }
28
29
        r = ioctl(fd, I2C_SLAVE, addr);
30
31
        if(r < 0)
32
        {
33
                perror("Selecting i2c device\n");
34
        }
35
36
37
        /**
38
         * Offset auf i2c schreiben um BMA020 zum auslesen
39
         * vorzubereiten
40
         * Data: 0x02, Addresse: 0x70
41
         */
42
43
        __u8 acc_w = 0x70;
44
45
        buf[0] = acc_w;
46
        buf[1] = 0x02;
47
48
        if (write(fd, buf, 2) != 2)
49
        {
50
                perror("Write error i2c\n");
51
        }
52
        else
53
        {
54
                printf("Write successful\n");
55
        }
56
57
        sleep(1.1);
58
59
        /**
60
         * daten von i2c lesen
61
         * 6 Byte lesen
62
         */
63
64
        read(fd, data, 6);
65
66
        printf("%x\n", data[0]);
67
        printf("%x\n", data[1]);
68
        printf("%x\n", data[2]);
69
        printf("%x\n", data[3]);
70
        printf("%x\n", data[4]);
71
        printf("%x\n", data[5]);
72
73
        printf("\n");
74
        return 0;
75
76
}

Vorausgesetzt der Write-Code ist soweit richtig (kein logischer Fehler 
also) funktioniert der einwandfrei. Lediglich das auslesen gibt mir nur 
"ff"s zurück.

Hier mal noch die Ausgabe des Programms:
1
root@gnublin:~/messung# ./mess
2
BMA020 Test
3
Write successful
4
ff
5
ff
6
ff
7
ff
8
ff
9
ff

und hier noch die Ausgabe von i2cdump:
1
root@gnublin:~/messung# i2cdump -y 1 0x38
2
No size specified (using byte-data access)
3
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
4
00: 02 12 c1 03 41 00 c1 c0 15 00 00 00 48 4e 30 4b    ????A.???...HN0K
5
10: 4d 07 39 63 80 80 ff ff ff ff ff ff ff ff ff ff    M?9c??..........
6
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
7
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
8
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
9
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
10
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
11
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
12
80: 02 12 c1 03 01 00 81 c0 15 00 00 00 48 4e 30 4b    ?????.???...HN0K
13
90: 4d 07 39 63 80 80 ff ff ff ff ff ff ff ff ff ff    M?9c??..........
14
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
15
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
16
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
17
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
18
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
19
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

Im Moment seh ich leider vor lauter Wald den Baum nicht mehr.
Danke schonmal für eure Hilfe!

von IbuzaP (Gast)


Lesenswert?

Das Problem hat sich erledigt:
gnublin bietet eine API für C++, die das soweit ganz gut übernimmt.

Zum testen hab ich mir ein kleines Programm geschrieben, dass die Werte 
aus dem BMA020 ausliest, sie in 10 Bit Format bringt und dazu noch die 
Änderungen der Werte im Vergleich zur vorherigen Messung ausgibt. Der 
Absolutwert dient lediglich zum testen.

Für Interessierte hier nochmal der Code mit Einsatz der API:
1
#define BOARD GNUBLIN
2
#define acc_10Bit(LSB, MSB)     ((int8_t)MSB << 2 | LSB >> 6)
3
#include "gnublin.h"
4
5
int main()
6
{
7
        gnublin_i2c i2c;
8
9
        int x2 = 0;
10
        int y2 = 0;
11
        int z2 = 0;
12
13
        int x1 = 0;
14
        int y1 = 0;
15
        int z1 = 0;
16
17
        //Aenderungswerte
18
        int dx = 0;
19
        int dy = 0;
20
        int dz = 0;
21
22
        //Absolutwert
23
        int absolut = 0;
24
        int i = 0;
25
26
        //Zu schreibende Daten
27
        unsigned char buffer[8];
28
29
        //Zu empfengende Daten
30
        unsigned char rxBuf1[8];
31
        unsigned char rxBuf2[8];
32
33
        //Adresse des BMA020 am I2C Bus
34
        i2c.setAddress(0x38);
35
36
        buffer[0] = 0x02;
37
38
        printf("Sende 0x02 an 0x70\n");
39
        i2c.send(0x70, buffer, 1);
40
        printf("Gesendet\n");
41
42
        printf("Dauerschleife Datenabfrage und Berechnung\n");
43
44
        while(1)
45
        {
46
                usleep(1000);
47
48
         if( i%2 == 0)
49
         {
50
                i2c.receive(0x02, rxBuf1, 6);
51
                x1 = acc_10Bit(rxBuf1[0], rxBuf1[1]) * 100;
52
                y1 = acc_10Bit(rxBuf1[2], rxBuf1[3]) * 100;
53
                z1 = acc_10Bit(rxBuf1[4], rxBuf1[5]) * 100;
54
55
                dx = x2 - x1;
56
                dy = y2 - y1;
57
                dz = z2 - z1;
58
59
                absolut = x1 + y1 + z1;
60
61
                printf("X: \t%d,\t Y: \t%d,\t Z: \t%d\n", x1, y1, z1);
62
                //Absolutwert ausgeben
63
                printf("Abs: \t%d\n", absolut);
64
65
66
         }
67
         else
68
         {
69
                //Daten auslesen
70
                i2c.receive(0x02, rxBuf2, 6);
71
72
                //10 Bit Werte erstellen
73
                x2 = acc_10Bit(rxBuf2[0], rxBuf2[1]) * 100;
74
                y2 = acc_10Bit(rxBuf2[2], rxBuf2[3]) * 100;
75
                z2 = acc_10Bit(rxBuf2[4], rxBuf2[5]) * 100;
76
77
                //Aenderungen berechnen
78
                dx = x1 - x2;
79
                dy = y1 - y2;
80
                dz = z1 - z2;
81
82
                //Absolutwer berechnen
83
                absolut = x2 + y2 + z2;
84
85
                //10 Bit Werte ausgeben
86
                printf("X: \t%d,\t Y: \t%d,\t Z: \t%d\n", x2, y2, z2);
87
88
                //Absolutwert ausgeben
89
                printf("Abs: \t%d\n", absolut);
90
         }
91
92
                dx = x1 - x2;
93
                dy = y1 - y2;
94
                dz = z1 - z2;
95
96
                printf("DX: \t%d,\t DY: \t%d,\t  DZ: \t%d\n\n", dx, dy, dz);
97
                i++;
98
        }
99
}

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.