Pages: [1]   Go Down
Author Topic: Map button matrix to integers  (Read 583 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Everyone, I have a button matrix - 64 buttons, below is some data from pressing the buttons down. I need to turn each buttons matrix position into an integer.
The first value is the integer I need to convert to, the second is the row and the third is the column. I have sampled just  a section of the button matrix presses.
Please can someone help me with the algorithm to map to the integer. I cant get something that will work for all instances:

Code:
I   C       R
----------------
48: 0x04 : 0x08
49: 0x04 : 0x04
50: 0x04 : 0x02
51: 0x04 : 0x01

52: 0x05 : 0x80
53: 0x05 : 0x40
54: 0x05 : 0x20
55: 0x05 : 0x10
56: 0x05 : 0x08
57: 0x05 : 0x04
58: 0x05 : 0x02
59: 0x05 : 0x01

60: 0x06 : 0x80
61: 0x06 : 0x40
62: 0x06 : 0x20
63: 0x06 : 0x10
64: 0x06 : 0x08
65: 0x06 : 0x04
66: 0x06 : 0x02
67: 0x06 : 0x01

68: 0x07 : 0x80
69: 0x07 : 0x40
70: 0x07 : 0x20
71: 0x07 : 0x10
72: 0x07 : 0x08
Thanks
Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 65
Posts: 2934
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you tried the Keypad library? http://arduino.cc/playground/
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The problem with using the keypad library is I have to trial and error what row and what column values are what button pressed, and then store it in a map. From my test data there is clearly a pattern, so i would rather the algorithm that maps from one to the other and would like some help figuring it out, if anyone can help
Thanks
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So i was successfuly in mapping the posiiton in the array to the midi. now I am interested in optimizing polling the key matrix. Please can anyone suggest improvements to the following polling algorithm:

Code:
void KeyMatrix::pollKeys() {
uint8_t cRows = 0, cCols = 0;
for (uint8_t maskRows = 1; maskRows != 0; maskRows += maskRows) {
PORTK = ~maskRows; //low one col with all others pull-up
_delay_us(10); //after setting the state of a pin there may need to be a delay
if (~PINH != 0) {
for (uint8_t maskCols = 1; maskCols != 0; maskCols += maskCols) {
if (~PINH & maskCols) {
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
button[cRows][cCols].time = flagmS;
}
button[cRows][cCols].isPressed = true;
} else
button[cRows][cCols].isPressed = false;
if (cRows > 4){
sendNote(cRows, cCols);
}

cCols++;
}
cCols = 0;
}
cRows++;
}
}

Thanks
Logged

Queens, New York
Offline Offline
Faraday Member
**
Karma: 65
Posts: 2934
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Both
Quote
for (uint8_t maskCols = 1; maskCols != 0; maskCols += maskCols) {
and
Quote
for (uint8_t maskRows = 1; maskRows != 0; maskRows += maskRows) {
Make no sense.

maskCols / Rows will never be nor get to zero to exit the for loops, because your starting at 1 and incrementing. You could just have easily wrote "for(;smiley-wink"

How does this work?
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Westbrook, CT
Offline Offline
Full Member
***
Karma: 2
Posts: 139
"Why should I bother with made-up games when there are so many real ones going on." (c) Kurt Vonnegut
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

How can you map readings of buttons to ints if they are boolean readings? They only have on/off states. However if you are talking about mapping them in the sense of their position, then consider using a multiple dimension array.

http://arduino.cc/forum/index.php?topic=44228.0

Or here is an example:

Code:
array [x][y] {
boolean read = digitalRead(array [x][y]);
}

Logged

Arduino Uno R3
Mac OSX Lion


Queens, New York
Offline Offline
Faraday Member
**
Karma: 65
Posts: 2934
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
array [x][y] {
boolean read = digitalRead(array [x][y]);
}
That does not make sense either. You cannot read 2 pins at the sametime with just one digital read. I don't know, maybe we finally can, and I just didn't get the memo.
« Last Edit: March 18, 2013, 09:58:11 am by HazardsMind » Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Firstly you can read two pins at the same time, infact you can read 8 if you read the whole port:

uint8_t a = PINB;

would read the whole of PINB into a.

Secondly:
Quote
Both
Quote
for (uint8_t maskCols = 1; maskCols != 0; maskCols += maskCols) {
and
Quote
for (uint8_t maskRows = 1; maskRows != 0; maskRows += maskRows) {
Make no sense.

maskCols / Rows will never be nor get to zero to exit the for loops, because your starting at 1 and incrementing. You could just have easily wrote "for(;"

How does this work?
Is also not true.
When you bit shift a mask so the left so that the one goes off the end, what value do you think the mask is equal to?
Yes! 0.
i.e
take the following:
value = 0b00000001;
If I shift:
value = (1 << 7);
I get 0b10000000;
Shift it one more value to the left and now value = 0.

Quote
How can you map readings of buttons to ints if they are boolean readings?
Very easily. A boolean value firstly is just a 1 or a 0, not an on/off. This is just a way for us to think about it - like true false. It just so happens that it can be stored in 1 bit. That doesnt stop an integer being able to store it. You may need a cast but so what?
Secondly, I never said anything about an int.
Infact if I had thoguth it was necessary to the problem I would have displayed that button is a struct:
Code:
struct data {
unsigned int time;
bool isPressed;
bool wasPressed;
uint8_t midiNote;
};
see bools...

Anyway, I think I cracked it, so thank you for the efforts.
Logged

Westbrook, CT
Offline Offline
Full Member
***
Karma: 2
Posts: 139
"Why should I bother with made-up games when there are so many real ones going on." (c) Kurt Vonnegut
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That does not make sense either. You cannot read 2 pins at the sametime with just one digital read. I don't know, maybe we finally can, and I just didn't get the memo.

Maybee, we both didn't get the memo smiley-grin But what I meant in my code is reading the value of a button that is on a specific X Y coordinate. A 2D array must be used for this to work.
Logged

Arduino Uno R3
Mac OSX Lion


Queens, New York
Offline Offline
Faraday Member
**
Karma: 65
Posts: 2934
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You cannot read 2 pins at the sametime with just one digital read
Direct port manipulation is different, that I know you can read multiple pins, but with a regular Digital/Analog read, you can't.

You should probably post your full code.
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

0
Offline Offline
Full Member
***
Karma: 0
Posts: 142
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK.
This is my class (.cpp):
Code:
KeyMatrix::KeyMatrix(Serial *serial, Midi *midi) {
this->serial = serial;
this->serial->printf("key matrix setup\n");
this->midi = midi;

//Prepare the rows for reading
DDRH = 0b00000000; //All Ts are inputs
PORTH = 0b11111111; //All pullups enabled
//read from PINH

DDRK = 0b11111111;//MK and BR are outputs - one is pulled low at a given time.
PORTK = 0b11111111; //Set them high for now. We can pull one low when scanning.
for (uint8_t i = 0; i < 8; i++) {
for (uint8_t j = 0; j < 7; j++) {
button[i][j].isPressed = false;
button[i][j].wasPressed = false;
button[i][j].midiNote = 12 + i*8 + (7-log(j)/log(2));
}
}
}

void KeyMatrix::pollKeys() {
uint8_t cRows = 0, cCols = 0;
for (uint8_t maskRows = 1; maskRows != 0; maskRows += maskRows) {
PORTK = ~maskRows; //low one col with all others pull-up
_delay_us(10); //after setting the state of a pin there may need to be a delay
if (~PINH != 0) {
for (uint8_t maskCols = 1; maskCols != 0; maskCols += maskCols) {
if (~PINH & maskCols) {
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
button[cRows][cCols].time = flagmS;
}
button[cRows][cCols].isPressed = true;
} else {
button[cRows][cCols].isPressed = false;
}
if (cRows >= 4 && cCols != 0){
sendNote(cRows, cCols);
}

cCols++;
}
cCols = 0;
}
cRows++;
}
}

void KeyMatrix::sendNote(uint8_t cRows, uint8_t cCols){

if (button[cRows][cCols].isPressed != button[cRows][cCols].wasPressed) {
//needs to be changed for midi output once debugging has confirmed the correct thing is occuring:
serial->printf("i: %d, j: %d. Time: %u, Note: %u\n",cRows, cCols, (button[cRows][cCols].time - button[cRows-4][cCols].time), button[cRows][cCols].midiNote);//output the midi note & add to arpeggiator array?
button[cRows][cCols].wasPressed = button[cRows][cCols].isPressed;
}
}
In terms of compilation everything works. I dont have access to the header file from where I am, but the struct that you need the details of is in my previous post.
This line:
Code:
button[i][j].midiNote = 12 + i*8 + (7-log(j)/log(2));
is trying to map the matrix location to the integer value I am trying to get out, however if j is zero I have problems...

I have not used Arduino methods here as i want it to be as fast as possible to poll, hence my use of masks. However the fact that I am incrementing cRows and cCols worries me that I may be losing any benefits.
« Last Edit: March 20, 2013, 06:18:38 am by a.mlw.walker » Logged

Pages: [1]   Go Up
Jump to: