Simple Phasenanschnittsteuerung

Guten Morgen zusammen,

habe mich grade erst hier im Forum angemeldet, daher bitte ich um Nachsicht bei eventuellen Fehlern was das Forum betrifft.

Nun zu meinem Problem: Für unser Technikerprojekt muss ich eine Phasenanschnittsteuerung mit einem Nano realisieren. Die erste Version mit einigen Delays war doch rcht unschön und entsprach nicht dem Niveau das wir anstreben. Zum Test der Hardware habe ich ein Programm aus einem Tutorial genommen und festgestellt, dass die Hardware korrekt abeitet, daran liegt es also schon mal nicht.
Nun habe ich einen doch recht simplen Code ohne Delays dafür mit einem Timer geschrieben, dieser funktioniert allerdings leider nicht. Das gesamte Team, dass eigentlich recht programmiererfahren (C++, Bascom...usw) ist, kann keinen Fehler finden. Allerdings sind wir recht neu was das Arduino C angeht.
Es wäre wirklich toll, wenn jemand mit mehr Erfahrung einen Blick auf den Code werfern kann und ein paar Tipps/konstruktive Kritik äußern kann. Danke schonmal dafür. Der Code sollte eigentlich sehr ausführlich kommentiert sein, so das ich die Funktion erstmal nicht erklären brauche denke ich.

Die Fehlerbeschreibung hab ich ganz vergessen.

Der Fehler ist, dass garnichts passiert mit der Lampe. Per LogicAnalyser ausgelesen wird der Zündepin nicht geschaltet. Ich denke also in irgendeiner Weise wird die Funktion zum Zünden nie aufgerufen, allerdings verstehe ich nicht warum nicht.

#include <TimerOne.h>

// Pinzuweisungen
const byte zeroPin=2;                           // Pin2 alias zeroPin
const byte ignitePin=3;                         // Pin3 alias ignitePin

// Konstanten festlegen
const int timertime=100;                       // 10ms Halbwellendauer / 100 Schritte (0-100%)=100µs 

// Variablen festlegen
int dimlevel=50;                               // Angabe AUF wie viel Prozent gedimmt werden soll (0%=aus | 100%=an)
boolean zerocross=0;                          // Nulldurchgangsmerker zum erkennen ob ein Nulldurchgang stattgefunden hat
volatile int timercounter=0;                   // Anzahl der Timerdurchgänge bis zum zünden, volatile da durch die Nulldurchgangs ISR veränderbar
volatile int timercounting=0;                  // Anzahl wie oft der Timer durchlaufen wurde



void setup() {
 pinMode(zeroPin, INPUT);                                   // zeroPin als Eingang festlegen
 pinMode(ignitePin,OUTPUT);                                 // ignitePin als Ausgang festelgen
 attachInterrupt(zeroPin,zero_cross_detected, RISING);      // den zeroPin mit der Interruptsuproutine zero_cross_detected verknüpfen
 Timer1.initialize(timertime);                              // Timer1 aktivieren
 Timer1.attachInterrupt(timer_counting,timertime);          // Timer1 die Dauer von timertime in Microsekunden und die ISR timer_counting zuweisen
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ISR der Nulldurchgangserkenung
void zero_cross_detected(){
  zerocross=1;
  timercounting=0;
  digitalWrite(ignitePin,LOW);
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ISR des Timer1
void timer_counting(){
  timercounting=timercounting+1;
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Triac zünden
void ignite_triac(){
  digitalWrite(ignitePin,HIGH);
  timercounting=0;
  zerocross=0;
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Zündzeitpunkt aus Frequenz und Dimmlevel berechnen
void ignite_timing(){
  timercounter=100-dimlevel;
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Hauptschleife
void loop() {
  ignite_timing();
  if(zerocross==1){
    if(timercounting>=timercounter){
      ignite_triac();  
    }
  }
  
}

Vielen Dank für alle Tipps und Kommentare, bin für alles offen, dass die programmierung Erfolgreicher und somit spaßiger macht :wink:

(deleted)

Das Pin ist zwar 2 aber der Interrupt hat die Nummer 0.
Darum funktioniert's nicht und die Funktion "digitalPinToInterrupt()" bügelt das aus.

Natürlich konntest Du auch

attachInterrupt(0,zero_cross_detected, RISING);

schreiben und wissen daß Du das Pin 2 benutzen mußt.

Grüße Uwe

Auch fehlen da noch volatile, und atomares Auslesen/Schreiben....

Oh man okay das werde ich nachher ändern und dass die Interruptnummer nicht zur Pinnummer passt ist hatte ich mal am Anfang im Kopf. Dumm gelaufen. Danke für die Lösung!!!

Zu dem volatile und dem atomaren auslesen. Das volatile hatte ich eigentlich gedacht verstanden zu haben. Aber das werde ich mir dann nochmal ansehen. Vielen vielen Dank.

Aber das werde ich mir dann nochmal ansehen.

Gute Idee!

Das "Warum?" findest du unter diesem Suchbegriff: "memory barrier"