Mulitplex Keypad Output
#1
Posted 07 March 2012 - 05:42 PM
#2
Posted 07 March 2012 - 07:16 PM
#3
Posted 07 March 2012 - 07:31 PM
If you want to connect this directly to the Netduino, you are going to need all 8 connections (less if you dont need every key, but what would be the fun in that?).
If you want to use as few pins as possible on your Netduino, then you are going to have to have some sort of external circuit to do this encoding for you. Personally, I would use a cheap PIC and then have that interfaced to the Netduino, though you could definitely use a Netduino mini for the purpose. There are even chips dedicated to this task.
Image was borrowed from an Arduino example found here.
#4
Posted 07 March 2012 - 08:00 PM
#5
Posted 07 March 2012 - 08:19 PM
Attached Files
#6
Posted 07 March 2012 - 08:32 PM
#7
Posted 08 March 2012 - 08:10 AM
Attached Files
#8
Posted 08 March 2012 - 12:21 PM
#9
Posted 08 March 2012 - 11:52 PM
#10
Posted 09 March 2012 - 07:12 AM
#11
Posted 09 March 2012 - 06:51 PM
When I saw Mario's idea I did not understand how it worked!
Once a friend had explained it I thought it was a great idea since it did not require three ICs as my idea did.
In Mario's original version I believe it is necessary to write many different SPI words to the 74HC595 to poll all of the rows and columns.
Here is my variation of Mario's idea, which I think only requires one 8-bit SPI write to be made to scan the whole matrix.
As with Mario's original, a bigger matrix can be scanned by adding another 74HC595.
The changes are to swap around the existing diodes and resistors, connect the ST_CP and SH_CP signals together, and to add four new diodes.
Before you go any further, you will need to take a copy of the diagram - this will not make much sense otherwise!
Joining the ST_CP and SH_CP lines makes the 74HC595 act more like a normal shift register (the outputs will change bit by bit as the SPI data is clocked into it). Using the 74HC595, there is one slight complication, the first data bit sent by the Netduino will not appear at Q0 until one clock cycle after it was sent. Also the last bit sent will appear at the start of the next transfer. (This is because of the latches in the 74HC595).
If you could get hold of a 74HC164 shift register, the first bit would appear immediately. But I think the 74HC595 is easier to find.
I may have made a mistake with the bit ordering in this part:
The data we send to the 74HC595 is sent MSBit (most significant bit) first. So at the end of the transfer the first bit sent ends up at Q6 (not Q7 due to delay). So I am proposing to send the value 0x01. On the first write this will set all the outputs low, and the '1' will be stuck at the start of the shift register. (We will ignore the return value from this SPI operation). On the next write (and all subsequent writes) when we send 0x01 again, the first clock makes the previous missing '1' appear at Q0, and then move all the way along to Q7 followed by zeros.
This pattern is shown in the yellow note at the top of the circuit.
Lets assume firstly that all of the matrix switches are OFF. (The diagram only shows three of the switches for clarity.)
The SPI data to the Netduino 'MISO' will remain high '1' for all the bits. This is because none of the voltages on the row connections A,B,C,D are LOW '0', so the resistor R1 pulls the MISO data line HIGH '1'.
Sending an SPI word to the 74HC595 will not change this because the diodes D0-D3 can only pull the rows A-D HIGH '1' not LOW '0'.
So when all the switches are OFF we receive 0xFF from the circuit (OFF = 0xFF - that's easy to remember!). This is shown in the yellow note on the left.
Now consider switch switch C-4 (Row C Column 4).
If C-4 is ON, the following happens:
- When Q7 is LOW '0' AND Q2 is LOW '0', the diode 'C' will conduct through the switch and R7 to Q7, and this pulls the MISO signal down to ground '0'.
- When Q2 is HIGH '1', diode D2 conducts, this makes diode 'C' turn OFF because the voltage at ROW 'C' is now higher, and so the MISO signal is pulled HIGH '1' by resistor R1.
- When Q7 is HIGH '1', there is no longer a path to ground through resistor R7, again diode 'C' turns off, and so the MISO signal is pulled HIGH '1' by resistor R1.
So when C-4 is pressed the data received by the Netduino will be 0x84, D-4 will give 0x88, and D-3 will give 0x48.
Possible mistakes:
- I may have got the bit ordering back to front (e.g. everything is LSbit first not MSbit),
- I am assuming that the Netduino samples the MISO signal on a falling clock edge. If I have got this wrong, the data read will be shifted by one bit.
So Glen if you are brave enough to try this, let us know how it goes.
(Use Mario's resistor values R1 = 47K, R4-7 = 4K7.)
I am ready to edit this post when the mistake reports start to arrive.
Paul
Attached Files
#12
Posted 11 March 2012 - 11:19 AM
Some early feedback. Having built your circuit on a breadboard, I'm finding that the value I'm getting back from the SPI WriteRead never changes from 0xFF. I'm currently re-working the build to make sure I have everything correct and will report back later this evening.
Software-wise I have this simple test rig .
public class Program { public static void Main() { // write your code here SPI spiDriver = new SPI(new SPI.Configuration(Pins.GPIO_NONE, false, 0, 0, false, false, 32, SPI.SPI_module.SPI1)); byte[] readbuffer = new byte[1]; byte[] writebuffer = new byte[1]; while (true) { writebuffer[0] = 0x01; readbuffer[0] = 0x00; spiDriver.WriteRead(writebuffer, readbuffer); Debug.Print(readbuffer[0].ToString()); Thread.Sleep(100); } } }
Many thanks for your continued support and interest in my quest ..
#13
Posted 11 March 2012 - 11:28 AM
#14
Posted 11 March 2012 - 01:26 PM
Did you spot that I forgot to connect the OE line to ground?
Sorry about that.
Hi Paul,
Yes, I had spotted that, I have also tied the MR line high, rather than drive it though the Netduino. Is that correct. One other thing I have thought about as well, and this is probably the clincher. I am using LED's rather than ordinary diodes, mainly as I don't have enough in my kit bag, but also I thought it would be cool to visualise the effect of closing the keypad switches. I'm thinking, and am on very new-be territory now, that the resistor R1 should be a lower value if I'm using LED's.
Glen
#15
Posted 11 March 2012 - 02:00 PM
Hi Paul,
Yes, I had spotted that, I have also tied the MR line high, rather than drive it though the Netduino. Is that correct. One other thing I have thought about as well, and this is probably the clincher. I am using LED's rather than ordinary diodes, mainly as I don't have enough in my kit bag, but also I thought it would be cool to visualise the effect of closing the keypad switches. I'm thinking, and am on very new-be territory now, that the resistor R1 should be a lower value if I'm using LED's.
Glen
Hello Glen, and hello Paul (when he'll be here).
Hacking is more than a fun...is somewhat an art!...Your supposed failure in the missing diodes is actually an amazing feature of the keypad. (and don't be shy: confess that it was a long awaited project in your mind!)
Anyway, led is also diodes, but they have an higher voltage drop than the ordinary diodes. The circuit should work anyway, but it's better if you power the whole circuit using +5V. The greater drop caused by the led will be compensated by the higher supply voltage.
No matter about the Netduino, 'cos is +5V-tolerant.
I'm here, waiting for news!
Cheers
#16
Posted 11 March 2012 - 02:28 PM
#17
Posted 11 March 2012 - 02:32 PM
Hi, I'm at Marwell Zoo eating lunch watching the Emu.
Wish were there!
Have fun!
#18
Posted 11 March 2012 - 07:33 PM
#19
Posted 11 March 2012 - 07:51 PM
How do I get c# to print in hexadecimal?
e.g.
Glens code:
byte[] writebuffer = new byte[1]; byte[] readbuffer = new byte[1]; while (true) { writebuffer[0] = 0x01; readbuffer[0] = 0x00; spiDriver.WriteRead(writebuffer, readbuffer); Debug.Print(readbuffer[0].ToString());
I think I should be able to write
readbuffer[0].ToString("X")but I get exceptions.
How do I do this?
(It is too difficult to debug the code in decimal.)
Paul
#20
Posted 11 March 2012 - 08:09 PM
I changed the clock edge in Glen's code:
public class Program { public static void Main() { // write your code here SPI spiDriver = new SPI(new SPI.Configuration(Pins.GPIO_NONE, false, 0, 0, false, true, 32, SPI.SPI_module.SPI1)); byte[] readbuffer = new byte[1]; byte[] writebuffer = new byte[1]; while (true) { writebuffer[0] = 0x01; readbuffer[0] = 0x00; spiDriver.WriteRead(writebuffer, readbuffer); if (readbuffer[0] != 0xFF) { Debug.Print("Col: " + ((readbuffer[0] >> 4) & 0xF).ToString() + " Row: " + ((readbuffer[0]) & 0xF).ToString()); } Thread.Sleep(100); } } }
Now I get:
Col: 1 Row: 1 Col: 1 Row: 2 Col: 1 Row: 4 Col: 1 Row: 8 Col: 2 Row: 1 Col: 2 Row: 2 Col: 2 Row: 4 Col: 2 Row: 8 Col: 4 Row: 1 Col: 4 Row: 2 Col: 4 Row: 4 Col: 4 Row: 8 Col: 8 Row: 1 Col: 8 Row: 2 Col: 8 Row: 4 Col: 8 Row: 8
EDIT: There is one slight issue - the rows and columns are back to front! Q7 seems to be column 1 not column 4, Q3 seems to be row A not row D.
It is as though the order in which the bits are read is backwards.
Thanks Mario for the original idea, and thanks Glen for the code.
I think I should Wiki this.
I'll correct the circuit diagram to show the !OE signal first.
Paul
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users