Programming button to begin LED Matrix Pattern

I'm working on a school project with some fellow classmates, and we have to build an intelligent square stepping mat that illuminates specific patterns for a person to follow similar to the game Simon says. The mat is a 10x4 LED matrix essentially, and we're using a decade counter to implement the matrix and illuminate different patterns. We've got the code for the first pattern sequence to compile and run properly, however, the problem we're running into is we need to implement a button that tells the pattern to begin, instead of it running on it's own when the arduino is connected.

(We're trying to make this user friendly for a client and I'm sure the last thing they want to do is sift through C++ code and change the pattern manually in the Arduino IDE.).

We would also like to implement other patterns into the code and make it so that each time the pushbutton is pressed, a new pattern shows up on the mat.

For example, we would like to cycle through the patterns and return to the first pattern after all the patterns have been displayed on the matrix by pushing the button.

10x4_MATRX.ino (1.85 KB)

Welcome to the forum

Please follow the advice on posting code given in Read this before posting a programming question in order to make your sketch easy to read, copy and test

In particular note the advice to Auto format code in the IDE and to use code tags when posting code here as it prevents some combinations of characters in code being interpreted as HTML commands such as italics, bold or a smiley character, all of which render the code useless

If the code exceeds the 9000 character inline limit then attach it to a post

The attached code in original post

//10x4 LED Matrix w/ 4017 IC
//Made by Dom Johnson
//03.22.2021

int clock = 9; //clock pin
int reset = 8; //reset pin

int x; // x,y for the loop 
int y; // x,y for the loop

#define led0 {B010,B100}

const int numPatterns = 16;//this is the number of patterns you want to display

byte patterns[numPatterns][8]= {led0};//pattern order

int buttonState = 0;

void setup()
{
 DDRD=B11111111;// this is a commed that makes pins 0-7 outputs
 
 //simple stuff here
 pinMode(4, INPUT);
 pinMode(1, OUTPUT);
 pinMode(clock,OUTPUT);
 pinMode(reset,OUTPUT);
 //reseting the 4017 IC, you have to do this
 digitalWrite(reset,LOW);
 delay(1);
 digitalWrite(reset,LOW);
}

void loop()
{
  int loops;

buttonState = digitalRead(4); //read state of pushbutton value
 
    for(x=0;x<numPatterns-1;x++)
    { // loop over the patterns 

       if (digitalRead(4) == HIGH)//Checks to see if button is pressed
       {
       digitalWrite(1, HIGH);//If button is pressed program will loop patterns
       }
       else
       {
       digitalWrite(1, LOW);
       }
     
      for (int z=0;z<10;z++)
      { //scrolls one bite at a time 

        for(int t=0;t<loops;t++)
        {// the delay we get with loops

          for(y=0;y<2;y++)
          {// loops over the array of bytes

     byte temp = patterns[x][y]; 
     byte temp_2=patterns[x][y];
       
      PORTD = (temp<<z)+(temp_2>>7-z);//writes digital outputs, Z is for how much bites it need to scroll
     
       delay(1000);// the time every row is on
     
       PORTD=B00000000;// all pins are low, fixes the ghosting effect
    // telles the 4017 IC to go to the next row
    
       digitalWrite(clock,HIGH);
     
       delay(10);
     
       digitalWrite(clock,LOW);  
   }
  }
 }
}
  delay(1000); // Delay a little bit to improve simulation performance
}

First thing I notice is that you are not debouncing the switch. When the switch is pressed it will mechanically 'bounce' which causes a stream of HIGH, LOW, HIGH, LOW, etc before it settles into the new HIGH or LOW state. The CPU is fast enough to see all of these transitions.

Secondly you are using pin 1. This is usually not a good idea as pins 1 and 2 on many Arduino boards are the hardware serial that is connected to the USB.

To implement what you want (multiple patterns) the simplest is to use the switch to increment a counter and use the counter to trigger the change in pattern displayed. Pick a value (say 0) for which there is no pattern displayed. Every time the counter goes +1 (ie, switch has been pressed), it displays the pattern for that number. Every time you increment, check if the highest pattern number + 1 has been reached. If it has, reset the counter back to 0 and start all over again.

Here are some alterations I made to the code. I'm using the DDRD command which makes pins 0-7 outputs. Should I change this to something else because as it is now I'm not able to see the pattern any more after changing the digital pins to 3-7

//10x4 LED Matrix w/ 4017 IC
//Made by Dom Johnson
//03.22.2021


int clock = 9; //clock pin
int reset = 8; //reset pin
int x; // x,y for the loop 
int y; // x,y for the loop

#define pattern1 {B100,B010}

const int numPatterns = 16;//this is the number of patterns you want to display

byte patterns[numPatterns][8]= {pattern1};//pattern order

int buttonPin;

void setup()
{
 int run;
  
 run = 0; //starts stopped
 buttonPin = 7; //whatever pin your button is plugged into
  
 DDRD=B11111111;// this is a commed that makes pins 0-7 outputs
 
 //simple stuff here
 pinMode(7, INPUT);
 pinMode(clock,OUTPUT);
 pinMode(reset,OUTPUT);
 pinMode(buttonPin, INPUT_PULLUP);
 //reseting the 4017 IC, you have to do this
 digitalWrite(reset,LOW);
 delay(1);
 digitalWrite(reset,LOW);
}

void loop()
{
  int run;
  int loops;

        if(digitalRead(buttonPin) == LOW) //funcitons based off of button pulling input pin LOW
        {
           if(run == 0)
           {
               run = x;
           }
           else
           {
               run = 0;
           }         
        }
      
        if(run > 0)
        {
      
          for(x=0;x<numPatterns-1;x++)
          { // loop over the patterns 
            
            for (int z=0;z<10;z++)
            { //scrolls one bite at a time 
              
              for(int t=0;t<loops;t++)
              {// the delay we get with loops
            
                for(y=0;y<2;y++)
                {// loops over the array of bytes
             
         
           byte temp = patterns[x][y]; 
           byte temp_2=patterns[x][y];
             
            PORTD = (temp<<z)+(temp_2>>7-z);//writes digital outputs, Z is for how much bites it need to scroll
           
             delay(1000);// the time every row is on
           
             PORTD=B00000000;// all pins are low, fixes the ghosting effect
          // tells the 4017 IC to go to the next row
          
             digitalWrite(clock,HIGH);
           
             delay(10);
            
             digitalWrite(clock,LOW);  
                
         }        
         }

  }
 }
}
  delay(1); // Delay a little bit to improve simulation performance
}

Secondly you are using pin 1. This is usually not a good idea as pins 1 and 2 on many Arduino boards are the hardware serial that is connected to the USB.

Umm.. Isn't that 0 & 1?

-jim lee

This doesn't make any sense. You have a multidimensional array with 16*8 (128) elements and only initialize the first 2 elements:

#define pattern1 {B100,B010}
const int numPatterns = 16;//this is the number of patterns you want to display
byte patterns[numPatterns][8] = {pattern1}; //pattern order

You have declared run as a local variable to loop(), didn't initialize it, then test it for 0 if the button is pressed.

  int run;
  int loops;

  if (digitalRead(buttonPin) == LOW) //funcitons based off of button pulling input pin LOW
  {
    if (run == 0)
    {
      run = x;
    }
    else
    {
      run = 0;
    }
  }

Why are you testing x<numPatterns-1? You will never access the last pattern this way.

          for(x=0;x<numPatterns-1;x++)

loops is a local variable you never initialize!!!

        for (int t = 0; t < loops; t++)

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