Zeitliche ausgabe bei änderung?

Guten abend.

Ich bin gerade ein bisschen am verzweifeln und brauche eure hilfe!
Ich versuch gerade einen Eingelesenen Wert (poti) im Programm zu
verarbeiten, soweit so gut, nun hab ich für das Poti 4 stufen in denen
eine bestimmte Zeit abläuft (1sek, 2sek, 3sek und 4sek). Nun möchte ich
über eine blinkende led anzeigen lassen in welcher Stufe ich gerade bin
(sufe 1 1mal blinken...) und das alles am besten ohne Taster, also wenn
ich am Poti dreh dann Blinkt die Led und das am besten 3 mal (z.b. Stufe
3-3mal blinken 2 s
ek Pause) Ich weiß jetzt leider nur nicht wie ich eine Wertänderung als
"start" einstelle und wieder 3er zyklus umgesetzt werden kann...

const int buttonPin = 2;
const int currentPin = 3;
const int ledPin =  4;
const int gatePin = 13;
int buttonState = 0;      
int sensorValue = A0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(currentPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(currentPin, HIGH);
  int sensorValue = analogRead(A0);
  buttonState = digitalRead(buttonPin);
//------------------------------------------------------------------------------------  
  if ((buttonState == HIGH)&&(sensorValue<=255)) {
    digitalWrite(gatePin, HIGH);
    delay(1000);
  }
  else {
    digitalWrite(gatePin, LOW);
  }
//------------------------------------------------------------------------------------ 
  if ((buttonState == HIGH)&&(sensorValue >= 255)&&(sensorValue <= 510)) {
    digitalWrite(gatePin, HIGH);
    delay(2000);
  }
  else {
    digitalWrite(gatePin, LOW);
  }
//------------------------------------------------------------------------------------
  if ((buttonState == HIGH)&&(sensorValue >= 510)&&(sensorValue <= 765)) {
    digitalWrite(gatePin, HIGH);
    delay(3000);
  }
  else {
    digitalWrite(gatePin, LOW);
  }   
//------------------------------------------------------------------------------------
  if ((buttonState == HIGH)&&(sensorValue >= 765)&&(sensorValue <= 1023)) {
    digitalWrite(gatePin, HIGH);
    delay(4000);
  }
  else {
    digitalWrite(gatePin, LOW);
  } 
//-----------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------  
  {
   Serial.println(sensorValue);
  delay(1); 
 } 
}

ich hoffe ihr könnt mir helfen!
Mfg

Hallo,

du mußt Dich von dem delay komplett trennen. Das muß aus Deinem Kopf verschwinden. delay blockiert an der Stelle den gesamten Programmablauf.

Der Code ist zwar noch nicht perfekt, um die Zeit eher zusammengeschustert, aber wenn Du wartest bis die Blinkanzahl vorbei ist, funktioniert es erstmal. Probiere mit millis() rum und dem Zeit-Merker, dann bekommste mit wie das läuft. Und schau dir das Bsp. Blinking ohne delay an.

analogRead_LED_blinken_001.ino (4.7 KB)

Man könnte auch einen etwas anderen Ansatz verfolgen:

const int ledPin = 13;
int sensorValue;
byte blinken;
unsigned long zielMillis;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  sensorValue = analogRead(A0);
  if (millis() >= zielMillis) {
    if (blinken == 0) {
      if (sensorValue <= 255) {
        blinken = 2;
      } else if (sensorValue <= 510) {
        blinken = 4;
      } else if (sensorValue <= 765) {
        blinken = 6;
      } else {
        blinken = 8;
      }
      Serial.print("sensorValue: "); Serial.print(sensorValue); Serial.print("   blinken: "); Serial.println(blinken/2);
      zielMillis = millis() + 2000;
    } else {
      digitalWrite(ledPin, !digitalRead(ledPin));
      blinken = blinken - 1;
      zielMillis = millis() + 500;
    }
  }
}

@agmue
Angenommen, millis() würde gerade mal 0xfffffffe liefern
(und das tut es irgendwann)

zielMillis = millis() + 500;

Dann steht zielMillis jetzt auf 498

Dieses

if (millis() >= zielMillis)

Wird dann unmittelbar wahr.
Ohne jede Wartezeit.

Der richtige Weg ist:

const unsigned long interval = 500;
unsigned long lastHit;

//.......
lastHit=millis();
//.......
if(millis()-lastHit >= intervall)

combie:
Der richtige Weg ist:
...

Ja, das ist richtig!

@combie
Für mich ist es gerade im Zusammenhang mit endlichen Automaten einfacher, eine Verabredungszeit zu definieren. Also: "Treffen wir uns in fünf Minuten." Unter Berücksichtigung des Überlaufs muß ich aber wohl umdenken. Danke für den morgendlichen Denkanstoß! Ich werde mich voraussichtlich deswegen nochmal mit einem eigenen Thema melden, da können wir das dann ausgiebig diskutieren.

da können wir das dann ausgiebig diskutieren.

Gern!
Da werden dann auch viele Mitleser was von haben.
Denn das ist ein Thema, welches man verinnerlicht haben sollte.

Hallo,

hab den Code nochmal vereinfacht. 4x fast die gleiche Funktion war irgendwie blöd. Wenn Du den Modus am blinken erkennen möchtest, kannste eh nicht wild am Poti drehen, sondern mußt warten bis die LED nicht mehr blinkt und mitzählen.

Von der LED Blinkfunktion nicht verrückt machen lassen, bei der kann man die EIN / AUS Zeit getrennt einstellen. Damit kann man kleine Effekte machen.

Nur was Du mit dem gatePin vor hast weis ich noch nicht. Weil das ist immer an und geht nie aus, weil du immer dafür von einer gültigen if zur anderen hüpft.

Jetzt bist Du dran. Verstehe wie das mit millis funktioniert und mach was daraus. :slight_smile:

analogRead_LED_blinken_002.ino (2.63 KB)

Doc_Arduino:
Jetzt bist Du dran.

Ok....

(1sek, 2sek, 3sek und 4sek)

Das habe ich nicht verstanden und darum mal großzügig weg gelassen.

Einen PulsBlinker habe ich in meiner Wühlkiste(braucht man ja öfter mal)
So ähnlich würde es dann bei mir aussehen....

enum PulsStatus {Start,Hell,Dunkel,Warte};
const unsigned long pause = 1000;   // zwischen den Pulsfolgen
const unsigned long puls  = 200;    // Hell und dunkel Phase


class Blinker
{
  private:
  unsigned long lastHit;              // Zeitstempel der letzten Aktion
  int pulseCount;                     // ausgegebene Pulse
  byte Led;
  PulsStatus status;                  // Zustandsmerker des Endlichen Automaten
  
  public:
  Blinker(byte led):status(Start),Led(led) // Konstruktor
  {
    pinMode(Led,OUTPUT);
    digitalWrite(Led,false);
  }
  
  void handle(int sollPulse) // der endliche Automat
  {
    switch(status)
    {
      case Start:   // Zustand: Start
                    pulseCount = 0;
                    if(sollPulse > 0) // Starte Pulsfolge/Blinkcode
                    {
                      digitalWrite(Led,true);
                      status     = Hell;
                      lastHit    = millis();
                    }  
                    break; 
    
      case Hell:    // Zustand: Led leuchtet 
                    if(millis() - lastHit >= puls) // hell ende 
                    { 
                      digitalWrite(Led,false);
                      status     = Dunkel;
                      lastHit    = millis();
                    }
                    break; 
                    
      case Dunkel:  // Zustand: Led Dunkelphase
                    if(millis() - lastHit >= puls) // dunkel ende
                    {
                      pulseCount++;
                      if(pulseCount < sollPulse) // nächster Puls
                      {
                        digitalWrite(Led,true);
                        status = Hell;
                      }else // Mache Pause zwischen den Pulsfolgen
                      {
                        status = Warte;
                      }
                      lastHit    = millis();
                     }
                     break; 
                    
      case Warte:   // Zustand: Pause zwischen den Pulsfolgen, LED dunkel
                    if(millis() - lastHit >= pause) // nächste Blinkfolge
                    {
                      status = Start;
                    }
                    break; 
     }
  }
};




Blinker blinker(13);

void setup() {}

void loop()  
{
  int stufe = map(analogRead(A0),0,1023,1,4);  // Stufe von 1 bis 4
  blinker.handle(stufe);  
}

korrigiert

Also ihr hab mir schon sehr geholfen!
jetzt mal zum Ablauf also wie ich mir das Programm vorgestellt hab.
Ich habe 4 einstellbare Stufen (über das Poti) in der Jeweils der gatePin HIGH wird für jeweils eine eine andere Zeit deshalb Stufe1=1sek HIGH, Stufe2=2sek HIGH... Das ist nur zum testen die Zeiten werden dann beim richtigen Projekt so um die 50-100ms betragen. Nun weiß ich ja nicht welche Stufe ich eingestellt hab wenn ich keinen PC am Arduino hab deswegen will ich das über eine Blinkende Led anzeigen. Sufe 1 = einmal Blinken dann Pausem Sufe 2 = zweimal Blinken dann Pause... und dieses Blinken soll eben nur "starten" wenn am Poti gedreht wird und es soll alles nur 3 mal Durchlaufen.

Ich hoffe ich habs jetzt ein bisschen verständlicher schreiben können.
Mfg fabi

PS: Doc kann deinen Sketch nicht öffnen -.-

skaterfabi11:
PS: Doc kann deinen Sketch nicht öffnen -.-

Komisch, bei mir geht es ...

Bin auf Deine Variante gespannt! :slight_smile:

Hallo,

ich kann ihn selbst wieder downloaden und öffnen. Weis nicht was bei Dir los ist. Haste vielleicht ein Plugin in Browser der das blockiert?

Mit Deiner "Stufenanzeige" an Hand vom LED blinken habe ich verstanden. Nur das mit dem max. 3x durchlaufen nicht. Aber man muß nicht alles verstehen.

Nur finde ich die Idee an Hand vom blinken ablesen zu wollen wie das Poti steht schon etwas blöd. Rennst Du weg oder guckst nicht genau hin und das blinken ist vorbei, weist Du nicht was gerade eingestellt ist. Du brauchst doch eine dauerhafte Anzeige. Entweder für jeden Modi eine LED oder Du nimmst noch ein Display dazu. Wäre so meine Idee. Aber Du kannst ja mal was anderes basteln, abseits der sonstigen Idee ... :slight_smile:

Doc_Arduino:
Aber Du kannst ja mal was anderes basteln, abseits der sonstigen Idee ... :slight_smile:

Die Kreativität ist ja gerade ein schöner Teil des Programmierens.

Doc_Arduino:
Rennst Du weg oder guckst nicht genau hin und das blinken ist vorbei, weist Du nicht was gerade eingestellt ist.

Deswegen hatte ich bei meinem Lösungsansatz Blinken - Pause - Blinken - Pause ... realisiert. Da könnte man auch mal wegrennen. Wie schon gesagt, ich bin gespannt, was bei raus kommt. :slight_smile:

Hallo,

okay, dann habe ich die Aufgabenstellung falsch verstanden. Mein Code ist damit nur halb fertig. Jetzt habe ich das so verstanden das sich das blinken der jeder Stufe 3x wiederholen soll. Du bist schon einen Schritt weiter der Sinn macht, :slight_smile: blinken wird unendlich wiederholt bis ein Wechsel der Stufe erfolgt.

combies struct ist auch immer wieder schön anzuschauen. :slight_smile:

Hallo,

@ combie:
ich kann Deinen Code nicht kompilieren.

sketch_jun07a:6: error: ISO C++ forbids initialization of member 'pause'
sketch_jun07a:6: error: making 'pause' static
sketch_jun07a:7: error: ISO C++ forbids initialization of member 'puls'
sketch_jun07a:7: error: making 'puls' static

Bei näherer Betrachtung sieht er irgendwie unfertig aus. Einmal wird LED13 direkt angegeben und dann soll man über 'led' die freie Wahl haben. Paßt nicht ganz. Haste den Code schon getestet oder nur als grobe Idee gepostet?

ich kann Deinen Code nicht kompilieren.

Getestet mit der 1.6.4 IDE

Einmal wird LED13 direkt angegeben und dann soll man über 'led' die freie Wahl haben. Paßt nicht ganz.

Das ist ein Versehen! (durch die Lappen gegangen)

Ersetze bitte die 13 durch Led.

Wenn deine IDE das nicht kann

class Blinker
{
  private:
  enum PulsStatus {Start,Hell,Dunkel,Warte};
  const unsigned long pause = 1000;   // zwischen den Pulsfolgen
  const unsigned long puls  = 200;    // Hell und dunkel Phase
// usw

Dann ändere bitte auf so:

const unsigned long pause = 1000;   // zwischen den Pulsfolgen
const unsigned long puls  = 200;    // Hell und dunkel Phase
class Blinker
{
  private:
  enum PulsStatus {Start,Hell,Dunkel,Warte};
// usw

Danke!
Werde ich oben korrigieren...

Hallo,

ich habe in der Zwischenzeit eine eigene Variante entwickelt, aufbauend auf dem Blinker struct von vor paar Wochen. Dabei bekam ich genau den gleichen Fehler, lag daran das eine Variablen Definition an der falschen Stelle stand im struct.

Von der Funktion wie Eure, nur die ein/aus der LED Zeit ist noch getrennt einstellbar.
Jetzt bin ich fertig und wollte allen möglichen Ballast raushauen um es dem Thread zu zeigen und bekomme einen komischen Effekt. Sobald ich die nicht benötigte SPI Library rauswerfe wird nicht mehr kompiliert. Dann werden alle Definitionen im struct angemeckert. Bin ratlos. :o

LED_Pulse_Blinker_Forum.zip (1.46 KB)

Hmm....

Bei mir machts noch nicht mal eine Fehlermeldung...
Wird einfach nicht fertig mit dem Kompilieren.

Ursache:
Es fehlt der Verweis auf die arduino.h
SPI.h bindet die natürlich ein.
Fehlt die SPI.h, dann fehlt auch die arduino.h

Deine *.h Datei sollte so aussehen: (zumindest tuts so bei mir)

#ifndef LEDBLINKER_H
#define LEDBLINKER_H

#include <arduino.h>

struct Blinker
{
 // Schnipp - schnapp
};
#endif

Hallo,

ich dachte die arduino.h ist eine Standard Lib und immer und überall dabei.
Na gut, muß ich auch noch darum kümmern.
Oder kommt der Effekt dadurch das die LedBlinker.h zeitlich vor der arduino.h eingebunden wird? Dadurch hat die LedBlinker.h noch nicht die Infos der arduino.h?

Doc_Arduino:
ich dachte die arduino.h ist eine Standard Lib

Arduino Standard, ja.
Lib eher nicht.

Doc_Arduino:
und immer und überall dabei.

In die Hauptdatei wird sie automatisch eingebunden.
Woanders nicht.

Tipp:
Du hättest ja auch keine *.h Datei machen müssen, sondern eine *.ino machen dürfen.
Oder einfach umbenennen.
Das include in der Hauptdatei kann dann auch weg.
(müsste fluppen....)

Hallo,

immer noch seltsam.

das mit dem
#ifndef LEDBLINKER_H
#define LEDBLINKER_H

klappt nicht. Wenn ich das weglasse funktioniert es mit nur #include <Arduino.h>
Nur ist das denn so jederzeit sauber? Nicht das die mehrfach eingebunden wird.

LED_Pulse_Blinker_Forum.zip (1.51 KB)