Forum: Mikrocontroller und Digitale Elektronik Drehrichtungserkennung Freigabe funktioniert nur meistens


von micha (Gast)


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
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.