UV-Belichtungstimer [Halbzeug]

Hi,

da ich mir einen kleinen UV-Belichter für die Leiterplattenherstellung bauen möchte, habe ich mir schon mal einen Timer zusammengestrickt, den ich im jetzigen Stadium hier zur Verfügung stelle. (Für Anfänger, wie ich einer bin)
Anfangs habe ich gesucht, wie es andere lösen, auch den einen oder anderen Beitrag gefunden, nur war mir das alles noch “zu spanisch”, also habe ich von null angefangen, einzige Erleichterung ist INTERVAL.h von combie.
Das jetzige Stadium ist noch ohne LCD-Anzeige und andere Erweiterungen die ich noch mit einbauen werde, wie Spannungsanzeige, Strommessung auf meiner UV-LED-Platine, und solche Gimmicks, die kein Anderer braucht, Ausgabe nur über den seriellen Monitor.
Es gibt 3 Tasten, PlusTaste, MinusTaste um in 10s Steps die Zeit von einem Startwert zu verändern, und die StartTaste, jeweils am Pin 2,3 und 4, der Ausgang ist Pin 6, die BuildinLED läuft mit (wie Ausgang).
Da das Ding verbaut wird, kommt nur ein ordinäres 2x16 LCD ohne I²C dran (1.90€), bei mir ist dafür Pin 12-7 vorgesehen.

#include <INTERVAL.h> // https://forum.arduino.cc/index.php?topic=413734.0

unsigned int Startwert = 150;  // Zeitvorwahl in Sekunden
unsigned int tempStartwert;
byte Zeitinterval = 10;        // Wert für plus/minusTaster (Sekunden)

unsigned int Minuten;
unsigned int Sekunden;

const byte plusTaster = 2;    // Die 3 Taster schalten gegen GND!
const byte minusTaster = 3;
const byte startTaster = 4;

const byte SchaltAusgang = 6; // Schaltausgang für Verbraucher (über Transistor/FET)

const uint32_t Entprellzeit = 10;
uint32_t aktMillis, tasterMillis;
bool aktTaster, altTaster;

void setup()
{
  Serial.begin(115200);
  Serial.println("** Timer from scratch **");
  Serial.print("StartWert: "); //Serial.println(Startwert);

  ///////// Startwert in Minuten und Sekunden ////////////
  Minuten = Startwert / 60;                             //
  Sekunden = Startwert % 60;                            //
  Serial.print(Minuten); Serial.print(":");             //
  if (Sekunden < 10)                                    //
  {                                                     //
    Serial.print("0");  //  damit es xx:00 wird         //
  }                                                     //
  Serial.print(Sekunden); Serial.println(" Minuten");   //
  ////////////////////////////////////////////////////////

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(SchaltAusgang, OUTPUT);
  digitalWrite(SchaltAusgang, LOW);

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
}

void loop()
{
  /////////////////// Abfrage plus-Taster ////////////////////////////

  aktMillis = millis();                         //
  altTaster = aktTaster;                        //
                                                //
  if (aktMillis - tasterMillis >= Entprellzeit) // einfaches Entprellen
  {                                             //
    tasterMillis = aktMillis;                   //
    aktTaster = digitalRead(plusTaster);        //

    if (aktTaster == LOW)
    {
      INTERVAL(200UL)
      {
        Startwert == tempStartwert;
        Startwert = Startwert + Zeitinterval;
        tempStartwert == Startwert; //Serial.println(Startwert);

        ///////// Startwert in Minuten und Sekunden ////////////
        Minuten = Startwert / 60;                             //
        Sekunden = Startwert % 60;                            //
        Serial.print(Minuten); Serial.print(":");             //
        if (Sekunden < 10)                                    //
        {                                                     //
          Serial.print("0");                                  //
        }                                                     //
        Serial.println(Sekunden); //////////////////////////////
      }
    }
  }
  /////////////////// Abfrage minus-Taster ////////////////////////////

  aktMillis = millis();                         //
  altTaster = aktTaster;                        //
                                                //
  if (aktMillis - tasterMillis >= Entprellzeit) // einfaches Entprellen
  {                                             //
    tasterMillis = aktMillis;                   //
    aktTaster = digitalRead(minusTaster);       //

    if (aktTaster == LOW && Startwert > 0)
    {
      INTERVAL(200UL)
      {
        Startwert == tempStartwert;
        Startwert = Startwert - Zeitinterval;
        tempStartwert == Startwert; //Serial.println(Startwert);

        ///////// Startwert in Minuten und Sekunden ////////////
        Minuten = Startwert / 60;                             //
        Sekunden = Startwert % 60;                            //
        Serial.print(Minuten); Serial.print(":");             //
        if (Sekunden < 10)                                    //
        {                                                     //
          Serial.print("0");                                  //
        }                                                     //
        Serial.println(Sekunden); //////////////////////////////
      }
    }
  }
  /////////////////// Abfrage Start-Taster ////////////////////////////

  aktMillis = millis();                         //
  altTaster = aktTaster;                        //
                                                //
  if (aktMillis - tasterMillis >= Entprellzeit) // einfaches Entprellen
  {                                             //
    tasterMillis = aktMillis;                   //
    aktTaster = digitalRead(startTaster);       //

    if (aktTaster == LOW && Startwert > 0 && digitalRead(LED_BUILTIN) == LOW)
    {
      digitalWrite(LED_BUILTIN, HIGH);
      digitalWrite(SchaltAusgang, HIGH);
      Serial.println("gestartet!");
    }
  }
  ////////////////////// Countdown ///////////////////////////////////

  if (digitalRead(LED_BUILTIN) == HIGH)   // blockt gegen Überlauf < 0
  {
    INTERVAL(1000UL)
    {
      //Serial.println(Startwert);  
      
      ///////// Startwert in Minuten und Sekunden ////////////
      Minuten = Startwert / 60;                             //
      Sekunden = Startwert % 60;                            //
      Serial.print(Minuten); Serial.print(":");             //
      if (Sekunden < 10)                                    //
      {                                                     //
        Serial.print("0");                                  //
      }                                                     //
      Serial.println(Sekunden); //////////////////////////////

      Startwert == tempStartwert;
      Startwert = Startwert - 1;
      tempStartwert == Startwert;
    }
  }
  if (Startwert <= 0 && (digitalRead(LED_BUILTIN) == HIGH)) // Bedingung nur 1x gültig
  {
    delay(1000); // <== Erst nach dem Delay ist die Zeit abgelaufen!
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(SchaltAusgang, LOW);
    Serial.println ("Zeit abgelaufen!");
  }
}

Der Startwert wird meine noch experimentell zu ermittelnde Belichtungszeit für die Leiterplatten sein, mit der Option die Zeit noch in 10s Schritten verändern zu können, geht auch noch während der Laufzeit. Ist letztere abgelaufen und der Ausgang weggeschalten, döst der Arduino vor sich hin, bis entweder mit der PlusTaste die Zeit eingestellt wird, oder der Reset gedrückt wird, dann wieder mit dem Startwert.
Statt der Taster könnte man auch Drehencoder verwenden, oder ein Poti am AnalogPin auswerten, bei mir tun es aber die 1.75cent Dinger aus China.

Gruß André

Timer_from_scratch.funktioniert4.ino (5.92 KB)

Mein Compiler gibt Warnungen, die ich als Fehler ansehen würde:

63:19: warning: statement has no effect [-Wunused-value]
65:23: warning: statement has no effect [-Wunused-value]
93:19: warning: statement has no effect [-Wunused-value]
95:23: warning: statement has no effect [-Wunused-value]
144:17: warning: statement has no effect [-Wunused-value]
146:21: warning: statement has no effect [-Wunused-value]

Zeile 149: Startwert <= 0 macht bei unsigned int Startwert hinsichtlich “kleiner” keinen Sinn.

SpaghettiCode:
(Für Anfänger, wie ich einer bin)

const byte plusTaster = 2;    // Die 3 Taster schalten gegen GND!

const byte minusTaster = 3;
const byte startTaster = 4;

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);

    if (aktTaster == LOW)

Sprechende Namen solltest Du auch durchgängig verwenden.

Für Deine Zielgruppe dürfte irritierend sein, daß ein gedrückter Taster LOW ergibt. Da wird meist andersherum gedacht. Das fände ich einen Kommentar oder eine Erklärung wert.

SpaghettiCode:
Da das Ding verbaut wird, kommt nur ein ordinäres 2x16 LCD ohne I²C dran (1.90€), bei mir ist dafür Pin 12-7 vorgesehen.

Sei nicht so knickerig, spendiere noch einen Euro für einen Adapter.

Zum Schluß noch ein dickes Lob für den Mut, hier was zu veröffenlichen. Du hast viele Dinge richtig gemacht :slight_smile:

Hi,

ich hatte es nochmal zwischengespeichert, mit dem Ergebnis *.ino.ino oder so ähnlich, ich hatte keine Warnungen, erst beim nochmaligen probieren ,jetzt hoffentlich korrigiert. Ansonsten geht das in den Code-Tags auf jeden Fall (IDE 1.8.5)

Das “Startwert <= 0” habe ich auch schon gesehen :wink:

Warum sollte ich in diesem Falle den I²C verbauen, ist nur ein Kropf, die freundlichen Chinesen sparen auch gern an der falschen Stelle, und sei es nur ein Kerko für 3cent.

Gruß André

Startwert == tempStartwert;

Das willst Du nicht, das ist ein Vergleich und keine Wertzuweisung. Ein "=" ist doch genug, sei nicht so verschwenderisch :slight_smile:

Hi,

in welcher Zeile (#), ist 3x im Sketch, und wenn ich das rausnehme geht das Hochzählen mit der PlusTaste nicht mehr.
Aber danke, daß Du reinschaust! Und danke fürs Lob!

Gruß André

Wenn Du tempStartwert komplett löscht, funktioniert Dein Sketch. Sieht zumindest so aus :slight_smile:

Ja,
Du hast Recht, da können 3x “Startwert == tempStartwert;” raus, aber das “<” muss bleiben, in der Zeile unten ( if (Startwert <= 0 && (digitalRead(LED_BUILTIN) == HIGH)) // Bedingung nur 1x gültig)

Ich korrigiere es oben gleich noch. (den Anhang)
Gruß André

PS: Da war ich wohl noch auf einem anderen Dampfer, und habe Überbleibsel stehen gelassen, wo ich mir den Countdown erarbeitet habe …

SpaghettiCode:
… aber das “<” muss bleiben …

Nö, aber so geht es:

if (Startwert == 0 && (digitalRead(LED_BUILTIN) == HIGH))

Ja,

Du hast natürlich Recht, ich hatte einfach nur das > weggenommen und damit aus dem kleiner-gleich ein “ist gleich” gemacht, also statt Vergleich, eine Zuweisung. Das ist noch nicht ganz in Fleisch und Blut übergegangen, der Unterschied aber schon bewusst.
Ich habe noch eine weitere Bedingung geändert, bei der minusTaste war es möglich, während des Ablaufs des Countdown den Wert unter Null, zu drücken, damit aber wieder ein hoher positiver Wert.

if (aktTaster == LOW && Startwert > Zeitinterval)

Zeitinterval war vorher 0, es ging also z.Bsp. 8-10= … und damit ein falscher Zustand.
In den Code Tags steht es noch so. Anhang ist korrigiert.

Update: Und agmue, Danke für Deine klasse Unterstützung! Durch Dich habe ich noch Fehler und überflüssiges Zeug gefunden. +

Gruß André

Irgendwie wäre es doch schön, ohne delay auszukommen?

Du kannst die Zeile löschen, wenn Du beim Start eine Sekunde addierst. Wenn Du dann noch zwei weitere Zeilen umsortierst, stimmt auch die Anzeige wieder.

Ja, das einzige delay habe ich an dieser Stelle komplett unkritisch gesehen, aber mit dem Hinweis zwei weitere Zeilen anders zu sortieren bekomme ich das auch noch hin. Mit nur +1 hätte es ja nur noch mehr verwirrt :wink:

UPDATE: Ich glaube ich habe es, hier nochmal im ganzen:

#include <INTERVAL.h> // https://forum.arduino.cc/index.php?topic=413734.0

unsigned int Startwert = 150;  // Zeitvorwahl in Sekunden
byte Zeitinterval = 10;        // Wert für plus/minusTaster (Sekunden)

unsigned int Minuten;
unsigned int Sekunden;

const byte plusTaster = 2;    // Die 3 Taster schalten gegen GND!
const byte minusTaster = 3;
const byte startTaster = 4;

const byte SchaltAusgang = 6; // Schaltausgang für Verbraucher (über Transistor/FET)

const uint32_t Entprellzeit = 10;
uint32_t aktMillis, tasterMillis;
bool aktTaster, altTaster;

void setup()
{
  Serial.begin(115200);
  Serial.println("** Timer from scratch **");
  Serial.print("StartWert: "); //Serial.println(Startwert);

  ///////// Startwert in Minuten und Sekunden ////////////
  Minuten = Startwert / 60;                             //
  Sekunden = Startwert % 60;                            //
  Serial.print(Minuten); Serial.print(":");             //
  if (Sekunden < 10)                                    //
  {                                                     //
    Serial.print("0");  //  damit es xx:00 wird         //
  }                                                     //
  Serial.print(Sekunden); Serial.println(" Minuten");   //
  ////////////////////////////////////////////////////////

  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(SchaltAusgang, OUTPUT);
  digitalWrite(SchaltAusgang, LOW);

  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
}

void loop()
{
  /////////////////// Abfrage plus-Taster ////////////////////////////

  aktMillis = millis();                         //
  altTaster = aktTaster;                        //
                                                //
  if (aktMillis - tasterMillis >= Entprellzeit) // einfaches Entprellen
  {                                             //
    tasterMillis = aktMillis;                   //
    aktTaster = digitalRead(plusTaster);        //

    if (aktTaster == LOW)
    {
      INTERVAL(200UL)
      {
        Startwert = Startwert + Zeitinterval;
        
        ///////// Startwert in Minuten und Sekunden ////////////
        Minuten = Startwert / 60;                             //
        Sekunden = Startwert % 60;                            //
        Serial.print(Minuten); Serial.print(":");             //
        if (Sekunden < 10)                                    //
        {                                                     //
          Serial.print("0");                                  //
        }                                                     //
        Serial.println(Sekunden); //////////////////////////////
      }
    }
  }
  /////////////////// Abfrage minus-Taster ////////////////////////////

  aktMillis = millis();                         //
  altTaster = aktTaster;                        //
                                                //
  if (aktMillis - tasterMillis >= Entprellzeit) // einfaches Entprellen
  {                                             //
    tasterMillis = aktMillis;                   //
    aktTaster = digitalRead(minusTaster);       //

    if (aktTaster == LOW && Startwert > Zeitinterval)
    {
      INTERVAL(200UL)
      {
        Startwert = Startwert - Zeitinterval;
        
        ///////// Startwert in Minuten und Sekunden ////////////
        Minuten = Startwert / 60;                             //
        Sekunden = Startwert % 60;                            //
        Serial.print(Minuten); Serial.print(":");             //
        if (Sekunden < 10)                                    //
        {                                                     //
          Serial.print("0");                                  //
        }                                                     //
        Serial.println(Sekunden); //////////////////////////////
      }
    }
  }
  /////////////////// Abfrage Start-Taster ////////////////////////////

  aktMillis = millis();                         //
  altTaster = aktTaster;                        //
                                                //
  if (aktMillis - tasterMillis >= Entprellzeit) // einfaches Entprellen
  {                                             //
    tasterMillis = aktMillis;                   //
    aktTaster = digitalRead(startTaster);       //

    if (aktTaster == LOW && Startwert > 0 && digitalRead(LED_BUILTIN) == LOW)
    {
      digitalWrite(LED_BUILTIN, HIGH);
      digitalWrite(SchaltAusgang, HIGH);
      Serial.println("gestartet!");
      Startwert = Startwert + 1;
    }
  }
  ////////////////////// Countdown ///////////////////////////////////

  if (digitalRead(LED_BUILTIN) == HIGH)   // blockt gegen Überlauf < 0
  {
    INTERVAL(1000UL)
    {
      Startwert = Startwert - 1;
      //Serial.println(Startwert);  
      
      ///////// Startwert in Minuten und Sekunden ////////////
      Minuten = Startwert / 60;                             //
      Sekunden = Startwert % 60;                            //
      Serial.print(Minuten); Serial.print(":");             //
      if (Sekunden < 10)                                    //
      {                                                     //
        Serial.print("0");                                  //
      }                                                     //
      Serial.println(Sekunden); //////////////////////////////
    }
  }
  if (Startwert == 0 && (digitalRead(LED_BUILTIN) == HIGH)) // Bedingung nur 1x gültig
  {
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(SchaltAusgang, LOW);
    Serial.println ("Zeit abgelaufen!");
  }
}

Das +1 steht in der letzten Zeile der Start-Taste-Abfrage, und wird anschließend im Countdown sofort wieder abgezogen.

Gruß André