Auto Absaugung

Ich habe noch nicht all zu viel Erfahrung mit dem Arduino.
Jedoch habe ich mir eine automatische absaug Einrichtung für meine Werkstatt gebaut die Folgendes Können muss: Stromfluss erkennen -> Staubsauger einschalten mit Nachlauf und auch manuell bedienbar sein(sprich ein, Aus , Auto). Gebaut ist alles schon ein Stromsensor der mir die werte liefert, ein Taster, zwei LEDs zur Identifizierung des Modus sowie ein 5V Relay und ein 12 Volt Schütz, dass mit dem Relay verbunden ist, zur Sicherheit, solch kleinen China teilen vertrau ich dann doch keine 8 Ampere an.
Auf jeden Fall hab ich schon einen alten Code Geschrieben der Anfangs Funktioniert hat doch dann machte was er wollte. Der neue funktioniert schon besser doch ich habe leider keinen Plan wie ich die Nachlauf zeit richtig integrieren soll.

Ebenfalls wäre es praktisch dass wenn während der Nachlauf zeit noch mal Strom Fließt das relay aktiviert bleibt.
Aber hier erst mal der Code:

int analogPin = A3;     // Pin, der gelesen werden soll
int currentReading = 0;           // Variable, die den gelesenen Wert speichert
int maxReading;
int minReading;
int offset;
int relayPin = 7;
int i;
int ZeitSpeicher;
bool ZeitGespeichert = true;
int Taster= 4;             // Taster Pin
int gedrueckt = 0;
int tasterstatus;
int modus= 1;             //Aus=1, An=2, Auto =3
bool RelayStatus=false;   // false = aus , True = an 
int ledAn = 1;
int ledAuto = 2;
int Nachlauf= 10000;      //in milisec
int Stromstaerke = 250;


void setup() {
  Serial.begin(9600);
   pinMode(relayPin, OUTPUT);
   pinMode(ledAn, OUTPUT);
   pinMode(ledAuto, OUTPUT);
   digitalWrite(ledAn, LOW);
   digitalWrite(ledAuto, LOW);
   digitalWrite(relayPin, HIGH);

}

void loop() {
          tasterstatus=digitalRead(Taster);
         if(gedrueckt == 1){
          if(tasterstatus == LOW){   // Taster Gedrückt gehalten?
           gedrueckt = 0;}}
         else{  
          if(tasterstatus == HIGH){
            gedrueckt=1;
            if(modus == 1){ modus = 2;
                            RelayStatus = true;      // An 
                            Serial.println("an");
                            digitalWrite(ledAn, HIGH);
                            digitalWrite(ledAuto, LOW);}
                            
            else if(modus == 3){ modus = 1;
                            RelayStatus = false;    // Aus              
                            Serial.println("aus");
                            digitalWrite(ledAn, LOW);
                            digitalWrite(ledAuto, LOW);}
                            
            else if(modus == 2){ modus = 3;
                            RelayStatus = false;    // Auto
                            Serial.println("Auto:");
                            digitalWrite(ledAuto, HIGH);}}}

          
          
          
          
           
                               //Automatik Strom erkennung
                               if(modus == 3){   
                                          maxReading = 0;
                                          minReading = 1024;
                                          for(i=0; i<=99; ++i){
                                            delay(2);
                                            currentReading = analogRead(analogPin);
                                            if (currentReading > maxReading) maxReading = currentReading;
                                            if (currentReading < minReading) minReading = currentReading;
                                          }
                                          offset = maxReading - minReading;

                                           //abfrage
                                          
                                          if(offset > Stromstaerke){ 
                                          Serial.println("Automatik An");
                                                         
                                                         //zeit Gespeichert?
                                                         if(ZeitGespeichert){
                                                            ZeitSpeicher= millis();
                                                            ZeitGespeichert = false;}
                                                        //Nachlauf
                                                        if(ZeitSpeicher + Nachlauf > millis()){

                                                             //ab hier wusste ich einfach nicht mehr Weiter, Vieleicht is aber das vorherige ebenfalls falsch.
                                                          
                                                        }
                                                            
                                          }}


      
      if(RelayStatus){digitalWrite(relayPin, LOW);}
      else{digitalWrite(relayPin, HIGH);}

Wo ich Schwierigkeiten habe steht im Code.
Aber noch mal zusammengefasst: Das Relay soll 10 Sekunden Nachlaufen und bitte nicht mit delay(); (die knöpfe müssen ja immerhin auch noch funktionieren) und es wäre toll wenn das Programm vorab erkennt ob es das Relay noch weiter aktiviert halten soll wenn es zwischen drin zb. einen Stromstoß gab.
Wenn mir jemand etwas auf die Sprünge helfen Könnte
würde ich mich sehr freuen. :grinning:

Hast du dir schon mal BlinkWithoutDelay angesehen.
Da ist genau die Funktion verbaut, die du für deine Zeitsteuerung brauchst.

Danke für die schnelle antwort.
Ja hab ich mir angeschaut ist im Code auch schon angeschnitten aber damit beginnen bei mir die Probleme erst richtig.

(die knöpfe müssen ja immerhin auch noch funktionieren)

Ich sehe keine Knöpfe!
Nur einen.

Auch ist mir der Ablauf nicht klar!
Z.B. Nachlauf auch im Handbetrieb?

Logik von Taster und Relais...
Invers?

Vielleicht noch mal klarer darstellen...

Ok also noch mal klarer
Es gibt nur einen Taster der die drei Modi hintereinander schaltet. Sowie zwei LEDs die erste leuchtet wenn der Automatik modus an ist die zweite wenn der "An" modus aktiviert ist. Natürlich soll es im "An" modus keien Nachlauf geben sondern nur im Automatik modus.
Und "aus" ist hoffentlich selbsterklärend.
Das relay steuert einfach nur ein Schütz das an 230 Volt angeschlossen ist.
Ich hoffe es ist nun verständlicher.

Die Logik von Taster und Relais?
Aktiv High, oder aktiv Low?

Hallo,

ich hab mir vor einiger zeit mal eine lib gebaut die die üblichen timer funktionen zur Verfügung stellt

delayOn, delayOff, pulsOn, cycle, blink

Rückgabe ist jeweis ein bool

Heinz

Timer.zip (2 KB)

Relay ist bei low aktiv
Was du mit dem Taster jetz genau meinst versteh ich zwar nicht aber beim drücken lässt er den Strom durch und ist halt auf einem Anschluss mit 5 Volt und auf dem anderen mit einem digitalen pin und über einen 1kohm Wiederstand mit ground verbunden.

mal eine lib gebaut

Sieht doch ganz gut aus...
Kann mir zwar nicht alle Funktionen auf die Schnelle erklären.

Die Ausschalt- Verzögerung ist doch genau das, was hier gebraucht wird.
Und zum entprellen kann man ihn auch wohl verwenden.


Relay ist bei low aktiv

Also inverse Logik.

beim drücken lässt er den Strom durch und ist halt auf einem Anschluss mit 5 Volt

Also positive Logik.

Hi

Taster positive Logik (HIGH beim Drücken, PullDOwn bereits vorhanden)
Relais negative Logik (AN bei LOW)

Was machen die ganzen INT in Deinem Sketch (Der übrigens in einem CODE-Tag besser kommt, als in einem Quote) - nur als Anregung, wenn's vll. doch Mal schön werden soll - für die Funktion sollte Das hier egal sein.

So, was willst Du:

  • Endlichen Automaten für AUS, AN, AUTO, ggf. kann man darin direkt die Nachlaufzeit mit verarzten

Bei AN schaltest Du stur das Relais an (würde mir dazu zwei Definitionen anlegen, AN=LOW, AUF=HIGH - dann liest sich der Sketch direkt flüssiger und wenn's doch Mal ein anderes Relais wird, ist die Logik mit diesen zwei Zeilen ruck zuck geändert.

Bei AUS schaltest Du das Relais AUS - ok, Das hätte jetzt aber auch Jeder so erwartet.

Bei AUTO erfasst Du den Strom, wenn Dieser über einer Schwelle liegt, setzt Du 'laston' auf millis().
Ebenfalls bei AUTO fragst Du ab, ob millis()-laston>Nachlaufzeit ist - wenn JA, schaltest Du den Staubi ab, wenn NEIN, an.

Dazwischen fehlt nur noch Dein Taster, Der die Modi durch schaltet und nach AUTO wieder auf AUS springt (entweder via enum oder lapidar 0 1 und 2).

MfG

Ich kann dir zeigen, wie es bei mir aussehen würde....
Aber ob dir das hilft, die Angelegenheit zu durchdringen?

#include <CombiePin.h>
#include <CombieTimer.h>
#include <CombieTools.h>

using namespace Combie::Tools;
using namespace Combie::Timer;
using namespace Combie::Pin; 


using CounterType = Counter<byte>;

RelaisINV<7>      relais;
InputPin<4>       taster; 
OutputPin<3>      manuell;
OutputPin<2>      automatik;
EntprellTimer     entprellen(20);
FlankenErkennung  flankenerkennung;
FallingEdgeTimer  toff(10000);    // abfallende Flanke wird verzoegert

CounterType       stufenschalter;



bool stromsensor()
{
  // liefert true, wenn maschine läuft
  // Auswertung überlasse ich dir
 return true; 
}


void wrapAround(CounterType &schalter)
{
  // der schalter darf nur die stufen 0 1 2 kennen
  if(schalter > 2) schalter.reStart();
}


void setup() 
{
 relais.init();
 taster.init();
 manuell.init();
 automatik.init();
 stufenschalter.onCount(wrapAround);
}


void loop() 
{
  manuell        = stufenschalter == 1;
  automatik      = stufenschalter == 2;
  stufenschalter = flankenerkennung = entprellen = taster;
  relais         = ((toff = stromsensor()) && automatik) || manuell;
}

CombieLib.zip (68.6 KB)

Ich habe ein vom Ablauf her ähnliches Projekt und teile gern den Code mit dir. Er ist ohne eigene Libs. Ich frage zwei Bewegungsmelder ab (die sind wie Taster entweder high oder low) und ich frage einen Sensor ab, so wie du im Endeffekt auch. Damit schalte ich ein Licht an und aus. Es gibt keine Modi, die kannst du ja aber abfragen und je nach dem mit if..., elseif..., else... den Code für die drei Modi ansteuern. Was ich mache ist, dass bei einer bestimmten Bedigung die "Nachlaufzeit" nochmal verlänget wird. Das wolltest du ja glaub ich auch.

vielleicht hilft es dir:

  const int maxHelligkeit = 85;           //Helligkeit bis zu der eingeschaltet wird
  const unsigned long leuchtdauer = 100000; // minimale Leuchtdauer in Millisekunden
  const int LEDhelligkeit = 100;           //in Prozent
  
  unsigned long einschaltZeit;


void setup() {

  
  Serial.begin(9600);
  pinMode(11,OUTPUT);
  
}

void loop() {
   
  int helligkeit = analogRead(A2);
  int bewegung1 = digitalRead(3);
  int bewegung2 = digitalRead(5);

Serial.println(helligkeit);
  
if (helligkeit < maxHelligkeit && (bewegung1 == HIGH || bewegung2 == HIGH)) 
{
  digitalWrite(11,(HIGH);
  
 einschaltZeit = millis(); 
}

if (bewegung1 == HIGH || bewegung2 == HIGH)
{
  einschaltZeit = millis();
}

if (millis() >= (einschaltZeit + leuchtdauer))
{
  digitalWrite(11,LOW);
 
}
}