Seq Pattern with specific duration

Hi all,

I'm a bit frustrated since 2 days as I'm stuck understand what I do wrong in my code...

A repetitive pulse (Metro library) set a counter (0 --> 15) reading each index of an array fill with 1 and 0.
When the value on the array is 1 that turn the Led ON and I want to turn it OFF after a specific time like a ON Duration (and before the next Pulse)…
when the value is 0, do nothing !

I can't use delay() so I go with the millis() function.
When the array have 2 consecutive 1 it’s seems to work correctly (the Led go OFF after the specific time) but when a 1 is follow by a 0 the Led stay ON longer that it should !
I’m pretty confused Why that behavior and what make it wrong…

Thanks a lot for your help

Florent

#include <Metro.h> 

Metro PatternMetro = Metro(250); 

bool ledState = false;
bool pattern[] = {1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 , 1}; // array of the sequencer 
int stepIndex = 0; // Step Index 
const int numSteps = 16; // Nb of steps
unsigned long currentMillis = 0;
unsigned long PreviousDuration = 0;

int M_Interval;   
long Time_On;


void setup() {
    pinMode(2, OUTPUT);
    PatternMetro.interval(250); // the interval of the pulse
    Time_On = 50; // Time (ms) during the Led is ON
}

void loop() {
  currentMillis = millis();
  if(ledState == true && (currentMillis - PreviousDuration) >= Time_On){
          ledState = false;
          digitalWrite(2, LOW);     
      }
   
  if(PatternMetro.check() == 1) { // Metronome
      if(pattern[stepIndex] == 1){ //If Value of the array is 1 Turn the Led ON !
          ledState = true; // set the State
          PreviousDuration = currentMillis; // Store the new Time
          digitalWrite(2, HIGH);
      }
      stepIndex = (stepIndex + 1) % numSteps; // Rise ... 0->15 Steps counter
      }
}

look this over, maybe it does what you want


const byte PinLed = LED_BUILTIN;
enum { Off = HIGH, On = LOW };

bool pattern [] = { 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 , 1 };
const int Npat = sizeof(pattern);
      int idx;

const unsigned long MsecPeriod    = 250;
const unsigned long MsecPeriodOn  =  50;
const unsigned long MsecPeriodOff = MsecPeriod - MsecPeriodOn;
      unsigned long msecPeriod;
      unsigned long msec0;

const char *StStr [] = { "    Next", "    LedOn", "    Wait" };
enum  { Next, LedOn, Wait };
int state;

char s [90];

// -----------------------------------------------------------------------------
void loop ()
{
    unsigned long  msec = millis();
    if ((msec - msec0) < msecPeriod)
        return;                     // nothing to do

    msec0 = msec;

    switch (state)  {
    case Next:
        Serial.println (idx);

        if (pattern [idx])  {
            digitalWrite (PinLed, On);
            msecPeriod = MsecPeriodOn;
            state = LedOn;
        }
        else
            msecPeriod = MsecPeriod;

        Serial.println (StStr [state]);

        if (Npat <= ++idx)
            idx = 0;
        break;

    case LedOn:
        digitalWrite (PinLed, Off);
        msecPeriod = MsecPeriodOn;
        state = Wait;
        Serial.println (StStr [state]);
        break;

    case Wait:
        msecPeriod = MsecPeriodOff; // wait for remaining period
        state = Next;
        Serial.println (StStr [state]);
        break;
    }
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode (PinLed, OUTPUT);
}

Not here it doesn't.

So... prove it. :expressionless:

Write the value of millis() and print "turning on" or "turning off" where you turn on and off the LED as appropriate.

Then a little maths, or do the diagnostic code so the start time and duration of the LED on period is printed.

I made the rate 1000 milliseconds and the on period 333, it is easy to see the perfect functioning. Catchy little rhythm there.

ON at 1000 for 333
ON at 2000 for 333
ON at 2999 for 333
ON at 4999 for 333
ON at 5998 for 333
ON at 8998 for 333
ON at 10997 for 333
ON at 12997 for 333
ON at 13997 for 333
ON at 15997 for 333
ON at 16997 for 333
ON at 17997 for 333
ON at 18997 for 333
ON at 20997 for 333
ON at 21997 for 333
ON at 24998 for 333
ON at 26997 for 333
ON at 28997 for 333
ON at 29997 for 333
ON at 31997 for 333
ON at 32997 for 333
ON at 33997 for 333
ON at 34997 for 333
ON at 36997 for 333

a7

For what passes as fun in my empty life I used a logic analyser to record the output of the sketch.



Looks like 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1...

Pulses are on a ~250 millisecond grid and measure ~50 milliseconds.

a7

Hi All,

sorry for the late reply !
Well, effectively my code work well !
My mistake, which i'm confused why, but it work fine like this, it's that what I write LOW have to be HIGH and what is HIGH have to be LOW !
With that way the result is what I expected...

thanks
Florent

The only appearances in your sketch of HIGH and LOW are around turning an LED on and off.

How did you wire the LED, and do,you have a series current-limiting resistor also?

LEDs can be wired so LOW lights them up, they can be wired so HIGH lights them up.

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.