Gyrodaten auslesen und Motor Pulse zählen

Hallo zusammen,

nachdem ich es hinbekommen habe bei meinem Arduino Uno den Motor anzusteuern und die Encoderpulse zu lesen, würde ich gerne parallel dazu Gyrodaten aus einem MPU6050 auslesen.
Leider funktioniert aber die Datenübertragung des MPU nicht zur gleichen Zeit.

Könnt ihr mir sagen, was ich falsch mache?

#include <Wire.h>        // IIC communication library
#include <MsTimer2.h>       // Internal Timer2 for ISR Routine

////////// Nidec 24H677H010 BLDC Motor Variablen ///////////////////////////
      const int nidecDirection = 8;         // CW/CCW Drehrichtung
      const int nidecBrake = 7;             // Bremse
      const int nidecPWM = 6;               // Nidec Motor PWM
      float rw, pulseCount,pwmOut,pwmOut2;

///////// Anfang der Integrated Service Routine ISR Zahler Variablen ////////
      #define nidecHalleffect 3             // Externer Interrupt für Nidec FG  Ausgang 6 Impulse/Umdrehung
      volatile long countHall = 0;          // Zählt die Pulse des Hall Encoders

///////// Anfang der MPU6050 Variablen //////////////////////////////////////
     const int MPU1=0x68;
     float AcX1,AcY1,AcZ1,GyX1,GyY1,GyZ1;

void setup() {

  //Nidec Motor Control Pins
  pinMode(nidecDirection,OUTPUT);
  pinMode(nidecPWM,OUTPUT);
  pinMode(nidecBrake, OUTPUT);
  pinMode(nidecHalleffect, INPUT);        
  
  // Initialer Zustand
  digitalWrite(nidecDirection,LOW);
  analogWrite(nidecPWM,245);                                                          // No PWM Signal
  digitalWrite(nidecBrake,HIGH);                                                      //Bremse an
  attachInterrupt(digitalPinToInterrupt(nidecHalleffect), Code_Hall, RISING); 
  
  MsTimer2::set(1000, ISR_Routine);
  MsTimer2::start();                        //start interrupt
  Serial.begin(9600);
}

void loop() {
}


void Code_Hall() 
{
  countHall ++;
} 


void ISR_Routine(){
  countpulse();                                                                           //Encoder Impulse Zählen
  MPUCAL();
}

void countpulse(){
  rw = countHall;                                                                       // Counter zu RW zuweisen
  countHall = 0;                                                                        // Counter löschen
  pulseCount = rw/6;                                                                    // 6 Pulse/Umdrehung

  Serial.print("Pulsecount = "); Serial.println(pulseCount,5);
  }

void MPUCAL(){

      Wire.beginTransmission(MPU1);
      Wire.write(0x3B);  
      Wire.endTransmission(true);
      Wire.requestFrom(MPU1,12,true);  

      AcX1=Wire.read()<<8|Wire.read();    
      AcY1=Wire.read()<<8|Wire.read();  
      AcZ1=Wire.read()<<8|Wire.read();  
      GyX1=Wire.read()<<8|Wire.read();  
      GyY1=Wire.read()<<8|Wire.read();  
      GyZ1=Wire.read()<<8|Wire.read();

      Serial.print(AcX1); 
      Serial.println();   

Zur gleichen Zeit kann es auch nicht funktionieren.
Aber wenn du alles richtig machst, funktioniert es ganz schnell hintereinander.

und wie stell ich das an?

Einen Sketch schreiben, der nicht blockiert, keine delays und keine zusätzlichen Schleifen enthält.

Und was genau muss ich da ändern? Das Problem liegt ja nur in diesem Teil des Code:

      Wire.beginTransmission(MPU1);
      Wire.write(0x3B);  
      Wire.endTransmission(true);
      Wire.requestFrom(MPU1,12,true);  

      AcX1=Wire.read()<<8|Wire.read();    
      AcY1=Wire.read()<<8|Wire.read();  
      AcZ1=Wire.read()<<8|Wire.read();  
      GyX1=Wire.read()<<8|Wire.read();  
      GyY1=Wire.read()<<8|Wire.read();  
      GyZ1=Wire.read()<<8|Wire.read();

Hallo,
eigentlich sollte das gehen. Allerdings ist Dein Sketch ein Wenig unglücklich. Du könntest es jedoch ohne die msTimer2.h lib machen. Ich kenne die lib nicht. Es könnte aber sein das das auslesen des Sensors über den Bus von einem Interrupt der lib gestört wird. letztlich ist die Laufzeit Deiner function ISR_Routine() mit der seriellen Ausgabe in der function counterpuls ziemlich lang. Damit wird dann der Bus ein Problem haben.

Bau das geordnet mit millis() auf dann sorgt der zeitliche Programm Ablauf dafür das das einlesen und Anzeigen hintereinander sind.
Die ISR Code_Hall() kann dann zwar immer noch dazwischen funken , aber ist ist ziemlich kurz. schau Dir auch noch mal das zu Atomic in der Referenz an. Auf dem Uno benötigt die Übergabe der Variablen count_Hall mehrere Zugriffe , wenn dann gerade ein neuer Interrupt eintrifft wird die Übergabe des Ergebnisses schief gehen.
Heinz

Nachtrag.
hab ich das jetzt übersehen , ich vermisse ein wire.begin() im setup

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.