Help with led matrix and decade counter

Hey all so Im building an 8x10 matrix where I have all my columns running to a shift register and the rows to a decade counter. I am trying to use a joystick where if i push it down it will light up the leds and they will stay on. I can only get one led to turn on at a time and didn’t know if there was a workaround for this.

#include <TimedAction.h>
//shit register pins
int latchpin = 4; 
int clockpin = 3; 
int datapin = 2; 
//decade counter pins
int clock = 13;
int Reset = 12;
//josstick x and y
int joyPinx = 0;                
int joyPiny = 1;  
int pushButton = 7;
//my x and y coordinates
int coordX = 0;                  
int coordY = 0;  
//when the joystick isnt pressed this is the center
int centerX = 500;               
int centerY = 500;
int clockPosition = 0;
int i = 0;
int j;
int lastbitused = 0;
int newbits;                
 
 /*TimedAction upAction = TimedAction(200, xUp);
 TimedAction leftAction = TimedAction(200, yLeft);
 TimedAction rightAction = TimedAction(200, yRight);
 TimedAction downAction = TimedAction(200, xDown);
 TimedAction moveAction = TimedAction(200, moveball);
 */
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
 pinMode(clock,OUTPUT);
 pinMode(Reset,OUTPUT);
 pinMode(pushButton, INPUT);
 digitalWrite(Reset,HIGH);
 delayMicroseconds(5);
 digitalWrite(Reset,LOW);
 Serial.begin(9600);
  




}
void loop()
{
coordX = analogRead(joyPinx);   
coordY = analogRead(joyPiny);
int bits = (pow(2,i)+1);


/*
upAction.check();
leftAction.check();
rightAction.check();
downAction.check();
moveAction.check();
*/
//move up
  if(coordX < 200){
     delay(100);
     Serial.println(clockPosition);
     digitalWrite(Reset,HIGH);
     delayMicroseconds(5);
     digitalWrite(Reset,LOW);
       //first I reset the clock then I run this for loop until the clock position in move up is met -1 which will put
       //the led right before the one selected to simulate how to move up 
     for(j = 0; j <clockPosition-1; j++){
       digitalWrite(clock, HIGH);
       digitalWrite(clock,LOW);
     }
     clockPosition--;
     j == 0;
   }
   if(coordX > 900){
     delay(100);
     digitalWrite(clock, HIGH);
     digitalWrite(clock,LOW);    
     clockPosition++;
  
   }
   //move left
   if(coordY > 900){   
     delay(100);
     digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, MSBFIRST,bits); 
     digitalWrite(latchpin, HIGH);
     i++;
     lastbitused++;
     Serial.println(lastbitused);     
  }
  //move right
  if(coordY < 200){
    delay(100);
    newbits = bits/2;
    digitalWrite(latchpin, LOW);
    shiftOut(datapin, clockpin, MSBFIRST, newbits); 
    digitalWrite(latchpin, HIGH);
    i--;
   }

 
}

void xUp(){
 
}
void xDown(){

}
void yLeft(){
  

}
void yRight(){
  
  
}

void moveball(){
   int Button = digitalRead(pushButton);
   if(Button == LOW){
    digitalWrite(latchpin, LOW);
    shiftOut(datapin, clockpin, MSBFIRST,1); 
    digitalWrite(latchpin, HIGH);
    delay(500);
    digitalWrite(clock,HIGH);
     delayMicroseconds(5);
    digitalWrite(clock,LOW);
       
 }

As of right now my code lets me move a single led in all directions but i want to be able to keep certain leds on. My end goal is to be able to draw a box. I also wasn’t sure how to make the decade counter count backwards so i had to hard code the move up by giving the illusion to the led is moving up even though it is just resetting every time. I also want to be able to eventually be able to draw a box then push a button and have a ball bounce around the screen and bounce off the box. Any help will do Iv’e been working at this for way to long.

I used 82 ohm resistors going to the shift register and 1k going to the decade counter and the lights turn on bright also

Here is my schematic http://www.instructables.com/files/orig … CAMAAN.bmp

I’ve not looked at your code yet but w/proper coding it can be done. First let’s review how this must work. When the 4017 is at count=1, the first row is enabled. Any “1” written to the shift register will turn it’s respective LED on. All 1’s across the SR will turn all the LEDs on. The 4017 is then clocked, enabling (only) row2, and a new pattern is written to the SR to turn on/off the row 2 LEDs. This process is repeated, over and over, very quickly such that the eye can’t see when those LEDs supposedly on are actually off (because their row is not enabled).

The coding for this usually stores an image in RAM ([a 2d array) of what LEDs are supposed to be on and off. This image is the clocked out to the SR, row by row, incrementing the counter by 1 between each row. Then, every so often, the joystick is read to modify, if/as needed, the image.

Does your code do the above ?

In your case it might be better/easier to input the joystick button to an external interrupt pin and then have [an ISR do all the joystick stuff.](attachInterrupt() - Arduino Reference)](2D Array - Syntax & Programs - Arduino Forum)

Ok I tried to change the code but im not quite sure how to shift in values from the joystick. I have an 8x10 matrix and am just putting in some binary but is it possible to manipulate these inside the array? also which would be the best format so if I push the joystick left it would go 00000001,00000011,00000111,00001111,000111111,00111111,011111111,11111111 so it would stay lit in the row like that

byte matrix[8] = {B1111111, B11111111, B10110101, B10000101, B10000101, B10110101, B01000010, B0111100};

I’m not entirely sure how to go about shifting out with the register I just started with

digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, MSBFIRST,matrix[n]); 
     digitalWrite(latchpin, HIGH);

bryane92:
I’m not entirely sure how to go about shifting out with the register I just started with

digitalWrite(latchpin, LOW);
 shiftOut(datapin, clockpin, MSBFIRST,matrix[n]); 
 digitalWrite(latchpin, HIGH);
I think that's the right idea. The clockpin is connected the the 595's SR clock, the latchpin is connected to the R clock and the datapin to the serial data in pin of the 595. I'm not sure what the bit order should be, that's easily fixable in any case.

So, assuming you cleared out the SR and 4017 counter in setup(), then your display update code would wrap the above in a for loop and cycle through the matrix values while clocking the 4017 pin.

  for(int n = 0; n < 10, n++){
     digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, MSBFIRST,matrix[n]); 
     digitalWrite(latchpin, HIGH);
     delay(XXX);       //keep LEDs on for a short time, perhaps use use delayMicroseconds() 
     //now clock the 4017
     digitalWrite(4017clkpin, HIGH);
     delayMicroseconds(1);     
     digitalWrite(4017clkpin, LOW);
  }

Let’s say you wanted the display to run at about 100 Hz (just above the flicker threshold for most people). Executing the instructions and shifting the data takes almost no time so the delay(XXX) above might want to be just under (1/100Hz) / 10 rows = 1 msec. One thing additional to maybe do is blank the output while clocking the 4017, to reduce and “carryover” or flicker when changing rows. Then again if the 4017 clock period is short enough, it may not even be seen.

Now you’ve got to figure out how to map joystick readings into matrix values. Can I infer from your prior code that it’s an analog joystick, hitched to your Arduino’s Vcc and gnd and it’s output(s) going into some analog pins ?

Yeah the joystick is an x and y joystick so I have the x plane hooked up to plane A0 and the Y plane to A1 and its running to ground and 5v. Ive looked everywhere for how to say start on the top left of the screen push the stick left and have the leds all turn on going left and stay on. Then I want to be able to go down with all the leds still on and draw lines on the screen that can navigate through the columns and rows.

bryane92:
Ive looked everywhere for how to say start on the top left of the screen push the stick left and have the leds all turn on going left and stay on. Then I want to be able to go down with all the leds still on and draw lines on the screen that can navigate through the columns and rows.

OK, that's not too hard (I think), but how do you intend to turn the LEDs off once they're on ?

Here’s what I think you said originally … that whenever you pressed some button on the joystick, it would light up the LED corresponding to the present X, Y position of the joystick. If you could poll the joystick “fast enough” to track it’s movement, you would draw a continuous line of “on” LEDs as the joystick move about.

Given you have a 8x10 matrix of LEDs (10 rows and 8 columns), how do you want to divide the joystick X and Y into that ? I mean if X corresponds to a horizontal position (some LED in a row) and Y to a vertical position (some column), do you want to divide the 8 possible X LEDs into 8 X positions and 10 Y LEDS into 10 Y positions … or keep it “square” and not use the top and bottom rows ? Since most Arduino A/Ds are 10 bits, they’ll read from 0 - 1023 bits for 0 - Vcc volts or from -X - +X position (same for Y axis) on the joystick. So dividing 1024 by 8 (or 10) should give you a “bit’s worth” in LED or row position. Dividing the A/D reading by it’s X/Y “bits worth” should give you the LED (and row) to turn on.

Example : For the Y axis … 1023 / 10 = 102.3. Let’s call that 102 to keep it easy. So an A/D reading from 0 - 102 means some LED in row #10, the bottom row, should be turned on. I’m assuming some up/down polarity on the joystick, which might be reversed from my assumption in reality. Still you get the idea. A reading between 103 and 205 is the next row up. A reading above 927 is the top row. So you could set up a bunch of if() … else () … if() statements or divide the reading by the “bit worth” in rows. A reading of 249/103 is 2.41 rows, which is 2 w/integer math. That’s means 2 up from the bottom row, aka some bit in row #8 should be on. That is the row number is ;

row# = 9 - (Y_A/D_reading / Y_rowworth)

Remember that while humans call it row1 (top) to row10 (bottom), the code uses 0-9, as in matrix[n], w/n going from 0 to 9.

For the X axis … 1023 / 8 = 127.875. Let’s call that 128 to keep it easy. So an A/D reading from 0 - 128 means the leftmost LED (in whatever row) should be on. Depending on how your store and shift out the data that’s either the MSB or LSB. Let me say, for now, it’s the MSB. I’m also assuming a left/right polarity on the joystick, which might be reversed from my assumption. A reading between 129 and 257 is the next-to-MSB. A reading above 903 is the LSB. So divide the reading by the “bit worth” in LEDs. A reading of 249/129 is 1.93, which is 1 w/integer math. That’s means 1 off from the MSB (bit #7), aka bit #6 should be on. that is the bit number (in the row) to be turned on is ;

bit# = 7 - (X_A/D_reading / X_bitworth)

If you’re leaving on all previously on bits that means (to me) a masking operation. I’d shift a “1” to the left, bit# of places to create a mask and then [bitwise ‘or’ that with the existing matrix[row#] to set the new LED on (in the image) while keeping the prior ones on. Then again you could use the [BitSet()[/i] function to change the matrix[row#]. I guess I’m still stuck in the olde schoole. :mrgreen:
So at the top of loop(), read in the joystick button. If it’s pressed then read in the X and Y joystick positions and do the above logic. Then update the display by running the SR and 4017 routine above. The loop() should execute about every 10 msecs (100 Hz).
PS - that assumes a perfect joystick that actually ranges from 0 to 1023 and is centered. You may have to do some offset and scaling math on the actual A/D reading before doing (something like) the above.](http://arduino.cc/en/Reference/BitSet)](& - Arduino Reference)

WOW! thank you for the help So heres what I have working now. I can move the joystick in all direction and an led lights up with it. I do this by having an int called colPosition and one called rowPosition this keeps track of where i am in the matrix. Then when i click the stick i use bitSet to set the matrix by doing matrix[rowPosition][colPosition] then I have it print out the matrix in the serial monitor. It works! I can see when i first start its an 8x10 of all 0s then wherever i click in the stick on the matrix the matrix will change that location from a 0 to a 1. My only problem now is getting the position of that LED to stay on and not move. I think my problem might be that I have all my code in the loop() method so when I click it just changes the led to that position. I found a library called TimedAction that allows for multithreading like in java. This way I can have my Yposition code in a method, the xposition code in another and the click in another yet. My only problem is that Im not sure how to use the variables in these methods in a whole new class like updateMatrix and how to have an led stay on while moving the joystick around. Any Ideas?

bryane92:
So heres what I have working now. I can move the joystick in all direction and an led lights up with it. I do this by having an int called colPosition and one called rowPosition this keeps track of where i am in the matrix. Then when i click the stick i use bitSet to set the matrix by doing matrix[rowPosition][colPosition] then I have it print out the matrix in the serial monitor. It works!

Well I am a bit (no pun intended) confused as to how you go wrong from the above. I'd think that the image in RAM should hold all "0s" until one (or more) bits in the image (your array of matrix[]) is set to a "1". There after I don't see how any bit ever gets reset to a "0" ???

Perhaps you could post your code ?

if(initial_click > 0 && initial_click < 6000){   
  bitSet(matrix[rowPosition][colPosition],0);
 for(int a = 0; a<10; a++){
   for(int s = 0; s <8; s++){
  Serial.print(matrix[a][s]);
   }
   Serial.println(" ");

}
 Serial.println(" "); 
    delay(1000);
}

This is pretty much saying if the joystick is clicked put a 1 in the current row and column but when it turns into a one nothing comes on

bryane92:
This is pretty much saying if the joystick is clicked put a 1 in the current row and column but when it turns into a one nothing comes on

Hmmm, so are you saying the printed (via serial monitor) image looks correct but the actual LED matrix is not the same (aka wrong) ? If so are the values inverted ... that is a logic 1 in the matrix should be a logic 0 to the LEDs ?

Or is there some larger disconnect btw the image in RAM and the actual LED output ? If so then we’re looking at an output “driver” problem.

Yeah they all start at 0 then I can change it to a one but Im not writing it to SR so maybe it knows I’m turning the bit on but im just not sending it to an output to execute the code

bryane92:
… but Im not writing it to SR …

Errrr, isn't that needed to turn an actual LED on (vs a virtual one in the matrix) ? I think so.