2017-05-11 2 views
2

J'ai trouvé quelques autres personnes à ce sujet, mais toutes codent dans Arduino, et j'ai du mal à le traduire dans mon projet.Données de magnétomètre sur MPU-9250 (uClinux)

Je fais partie d'une équipe de recherche développant un satellite Cube pour le lancement, et mon rôle est de communiquer avec les périphériques, y compris l'IMU (MPU-9250). Je suis la compilation croisée avec uClinux, codant en C.

Jusqu'à présent, je peux lire avec succès l'accéléromètre, le gyroscope et la température, mais je ne peux pas obtenir les lectures du magnétomètre. Le magnétomètre (AK8963) a sa propre adresse (0x0C), et je l'ai essayé de communiquer avec lui en écrivant à I2C_SLV0_ADDR (0x25), I2C_SLV0_REG (0x26), et I2C_SLV0_CTRL (0x27). Une fois que je ne semble pas pour obtenir des résultats, j'ai essayé de le résoudre en écrivant à FIFO Activer (0x23) et I2C Master Control (0x24)

La présente fiche technique et inscrire carte laisser entendre que les valeurs prises de le magnétomètre est stocké dans les registres Données du capteur externe (0x49-0x60), mais je n'obtiens rien dans ces registres lorsque j'essaie cela.

Voici un code qui montre les données que je vous écris pour les registres:

write_register(0x23, 0x04); 
write_register(0x24, 0b11110000); 
write_register(0x25,0x8c); 
write_register(0x26,0x00); 
write_register(0x27,0b11110001); 

Mes questions sont les suivantes: 1. Vais-je sur ce processus de la bonne façon, ou suis-je complètement?

  1. Si je suis sur la bonne voie, est-ce que je lis dans les bons registres?

Merci pour votre aide tout le monde! Faites-moi savoir s'il y a quelque chose que je dois clarifier!

+0

Eh bien, je ne connais pas l'appareil, mais je ne comprends pas comment lire un ensemble de registres ne peut rien obtenir? – ThingyWotsit

Répondre

2

Très bien! J'ai compris ma propre question :)

1) J'allais en effet dans le mauvais sens. Il y a un moyen beaucoup plus facile de faire cela et je vais montrer comment dans le détail.

2) Je ne lisais pas dans les registres corrects. Je vais montrer ce qu'il faut faire ci-dessous. Donc, la connexion au Magnétomètre est super facile, mais pas intuitive du tout. Il agit comme son propre esclave avec sa propre adresse d'esclave, mais cette adresse est inaccessible au départ.

Comme je suis en train de compiler avec uClinux, je peux utiliser la commande bash i2cdetect 0 (lors de la projection dans ma SmartFusion2) pour vérifier tous les esclaves sur mon bus i2C 0. Quand j'exécuter cette commande après la réinitialisation de mon conseil, je suis la carte d'adresse suivante imprimais:

 0 1 2 3 4 5 6 7 8 9 a b c d e f 
00:   -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

Vous pouvez donc voir que seule l'adresse de l'IMU (0x68) montre. Pour que le magnétomètre s'affiche correctement, vous devez activer un bit de bypass sur INT_PIN_CFG (0x37). J'ai joint mon code ci-dessous au cas où quelqu'un aurait besoin de le reproduire.

#include <stdio.h> 
//#include <linux/i2c-dev.h> 

#include <stdint.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <fcntl.h> 

#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 
#define IMU_ADDR 0x68 
#define IMU_WHO_AM_I 0x75 


int file; 

void i2c_init(); 
void write_register(uint8_t register_address, uint8_t value); 
uint8_t read_register(uint8_t register_address); 

void i2c_init(address){ 
    int adapter_nr = 0; 
    char filename[20]; 

    snprintf(filename, 19, "/dev/i2c-%d", adapter_nr); 
    file = open(filename, O_RDWR); 
    if(file < 0) 
     printf("Error: Failed to open file %s\n", filename); 
    int success= (ioctl(file, I2C_SLAVE, address)); 
    if(file < 0) { 
     printf("Error: IMU I2C Failed to Open\n"); 
     //return -1; 
    } 
} 
void write_register(uint8_t register_address, uint8_t value){ 
    uint8_t data[]={register_address,value}; 
    write(file, data,ARRAY_SIZE(data)); 
} 
uint8_t read_register(uint8_t register_address){ 
    uint8_t value; 
    if(write(file, &register_address, sizeof(register_address)) !=1) 
    { 
     printf("%d\n",write(file, &register_address, sizeof(register_address))); 
     printf("Failed to send data\n"); 
    } 
    read(file, &value, sizeof(value)); 
    return value; 
} 

int main(){ 
    i2c_init(IMU_ADDR); 

    printf("\nNow testing the 'Who am I?' IMU register. Output should be 0x71\n"); 
    printf("Register 0x75: 0x%02X \n", read_register(IMU_WHO_AM_I)); 

    write_register(0x37, 0x22); 
    i2c_init(0x0C); 
     printf("\nNow testing the 'Who am I?' Magnetometer register. Output should be 0x48\n"); 

    printf("Register 0x00: 0x%02x\n", read_register(0x00)); 

    return 0; 
} 

Une fois que le code est compilé et exécuté, la commande retourne i2cdetect 0 la Datamap suivante.Le programme renvoie également 0x48, la valeur correcte lors de la lecture à partir du «qui suis-je?» Du magnétomètre. registre. Le magnétomètre peut maintenant être lu comme n'importe quel autre registre. J'espère que cela t'aides!!