1
\$\begingroup\$

General Description

(A rough block diagram is linked below.)

I rewired my organ with digital electronics. I have a microcontroller (Teensy LC) that is used to scan the keys (pressed or not). It communicates with a host GNU/Linux machine via USB which handles the keystates and decides whether a "key press" or "key release" has happened, and further processing happens.

The microcontroller only has 23 digital I/O pins, but the organ has some 200 switches (keys and stops) to monitor. I use 16:1 analog multiplexers to scan through the keys. Each multiplexer has its "1" side to one of the microcontroller's I/O pins, and each of the pins on the multiplexers' "16" side is connected to an organ key (switch). There is a common cathode set up so that if a key is pressed, the input going to the multiplexer is "high" (3.3v in this case), and if a key is not pressed, the input is floating. There shouldn't be any floating, though, because I configured my microcontroller to pull down its inputs.

The multiplexers' channels are selected digitally. Since there are 16 channels, I have 4 channel selection bits. All the multiplexers' channels are selected in tandem. That is, the four channel selection bits are sent from the microcontroller to all the multiplexers at the same time. In this way, my scanning algorithm is basically:

 uint8_t buf[RAWHID_TX_SIZE]; /*This gets initialized to 0*/
 uint8_t pins[16] = {4,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20};
 for (uint8_t channel{0}; channel < 16; ++channel)
 {
     //Pins 0-3 are output to multiplexers for channel selection.
     digitalWrite(0, channel & 1);
     digitalWrite(1, channel & (1<<1));
     digitalWrite(2, channel & (1<<2));
     digitalWrite(3, channel & (1<<3));
     for (uint8_t pin{0}; pin < 16; ++pin)
     {
         auto val = digitalRead(pins[pin]);
         if (val == HIGH)
             buf[current_byte] |= 1 << current_bit;
          //increments current_bit and rolls current_byte if necessary.
         increment_bit();
     }
 }

The problem

When I press and hold a key, other keys are ghosted randomly.

One hypothesis for this behaviour is that this is due to inductance: the wires from the keys were wrapped in their original (1950s) bundle and are routed from the keys down to my electronics: perhaps a 5-foot run. I thought that the current going through a wire was inducing a weak current in nearby wires. Some pragmatic arguments for this hypotheses:

  1. Adding a resistor to the common cathode helps alleviate the symptoms. In fact, the problem got better to the extent that the organ was playable! If too much resistance was added, the wanted keys wouldn't stay on when pressed, and if too little resistance, unwanted keys would sound intermittently.
  2. The pedal register was worse, and it has the longest run of bundled wires.
  3. The problem is worse when multiple keys are pressed. this presumably induces more unwanted current to unwanted keys.

Arguments against this hypothesis:

  1. the current to wanted keys should be minimal since the input impedance on the microcontroller INPUT pins is great.
  2. I re-re-wired the organ taking all the wires out of their bundles, and the problem persists. Now, the wires don't route all the way to one side before coming back to the center where the electronics are; they come straight down to the electronics. This provides shorter wires, and no close bundling. for the pedals, I now am using ribbon cables rather than the original bundle.

I have no other hypotheses.

Some Things I've Tried

  1. As stated above, I have rerewired the instrument to remove all bundles of wires, and the problem is still quite bad. It may be a little better than when there were bundles.
  2. Also as stated above, I've added various levels of resistance to the common cathode. It helps, but I'm unsatisfied with that solution because it causes the wanted current to be reduced. This causes wanted notes sometimes to stop and start sounding which is unacceptable.
  3. I've added waits in my microcontroller loop. I thought that perhaps the internal pull down resistors and common cathode didn't have enough time to settle after choosing a different multiplexer channel. Adding several milliseconds (even several hundreds of milliseconds) of "settle" time didn't help the problem.

My block diagram:

https://docs.google.com/drawings/d/1t0-678GEKiEOc5mfhdrkhAOrTBnCsvIwJLRNt2-gQYk/edit?usp=sharing

\$\endgroup\$
  • \$\begingroup\$ analog mux: seems less than ideal. I would use a shift register like 74HC165 or a digital mux and put the pull ups on the keyboard side. 8-way resistor packages are fairly cheap. \$\endgroup\$ – Jasen Apr 11 '17 at 0:55
  • \$\begingroup\$ I sat down to spend more time diagnosing the problems, and it "just worked". I played the organ for a few weeks, and now it just doesn't work. I'll sit down to diagnose it soon...perhaps it'll "just work" again. I'm thinking there may be shorts in the wiring that only happen when I move parts around. \$\endgroup\$ – Limited Atonement May 16 '17 at 2:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.