2017-03-15 7 views
0

J'utilise des capteurs gyroscopiques/accélérométriques (https://www.sparkfun.com/products/13284) avec un Arduino pour enregistrer la rotation. J'utilise un total de huit de ces capteurs. J'utilise également un multiplexeur pour aider avec les multiples capteurs (https://learn.adafruit.com/adafruit-tca9548a-1-to-8-i2c-multiplexer-breakout/overview). Après que mon Arduino reçoive les données, je l'utilise dans le traitement pour créer une image en deux dimensions de tous les capteurs rotatifs.L'esquisse de traitement à l'aide des données d'Arduino est en retard

Je suis actuellement confronté à un problème avec un retard significatif (l'animation de la rotation s'arrête, puis redémarre plusieurs fois). J'utilise Processing pour l'interface visuelle et la communication série pour envoyer des données de l'Arduino (avec des capteurs attachés) à l'ordinateur qui exécute Processing. À l'heure actuelle, mon code lit le capteur, puis envoie une valeur avec un préfixe de lettre à analyser plus tard par le code de traitement. Par exemple, s'il lit la "valeur x1 du capteur", il envoie "S" suivi de la valeur x1 associée. Du côté du traitement, il vérifie d'abord si le "S" est présent, et si c'est le cas, lit la valeur suivante dans la variable appropriée pour l'affichage de mon animation.

Joint le code Arduino (fichier .ino) et l'esquisse de traitement (fichier .pde). Afin d'accélérer le traitement des données, j'ai essayé de lire un quart des données pour chaque image d'animation. Ainsi, dans la méthode "serialEvent", qui s'exécute chaque fois que des données sont envoyées depuis l'Arduino, il y a des conditions comme "if (frameCount% 4 == 0) {read first quarter of data}", "if (frameCount% 4 == 1) {lisez le deuxième quart des données} "etc. Cela n'a pas fonctionné non plus, mais vous le verrez dans le code ci-dessous.

Tout est utile!

ARDUINO CODE:

#include<Wire.h> 
#include "Wire.h" 
#define TCAADDR 0x70 
extern "C" { 
    #include "utility/twi.h" // from Wire library, so we can do bus scanning 

    #include <LSM9DS1_Registers.h> 
    #include <LSM9DS1_Types.h> 
    #include <SparkFunLSM9DS1.h> 
    #include <SPI.h> 
    LSM9DS1 imu; 
    #define LSM9DS1_AG 0x6B // Would be 0x6A if SDO_AG is LOW 
    #define PRINT_CALCULATED 
} 

const int MPU_addr = 104; // I2C address of the MPU-6050 
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ; 

void tcaselect(uint8_t i) { 
    if (i > 7) return; 

    Wire.beginTransmission(TCAADDR); 
    Wire.write(1 << i); 
    Wire.endTransmission(); 
} 

void setup() { 
    Serial.begin(9600); 
    Wire.begin(); 

    tcaselect(0); 
    setter(); 

    tcaselect(1); 
    setter(); 

    tcaselect(2); 
    setter(); 

    tcaselect(3); 
    setter(); 

    tcaselect(4); 
    setter(); 

    tcaselect(5); 
    setter(); 

    tcaselect(6); 
    setter(); 

    tcaselect(7); 
    setter(); 

    Serial.println("done"); 

} 
void loop() { 

    tcaselect(0); 
    looperZero(); 

    tcaselect(1); 
    looperOne(); 

    tcaselect(2); 
    looperTwo(); 

    tcaselect(3); 
    looperThree(); 

    tcaselect(4); 
    looperFour(); 

    tcaselect(5); 
    looperFive(); 

    tcaselect(6); 
    looperSix(); 

    tcaselect(7); 
    looperSeven(); 

} 

void setter() { 
    Serial.begin(9600); 
    imu.settings.device.commInterface = IMU_MODE_I2C; 
    imu.settings.device.agAddress = LSM9DS1_AG; 
    imu.begin(); 
} 



void looperZero() { 
    imu.readAccel(); 

    Serial.print("A"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 
    Serial.print("B"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("C"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 

// 
// imu.readGyro(); // Update gyroscope data 
// Serial.print("a"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("b"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("c"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 

} 

void looperOne() { 
    imu.readAccel(); 

    Serial.print("D"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("E"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("F"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 


// 
// imu.readGyro(); // Update gyroscope data 
// Serial.print("d"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("e"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("f"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 
} 

void looperTwo() { 
    imu.readAccel(); 

    Serial.print("G"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("H"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("I"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 


// imu.readGyro(); // Update gyroscope data 
// Serial.print("g"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("h"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("i"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 
// 
} 

void looperThree() { 
    imu.readAccel(); 

    Serial.print("J"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("K"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("L"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 


// imu.readGyro(); // Update gyroscope data 
// Serial.print("j"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("k"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("l"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 
// 
} 

void looperFour() { 
    imu.readAccel(); 

    Serial.print("M"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("N"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("O"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 

// 
// imu.readGyro(); // Update gyroscope data 
// Serial.print("m"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("n"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("o"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 

} 

void looperFive() { 
    imu.readAccel(); 

    Serial.print("P"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("Q"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("R"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 

// 
// imu.readGyro(); // Update gyroscope data 
// Serial.print("p"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("q"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("r"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 

} 

void looperSix() { 
    imu.readAccel(); 

    Serial.print("S"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("T"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("U"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 

// 
// imu.readGyro(); // Update gyroscope data 
// Serial.print("s"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("t"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("u"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 

} 

void looperSeven() { 
    imu.readAccel(); 

    Serial.print("V"); 
    Serial.println(imu.calcAccel(imu.ax), 2); 
    //delay(10); 

    Serial.print("W"); 
    Serial.println(imu.calcAccel(imu.ay), 2); 
    //delay(10); 

    Serial.print("X"); 
    Serial.println(imu.calcAccel(imu.az), 2); 
    //delay(10); 

// 
// imu.readGyro(); // Update gyroscope data 
// Serial.print("v"); 
// Serial.println(imu.calcGyro(imu.gx)); // Print x-axis rotation in DPS 
// Serial.print("w"); 
// Serial.println(imu.calcGyro(imu.gy)); // Print y-axis rotation in DPS 
// Serial.print("x"); 
// Serial.println(imu.calcGyro(imu.gz)); // Print z-axis rotation in DPS 
    delay(50); 
} 

Code de traitement serialEvent:

void serialEvent(Serial port) { 
    String inData = port.readStringUntil('\n'); 
    inData = trim(inData);     // cut off white space (carriage return) 
    //println(inData); 
    if (frameCount % 4 == 0) { 

    if (inData.charAt(0) == 'S') {  //S 
     inData = inData.substring(1);  
     rightHipX1 = float(inData); 
    } 
    if (inData.charAt(0) == 'T') {  //T 
     inData = inData.substring(1);  
     rightHipY1 = float(inData); 
    } 
    if (inData.charAt(0) == 'U') {  
     inData = inData.substring(1); //U 
     rightHipZ1 = float(inData); 
    } 
    if (inData.charAt(0) == 'V') {  //V 
     inData = inData.substring(1);  
     rightHipX2 = float(inData); 
    } 
    if (inData.charAt(0) == 'W') {  //W 
     inData = inData.substring(1);  
     rightHipY2 = float(inData); 
    } 
    if (inData.charAt(0) == 'X') {  //X 
     inData = inData.substring(1);  
     rightHipZ2 = float(inData); 
    } 
    } 
    if (frameCount % 4 == 1) 
    { 
    if (inData.charAt(0) == 'M') {  
     inData = inData.substring(1);  
     rightLegX1 = float(inData); 
    } 
    if (inData.charAt(0) == 'N') {  
     inData = inData.substring(1);  
     rightLegY1 = float(inData); 
    } 
    if (inData.charAt(0) == 'O') {  
     inData = inData.substring(1); 
     rightLegZ1 = float(inData); 
    } 
    if (inData.charAt(0) == 'P') {  
     inData = inData.substring(1);  
     rightLegX2 = float(inData); 
    } 
    if (inData.charAt(0) == 'Q') {  
     inData = inData.substring(1);  
     rightLegY2 = float(inData); 
    } 
    if (inData.charAt(0) == 'R') {   
     inData = inData.substring(1);  
     rightLegZ2 = float(inData); 
    } 
    } 
    if (frameCount % 4 == 2) 
    { 
    if (inData.charAt(0) == 'D') {  
     inData = inData.substring(1);  
     leftHipX1 = float(inData); 
    } 
    if (inData.charAt(0) == 'E') {  
     inData = inData.substring(1);  
     leftHipY1 = float(inData); 
    } 
    if (inData.charAt(0) == 'F') {  
     inData = inData.substring(1); 
     leftHipZ1 = float(inData); 
    } 
    if (inData.charAt(0) == 'A') {  
     inData = inData.substring(1);  
     leftHipX2 = float(inData); 
    } 
    if (inData.charAt(0) == 'B') {  
     inData = inData.substring(1);  
     leftHipY2 = float(inData); 
    } 
    if (inData.charAt(0) == 'C') {   
     inData = inData.substring(1);  
     leftHipZ2 = float(inData); 
    } 
    } 
    if (frameCount % 4 == 3) 
    { 
    if (inData.charAt(0) == 'G') {  
     inData = inData.substring(1);  
     leftLegX1 = float(inData); 
    } 
    if (inData.charAt(0) == 'H') {  
     inData = inData.substring(1);  
     leftLegY1 = float(inData); 
    } 
    if (inData.charAt(0) == 'I') {  
     inData = inData.substring(1); 
     leftLegZ1 = float(inData); 
    } 
    if (inData.charAt(0) == 'J') {  
     inData = inData.substring(1);  
     leftLegX2 = float(inData); 
    } 
    if (inData.charAt(0) == 'K') {  
     inData = inData.substring(1);  
     leftLegY2 = float(inData); 
    } 
    if (inData.charAt(0) == 'L') {   
     inData = inData.substring(1);  
     leftLegZ2 = float(inData); 
    } 
    } 
} 

Puis, après l'importation des données, il est alors tout à l'aide d'une rotation sur des éléments visuels de mon croquis de traitement.

Répondre

1

La puce de votre carte multiplexeur est un TCA954A. Le datasheet indique que la fréquence maximale est 400kHz. Votre débit dépendra de * la taille du paquet en bits (commande de lecture/écriture, l'adresse et les données: 2 octets par axe) * le nombre de périphériques I2C

Si vous faites les calculs, vous verrez probablement que vous ne peut pas atteindre le plein potentiel de vos capteurs. En plus de cela, le bus I2C est plus lent que SPI, car il y a des données de contrôle échangées. Le plus rapide, vous pouvez aller est un flux SPI avec DMA. L'horloge complète est utilisée uniquement pour les données et directement écrite dans la mémoire du MCU (généralement un tableau). Vous pouvez ajouter plusieurs esclaves sur un seul bus SPI, vous avez juste besoin d'une broche pour sélectionner la puce (CS) pour chaque esclave. Il y a un nice diagram on Wikipedia.