Absolute Trouble Figuring What to do for Implementing Pattern Changes.

First of all, thanks for reading. I’m apologize upfront for the lack of knowledge and ignorance. Your patience is appreciated.

I bought an Arduino Uno about a month ago. I have been able to figure out everything I want to do with it programming wise, up until now, that is.

My kid wanted flashing lights on his power wheel. So I figured this was a good time to make something.
I decided to make 6 leds flash in 5 different patterns? programs? I’m sure the code isn’t written the best way as per a novice, but it works like I want it to.

So my problem. I wanted to implement a momentary push button to cycle these 5 programs. The thing is, I don’t know which suits best. I read that you shouldn’t use the delay function when doing this, but I’ve seen at least 4 examples where an individual was making program changes with a button and had delays all through the code. The one I remember was using the Case Switch function.

So I read up, I looked at the code the guy used and tried to work it into mine that way, but became confused pretty quick. I saw a number of different methods as well, so naturally, being new in all this definitely kind of overwhelmed me.

I uploaded my code. Please note that in my sketch I have pin 6 labeled as output. This is the pin I want to change to input for program changes. Please feel free to critique that code and offer insights as ways to shorten if applicable. Again thanks for reading. It’s much appreciated.

Kiddy.txt (24.8 KB)

It's unclear what you want the pushbutton to do. Select a specific pattern some way? Start and play each pattern in sequence? Play a randomly chosen pattern?

Your code compiles. When you run it, does it play all patterns in your sketch one after another?

While delay() can cause problems in many cases (because nothing else can happen during the delay), this doesn't appear to be a problem in your sketch--depending on what you want the pushbutton to do.

--Michael

thekidson: I bought an Arduino Uno about a month ago. I have been able to figure out everything I want to do with it programming wise, up until now, that is.

Congratulations!

thekidson: I'm sure the code isn't written the best way

You are absolutely right!

thekidson: So my problem. I wanted to implement a momentary push button to cycle these 5 programs. The thing is, I don't know which suits best.

The best is a structured program modelled after the IPO programming model.

I - Input P - Processing O - Output

In Arduino this is easy. You just have to write three own functions and call them in the loop such like:

void loop()
{
  input();
  processing();
  output();
}

Input in your program would be: - Read the button state

Processing in your program would be: - If the button was pressed, switch to the next light pattern - If a cycle of the light pattern has been shown for some time, show the next cycle of the pattern

  • Output in your program would be:
  • Set the led pins to HIGH or LOW accordingly to their current state

thekidson: I read that you shouldn't use the delay function when doing this

This is absolutely correct! While "delay" may be acceptable in certain non-interactive, very simple programs, where things always happen automatically one after the other, "delay" is pure poison for every interactive program that shall react on some user input.

thekidson: I uploaded my code. Please note that in my sketch I have pin 6 labeled as output. This is the pin I want to change to input for program changes.

So you want to have 6 output pins for 6 LEDs. Which 6 pins do you want to use? And you want 1 input pin for one button. This is pin-6.

thekidson: Please feel free to critique that code and offer insights as ways to shorten if applicable.

I'd better rewrite the whole program.

First thing would be a suitable data structure for the light patterns to work with.

As I can see, your LEDs will always be in binary states OFF and ON. In digital you could represent this by Number '0' for OFF and '1' for ON.

So what would you think about your lightshow pattern like that:

byte pattern1[]={ // K.I.T.T.
  0b100000,
  0b010000,
  0b001000,
  0b000100,
  0b000010,
  0b000001,
  0b000010,
  0b000100,
  0b001000,
  0b010000,
};

The ten bytes in the array represent each cycle of the pattern and which LED is ON '1' or OFF '0' during the cycle.

In the same way, you could declare many different light patterns for 6 LEDs. Pattern with less than 10 bytes (cycles), or patterns with more than 10 bytes (cycles) if you like.

And after you have declared the data structures (patterns) you want to show, you then could create the processing logic.

Maybe you need some help with structured programming?

Perhaps the Thread planning and implementing a program will have some useful ideas?

...R

Thank you everyone for your timely responses.

mjward: It's unclear what you want the pushbutton to do...... ...does it play all patterns in your sketch one after another? --Michael

I want it to change patterns when pressed...Yes it cycles through all the patterns.

[quote author=jurs link=msg=2052244 date=1421785948 Maybe you need some help with structured programming? [/quote]

Yea, I probably need some..To be honest I never heard of structured programming until you made mention of it. Reading the input, proccessing, output concept actually was releiving. And pretty much simplified the thinking part.

jurs: First thing would be a suitable data structure for the light patterns to work with.

As I can see, your LEDs will always be in binary states OFF and ON. In digital you could represent this by Number '0' for OFF and '1' for ON.

So what would you think about your lightshow pattern like that:

byte pattern1[]={ // K.I.T.T.
  0b100000,
  0b010000,
  0b001000,
  0b000100,
  0b000010,
  0b000001,
  0b000010,
  0b000100,
  0b001000,
  0b010000,
};

The ten bytes in the array represent each cycle of the pattern and which LED is ON '1' or OFF '0' during the cycle.

In the same way, you could declare many different light patterns for 6 LEDs. Pattern with less than 10 bytes (cycles), or patterns with more than 10 bytes (cycles) if you like.

And after you have declared the data structures (patterns) you want to show, you then could create the processing logic.

So how does one determine the values? And forgive me, but what does the 'b' represent? Also what do the eight characters each line represent? I understand the 0's and 1's are on and off, but, what exactly am I looking at, when looking at figure '0b010000'. Thanks again for your time.

thekidson: I understand the 0's and 1's are on and off, but, what exactly am I looking at, when looking at figure '0b010000'. Thanks again for your time.

Did you ever hear about that computers work only with 0s and 1s?

You are looking at the "binary representation of a number".

The "0b" is the "binary prefix" to show the compiler that a binary number is following, that consists only of 0s and 1s for "bit set" or "bit not set".

So indeed x= 0b000001; is the same as x= 1; x= 0b000010; is the same as x= 2; x= 0b000011; ist the same as x=3; x= 0b000100; ist the same as x=4; and so on.

When using the binary representation, you can use every bit in the binary for "LED ON" or "LED OFF". And when using x= 0b000011; it is much easier to see which 2 LEDs are to be set to ON in the cycle as when using x= 3; which is absolutely the same: A number with the last two bits set to '1'.

In an Arduino program a number such like x= 0b000011; can easily be used as a human readable representation for "a LED pattern with the last two LEDs set to ON". But in real life it is only a number in the RAM of the Arduino controller.

jurs: Did you ever hear about that computers work only with 0s and 1s?

You are looking at the "binary representation of a number".

The "0b" is the "binary prefix" to show the compiler that a binary number is following, that consists only of 0s and 1s for "bit set" or "bit not set".

So indeed x= 0b000001; is the same as x= 1; x= 0b000010; is the same as x= 2; x= 0b000011; ist the same as x=3; x= 0b000100; ist the same as x=4; and so on.

When using the binary representation, you can use every bit in the binary for "LED ON" or "LED OFF". And when using x= 0b000011; it is much easier to see which 2 LEDs are to be set to ON in the cycle as when using x= 3; which is absolutely the same: A number with the last two bits set to '1'.

In an Arduino program a number such like x= 0b000011; can easily be used as a human readable representation for "a LED pattern with the last two LEDs set to ON". But in real life it is only a number in the RAM of the Arduino controller.

Ok so basically the 0b prefix tells the compiler we are going to be typing 1's and 0's instead od actual script? Then I assume the six digits that follow the prefix are my outputs?

The other part that I might be having trouble trying to grasp is this. Do I define my inputs and outputs with script in the setup and loop sections? Then just write the patterns in the way you suggest? Or am I missing something?

I do agree, the way that the KITT pattern is redone makes it a lot easier to visualize in your head whats going on.

thekidson: Ok so basically the 0b prefix tells the compiler we are going to be typing 1's and 0's instead od actual script? Then I assume the six digits that follow the prefix are my outputs?

Sort-of. The 0b means that you are writing a number as binary digits (bits) rather than decimal digits (0 through 9.) You are defining a piece of data that describes the desired pattern. Rather than write a lot of code to do all of the explicit output control, you put the pattern in a data structure, and then write a relatively small generic piece of code to read the data and output the patterns.

The other part that I might be having trouble trying to grasp is this. Do I define my inputs and outputs with script in the setup and loop sections? Then just write the patterns in the way you suggest? Or am I missing something?

Yes, set up the pins in setup(). And define the patterns you want. What you're missing is the code in loop() that will read the patterns and actually set the outputs.

I do agree, the way that the KITT pattern is redone makes it a lot easier to visualize in your head whats going on.

Easier to see what's going on, easier to write and modify, and a lot less total code.

To read the data and write the outputs, you will have to extract the output values from the data. The way it's all encoded as bits in a byte is a very efficient way to store the data. The downside is that it will take a bit more code and some bitwise boolean operators to extract the data. The "&" operator is a bitwise boolean AND: it takes two values, and does a bit-by-bit AND operation: for each bit, if the corresponding bits of the two operands are a 1, the result is a 1, else it's a zero.

For example:

byte a = 0b10101010;
byte b = 0b11001100;
byte c = a & b;

The result of this is c will be 0b10001000.

Another way to look at it, writing it like an arithmetic problem, so that all of the corresponding bits are aligned in columns:

  0b10101010
& 0b11001100
--------------
  0b10001000

The left-most bit is 1 because that bit is 1 in a and b.

The next bit is 0 because that bit is 0 in a, so it doesn't matter what that bit is in b.

The next bit is 0 because that bit is 0 in b, so it doesn't matter what that bit is in a.

The next bit is 0 because that bit is 0 in both a and b.

The next bit is 1 because that bit is 1 in both a and b.

And so on...

So how does this help you? It gives you a way to test the individual bits in each byte of the pattern. You need to do this to figure out what values to write to each output. There are many ways to code this up, but here is one way that is (relatively) easy to understand. Let's make a function that sets a single output:

void setOutputPin(byte pin, byte mask, byte pattern)
{
  // Set the output "pin" depending on whether the "mask" bit is set in "pattern"
  // To be useful, only a single bit in "mask" should be set at one time.
  if (mask & pattern)   // True if the same bit in mask and pattern are set
    digitalWrite(pin, HIGH);
  else
    digitalWrite(pin, LOW);
}

This function takes one byte of the pattern, a mask value describing the interesting bit in the pattern, and a pin number. The mask has a single bit set that is the bit corresponding to the LED indicated by pin. It does a bitwise AND of the mask and the pattern to see if the desired bit is set in the pattern, and sets the output HIGH if the bit was set, and LOW if it was clear.

Now, that takes care of one bit. How to output all of the LEDS in the current pattern byte? Well, it just takes calling the setOutputPin() function once for each pin, giving it the same pattern byte:

void SetOutputPattern(byte pattern)
{
  // Set all of the outputs according to the pattern byte
  setOutputPin(LED1, 0x00000001, pattern);
  setOutputPin(LED2, 0x00000010, pattern);
  setOutputPin(LED3, 0x00000100, pattern);
  setOutputPin(LED4, 0x00001000, pattern);
  setOutputPin(LED5, 0x00010000, pattern);
  setOutputPin(LED6, 0x00100000, pattern);
}

For each output pin (LED1 through LED6 are assumed to be defined as pin numbers) it calls setOutputPin to set that pin number, using a mask value that picks out the bit that corresponds to that pin, and the current pattern byte that was passed in as a function parameter. Now, all that's necessary to do is loop through all of the bytes in the pattern array, calling setOutputPattern() for each byte, and waiting an appropriate time before calling it again. Then, define several pattern arrays, and come up with some code to select a pattern to display, and then display that pattern. And, of course, while looping through the patterns, you will need to check if the button is pressed (and debounce the button press!) to select the next pattern.

I'll give you a chance to let all of this sink in, and maybe come up with some of this additional code before I totally overload you with more new concepts. Take some time to read and re-read all this until it starts to make sense, and feel free to ask questions.

thekidson:
I do agree, the way that the KITT pattern is redone makes it a lot easier to visualize in your head whats going on.

OK, I’ve written a complete demo program handling patterns and cycles.

#define BUTTONPIN 6
#define INPUTMODE INPUT_PULLUP  // INPUT or INPUT_PULLUP

byte ledPins[]={2,3,4,10,11,12};
#define NUMLEDS (sizeof(ledPins))

byte pattern1[]={ // K.I.T.T.
  0b100000,
  0b010000,
  0b001000,
  0b000100,
  0b000010,
  0b000001,
  0b000010,
  0b000100,
  0b001000,
  0b010000,
};

byte pattern2[]={ // left to right
  0b100000,
  0b010000,
  0b001000,
  0b000100,
  0b000010,
  0b000001,
};


byte pattern3[]={ // from outer to middle
  0b000000,
  0b100001,
  0b010010,
  0b001100, 
};


byte pattern4[]={ // double left to right
 0b100100,
 0b010010,
 0b001001,
};

struct pattern_t {byte* index; byte numCycles; int cycleTime; boolean reverse;};

pattern_t patterns[]={
  {pattern1, sizeof(pattern1)/sizeof(pattern1[0]),  500, false},
  {pattern2, sizeof(pattern2)/sizeof(pattern2[0]), 1500, false},
  {pattern3, sizeof(pattern3)/sizeof(pattern3[0]), 1000, false},
  {pattern4, sizeof(pattern4)/sizeof(pattern4[0]),  750, false},
};

#define NUMPATTERNS (sizeof(patterns)/sizeof(patterns[0]))

byte currentPattern;
byte currentCycle;
unsigned long activeSince;
boolean buttonPressed;

void input()
{
  static byte lastButtonState;
  byte state=digitalRead(BUTTONPIN);
  if (INPUTMODE==INPUT_PULLUP) state=!state;
  buttonPressed=false;
  if (state!=lastButtonState)
  {
     if (state==HIGH) buttonPressed=true;
     delay(10); // debounce the button change with a short delay
  }
  lastButtonState=state;
}

void processing()
{
  if (buttonPressed)  
  { // if the button was pressed, switch to next pattern
    currentPattern++;
    if (currentPattern>=NUMPATTERNS) currentPattern=0;
    currentCycle=0;
  }
  else if (millis()-activeSince>= patterns[currentPattern].cycleTime)
  { // if cycleTime is over, switch to next cycle
    currentCycle++; 
    if (currentCycle>= patterns[currentPattern].numCycles) currentCycle=0;
    activeSince=millis();
  }
}

void output()
{
  static byte lastOutputPattern=-1;
  static byte lastOutputCycle=-1;
  // First check of pattern or cycle had been changed since last output
  // if not, do nothing and return
  if (currentPattern==lastOutputPattern && currentCycle==lastOutputCycle) return;
  lastOutputPattern=currentPattern;
  lastOutputCycle=currentCycle;
  // read the current cycle pattern into a byte variable
  byte ledBits=patterns[currentPattern].index[currentCycle];
  for(int i=0; i<NUMLEDS; i++)
  { // set alle LEDs ON/OFF accordingly to the active cycle pattern
    digitalWrite(ledPins[i],bitRead(ledBits,i));
    Serial.print(bitRead(ledBits,i)); // just for some Serial debugging
  }
  Serial.println(); // just for some Serial debugging
}


void setup()
{
  // Activate Serial, just for some serial debugging
  Serial.begin(9600);   
  // set button to INPUTMODE
  pinMode(BUTTONPIN, INPUTMODE);
  // set all LEDs to OUTPUT
  for (int i=0; i<NUMLEDS; i++) pinMode(ledPins[i],OUTPUT);
}

void loop()
{
  input();       // check if the button was pressed
  processing();  // do logical switching actions 
  output();      // set LED outputs and show some Serial debugging messages
}

I don’t know if you can understand all of the code, but perhaps you can see how to declare and use new LED patterns and cycles in this structured code.