Forum: Mikrocontroller und Digitale Elektronik Problem bei Stillstandsdetektion eines BLDC-Motors


von Fragender (Gast)


Lesenswert?

Hallo,

ich baue im Moment einen BLDC-Regler mit einem ATmega88 (siehe auch 
meinen anderen Thread: 
Beitrag "Probleme mit 30°-Verschiebung bei BLDC-Ansteuerung").
Mein nächstes Ziel ist es, den Stillstand des Motors zu erkennen und 
dann einen Neuanlauf zu starten.
Im Moment ist es wie folgt implementiert:
Die 30° Phasenverzögerung zur phasenrichtigen Kommutierung, erzeuge ich 
mit dem TIMER1 des ATmega88.
Läuft dieser über, so soll der Motor neugestartet werden.

Problem:
Wenn ich den Motor festhalte, fängt der Motor nur zu pfeifen an.
Ich vermute mal, dass obwohl der Motor schon stillsteht, durch den Timer 
noch in den nächsten Kommutierschritt geschaltet wird, dass dann dadurch 
eine Spannung in den Wicklungen induziert wird, die den 
Analog-Komparator zum weiterschalten bewegt.

Wird eine Stillstands-Detektion für gewöhnlich eingentlich 
implementiert?
Wenn ja, wie macht man das für normalerweise?

Schonmal Danke für eure Antworten!

von Peter (Gast)


Lesenswert?

Schaltplan + Quellcode fehlt.

von Fragender (Gast)


Lesenswert?

Hier ein Code-Auszug:

Relevanter Teil meiner Anlauf-Routine:
1
...
2
3
// Einstellung des Timers für Kommutier-Timing
4
  TIFR1 = TIFR1;          // Flag loeschen
5
  OCR1A = 0;
6
  TCNT1 = 0;
7
  
8
  ACSR |= (1<<ACIE);        // aktiviert Interrupt
9
  
10
  sei();
11
  
12
  delay_ms(100);
13
  
14
  // Einstellung des Time-Outs
15
  TIFR1 |= (1<<ICF1);      // Flag löschen
16
  TIMSK1 |= (1<<ICIE1);
17
  
18
  motor_start = 0;
19
}

Teil der für das Kommutieren zuständig ist:
1
void next_commutate_state (void)
2
{
3
  switch (rotor_state)
4
  {
5
    case (0):
6
      
7
      AH_ON;
8
      BL_OFF;
9
      CL_ON;
10
      
11
      SENSE_B;
12
      rotor_state = 1;
13
      break;
14
15
    case (1):
16
      
17
      AH_OFF;
18
      BH_ON;
19
      CL_ON;
20
      
21
      SENSE_A;
22
      rotor_state = 2;
23
      break;
24
  
25
    case (2):
26
      
27
      AL_ON;
28
      BH_ON;
29
      CL_OFF;
30
      
31
      SENSE_C;
32
      rotor_state = 3;
33
      break;
34
35
    case (3):
36
      
37
      AL_ON;
38
      BH_OFF;
39
      CH_ON;
40
      
41
      SENSE_B;
42
      rotor_state = 4;
43
      break;
44
45
    case (4):
46
      
47
      AL_OFF;
48
      BL_ON;
49
      CH_ON;
50
      
51
      SENSE_A;
52
      rotor_state = 5;
53
      break;
54
      
55
    case (5):
56
      
57
      AH_ON;
58
      BL_ON;
59
      CH_OFF;
60
      
61
      SENSE_C;
62
      rotor_state = 0;
63
      break;
64
  }

ISRs:
1
  
2
3
// back EMF zero crossing detection
4
ISR (ANALOG_COMP_vect)
5
{
6
  
7
  OCR1A = TCNT1 >> 1;    // entspricht 30°
8
  
9
  TIFR1 = TIFR1;          // Flag löschen
10
  TCNT1 = 0;
11
  TIMSK1 |= (1<<OCIE1A);
12
  
13
  ACSR &= ~(1<<ACIE);
14
}
15
16
17
// Bei Erreichen von OCR1A, kommutieren
18
ISR (TIMER1_COMPA_vect)
19
{
20
  next_commutate_state();
21
  
22
  TIMSK1 &= ~(1<<OCIE1A);
23
  ACSR |= (1<<ACI);        // Flag löschen
24
  ACSR |= (1<<ACIE);
25
}
26
27
28
// bei Erreichen von ICR1, Motor neustarten
29
ISR (TIMER1_CAPT_vect)
30
{
31
  motor_start = 1;
32
}

Teil von main, in der Komponenten initialisiert werden
1
// Hauptprogramm
2
int main (void) 
3
{
4
  // PWM
5
  TCCR0A |= (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(0<<WGM01)|(1<<WGM00);
6
  TCCR0B |= (0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00);
7
  
8
  TCCR2A |= (0<<COM2A1)|(0<<COM2A0)|(0<<COM2B0)|(0<<COM2B1)|(0<<WGM21)|(1<<WGM20);
9
  TCCR2B |= (0<<WGM22)|(0<<CS22)|(0<<CS21)|(1<<CS20);
10
  
11
  // Analog Comparator  
12
  ACSR |= (0<<ACD)|(0<<ACBG)|(1<<ACI)|(0<<ACIE)|(0<<ACIC)|(0<<ACIS1)|(0<<ACIS0);
13
    ADCSRB |= (1<<ACME);       // aktiviert Multiplexer
14
  
15
  
16
  // Timer1 einstellen
17
  // normal mode; Prescaler auf 8 (Zählertaktdauer = 1us)
18
  TCCR1A = 0;
19
  TCCR1B = (1<<WGM13)|(1<<WGM12)|(0<<CS12)|(1<<CS11)|(0<<CS10);
20
  
21
  ICR1 = 0x1000;          // entspricht: 1 * 16^3 * 1us = 4,096ms
22
  
23
...

Schaltplan ist eigentlich zu dem von Mikrokopter identisch.
Ein Fehler in der Hardware kann man eigentlich ausschließen.
Geht ja alles soweit.
Ich will ja nur eine Stillstands-Detektion hinzufügen.

von Fragender (Gast)


Lesenswert?

Habs glaub ich gelöst...
Wenn der Timer-Wert einen bestimmten Wert unterschreitet (und zwar 
kleiner als der Wert bei der schnellsten Drehzahl ist), dann lös ich 
einen Neustart aus.

Werden für gewöhnlich eigentlich solche Schutzmaßnahmen implementiert 
(wenn ja, wie sieht das dann grob aus), oder mach ich mir nur einen zu 
großen Kopf? ;)

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.