Probleme mit der Zeitsteuerung und der Datenspeicherung

Hallo in die Runde,

da meine "Programmierkenntnisse" noch in den Kinderschuhen stecken, komme ich derzeit nicht mit einem wahrscheinlich banalen Problem zurecht. Ich bin dabei mit einem Arduino UNO R3 folgendes zu realisieren: Der Arduino soll über Füllstandssensoren 3 DC Motoren an- und ausschalten, wobei ein Motor jedoch nach auslösen eines Sensors noch eine bestimmte Zeit weiterlaufen soll. Prinzipiell hatte ich da an eine Verschachtelung von Bedingungen gedacht und für die "Nachlaufzeit" sollte die millis() Funktion herhalten. Nur damit komme ich nicht zurecht.

Das ist Problem Nr. 1.

Problem Nr.2 ist, dass meine anschliessende Messung / Berechnung mit den Messwerten [u]genau[/u] einmal durchgeführt werden soll… und das Ergebnis für eine spätere Weiterverwendung (dauerhaft) gespeichert werden soll. Da der Programm-Loop aber immer und immer wieder ausgeführt wird, wird ja nach meinem Verständnis die Messung/ Berechnung immer wieder auf`s Neue ausgeführt….( Meine Idee war da, den EPROM oder SRAM zu verwenden. ) Aber ob das geht, und wenn ja wie konnte ich mangels meiner eher dürftigen Englischkenntnisse im Forum nicht endgültig beantworten .

Nun hoffe ich inständig, dass ich hier ( für mich leicht verständliche ) Anregungen finden kann, die mich ein Stück weiterbringen .

Also im Vorfeld schon einmal DANKE

hallo, hier findest Du alles was Du brauchst: http://arduino.cc/de/Reference/HomePage

hier alles zu den Millis http://arduino.cc/de/Reference/Millis

hier alles zum "einmalDurchlauf" RunAction http://forum.arduino.cc/index.php?PHPSESSID=sdips5jtph4pdcjekdifufndb5&topic=212782.msg1560071#msg1560071

Ich hoffe es hilft Dir ein wenig weiter. Gruß und Spaß Andreas

Problem 2: Was ist "dauerhaft" ? - bis zum nächsten Reset, aber über beliebig viele loop - Zyklen : eine globale Variable, also eine die ausserhalb von     void loop () { /* ... */ } definiert ist. (Das liegt im RAM und ist ohne Stromversorgung und mit Reset weg ) - dauerhafter gehts mit dem eeprom. der wird aber langsam und mühsam byte für byte geschrieben und gelesen. - Im Flash kannst du Werte speichern, die du schon beim Programmieren kennst.

Nach deiner Beschreibung wird nach Reset ( oder auf einen anderen externen Befehl hin ) einmal gemessen, berechnet, und danach das Ergebnis gemerkt. Dafür reichen globale Variable.

Hi zusammen ,

vielen Dank für die superschnellen Antworten. Die genannten Links werde ich mir gleich mal ansehen und vielleicht werde ich etwas schlauer daraus, auf deutsch sind sie ja schon mal .

[u]Hier noch ein paar Details zu meinem Vorhaben:[/u] Mit "dauerhaft" speichern meinte ich folgendes: Der Messvorgang soll erst durch einen Tastendruck starten.Nachdem der gewünschte Füllstand erreicht ist, soll am Ende ein Spannungswert herauskommen, den ich als Mittelwert aus 20 Einzelmessungen ermittle, die im Zeitabstand von jeweils 1/4 Sekunde erfasse. ( ich wollte hierfür ein Array verwenden ). Dieser Vorgang ist ja nun im Loopteil ( also meiner Dauerschleife ) .. die Messung wird also beim nächsten Durchlauf wieder ausgeführt, das Array wird wieder neuer gefüllt und unter Umständen ändert sich damit auch mein zuvor erhaltenes Messergebnis. Aber genau das soll eben nicht passieren, da ich dieses auf einem LCD ausgeben möchte und auf dieser eindeutigen Grundlage ein Relais geschaltet werden soll.)

Wenn ich den Arduino stromlos schalte, kann das Ergebnis dann ruhig gelöscht werden, da der ganze Prozess bei einem Neustart wieder bei 0 starten soll.

Also …Knopf drücken…Anlage ein, Messung beginnt…Ergebnis kann auf dem LCD angezeigt werden.. und je nach Ergebnis wird dann eine Pumpe über ein Relais angesteuert ! )

VG

Habe gerade mit millis() und einer LED rumgespielt…

LED soll nach einmaliger Betätigung eines Drucktasters aufleuchten und für 6 sec. anbliesen und dann ausgehen…

Das funktioniert soweit auch, aber bei erneutem Tastendruck passiert nichts mehr. Habe hier eine while Schleife verwendet und der Arduino wurde während der gesamten Zeit nicht vom Strom getrennt. Habe jetzt das Prog, neu geladen und in der Mehrzahl der Fälle funktioniert es dann wieder für einen Durchlauf. Das müsste doch aber auch weniger umständlich und ohne jeweiliges Neuladen und "Strom aus/ Strom an" zumachen sein, oder ?

Poste deinen Code, sonst ist das wieder Hellseherei :)

Den dazu per Raute-Symbol # in Code-Tags packen

Das müsste doch aber auch weniger umständlich und ohne jeweiliges Neuladen und "Strom aus/ Strom an" zumachen sein, oder ?

Ein Reset müsste auch reichen. ;)

Nein im Ernst, ein Arduino sollte jahrelang laufen können und auf beliebig viele Tastendrücke reagieren.

jetzt nicht lachen - hier der Sketch zur LED

const int buttonPin = 2;
const int ledPin = 13;
int buttonState = 0 ;
int laufzeit = 0 ;

void setup()

{

pinMode(ledPin,OUTPUT);
pinMode(buttonPin, INPUT);

}

void loop()

{

buttonState = digitalRead(buttonPin);

if ( buttonState == HIGH )

{

while ( laufzeit < 6000 )

{

digitalWrite(ledPin, HIGH);
laufzeit = millis();
}

}

else

{
digitalWrite(ledPin, LOW );
}

}

Wenn du jetzt noch code tags drum machst, und evtl. die eine oder andere Leerzeile entfernst, ist das doch schon leserlich ;)

Ist der Taster bei HIGH oder bei LOW gedrückt ? Bei HIGH brauchst du einen Pulldown Widerstand. ( Oder beleidige ich dich mit solchen Hinweisen ? )

Wenn ich deine Aufgabenstellung richtig verstanden habe, soll die LED immer an sein, wenn buttonstate == HIGH und danach noch 6 sekunden länger ?

Bei HIGH also immer Led an ? Das ist einfacher als du es jetzt hast. ;) Dann setze doch im else Zweig die LED nicht gleich auf LOW, sondern vergleichelaufzeit(was die letzte Zeit während HIGH enthält) mit dem aktuellen millis() Wert. Erst wenn die Differenz > 6 sec ist, geht die LED aus.

millis() hat einen beliebig hohen Wert. Es kommt immer nur auf die Differenz zu einem gemerkten Anfangswert an

Nachtrag: Du hast Glück, bei dieser Aufgabenstellung stört Tasterprellen überhaupt nicht ;)

ok, da ich gern die geforderten Infos liefern möchte: Was sind genau meinst Du mit Code Tags ?? Wenn ich das wüsste, dann kann ich das gern nachreichen. Und wie genau sieht dein Vorschlag mit dem Vergleich der Zeit in einem Codebeispiel aus, kann mit dieser Info derzeit noch nichts anfangen ?

Pull Down Widerstand war übrigens keine Beleidigung…. meine Kenntnisse sind zwar ausgesprochen bescheiden, aber das ein oder andere konnte ich mir bislang anlesen…insofern lieber zu viele Infos als zu wenig.

Ein Blick auf die Uhr sagt allerdings, dass ich erst in einigen Stunden weiter herumexperimentieren werde ...

Du hast Text , den markierst du und drückst dann ^ dieses Rautesymbol.
Das schreibt [ code ] davor und [ / code ] dahinter, und dann sieht das Ganze so aus:

Du hast Text , den markierst du und drückst dann       ^    dieses Rautesymbol.

Schau das berühmte blinkwithoutDelay Beispiel an.

Dein Fehler ist, dass du dir zwar schön einen millis() Wert merkst,

     laufzeit = millis();

aber die Abfrage, ob dieser Wert

( laufzeit < 6000 )

ist, führt dazu, dass deine Logik 6 sekunden nach Programmstart nicht mehr funktioniert ;(

Bin sicher, sowas

if ( digitalRead(TasterPin) == LOW) {
    if (millis() - laufzeit ) > 6000) digitalWrite( LedPin, LOW);
}

hättest du auch selber hingekriegt…

Hallo,
Code Tags:
Wenn Du postet siehst Du oben rechts neben der Schreibmaschine das Raute “#” Zeichen.
Du kopierst Deinen Code, dann # anklicken, dann Code einfügen.
Gruß und Spaß
Andreas

Bildschirmfoto 2014-03-20 um 01.19.png

Oder du markierst den ganzen Code und drückst dann auf das Raute "#" Zeichen.

Code Tags ist jetzt klar…

Skript mit millis() <6000 ( siehe oben ) habe ich an diversen Stellen ausprobiert….leider ohne Erfolg ! Ist wohl schon zu spät :drooling_face:

Guten Morgen,

könnte ich evtl. noch einen kleinen Tip bekommen, wie und welche Stelle ich die Geschichte mit der Zeitsteuerung eintragen kann...ich brauch wohl immer erst ein Beispiel um die Funktion zu verstehen . 8)

Die “Geschichte mit der Zeitsteuerung” geht immer so, dass du, wenn du den Start eines Zeit-Intervalls feststellst, dir den Wert von millis() merkst.

static unsigned long start;  // static: Wert bleibt erhalten, unsigned long: der richtige Datentyp
if (digitalRead(taster) == HIGH) start = millis();

Den Zeitablauf erkennst du dann daran, dass die differenz aus aktueller Zeit und Startwert zu groß wird:

if ( millis() - start >= 6000)
     digitalWrite(ledPin = LOW);

Wenn du zyklisch (z.B. alle 10 sec) etwas machen willst, ist der Zeitablauf gleichzeitig der Start den nächsten Intervalls

static unsigned long start;
static boolean wert;  
if ( millis() - start >= 10000) {
     wert = ! wert ; // wechsel HIGH <-> LOW
     digitalWrite(ledPin, wert);
     start = millis();
}

Das fändest du auch als BlinkWithoutDelay Tutorial
Nachtrag:Sogar auf Deutsch

Guten Morgen ,

ich habe folgendes Problem: In einer Unterfunktion sollen zwei Motoren angesprochen werden. Der erste soll nach dem Aufrufen des Codeteiles nach dem Abfragen von 2 Sensorständen sofort loslaufen, bis einer der Sensoren von Low auf High wechselt. Und wenn dieser Motor läuft soll der 2.Motor mit einer Zeitverzögerung von 2 sec auch anlaufen und 2 Sekunden später sofort wieder ausgehen.

Der Code kommt aber nur bis zum Anlaufen des 1. Motors ...das war`s und ich komme nicht drauf, weshalb. Hat jemand eine Idee ?Hier ist mal der Code:

void fuellen ()                                 
       
{
    
    if ( (digitalRead(Sensor1Pin) == LOW ) && (digitalRead(Sensor2Pin) == LOW ))  //
         
  
        {
          //start2 = millis();  // hier beginn eine 2.Zeit, welche nur in diesem Codeteil verwendet werden soll
          
          Pumpe2->setSpeed(200);  // Pumpe 2 beginnt zu laufen wenn Sensor1 und Sensor 2 kein Wasser am Sensor erkennen---> 
          Pumpe2->run(FORWARD);
          
          Serial.println("Fuellen beginnt jetzt ");
          Serial.println("Pumpe 2 startet");
          
          
        }
        
            if ( millis() - start2 > 2000 ) // erst 2 Sekunden nach Beginn von dieser Sequenz soll hier Pumpe 1  für 1,5 Sekunden anlaufen ) 
                {
                    Pumpe1->setSpeed(150);
                    Pumpe1->run(FORWARD);
                    Serial.println(" Pumpe 1 startet 2 sekunden spaeter ");
                 } 
          else if ( millis() - start2 > 4000 )
                {
                   Pumpe1->setSpeed(0);
                   Serial.println(" Pumpe 1 stoppt nach 2 Sekunden ");
                }
        
      else
        { 
          if  (digitalRead(Sensor1Pin) == HIGH)
           
            {
              Pumpe2->setSpeed(0);               // wenn der Sensor erkennt, das der Füllstand erreicht ist, soll Pumpe 2 wieder stoppen
              Serial.println("Pumpe 2 stoppt wenn Sensor 1");
              Zustand = MESSEN;                      
              Serial.println("Fuellvorgang beendet");  
             }
        }
  }