Drehrichtungserkennung Freigabe funktioniert nur meistens

Gast #2409811
Lesenswert?

Hallo zusammen,

bräuchte mal Hilfe, bei einem Programmteil, der mit einem Hallsensor mit 
Latch die Drehrichtung und Drehzalt auswerten soll. Drehzahl ist ca. 
15-200 U/min und es sind auf einer Kreisscheibe 5 Magnete. Die Variable 
Kadenz soll gibt reziprok die Drehzahl aus. Bei Rückwärtslauf und bei 
starkem Drehzahlabfall oder Stillstand soll Kadenz=255 gesetzt werden. 
Im Vorwartssinn ist das Signal vom Hall am INT (beide Flankenwechsel) 
Ruhe = high und bei passieren eines Magnets kurz low. Rückwarts 
demenstsprechen lange low und kurz high.

Die Auswertung funktioniert meistens; manchmal beim Rückwartslauf gibt 
es kurze Freigaben beim passieren eines Magnets, und noch nicht 
nachvollziehbar beim erneuten Vorwärtsgang gibt es keine Ausgabe von 
Kadenz<255.

Bin gerade zu festgefahren und seh den Fehler nicht. Erst dachte ich 
wenn low relativ gross ist beim Stop, danach nach beim Vergleich 
low<high nie aus dem high=0 rauskommt. Wars aber leider nicht.

Also wäre über einen unbefangenen Blick darüber mit resultierenden 
Vorschlägen dankbar.

Grüsse Micha
1
#include <stdio.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
//#include "lcd.h"
5
#include <stdlib.h>
6
#include <avr/pgmspace.h>
7
#include <avr/eeprom.h>
8

9

10
volatile uint8_t Kadenz=255, K_counter, K_high, K_diff;
11
// TIMER1 OVF INT
12
ISR(TIMER1_COMPA_vect) {
13
  K_counter++;
14
  if(K_counter > 250) {Kadenz=255; K_high=0; PORTB ^= (1<<5); }
15
  if(K_counter > K_diff) {Kadenz=255; K_high=0; PORTB ^= (1<<5); }
16

17
}
18

19
void Timer1CTC_Init (void) {
20
  // TIMER1 als Zählerbasis für PAS (CTC 27800 macht 255 ticks für 14Kadenz und 17/200) und speed, evtl zeittakt
21
  TCCR1B = (1<<WGM12) | (1<<CS10);
22
  TIMSK |= (1<<OCIE1A);
23
  OCR1A = 27800;
24
  }
25

26

27
//INT0 PD2 pin4 für PAS
28

29
ISR(INT0_vect) {
30
    static uint8_t K_low, K_state;
31

32
  if((PIND & (1<<PD2)) > K_state) {           //steigend
33
      if (K_counter >= K_high) K_low= K_counter - K_high;
34
      K_counter=0;
35
      }   
36
  else                                        //fallend
37
    {  K_high=K_counter;
38
       //K_counter =0;
39
    }
40
  K_state = PIND & (1<<PD2);
41
  PORTB ^= (1<<PB4);
42
  if(K_high > K_low) {
43
    Kadenz = K_high + K_low;
44
    if(Kadenz > 166) K_diff =255;      // bei Drehzahlabfall um x1.5
45
    else K_diff = Kadenz + (Kadenz>>1);    // im COMPA1 abschalten 
46
    }
47
  else {
48
    Kadenz =255;
49
    // K_high = 0; TEST- raus wegen probleme beim wiederanfahren - keine Verbesserung
50
    }
51
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren