Servo wird nicht mehr angesteuert wenn Interrupt aktiv ist

Hallo Zusammen

Ich habe folgendes Problem:

Ich habe ein Door-Opening-System Programmiert, entweder macht man die Tüt mittels Code oder mit einem Taster (tastertur) auf. Mein Programm funktioniert einwandfrei, ausser dass der Servo nicht angesteuert wird, sobald ich den Timer (Interrupt) in das Programm mit einfüge. Sobald der Interrupt als Kommentar programmiert ist, fährt der Servo die Positionen wieder an.

Der Servo wird in der Gleichen if-Bedingung gesetzt wie zum Beispiel die grüne LED (ledgruen), alles funktioniert einwandfrei die grüne LED leuchtet das Display zeigt das an was es sollte und auch die Variablen werden auf 0 gesetzt. Nur der Servo fährt nicht mehr seine Position ab.

#include <LiquidCrystal.h>
#include <Servo.h>
#include "TimerOne.h"
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
Servo servo;
int tasterok = 7;
int tastercode = 8;
int tastertur = A2;
int ledgruen = 10;
int ledrot = A0;
int piepser = A1;
int ledgelb=9;
int statuscode = 0;
int statusok = 0;
int statustur = 0;
int statuszahl = 0;
int zahlrichtig = 0;
int zaehlerzahlrichtig = 0;
int zahlfalsch = 0;
int zaehlerzahlfalsch = 0;
int zaehlerschritt = 0;
int zahlercodefalsch = 0;
int statuscodefalsch = 0;
int ledblinken = 0;



void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  servo.attach(6);
  pinMode (tasterok, INPUT);
  pinMode (tastercode, INPUT);
  pinMode (tastertur, INPUT);
  pinMode (ledgruen, OUTPUT);
  pinMode (ledrot, OUTPUT);
  pinMode (ledgelb, OUTPUT);
  pinMode (piepser, OUTPUT);

  Timer1.initialize (0.5 * 1000000);
  Timer1.attachInterrupt(blinken);
}

 //was tun wenn tür sich öffnet


void blinken()
{

  if (ledblinken == 1)
  {
    digitalWrite(ledgelb, digitalRead(ledgelb) ^ 1);
  }
}


void loop()

  
// Was tun wenn Code richtig

servo.write(90)


 if ((statusok == 1 && zahlrichtig == 1 && zaehlerschritt == 4 && !(zahlfalsch == 1)))
  {
    ledblinken=1;
    servo.write(180);
    digitalWrite(ledrot, LOW);
    digitalWrite(ledgruen, HIGH);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Code Right");
    delay(2000);
    lcd.clear();
    lcd.print("Door Open");
    lcd.setCursor(0, 1);
    lcd.print("please enter");
    delay(5000);
    servo.write(90);
    statuszahl = 0;
    zahlrichtig = 0;
    zaehlerzahlrichtig = 0;
    zahlfalsch = 0;
    zaehlerzahlfalsch = 0;
    zaehlerschritt = 0;
    zahlercodefalsch = 0;
  }
  else
    ledblinken = 0;

  

//was tun wenn von innen geöffnet werden will


 
 if (statustur > 982)
  {
    ledblinken = 1;
    servo.write(0);
    digitalWrite(ledrot, LOW);
    digitalWrite(ledgruen, HIGH);
    lcd.clear();
    lcd.print("Door Open");
    lcd.setCursor(0, 1);
    lcd.print("please exit");
    delay(7000);
    servo.write(90);
    statuszahl = 0;
    zahlrichtig = 0;
    zaehlerzahlrichtig = 0;
    zahlfalsch = 0;
    zaehlerzahlfalsch = 0;
    zaehlerschritt = 0;
  }
  else
    ledblinken = 0;

Und warum benutzt du einen Interrupt ?
Das Blinken machst du doch besser mit BlinkWithoutDelay.

habe es auch mit BlinkWithoutDelay probiert, nur leider funktioniert dies auch nicht, da ich in der if-Schlaufe ein delay() habe funktioniert das blinken auf diese weise nicht...

doubbleg98:
habe es auch mit BlinkWithoutDelay probiert, nur leider funktioniert dies auch nicht, da ich in der if-Schlaufe ein delay() habe funktioniert das blinken auf diese weise nicht...

Ja, dann musst du das delay auch ersetzen.
Die delays werden dir immer wieder auf die Füße fallen.
Auch dafür kannst du das Beispiel BlinkWithoutDelay anwenden.
Für so eine simple Funktion brauchst du keinen Interrupt.
Und wie du siehst, bekommst du Probleme mit dem Servo.
Das wirst du nicht ändern können, außer ohne Interrupt.

Alle delays raus.
Sketch umbauen. State-Machine draus machen.
Überrall wo du heute delays verwendest deutet das auf einen zusätzlichen Statusübergang.
Viele Ifs werden auch einen Statusübergang bedeuten.
Also soll der Umbau "relativ" einfach erfolgen können. Ist nur Schreibarbeit.
Danach klappt auch das blinken wieder.

Oder eine Blinkled verwenden ^^

Hi

Vll. noch eine Erklärung, WARUM Das bei Dir nicht klappt:
Sowohl Servo wie Deine Warterei benutzen den gleichen Timer - da Du selber am Timer rumschraubst, ist das Servo 'draußen'.

Vll. kannst Du dieses Projekt so belassen, wenn Du einen anderen Pin für das Servo benutzt (Der an einem anderen Timer hängt) bzw. den Timer für Deine Blinkerei änderst.

Der Umbau auf millis() macht sich vll. nicht ganz von alleine (ist also schon etwas Arbeit) - Die solltest Du aber trotzdem investieren - die delay's werden Dir immer wieder in die Suppe spucken, da hier der µC (so gut wie Nichts) Produktives macht.

MfG

postmaster-ino:
Vll. kannst Du dieses Projekt so belassen, wenn Du einen anderen Pin für das Servo benutzt (Der an einem anderen Timer hängt)

Das wird nichts helfen, denn die Servo-Lib benutzt immer den Timer1 um die Servo Impulse zu erzeugen. Wenn die Servo Lib benutzt wird, kann man den Timer1 für nichts anderes benutzen.

Edit: P.S. Auf einem Mega könnte es funktionieren, da wird für die ersten 12 Servos der Timer 5 benutzt. erst ab dem 13. Servo wird auch Timer 1 genutzt.