Blink Sequenz mit Millis

Hallo zusammen,

lasst mich zunächst kurz vorstellen. Meine Name ich Matthias, Arduino ist für mich eher mittel zum
Zwecke Modellbau.

Nun zu meinem Problem ich will eine LED in einer bestimmten Abfolge blinken lassen
und zwar AN AUS AN langes AUS und wieder von vorne.
Weil ein andere Programmteil während dessen weiterlaufen soll muss ich das mit millis() ohne delay
machen.
Einfaches Blinken geht aber die Sequenz kieg ich nicht hin:
Zunächst habe ich 3 Intervalle definiert:

unsigned long interval_k = 5; // Interval kurz
unsigned long interval_l = 10; // Interval lang
unsigned long interval_ll = 20; // Interval langlang

über 2 if abfragen will ich dann entscheiden wieviel Zeit ist um also lange oder kurze Pause:

if (millis() - previousMillis > interval_k && millis() - previousMillis < interval_l ) {
previousMillis = millis();
value = !value;
digitalWrite(9, value);
}
if (millis() - previousMillis_1 > interval_l && millis() - previousMillis_1 < interval_ll ) {
previousMillis_1 = millis();
digitalWrite(9, LOW);
}

haut nicht hin. Bin gerade etwas Ratlos.
Danke und bitte nicht schimpfen :o

Hallo,
poste Deinen Sketch mal in Code-Tags "</>", oben links im Editor.
Sei herzlich willkommen im Forum. Du bist sicher Anfänger und mit den Gepflogenheiten des Forum
noch nicht so sehr vertraut.
Wir sind es hier eingentlich gewohnt, das der Code eines Sketch in Code-Tags gesetzt wird.
Das erhöht die Übersichtlich ernorm, und erleichtert es uns, Dir und anderen zu helfen.

Diese Code-Tags befinden sich oben links im Editor als Symbole zum anklicken. Optisch kannst Du
diese erkennen. So "</>" werden sie dargestellt.
Eine ausführliche Hilfe zum Forum gibt es auch.

Was ist das?

previousMillis
value
previousMillis_1

Dein Sketch kann in dieser Form auch nicht funktionieren, Du hast dort mindestens 3 Variablen die
nicht richtig deklariert sind.
Ich meine diese hier: previousMillis, value und previousMillis_1.

Wenn Du in einem Sketch eine Variable nutzen möchtest, dann muß diese zwingend als solche deklariert
werden. Wie man Variablen in einem Sketch nutzt, kannst Du z.B. hier sehr schön nachlesen.

Da nun keiner weiß, ob Du diese Ausdrücke als Variablen nutzen möchtest, und Dein Sketch- ich sage
einmal vorsichtig,"etwas chaotisch" dahin getippt ist- habe ich mich entschlossen Dir einmal einen
Lösungsansatz zur Hand zu geben.

Hier hast Du etwas für 2-Zeiten, eine 3. bekommst Du sicher selbst hin.

In diesem Sketch blinken 2 LED´s in einem bestimmten Intervall. Ich weiß, Du möchtest das aber mit
3 Intervallen bewerkstelligen- Wir stellen hier eigentlich keine fertigen Sketche ins Forum, weil wir
erwarten, das die andere Seite sich an der Arbeit beteitigt.

Wenn Du den nachfolgenden Sketch aufmerksam verfolgst, dann kommst Du sicher dahinter, wie man
einen 3. Intervall implentieren kann.

Für das "blinken lassen" gibt es eine schöne Lib mit der Du das Prinzip erkennen kannst.

Hier nun für Dich der Sketch:

// each "event" (LED) gets their own tracking variable
unsigned long previousMillisTonLED=0;
unsigned long previousMillisPauseLED=0;

// different intervals for each LED
int intervalTonLED = 500;
int intervalPauseLED = 1000;

// each LED gets a state varaible
boolean PauseLEDstate = false;     // the LED will turn ON in the first iteration of loop()
boolean TonLEDstate = false;     // need to seed the light to be OFF

void setup() {
   pinMode(13, OUTPUT);
   pinMode(12, OUTPUT);
}
void loop() {
   // get current time stamp
   // only need one for both if-statements
   unsigned long currentMillis = millis();

   // time to toggle LED on Pin 12?
   if ((unsigned long)(currentMillis - previousMillisTonLED) >= intervalTonLED) {
      TonLEDstate = !TonLEDstate;
      digitalWrite(12, TonLEDstate);
      // save current time to pin 12's previousMillis
      previousMillisTonLED = currentMillis;
   }

// time to toggle LED on Pin 13?
  if ((unsigned long)(currentMillis - previousMillisPauseLED) >= intervalPauseLED) {
      PauseLEDstate = !PauseLEDstate;
      digitalWrite(13, PauseLEDstate);
      // save current time to pin 12's previousMillis
      previousMillisPauseLED = currentMillis;
  }
}

Sollte Dir die Implementierung der Intervalle, trotz Deiner Mitarbeit, denoch nicht gelingen- wird
sich sicher jemand finden, der die bei der Lösung Deines Problem mit Rat und Tat zur Seite steht.
Arbeite Dich da mal ruhig ein, dann wirst Du dieses Problem schon lösen können. Das schaffst Du!
Gruß und Spaß
Einen vergnüglichen Tag wünsche ich Dir- und mir.
Andreas

Hallo und willkommen im Forum!

Mein Vorschlag:

const unsigned long interval[] = {50, 100, 200};
const byte ledPin = 13;
unsigned long previousMillis;
byte index;
bool value;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  if (millis() - previousMillis >= interval[index]) {
    previousMillis = millis();
    value = !value;
    digitalWrite(ledPin, value);
    index++;
    index = index % (sizeof(interval) / sizeof(interval[0]));
  }
}

Also interval als Feld konstanter Werte.

Modellbau: Anleitung: Endlicher Automat mit millis()

alcon:
haut nicht hin. Bin gerade etwas Ratlos.

Es hat auch bei mir einige Zeit gedauert, bis ich es hinbekommen habe, was mich wundert, weil die Aufgabe ja ziemlich simpel klingt. Aber für manche Sachen bin ich ab und zu einfach zu doof.

Mein Code (ein endlicher Automat):

// Blinken ohne delay()

uint8_t  LEDPin=13;                        // Pin, an dem die LED haengt
enum     phase_e {ON1, OFF1, ON2, OFF2};   // "Namen" fuer die Phasen
uint16_t duration[]={500, 500, 500, 1000}; // Dauer der Phasen in Millisekunden
phase_e  phase;                            // Enthaelt aktuelle Phase
uint32_t millisMem;                        // Merker fuer millis(), wird am Ende d. letzten Phase aktualisiert

void setup()
{
  pinMode(LEDPin, OUTPUT);
  phase=ON1;
  millisMem=0;
}

void loop()
{
  switch(phase)
  {
    case ON1:
               if(millis()<(millisMem+duration[0]))
               { digitalWrite(LEDPin, HIGH); }
               else
               { phase=OFF1; }
               break;
    case OFF1:
               if(millis()<millisMem+duration[0]+duration[1])
               { digitalWrite(LEDPin, LOW); }
               else
               { phase=ON2; }
               break;
    case ON2:
               if(millis()<(millisMem+duration[0]+duration[1]+duration[2]))
               { digitalWrite(LEDPin, HIGH); }
               else
               { phase=OFF2; }
               break;
    case OFF2:
               if(millis()<millisMem+duration[0]+duration[1]+duration[2]+duration[3])
               { digitalWrite(LEDPin, LOW); }
               else
               { phase=ON1; millisMem=millis(); }
               break;
    default:
               break;
  }
}

alcon:
Danke und bitte nicht schimpfen :o

Hast Du sie noch alle, Dich davor zu fürchten, ausgeschimpft zu werden?! Also ehrlich!

Gruß

Gregor

Falls dann sich dann dennoch jemand erlaubt, nicht nett zu antworten, gibt es mich, den Moderator. 8) 8)

Nur wen man schon besser kennt, darf man ärgern und pisakern.

Grüße Uwe

Hallo,

muß auch sagen, grundlegend darf jede Frage gestellt werden. Ob man dann eine gute Anwort bekommt ist die nächste Frage. Aber von vornherein nicht trauen ist die falsche herangehensweise. Mit lustigen Antworten darf jedoch immer gerechnet werden. Wir sind hier im Herzen alle ganz nett. :slight_smile:

@ Uwe: du machst deinen Job bis jetzt hervorragend, muss man mal sagen dürfen.

Hallo zusammen,

vielen Dank für die freundliche Aufnahme, nicht schimpfen war nicht ganz ernst....
Aber es gibt schon Foren da wird ordentlich draufgehauen.... wie auch immer.

Mit eueren Hinweisen funktioniert es, was mir noch nicht klar ist warum hat meine Idee
nicht funktioniert ?

Danke
Matthias

ach ja hier der ganze Sketch:

#include "makros.h"
#include "debug.h"
#include "RCReceive.h"


int value_20 = 0;
const byte PIN_RC = 3;
boolean value = LOW;                  // Startwert der LED, value ist LED Posilicht
unsigned long previousMillis = 0;      // speichert wie viele Sekunden seit derletzten Änderung vergangen sind
unsigned long previousMillis_1 = 0;
unsigned long interval_k = 5;          // Interval kurz zwischen zwei Änderungen 10 
unsigned long interval_l = 10;         // Interval lang zwischen zwei Änderungen 100
unsigned long interval_ll = 20;         // Interval lang zwischen zwei Änderungen 100

// Der Empfänger
RCReceive rcReceiver;

void setup() 
{
  rcReceiver.attachInt(PIN_RC);
  pinMode (5, OUTPUT); 
  pinMode (9, OUTPUT);
 
}

void loop() 
{
  if (rcReceiver.hasNP() && !rcReceiver.hasError()) {
    doWork();
    delay(100);
      if (millis() - previousMillis > interval_k && millis() - previousMillis < interval_l  ) {
      previousMillis = millis();   
      value = !value;
      digitalWrite(9, value);
      }
      if (millis() - previousMillis_1 > interval_l &&  millis() - previousMillis_1 < interval_ll ) {
      previousMillis_1 = millis();  
      digitalWrite(9, LOW);
      }
  else if (rcReceiver.hasError()) {
    // 
  delay(100);
  }
}
}
void doWork() {
  byte value = rcReceiver.getValue();
  if (value > 16 && value < 20)
  {
    analogWrite(5, 5); 
  }
   else if (value > 20)
  {
   value_20 = value +20;
   analogWrite(5, value_20); 
   digitalWrite(5, LOW);
   delay (5);
   analogWrite(5, value_20); 
  }
  else
  {
    digitalWrite(5, LOW); 
  } 
}

alcon:
... was mir noch nicht klar ist warum hat meine Idee nicht funktioniert ?

Dein Programm macht durchaus etwas, aber 5 ms sind sehr kurz, da siehst Du bei einer LED nicht so viel (liegt am Auge, nicht an der LED). Ein Oszi zeigt das:
Blink_Sequenz.png

alcon:
...
Aber es gibt schon Foren da wird ordentlich draufgehauen....
...

Das liegt oft daran, dass die Leute dort nicht allzu alt sind und denken, dass jemand, der etwas nicht weiß, ein Depp ist. So habe ich oft genug gedacht.

Was ich echt albern finde, sind Foren, in denen man anscheinend schon nach 10 Postings den Titel „Linux-Guru“ oder „Hohepriester“ vor sich hertragen darf. Naja, mit 15 hätte ich sowas wahrscheinlich auch toll gefunden (damals wohl eher cool).

Gruß

Gregor (älter als 15)