Diode Matrix - wtf am I not understanding

Ok so, facts on the wire: using a Teensy. I have ripped the guts from an old Yamaha PSS-170 except for the two diode matrices, one for the keys, the other for the various buttons. The keyboard has 6 columns and 8 rows, but not that many keys. Here is a photo:

As you can see, I have soldered in Red wires for the Rows and Blue for the Columns. The reds are connected to pins 16-23, the blues pins 0-1. At the moment the multimeter is clamped to the wire that would go to 23 and grounded to the Teensy, and is reading voltage from my keypress.

If I run

pinMode(5, OUTPUT);
digitalWrite(5, HIGH);

and then press the lowest F# key on the bed, I can measure 2.94v at the other end of the row that is wired into pin 0 with the meter. If I set it to LOW, the meter reads 0.

I have attempted many combinations of INPUT_PULLUP and OUTPUT and so forth and I cannot seem to make the thing reliably recognize when a key has been pressed or not, I just get nothing but 1s or 0s.

I’d check out the functioning of the diode matrix by drawing a schematic and check it with a multimeter before involving the microcontroller as you want to be absolutely sure quite how the physical hardware behaves before adding in the teeny and the various electrical characteristics it can present depending on quite how it gets configured. This will also spot gotcha bits of hardware like spurious diodes performing other nefarious functions.

I have verified that combination of wires with the multimeter. If I can make that circuit behave correctly, the rest should follow, but I can’t even make that single one say if it’s pressed or not.

***whole keyboard was functional before I eviscerated it. :>

I did, however, have another go at it with the multimeter, and it does appear that one of my wire connections is bad, the fifth key of every group of six doesn’t work. It would not be difficult, just tedious, to replace the diodes, it’s an 80s PCB, everything is discrete and through-hole, but they seem fine.

There is a voltage drop of about .5v across em, but that should not be enough to kill a digital signal. This is totally me not getting it, and I’m frankly suspicious of the information and example code that google is giving me, I don’t trust anything on the internet anymore…

So the page I linked to, what he is doing is putting the pullups on the columns, which are on the “open” side of the diode, that allows the signal through, and then driving the rows as OUTPUT and LOW, and then attempting to read the column pins.

To me, this shouldn’t work - signal should not travel from the row pin to the column pin, because diodes do not let signal go that way, right?

The only way I could see it working, is if by driving OUTPUT/LOW on the row pin, if you make it a sink, sending a negative voltage, but at this point I can’t even keep typing because nothing is falling together in my head that allows you to read the column pin, which is on the “send” side of the diode, by modifying the row pin, which is on the “out” side.

Drawing out a schematic really helps as it gives you a clear understanding of what you expect to happen. Simply repeating on one key your are certain about is an important test of the teensy end,and it should resolve concerns about what will and will not work in your situation. Presumably it’s a scanned matrix so you want to be absolutely sure what actually constitutes an acceptable transition that will reflect a key going down. Was it originally touch sensitive or simply on and off key sensing? And what voltage levels do the teensy use and at what threshold do they switch? A potentiometer can be quite helpful on that. What mode should the output scans driving the rows be operated in when they are not selected? High impedence, pulled low, pulled high? Does this state affect other rows, and are the diodes actually the way round your circuit assumes they are? It quite possible that you may be switching high for active line and the original design switched low… What mode should the input sense ends be set to when they scanning, is there a debounce delay required? Perhaps build a test rig with a couple of diodes just to be sure quite what is going on…

Sorry if this is stuff you’ve checked but whenever I’ve approached this sort of thing in an experimental way I’ve ended up having to get really methodical. One fo my key scanners taught me an awful lot about settling times and the correct time to wait for circuits to settle and ended up multiplying the overall clock by three to get a good solid trusted sense in the middle of the pulse without edge effects. .

It’s pretty clearly a bunch of discrete diodes on a PCB. I have mapped the thing out and if you have a look at that original photo, you can see that I’m supplying 3.3v from the Teensy, and it’s coming out the other side of a pressed key at 2.94 I think.

What mode should the output scans driving the rows be operated in when they are not selected?
High impedence, pulled low, pulled high?
What mode should the input sense ends be set to when they scanning

These are indeed the very questions I was hoping someone could offer some insight on.

Perhaps build a test rig with a couple of diodes just to be sure quite what is going on…

As previously mentioned, I have identified (in the photo) one specific diode which is fully functional, according to my multimeter. I have been trying various things with that one pair and key for days now and none of the materials out there are making any sense to me.

I’d be surprised if 2.94 v isn’t a good sensible (ie can be emphatically sensed) value as long as the pin is in the right mode.

Diodes are generally pretty rugged in these sorts of roles so it would be surprising if they are trashed.

PSS170_servicemanual.pdf (20.6 MB)

I don’t follow your wiring. Keyboard diode matrices work by multiplexing output pins and reading input pins. You need to make sure that one set (row/column) is connected to the current direction (input/output) and the other set to the other direction. This is defined by the diodes polarity and position. You then enable one output at a time and read all the inputs to build up the system of the whole keyboard.

Courtesy of Wyleu, here is the schematic I’m attempting to cannibalize:

So you’re saying, I set the Nx inputs(?) to INPUT_PULLUP, and then cycle through the Bx outputs, setting them to OUTPUT LOW one by each while the others stay as INPUT, and then measure the Nx inputs for LOW?

Doesn’t that imply that current is flowing backward through the diodes? This is where I’m confused.

Anyways I did attempt that, but I will try once more… tomorrow probably…

No, the opposite. Set B1…B8 as input with pull-down resistors. Set N1 high and read B1…B8 to get the state of C5, F4#, etc… Then set N1 low and N2 high and read B1…B8 to get the state of B5, F4, etc.

[Edit] You could also do it the way you suggested. If N1 is pulled high be weak resistor then if C5 is pressed when B1 is low, input N1 would be pulled down and so a low reading would indicate the key pressed. You may even find out more reliable and microcontrollers tend to have built-in pull-up resistors more often than pull-down so you may not need external components.

1 Like

Built-in pullup is indeed the case on Teensy, not so sure about pulldown.

I think Teensy does have pull-down. The INPUT_PULLDOWN option was added to the lib a few years ago. But I would recommend trying the pull-up option. It should work. I did something similar with an 88-key weighted keyboard and a Bluepill board, reusing the blocking diodes for the keys and switches.

Note that if the keyboard has velocity sensing them there are likely two switch contacts pre key, one for when the key is released and one for when the key is pressed. You calculate velocity by measuring the time between these switches changing state.

The diodes are there to block signals and avoid duplicate key detection. If you assert row 1 then press two keys in column 1 in row 1 and row 2, there would be an electrical path through both of these keys and the signal would appear on row 1 & row 2. Any other keys pressed on row 2 would also be detected as being on row 1. The diode blocks the signal hence keeping the rows/columns seperate.

You can usually do things in reverse if you invert most of the signals. There are a few reasons why sourcing current from an input (using pull-up resistors) and pulling the input down to ground are advantageous including:

  • Simple sensors - the sensor can be a switch with one side connected to ground - no need to supply voltage / current from the switch.
  • Less susceptable to noise - A switch that connects to a solid ground will drain current well avoiding fluctuations. A current sourcing switch is more prone to variation, e.g. due to a single current source being shared with multiple and varying parallel paths.
  • More common - mostly because of the above reasons, chip manufacturers tend to include internal weak pull-up resistors more often than pull-down.

I would always recommend using pull-up and switched ground where possible. People often find this less intuitive but it is just a matter of persective.

1 Like

I’m actually clear on what’s going on in the diode matrix - I actually did sit down and map out the whole thing because I failed to find the service doc where @wyleu is apparently a document wizard. It’s the electrical theory that I’m still all jumbled up on.

Part my problem is that once I figured out how to study very late in life, the documents that I discovered, was told were legit, and read, were the public domain NEETS documents from the US Navy (if I remember correctly) and they reverse positive and negative throughout. Their explanation makes as much sense as the other one, but I have learned since, is in opposition to the rest of the electronics-using universe.

On top of that I still think of electronics as plumbing with atoms, and while that sort of works, it really doesn’t, anymore than you can use Euclidian geometry to measure distances on a sphere.

You and someone on the Teensy forums have assured me that this wiring works, so that means that it was my code that caused it not to work, and that is a situation that actually makes me quite happy and encouraged. My mistakes I can fix, but if my mistake is trying to do something impossible, I can’t. :>

edit: and yes, apparently the Teensy I’m using in particular does have both pullup and pulldown, so in theory I can do either. But I’ve got two 4.1 coming in the mail, which have enough pins for both the keybed and the buttons… and enough CPU to just pack a little synth right in there too if I take the notion.

The device itself is nothing exciting, generic 100-voice 2opFM “rompler” type and the keys are not velo-sensitive. I have a small collection of Pi2s and Pi3s that are good enough to do all the basic noises, so as soon as I get these diodes wrangled my plan is to start making these boring toys more fun and give them out as gifts, of course with the VNC interface and the ability to plug in a real controller and so forth.

Ultimate goal is to get all my synthy friends hooked on zynths. :>

From Teensy Code

#define INPUT 0
#define OUTPUT 1
#define INPUT_PULLUP 2
#define INPUT_PULLDOWN 3
#define OUTPUT_OPENDRAIN 4
#define INPUT_DISABLE 5

These are set up for each specific pin using
pinMode(pin, mode);

so to set pin 5 to be an Input pin with a Pulldown resistor in circuit then you use
pinMode(5, INPUT_PULLDOWN);

To define the modes
#define INPUT 0
Simply set this pin to be read as an input. It is the responsibility of the builder to ensure that the value is 1 or 0 to be read properly. If the pin is left unconnected by a switch say , so the pin floats then it will almost definitely pick up local radio signals and generate a stream of completely random 1’s and 0’s which is probably not what you want as it would frequently mis-trigger when your switch wasn’t closed. . .

#define OUTPUT 1
The pin is configured as an output which will be either a 1 or a 0 depending on the software. The odds are it will be complementary pair of transistors between the positive rail and ov … When one transistor is on the other is off, so the pin will change from supply voltage to 0v when set by
pinMode(5, OUTPUT);

#define INPUT_PULLUP 2

This input mode and it’s PULLDOWN friend gets you out of the disconnected switch problem mentioned in the sectio above, and it means that the microcontroller connects a resistor from the Positive supply to the input pin. What this means is that if the pin isn’t specifically set to + supply volt or 0v by the builder will be set to supply voltage via the resistor. So this makes a very good switch because by using this
pinMode(5, INPUT_PULLUP);

You can read the state of the switch because if the switch is pressed the pin is hard wired to the 0V and the resistor will simply leak a little current but will not pull the switch back to supply voltage until the switch is released. . .

#define INPUT_PULLDOWN 3

This is simply the opposite of the case above but would be used where a switch is turning on a supply voltage so you want to PULLDOWN the line normally and use the switch to supply the supply voltage to read the pin and make sure if it’s one or zero.

#define OUTPUT_OPENDRAIN 4

This output mechanaim uses only the one output switch to turn on and off and allow a current to flow from the positive supply down throu’ this Field effect transistor switch to OV. It the sort of thing that allows an LED to be tuend on and off, but it is limited by the amount of cuurent that can flow throu each i/o pin on the microcontroller.

#define INPUT_DISABLE 5

Turns off the pin completely …The state is possibly unknown.

Seems quite good…

1 Like

@jtode - I’m not sure what you meant by that statement, and I may be stating something you already know, but here goes - the .5V voltage drop you’re seeing is normal, not in any way a symptom of a problem with the diodes. The forward voltage drop of silicon diodes is usually around .6 to .7 volts.

I think both “conventional”-wrong-backwards flow and “electron”-right-correct flow are alive and flourishing in the “electronics-using universe”. The NEETS course is pretty good, although it stills show signs of coming from the vacuum tube era. I like Electronic Principles by Malvino for the same subject matter. Although it does assume you know some of the basics that NEETS covers.

I think of it as plumbing with electrons, and the atoms are sorta-kinda collectively the pipes. I like the Euclidean geometry metaphor-analogy - Korzybski uses it in many of his works, including Science and Sanity.

What a wonderful goal!

1 Like

I studied “Physical Electronics” at university which is the very low level, physics of electronic and electron behaviour. I still tend to consider most electronics as plumbing. It is a good analogy that lets you understand most circuits quickly. It doesn’t really matter which way the circuit flows (current or electrons) as long as you use just one approach. It is far more common to consider the flow of current when working on electronic circuits. I’m surprised that anyone teaches the opposite outside a physics class! Macro electronics is based around current flow with components like diodes schematically and physically indicating current flow.

I’m sorry if my use of the word “current” to differentiate from electron flow offends anyone. Like I said earlier, it kinda doesn’t matter.

Let your flow be happy and gay!

1 Like

I remember when encountering a diode matrix the first time I found it confusing, so let me try to explain - forgive me if these is overly detailed:

Let’s assume as in your description that you set Nx inputs to INPUT_PULLUP, Bx are set to OUTPUT. With no keys pressed, the inputs will be high of course, thanks to the pull-up resistors. Now say you set B8 low, and press the F1 key. The left side - cathode - of diode D1 will then be 0V, and the right hand side - anode - will be connected to 3.3 V via the input pull-up resistor. Since the voltage on the anode is higher than on the cathode the diode will conduct. Current will flow from the pull-up resistor through the diode to 0V.

In this state, an ideal diode would have the same potential on the anode and cathode - after all it’s conducting, so it will behave like a conductor, i.e. a short circuit. The cathode is fixed a 0V due to it being connected to a LOW output, so the anode will also be at 0V. With the anode connected to the input, it will drop to 0V too. There will be current flowing in the pull-up resistor, namely exactly the current needed to get a voltage drop of 3.3V over it.

A real (silicon) diode has a voltage drop of about 0.5 to 0.7 V, so in reality the voltage on the input will be in that range; it is still low enough to be interpreted as a LOW level.

One thing that seems slightly suspicious to me is that with a supply voltage of 3.3 V you measure 2.94 V after the diode voltage drop. The 1SS176 looks to be a standard silicon diode, and so will have a voltage drop of at least 0.5 V - indeed the curves in the data sheet indicate it should be 0.6 V minimum. But I don’t have a good explanation for the discrepancy. Indeed, the higher the value of the input pull-up resistor the lower the voltage drop and the higher the voltage, but 0.36 V seems to low for a silicon diode.

One thing I’m wondering here is if there might be a timing problem in your program, i.e. you set the outputs at one point and read the input values immediately after, and the time between the two operations is to small to allow the voltage on the input to change. There could be several reasons for this, for instance that when setting an output pin there is a slight propagation delay though the microcontroller so that the pin state is actually not changed until a few ten or hundred nanoseconds later.

Does the Teensy have a LED or perhaps you could connect one to an output (with appropriate current limit resistor in series)? My idea would be to do an experiment where you set a single output to the active state (LOW in the example here, but it depends on which way you are driving the matrix - it seems you have tried both using Nx as inputs with pullups, driving single Bx lines low, and the reverse, using Bx as inputs with pulldowns, driving single Nx lines high, both of which should work), and simply in your program copy the corresponding input pin state to the LED, so that you can observe what the Teensy sees in a simple manner. Put the bit copying code in an infinite loop so that the LED will show the state of the input pin in real time.

The idea here is to first try and duplicate what you are seeing with your multimeter, i.e. reading a single row or column line, and go on from there. Once you have verified that the Teensy can in fact read the state of the pin properly, you can start implementing your scanning routine.

1 Like