Loops and momentary switches

So..... I have various components of a program that work independently, Keypad, LED light patterns, but for the life of me, being rather new to all this I can't get them to play together nicely.

The DisplayPattern routine works perfectly outside the switch, but inside it only does the pattern one change at a time for each keypress.

press 9 LED1 goes high
press 9 LED2 goes high
press 9 LED1 goes low
press 9 LED1 goes low
press 9 LED5 goes high

and so forth.

What I am trying to achieve is that the sequence continues itself, until either the same key is pressed again, or the D key is pressed, where all LEDs are set low, and the system simply waits for a sequence to be called again

Keys 1 thru 6, are already toggling relays well, one press for on, one press for off again so I snipped the code down to the not working part. I must admit, I am not sure I understand the DisplayPattern function as it is not my own work, but simply did what I wanted it to.

void loop() {
  char key = kpd.getKey();
  if(key)
  {
    switch (key)
    {
      case '7':
      DisplayPattern(led_pattern1, sizeof(led_pattern1));
      delay(SPEED_MS);
      break;
      case '8':
      DisplayPattern(led_pattern2, sizeof(led_pattern2));
      delay(SPEED_MS);
      break;
      case '7':
      DisplayPattern(led_pattern3, sizeof(led_pattern3));
      delay(SPEED_MS);
      break;
      case'D'
      //All outputs low, all sequences halted.
      default:
      Serial.println(key);
    }
  }
}
{
  static int pattern_num = 0; // keeps count of patterns
  unsigned char mask = 1;     // for testing each bit in pattern

  // do for LEDs on pin 2 to pin 7
  for (int i = 2; i <= 7; i++) {
    // check if bit in pattern is set or not and switch LED accordingly
    if (pattern[pattern_num] & mask) {
      digitalWrite(i, HIGH);
    }
    else {
      digitalWrite(i, LOW);
    }
    mask <<= 1;   // adjust mask for checking next bit in pattern
  }
  pattern_num++;  // move to next pattern for next function call
  // keep pattern within limits of pattern array
  if (pattern_num >= num_patterns) {
    pattern_num = 0;
  }
}

stevehiding:
The DisplayPattern routine works perfectly outside the switch, but inside it only does the pattern one change at a time for each keypress.
snip

void loop() {

char key = kpd.getKey();
 if(key)
 {
   switch (key)
   {
     case '7':
     DisplayPattern(led_pattern1, sizeof(led_pattern1));
...

You have all of the switch(key) inside of if(key), so it only gets executed if(key) !

What you want is a separate value to switch() on for selecting the pattern, then set that value whenever there is a key e.g.

byte displayMode= 'D'
void loop() {
  char key = kpd.getKey();
  if(key)
  {
     switch( key )
     {
     case '7':
     case '8':
     case '9':
     case 'D':
          displayMode= key;
          break;
     default:
          // all other keys do not affect displayMode
          break;
     }
  }

  switch (displayMode)
  {
    case '7':
     DisplayPattern(led_pattern1, sizeof(led_pattern1));
...

? why is 7 used in two different case statements that should be a different number. The second 7 case will never execute?

rogertee:
? why is 7 used in two different case statements that should be a different number. The second 7 case will never execute?

Ah, didn't notice that... won't even compile then.

Yours,
TonyWilk

The case mode is solved, at last compile, there were only 2 case statements, and I added the third (obviously without compiling and editing correctly). One should not try posting at stupid o'clock!

I'll try the suggested code as soon as I get home, then adding in the relay switching that already works

TonyWilk:
You have all of the switch(key) inside of if(key), so it only gets executed if(key) !

What you want is a separate value to switch() on for selecting the pattern, then set that value whenever there is a key e.g.

Thank you for that, it almost worked perfectly. I added a "set all low" to case'D', otherwise it simply stopped the pattern dead with whatever was set high remaining high.

It has however had a strange side effect. It seems to have corrupted the patterns for the sequences. where I used to get

12__56
34
I now get
12__56
_2_4_6

The patterns are defined in the form below and when used originally, outside this sketch did work perfectly, whereas now the only one that does work is "flash all" defined as 0x3f, 0x00,

unsigned char led_pattern2[] = {

 //inner 2, outer 4
 0x33, 0x00, 0x33, 0x00,
 0x0c, 0x00, 0x0c, 0x00,
};

For anyone interested in the end use of this sketch, it is to control various lighting systems on a rescue vehicle, and this segment is about setting flash patterns for the strobes on the roof via some optocouplers and some solid state relays. It will all be driven by a 4x4 keypad with a 26x2 display to show which of the lights on keys 1-6, A & B are active. * is to be "all on" for a walk test and # to be "all off".

Tonight's project is to ignore the corrupted flash patterns for a few hours and try merge in my other sketch that controls the display, and the top two keypad rows.

stevehiding:
It has however had a strange side effect snip

Got lost a bit in your description there(*)... if you still have some bother - post your new code - ta.

Yours,
TonyWilk

(*) might not be your fault, 'twas 'happy hour' at the pub :slight_smile:

TonyWilk:
Got lost a bit in your description there(*)... if you still have some bother - post your new code - ta.

Code is pretty much as suggested earlier, other than the addition of the set all low in case'D'

void loop() {
  char key = kpd.getKey();
  if (key)
  {
    switch ( key )
    {
      case '7':
      case '8':
      case '9':
      case '0':
      case 'C':
      case 'D':
        displayMode = key;
        for (int i = 2; i <= 7; i++) {
          digitalWrite(i, LOW);
        }
        break;
      default:
        // all other keys do not affect displayMode
        break;
    }
  }

  switch (displayMode)
  {
    case '7':
      DisplayPattern(led_pattern1, sizeof(led_pattern1));
      delay(SPEED_MS);
    case '8':
      DisplayPattern(led_pattern2, sizeof(led_pattern2));
      delay(SPEED_MS);
    case '9':
      DisplayPattern(led_pattern3, sizeof(led_pattern3));
      delay(SPEED_MS);
    case '0':
      DisplayPattern(led_pattern4, sizeof(led_pattern4));
      delay(SPEED_MS);
    case 'C':
      DisplayPattern(led_pattern5, sizeof(led_pattern5));
      delay(SPEED_MS);

  }
}

What has happened, is that my light sequences are changed as described earlier with 1-6 corresponding to first the original pattern, then the pattern with the code above. Rather than fill a post with the entire code, including pattern definitions, Light control - Pastebin.com this includes the details of the original author of the light sequencer who wrote the sketch to just cycle repeatedly through some 4 output sequences.

I suspect the fact I am still pretty new to all this means I am not being as clear as I could, so please, let me know if you think I could be clearer.