ich versuche gerade mit einem Arduino Uno und dem BLDC-Motor Nidec 24H677H010 die Rotationsgeschwindigkeit des Rotors auszulesen. Dazu verwende ich einen externen Interrupt und habe leider das Problem, dass mein Sensorwerte vom Hallsensor nicht im Programm ankommen.
Könnt ihr mir sagen, was ich falsch mache bzw. warum ich keine Werte erhalte?
Nachstehend mein aktueller Code:
#include <MsTimer2.h> // Internal Timer2 for ISR Routine
#include <PinChangeInterrupt.h> // Create external interrupts
#include <MPU6050.h> // MPU6050 library
#include <Wire.h> // IIC communication library
#include <PWM.h> // Require Timer1 PWM frequency of 20Khz-25Khz for Nidec 24H677 BLDC Motor
//************** Nidec 24H677H010 BLDC Motor Variablen ****************
const int nidecDirection = 8; // CW/CCW Drehrichtung
const int nidecBrake = 7; // Bremse
const int nidecPWM = 6; // Nidec Motor PWM
///////// Anfang der Integrated Service Routine ISR Zahler Variablen ////////
#define nidecHalleffect 4 // Externer Interrupt für Nidec FG Ausgang 6 Impulse/Umdrehung
volatile long countHall = 0;// Zählt die Pulse des Hall Encoders
////////////////// Ende der Integrated Serivce Routine ISR Zähler Variablen//
void setup() {
//Nidec Motor Control Pins
pinMode(nidecDirection,OUTPUT);
pinMode(nidecPWM,OUTPUT);
pinMode(nidecBrake, OUTPUT);
pinMode(nidecHalleffect, INPUT); //Input für Halleffect
// Initialer Zustand
digitalWrite(nidecDirection,LOW);
analogWrite(nidecPWM,0); // No PWM Signal
digitalWrite(nidecBrake,HIGH); //Bremse an
Serial.begin(9600);
}
void loop() {
//Externer Interrupt: Für Messung der Motorgeschwindigkeit
attachPinChangeInterrupt(nidecHalleffect, Code_Hall, CHANGE);
}
void Code_Hall()
{
countHall ++;
Serial.print("Count Hall =");
Serial.println(countHall);
}
1) Welche Hardware hast Du?
2) Serial Ausgaben in der Interruptroutine sind tödlich. Die gehören dort nicht hin.
Kontrolliere in loop ob sich der Zähler verändert hat und gib dann die Infos aus.
Prinzipiell gibt es 2 Ansätze um Drehzahl zu messen: Bei langsamer Drehzahl die Zeit zwischen 2 Impulsen messen (Flanke); bei schneller Drehzahl die Impulse in einem gewissen Zeitintervall messen.
Grüße Uwe
Der UNO hat die Interrupteingänge 0 und 1 auf den Pins 2 und 3. Auch andere Pins sind Interrupfähig, müssen aber anders angesprochen werden und die Kontrolle welcher Pin wieso ausgelöst hat mußt Du auch übernehmen.
Schmeiß mal alle Bibliotheken raus die es nicht braucht (praktisch alle). Den Motor kannst Du für die Programmierung der Interrupterkennung auch manuell drehen.
Hallo,
in deinem ersten Sketch, hast Du da eine Serielle Ausgabe bekommen , bzw ist die ISR bearbeitete worden, wurde der Eingang überhaupt erkannt.
Mal ganz normal den Sensor auf einen Eingang legen und damit die TestLED ansteuern , oder eine Serielle Ausgabe machen.
Zur Übergabe der Variablen aus der ISR solltest du noch den Interrupt abschalten , oder das in einem atomic Block umladen.
Hallo
gerade gesehen
kenne ich nicht und mein Compiler bockt, muss aber gestehen ich hab die libs oben alle weggelassen.
siehe #3
lesen kannst Du sicher selber
analogWrite(nidecPWM,500); // No PWM Signal
Was soll das sein?
Weiterhin wird Atomic missachtet.
attachInterrupt(digitalPinToInterrupt(nidecHalleffect), Code_Hall, CHANGE);
Gibts einen besonderen Grund, dass das über 100 Tausend mal pro Sekunde gemacht werden muss?
00000536 <__vector_2>:
IMPLEMENT_ISR(INT1_vect, EXTERNAL_INT_1)
536: 1f 92 push r1
538: 0f 92 push r0
53a: 0f b6 in r0, 0x3f ; 63
53c: 0f 92 push r0
53e: 11 24 eor r1, r1
540: 2f 93 push r18
542: 3f 93 push r19
544: 4f 93 push r20
546: 5f 93 push r21
548: 6f 93 push r22
54a: 7f 93 push r23
54c: 8f 93 push r24
54e: 9f 93 push r25
550: af 93 push r26
552: bf 93 push r27
554: ef 93 push r30
556: ff 93 push r31
558: e0 91 02 01 lds r30, 0x0102 ; 0x800102 <intFunc+0x2>
55c: f0 91 03 01 lds r31, 0x0103 ; 0x800103 <intFunc+0x3>
560: 09 95 icall
562: ff 91 pop r31
564: ef 91 pop r30
566: bf 91 pop r27
568: af 91 pop r26
56a: 9f 91 pop r25
56c: 8f 91 pop r24
56e: 7f 91 pop r23
570: 6f 91 pop r22
572: 5f 91 pop r21
574: 4f 91 pop r20
576: 3f 91 pop r19
578: 2f 91 pop r18
57a: 0f 90 pop r0
57c: 0f be out 0x3f, r0 ; 63
57e: 0f 90 pop r0
580: 1f 90 pop r1
582: 18 95 reti
Der ISR Prolog und Epilog scheint mir doch, für einen schnellen Interrupt doch arg ausufernd zu sein.
Mußt Du die Pin Nummer angeben und nicht die Nummer des Interrupts.
Also beim Arduino UNO 2 für Pin 2 und 3 für pin 3.
digitalPinToInterrupt
Rechnet von der PinZahl zur Interruptzahl um.
Wie gesagt attachinterrupt brauchst Du nur ein mal zum Initialisieren der Interruptroutine (Funktion) siehe Beispiel in : attachInterrupt() - Arduino Reference