Go Down

Topic: 3x3 Matrix - WASD (Read 4657 times) previous topic - next topic

Xeyow

Oct 09, 2014, 11:53 am Last Edit: Oct 10, 2014, 06:46 am by Xeyow Reason: 1
Hello there Arduino users. I`m new on this forum and i hope there`s someone here that can help me. Well: i managed to create on my breadboard a 3x3 led matrix. Using some simple for`s instructions in void setup() my matrix looks like these (i will use pins number - like i connected the leds to the arduino). I named the matrix led.

11 12 13
8 9 10
5 6 7

What i want to do: when the program uploads, the led[2][2] (the one in the center) to light up. Using serial monitor, type W (for up) and so on with A S D, that will control the possition of the lighten led. So if i type W, move led UP, and so on... But when i light the next led, turn down the previous led.

I can`t make it work... Any help? This is my code for the letter W.

Code: [Select]
int i=2; int j=2;
void loop()
{
 digitalWrite(led[i][j], HIGH); //turns on led[2][2] the center one
 if(Serial.available() > 0)
 {
   char litera = Serial.read();
   if(litera == 'w')
   {
     digitalWrite(led[i][j], LOW); //should turn the [2][2] led down
     delay(100);
     digitalWrite(led[i--][j], HIGH);//should turn the upper led
     delay(1500);
   }
 }
}


I need to get it work for at least the letter W (up direction), then i think i can do it for the other letters, using a SWITCH CASE. Thanks for reading, hope there`s someone that can help me

PaulRB

#1
Oct 09, 2014, 12:23 pm Last Edit: Oct 09, 2014, 12:26 pm by PaulRB Reason: 1
Hi,

First of all, ALWAYS post your complete sketch. Don't ask us to guess what the rest looks like.

Secondly, ALWAYS use code tags (the # button above the box where you type your post). If you read what you posted, you will see that not using code tags has altered the sketch as you see it on your screen. For example I suspect you typed
Code: [Select]
led[i][j] but this has appeared as "led[j]".

Paul

Xeyow

Code: [Select]
int led[3][3];

void setup()
{   
  int n=11;
  for(int j=1;j<=3;j++)
    led[1][j]=n++;
   
  n=8;
  for(int j=1;j<=3;j++)
    led[2][j]=n++;
   
  n=5;
  for(int j=1;j<=3;j++)
    led[3][j]=n++;
   
  for(int i=1;i<=3;i++)
    for(int k=1;k<=3;k++)
      pinMode(led[i][k], OUTPUT);
  Serial.begin(9600);     
}

int i=2; int j=2;
void loop()
{
  digitalWrite(led[i][j], HIGH);
  if(Serial.available() > 0)
  {
    char litera = Serial.read();
    if(litera == 'w')
    {
      digitalWrite(led[i][j], LOW);
      delay(100);
      digitalWrite(led[i--][j], HIGH);
      delay(1500);
    }
  }
}


So this is my full code. In the setup function i managed to make a matrix like my leds are connected to the arduino:

11 12 13
8 9 10
5 6 7


I assume that the problem is in the IF instruction, but it`s logical that i turn off the led i turned on before (led[2][2]). and light up the one above (i=i-1 or i-- so it`s the above row). But it does not work.

Xeyow

#3
Oct 09, 2014, 08:58 pm Last Edit: Oct 09, 2014, 08:59 pm by Xeyow Reason: 1
As i can see... the result i come up to is the following one:

The matrix of leds starts with led[2][2] turned on, after entering in serial monitor: w, the led above turns on, but the other one (led[2][2]) remains turned on. I think it`s because void loop repeats this in the IF that compares litera with w:

Code: [Select]
digitalWrite(led[i][j], LOW);

PaulRB

Hi,

There is something you do not understand yet about arrays in C/C++.

When you make an array like "int a[3]", the indexes you should use are a[0], a[1] and a[2]. You must not use a[3]. If you do, there will be no warning message, but you will get an incorrect/unexpected result.

This is different to BASIC and some other languages.

Paul

Xeyow

#5
Oct 10, 2014, 06:45 am Last Edit: Oct 10, 2014, 06:49 am by Xeyow Reason: 1
Using the declaration i made in the setup, led[2][2] is the center one. From what you said, the center one would be a[1][1]....

Let's say i make the matrix declaration like you said, it would be: (i won't use brakets)

a00 a01 a02
a10 a11 a12
a20 a21 a22


I need to make the instruction for letter ("litera" in romanian) 'w'. I just can't turn off the starting led, and turn on the above one, and after turning this 'w' led, it would stay turned on untill i type a new letter (w a s d) in serial monitor.

PaulRB

So now you know about array indexes in C, does your sketch now work correctly?

Another important thing to learn is the difference between saying "--i" and "i--". The former decrements i before its value is used and the latter decrements i after its value is used.

Xeyow

I will tell you if it works after i get home. I'll try what you told me. Hope it works...

Grumpy_Mike

What do you think your loop function does?
When it receives a 'w' it will put the pin low for 0.1 second at all other times it will be high. This will be hard to see.

Xeyow

#9
Oct 10, 2014, 08:36 am Last Edit: Oct 10, 2014, 08:38 am by Xeyow Reason: 1
At first: when i type w, the center led blinks. The second time i type w, the above led turns on but the center one still stays turned on.
Can you help me with the loop function?

Grumpy_Mike

That is because of this line
Code: [Select]
      digitalWrite(led[i--][j], HIGH);
It changes the value of the variable I, it decrementing it.
As nothing ever increments it the more you input w the smaller it gets until it is negitave.

What exactly do you want to do and how are the LEDs wired up? Unless we know the circuit the code makes little sense.

Also look at how you initialise that array, you are going round the houses with the way you do it.
You can do it in the same statement that you declair the array.

Xeyow

My setup is this: all the 9 leds have ground(-) in common, so they are wired up in parallel. Next, i will type the matrix as i wired up the positive legs to the arduino:

11 12 13
8 9 10
5 6 7

What i want to do: enter in serial monitor letter: "s" for START, and turn on the center led (pin 9). Next: enter in serial monitor one of the following letters: w (turn on above led), a (turn on left led), s (turn on under led) and d (turn on right led). I know that sometimes the counter i or j will be negative. When i type a letter, turn off the previous led and turn on the next one, depending the dorection ( w a s d ). And at the end, when i want to stop playing with leds, type "t" for STOP, and turn off the last led.

Hope you understood what i want...

Grumpy_Mike

Quote
My setup is this: all the 9 leds have ground(-) in common,

Ok, I assume that you have series resistors in each LED and with that wiring a HIGH will turn it on and a LOW will turn it off.

Quote
so they are wired up in parallel.

No those are the wrong words. Nothing is in parallel.

So let's look at your code:-
Code: [Select]

int i=2; int j=2;
void loop()
{
  digitalWrite(led[i][j], HIGH);
  if(Serial.available() > 0)
  {
    char litera = Serial.read();
    if(litera == 'w')
    {
      digitalWrite(led[i][j], LOW);
      delay(100);
      digitalWrite(led[i--][j], HIGH);
      delay(1500);
    }
  }
}

For a start why not have meaningful names? Change i and j to row and column.
Next change the variables when you have inputted data. Remember the index values to use are 0 to 2. Make the index variables wrap round. That is if they exceed the limits of the array in either direction correct them.
An example of doing this is:-
Code: [Select]

if(row > 2) row = 0;
if(row < 0) row = 2;

When you receive an 's' make row and column both equal to 1, then turn on the LED given by  row and column.

Then when you get a 'w', first turn off the LED given by row and column, then decrement column, adjust for wrap round and then turn on the LED given by  row and column.
The same thing for the other directions.

When you get 't' for stop just turn off the LED given by row and column.

Hope that helps.

Xeyow

#13
Oct 10, 2014, 11:27 am Last Edit: Oct 10, 2014, 11:30 am by Xeyow Reason: 1
Now i discovered that the leds are not in parallel. I will arrive home in about 4 hours and i will try your way.... Hope it works.

One more q:

Is there any way i can make serial monitor "auto-enter" what i type in? So i won't need to hit enter after every letter?

Xeyow

#14
Oct 10, 2014, 12:10 pm Last Edit: Oct 10, 2014, 12:14 pm by Xeyow Reason: 1
8) I feel good now that using your help i managed to do it.

Code: [Select]
int led[3][3];
void setup()
{    
 int n=11;
 for(int col=0;col<3;col++)
   led[0][col]=n++;
   
 n=8;
 for(int col=0;col<3;col++)
   led[1][col]=n++;
   
 n=5;
 for(int col=0;col<3;col++)
   led[2][col]=n++;
   
 for(int row=0;row<3;row++)
   for(int col=0;col<3;col++)
     pinMode(led[row][col], OUTPUT);
 Serial.begin(9600);    
}

int row=1;
int col=1;

void loop()
{
 if(Serial.available() > 0)
 {
   char litera = Serial.read();
   if(litera == 'e') //e for start
     digitalWrite(led[1][1], HIGH);
     else
       if(litera == 'w')
       {
         digitalWrite(led[row][col], LOW);
         row=row-1;
         if(row > 2)
           row = 0;
         if(row < 0)
           row = 2;
         digitalWrite(led[row][col], HIGH);
       }
       else
         if(litera == 's')
         {
           digitalWrite(led[row][col], LOW);
           row=row+1;
           if(row > 2)
             row = 0;
           if(row < 0)
             row = 2;
           digitalWrite(led[row][col], HIGH);
       }
 }
}


I didn`t write the instructions for A and D because i wanted to see if what i did untill now works. And it works. Every time i type W or S, the previous led turns off and the next one turns on. Thanks very much.

Last Q: is there any chance to make serial monitor (or using other way) to "auto-enter", so every time i type a letter, "he" hits enter?

Thanks for your time to help me.  :D

Go Up