Forum: Mikrocontroller und Digitale Elektronik Problem mit Nulldurchgangserkennung mit PCINT


von Nils S. (kruemeltee) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo,

ich baue gerade einen 3 Phasen Dimmer. Nun hats heute beim Programmieren 
die ganze Zeit gesponnen und gerade eben kam ich darauf, mir einfach mal 
die Nulldurchgangserkennung anzusehen.

Im Anhang der Schaltplan. Momentan hängen alle drei Phasen auf einer um 
zu sehen, wie falsch die Nulldurchgänge gezählt werden.

Nun hab ich nach einer kurzem Zeit, in der das Gerät läuft, z.B. 
folgende Ausgabe für gezählte Nulldurchgänge:
L1: 607
L2: 242
L3: 2479

Der Controller ist ein mega1284p, der mit 16mhz läuft. Laufen tut er mit 
den 16 sicher, ein Timer lässt zum Testen alle Sekunde eine LED toggeln.

Hier der Quellcode:
1
volatile unsigned int zero_crossings[3] = { 0, 0, 0 };
2
3
ISR(PCINT1_vect) {  // zero cross detection
4
  cli();
5
  if(!(PINB&(1<<PB1))) {  // PHASE L1
6
    zero_crossings[0]++;
7
  }
8
  if(!(PINB&(1<<PB3))) {  // PHASE L2
9
    zero_crossings[1]++;
10
  }
11
  if(!(PINB&(1<<PB4))) {  // PHASE L3
12
    zero_crossings[2]++;
13
  }
14
  sei();
15
}
16
17
void show_zero_cross() {
18
  lcd_clrscr();
19
  while(get_btn() != BTN_DOWN) { 
20
    printf_lcd(0,0,"L1:%05u L2:%05u", zero_crossings[0], zero_crossings[1]);
21
    printf_lcd(0,1,"L3:%05u", zero_crossings[2]);
22
  }
23
  return;
24
}
Initialisiert wird der PCINT so:
1
  PCICR = (1<<PCIE1);
2
  PCMSK1 = (1<<PCINT9)|(1<<PCINT11)|(1<<PCINT12);
3
  DDRB &= ~((1<<PB1)|(1<<PB3)|(1<<PB4));


Ich würde gerne Wissen, was da schief läuft, da sitz ich seit gestern 
Abend dran...

von spess53 (Gast)


Lesenswert?

Hi

>Ich würde gerne Wissen, was da schief läuft, da sitz ich seit gestern
>Abend dran...

Deine Optokoppler werden durch BE-Toleranzen nie gleichzeitig schalten. 
In deiner IR-Routine werden dann die schnelleren mehrfach gezählt. Da 
reicht eine einfache Pegelabfrage nicht. Das geht nur, wenn du den 
Portzustand mit dem Zustand des vorherigen Interrupts vergleichst.

MfG Spess

von micha (Gast)


Lesenswert?

Hi, ich würde auch schätzen, daß in der "einfachen" Optokoppler 
Schaltung Schwierigkeiten begraben sind.
Um das zu debuggen könnte man zuerst mal Testsignale einspeisen, um die 
SW zu prüfen, dann mal mit dem Oszi auf die Ausgänge der Optos schauen, 
wie da die Signale ausschauen.
Ich persönlich würde die Nulldurchgänge mit einem Komparator / 
Schmitt-Trigger detektieren und auswerten und entsprechend sichere und 
steilflankige Signale an den µC liefern.
Hoffe, ich habe deine Fragestellung ausreichend verstanden und konnte 
dir helfen... Micha.

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

Also dann irgendwie so:
1
ISR() {
2
   static last_state_L1 = 0;
3
   PIN_L1 = get_pin_optokoppler();
4
   ...
5
   if(PIN_L1 != last_state_L1) {
6
      nulldurchgang_erkannt();
7
      last_state_L1 = PIN_L1;
8
   }
9
10
   ...
11
   ...   
12
}
So wills grad nich, leider kann ich erst heute Abend weitermachen, muss 
jetzt los...

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ich würde auch die Kollektorwiderstände der Optokoppler auf 1k 
reduzieren.

von spess53 (Gast)


Lesenswert?

Hi

>Also dann irgendwie so:

Hör doch auf mit deinen Pin-Abfragen. Lies den Port (->Pin) ein, 
maskiere die uninteressanten Bits aus und speichere den Wert. Beim 
nächsten Interrupt machst du mit dem neuen Wert ein Exor mit diesem 
Wert, und schon hast du die geänderten Bits. Also so ähnlich wie in 
P.Daneggers Tastenabfrage.

MfG Spess

von micha (Gast)


Lesenswert?

Reichen dir eigentlich die 3,5mA auf der Opto-LED?
230V / 66k = 3,5mA

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.