Ring-counter

I need a ring-counter to continuously display 4 input values in sequence.

For this I need a ring counter to enable each value in turn.

My sketch works okay on the breadboard using the dreaded “delay”. So I added the timer sketch to replace “delay” and my wheels fell off!

(The “digitalWrite (ledPin, flxState)” was to monitor my timer sketch on on-board LED pin 13.)

I tried many ways to include the timer sketch without success - it seems to disturb the “for”-cycle, whatever I do.

Instead, the current sketch (using “delay(1500)” works but a strange thing happens which I don’t understand either : the pin13 LED now toggles every cycle of the ring-counter! Why does that happen?

I realise that the “for” is strict within the {… } and the prime question is still HOW do I replace the “delay(timer)” to avoid “delay” ?

      int timer = 1500;
      long previousFMillis = 0 ;
      long intervalF = 700 ; 
      int flxState ;
      int ledPin = 13;
 
 void setup() {
  
    for (int dogPin = 3; dogPin < 7; dogPin++)  
    pinMode  (dogPin, OUTPUT) ;
    pinMode  (ledPin, OUTPUT)  ;    
}
void loop() {
   
      unsigned long currentFMillis = millis() ;
      if  (currentFMillis - previousFMillis > intervalF) 
     previousFMillis = currentFMillis;   
       flxState =  !flxState ;
       
        digitalWrite  (ledPin, flxState) ;

  for (int dogPin = 3; dogPin < 7; dogPin++)  
     { 
       digitalWrite(dogPin, HIGH); 
       delay (timer) ;
       digitalWrite  (dogPin, LOW);    
      }
     }

Newbie10:

(The “digitalWrite (ledPin, flxState)” was to monitor my timer sketch on on-board LED pin 13.)

I tried many ways to include the timer sketch without success - it seems to disturb the “for”-cycle, whatever I do.

Instead, the current sketch (using “delay(1500)” works but a strange thing happens which I don’t understand either : the pin13 LED now toggles every cycle of the ring-counter! Why does that happen?

void loop() {

unsigned long currentFMillis = millis() ;

if (currentFMillis - previousFMillis > intervalF)

previousFMillis = currentFMillis; //This is the only thing that happens when time interval is over. Note the semicolon, the if-statement ends here.

flxState = !flxState ; // This happens every loop regardless of the if-statement

digitalWrite (ledPin, flxState) ; // This happens every loop regardless of the if-statement

for (int dogPin = 3; dogPin < 7; dogPin++) // This for-loop happens every main program loop regardless of the if-statement

{

digitalWrite(dogPin, HIGH);

delay (timer) ;

digitalWrite (dogPin, LOW);

}

// Shouldn’t the entire section up to here not be within a {} section to only execute when the time interval ends? (if-statement is true)

}

I’m not sure how your wish for a ring-counter fits into all this. The code you supplied doesn’t seem to have any hint of it yet.

Adding to Valen’s analysis ;

  • You’re missing {} for your if() statement, not that they’ll make a difference 'cuz

  • The for() loop will execute 4 times every time the main loop() executes.

  • Look at the relative sizes of timer vs intervalF. 4 x timer >> intervalF.

  • Times should be unsigned longs to match the in/out of delay() and millis().

If you auto-format your code (indentations), it’s clearer as to what happens.

int timer = 1500;
long previousFMillis = 0 ;
long intervalF = 700 ;
int flxState ;
int ledPin = 13;

void setup() {
  for (int dogPin = 3; dogPin < 7; dogPin++)
    pinMode  (dogPin, OUTPUT) ;
  pinMode  (ledPin, OUTPUT)  ;
}
void loop() {
  unsigned long currentFMillis = millis() ;
  if  (currentFMillis - previousFMillis > intervalF)
    previousFMillis = currentFMillis;
  flxState =  !flxState ;

  digitalWrite  (ledPin, flxState) ;

  for (int dogPin = 3; dogPin < 7; dogPin++)
  {
    digitalWrite(dogPin, HIGH);
    delay (timer) ;
    digitalWrite  (dogPin, LOW);
  }
}

http://arduino.cc/en/Reference/Delay

http://arduino.cc/en/Reference/Millis

Thanks for the input.

Let me be clear about this : the ring counter works perfectly with the delay(timer) bit in it.

Meaning that the ring counter starts perfectly at D3 (pin 3) waits the “delay”-period, then switches off D3 and D4 on… and clicks up nicely to (and including) D6 (pin 6) and then back to D3. It cycles and cycles forever, perfectly correctly! No problems at all.

The problem comes in when I try to replace “delay(timer)”.

How do I replace “delay(timer)” with a clock/oscillator which doesn’t use “delay” (for obvious reasons)?

THAT is the PRIME QUESTION.

I tried using the xyzFMillis in my sketch with “flxState” , a simple clock/oscillator, using D13 (Pin13) as visual verification that xyzFMillis/flxState works.

Now to try to replace “delay”.

So far nothing works to achieve this : I keep getting all 4 outputs switching on/off together in sync with my “flx” (clock/oscillator). It’s obvious to me that whatever I have tried interferes with the “for” loop.

What am I doing wrong? What can I do to avoid using “delay” here ?

// ringcounter19g

int timer = 500;
unsigned long previousFMillis = 0 ;
unsigned long intervalF = 1650 ; 
int flxState ;
int ledPin = 13;

void setup() {

  for (int dogPin = 3; dogPin < 7; dogPin++)  
  {  
    pinMode  (dogPin, OUTPUT) ;
  }  
}
void loop() {

  unsigned long currentFMillis = millis() ;
  if  (currentFMillis - previousFMillis > intervalF)
  { 
    previousFMillis = currentFMillis;   
    flxState =  !flxState ; 
    digitalWrite  (ledPin, flxState) ;
  }
  for (int dogPin = 3; dogPin < 7; dogPin++)  
  { 
    digitalWrite(dogPin, HIGH); 
    delay (timer) ;
    digitalWrite  (dogPin, LOW);    
  }
}

You simply repeat the same process. Im in a movie theather so i cant wrute code

Newbie10:
What can I do to avoid using “delay” here ?

Time for a state machine. Increment the state variable like you did for the LED. Use the *switch_case()* statement to turn the pins on and off depending on the state variable.
void loop() {
  unsigned long currentFMillis = millis() ;
  if  (currentFMillis - previousFMillis > intervalF)
  {
    previousFMillis = currentFMillis;
    flxState =  !flxState ;
    digitalWrite  (ledPin, flxState) ;
  }
  // run a state machine to switch pins on and off
  // increment the state variable after fixed intervals of time
  if  (currentFMillis - oldMillis > timer)
  {
    pinState++;
    oldMillis = currentFMillis;
    // now do the pin logic
    switch (pinState) {
      //add the case by case code here
    }
  }
}

http://arduino.cc/en/Reference/SwitchCase