6
\$\begingroup\$

My 2 year-old nephew likes nothing more than to plug/unplug RCA jacks. Whenever he's around, tv inputs get switched, audio plugs are swapped, etc.

So... For his birthday, I decided to build him a little box with a panel full of RCA jacks and some buttons and nice blinky leds and beepy noises. The idea is to have an array of about 12 RCA jacks, into which he can plug cables to his heart's content. To give him some feedback, an arduino will generate different blinky led patterns and wacky noises (using the Mozzi library) depending on which pairs of RCA jacks are connected.

My question is... What's an efficient way to detect which pairs of RCA jacks are shorted via a cable? Ideally, for 12 RCA jacks, I would want to uniquely detect up to 6 connected pairs.

I have a few ideas (below), but I can't help but think there must be a more elegant solution to the problem.

Possible combinations Some combinatorics tells me that the number of ways I can choose p pairs out of n jacks is:

C(n,p) = n!/((n-2p)!*p!*2^p)

That's basically the number of permutations of 2p jacks out of n (=n!/((n-2p)! ), divided by number of pair reversal combinations 2^p (i.e. reversing a cable), and divided by the number of pair permutations p! (i.e. the order of plugging in the cables)

So, for 12 jacks and using anywhere from 0 to 6 cables, there are: sum(C(12,p) for p=0..6) = 140152 possible pairings (I think...)

Some ideas I came up with:

1) connect each of 12 jacks to an arduino digital IO pin with a pullup resistor. Scan for pairings by setting one pin to OUTPUT LOW and checking for a low signal on the other eleven (configured as INPUT pins). Repeat 11x (each time, setting another one of the twelve to OUTPUT LOW)

Advantage: uniquely detect any of the 140152 possible pairings

Disadvantage: Lots of pins in use

2) Create a string of resistors from 5V to ground, via the 12 jacks, like this: GND - R - p1 - R - p2 - R - p3 - R - p4 - R - ... - p12 - 5V

Connect pin p1 to an analog input as well. When a cable is plugged in to two jacks, some of the resistors are bypassed, changing the voltage at pin p1. For equal values of R, we can determine only the total number of resistors bypassed. For sequentially doubling values of R (1,2,4,8,...), we can deduce from the voltage at p1 exactly which resistors have been bypassed (sort of... we'll be limited by noise and the arduino's 10 bit ADC)

Advantage: Simple, only 1 analog pin used

Disadvantage: This method can't uniquely identify all 140152 pairings (notably when plugging in multiple cables), but I don't think my 2-year old nephew will notice the shortcoming.

3) Something something RLC filter... I have no idea what I'm talking about.

\$\endgroup\$
10
  • \$\begingroup\$ Why not your first idea? Even for a modest Atmel chip (I have no idea about which exact types they put in Arduino's, as it's not really a pro-resource, so I can't officially answer to that respect) 12 pins in use is close to nothing. Most Atmels I stock have 14+ I/O pins and only very, very few have less than 12. I'm assuming the "Mozzi Library" uses a only one or two PWM blocks and/or pins for "audio". I'd be surprised if a 'duino board in the €10,- vicinity can't support it all. \$\endgroup\$
    – Asmyldof
    Dec 28, 2015 at 15:55
  • \$\begingroup\$ You're right, there's no reason why solution 1 won't work, and I will probably end up going that route. At this point I see it more as an interesting electronics puzzle, because I feel there must be some very elegant circuitry solution, which eludes me. \$\endgroup\$
    – Jesuis
    Dec 28, 2015 at 16:13
  • \$\begingroup\$ There are plenty of different pulse and multiplexing routes that can limit the pin count in different ways, but the circuitry would have to go somewhere and probably cost, on a small order from local supplier, the same as a whole extra Arduino connected by serial, I2C or SPI, so I would guess, start with one 'duino, buy a second if you run out after all to be a more effective solution. Of course, if you want to theorise more about advanced trickery rather than 'what's the best choice here', I'll be back in January for a more aimed question ;-). \$\endgroup\$
    – Asmyldof
    Dec 28, 2015 at 17:02
  • \$\begingroup\$ Damn you Sir! I trust you were inspired by this. An afternoon and two dozen backs-of-envelopes gone, never to be used again!. 12RCAs fit into a 4 line CharliePlex nicely, and as they're 2 pole, you could isolate the shields and use that as an extra degree of freedom, against Olin's suggestion. Still can't think of anything better than 12 pins and go through the detection exhaustively, as per your option 1. \$\endgroup\$
    – Neil_UK
    Dec 28, 2015 at 17:03
  • \$\begingroup\$ Charlieplexing springs to mind: electronics.stackexchange.com/a/37362/8627 \$\endgroup\$
    – jippie
    Dec 28, 2015 at 17:07

3 Answers 3

3
\$\begingroup\$

Connect all the shields to ground, so the only thing to detect is which center pins are connected to which other center pins.

This is pretty easy to do with scanning. Set up the electronics so that each pin can be driven one way but passively pulled the other. Since built-in pullups are more common in microcontrollers, I'll assume each line has a passive pullup and can be actively driven low.

Now you simply go thru the possible combinations. Drive pin 1 low (all others passively pulled high), and read all the pins. The one that is low is connected to pin 1. Now drive pin 2 low and release all others and read all the pins, etc.

Let's say you do this slowly, like every 100 µs. Each 100 µs interrupt you read the pins from the previous output state, then switch to the new output state. That requires 12 interrupts or 1.2 ms to get the complete picture of what is connected to what. That's way faster than humans can notice, so even at this slow scanning rate the processor will know what it connected to what instantaneously in human time.

\$\endgroup\$
3
\$\begingroup\$

An Arduino UNO has 18pins, and the more small-enclosure friendly Nano has 20pins. So they would be fine for approach 1. There would be 6 or 8 pins respectively for noises and blinky-LEDs.

It'd only need one pin for noise, so a Nano would have 7 pins for LEDs.

If you drive LEDs with multiplexing, it could drive \$3\times4=12\$ LEDs, or \$2\times3\times4=24\$ LEDs with 'Charlieplexing'. I'd probably limit it to \$2\times3\times3=18\$ LEDs, so 3 LEDs in each group/string.

For 3 LEDs in a 'string' the pins should be able to drive them directly, keep the total current/pin to under 20mA, and it should be fine.

\$\endgroup\$
2
  • \$\begingroup\$ "Charlieplex" on 7 pins would allow 7*6 = 42 leds, modern leds are bright enough at 2mA. \$\endgroup\$ Dec 28, 2015 at 18:58
  • 1
    \$\begingroup\$ another LED drive approach would be to use the same pins that drive the jacks to drive 12 LEDs, now when the wire is in place both leds would light up at the same time. \$\endgroup\$ Dec 28, 2015 at 19:01
1
\$\begingroup\$

Okay, Let me dive into this shortly (for me, so no more than an hour or two ;-) ).

As a first response, that I thought of when I started typing about licking down below:
Three year old nephews have very small bodies and a lot of nervous system development left to do, so it is ultimately important you make sure that you get only RoHS and preferably RoHS/REACH parts, since Lead and other heavy metals are no good for tiny nervous systems (nor for adult ones, but we can cope with minor amounts over longer time spans). So don't go to your bargain bins for wire or boxes, but check decent outlets, so you know it's been qualified. Also use lead free solder. For hobby work often I don't fuss about it with people and in fact I use a lot of Leaded myself in prototyping still, but when you're talking about developing children, it's somewhat different.

On to the answer I started with:

First up, as I made clear in the comments, there is no way that making an elaborate architecture around a reduced number of I/O pins is going to be cheaper or more time efficient than just buying the MCU platform with enough I/O pins, but since you say you'd be interested in those tricks anyway:

Let's pretend we're living in the times where a processor platform with some I/O costs €100 to $130 (yes that change of type is intentional) of equivalent now-day-money and the one you'd need for full software solution with "Whoaaaa-many" I/O pins would cost you €300 to $350. In which case trickery may be useful indeed:

There are many ways, both analogue and digital with the inclusion of extra wiring, diodes, resistors and/or capacitors to detect combinatorial paths up to the entire totality of your full 140152 options with less than 12 pins.
I just copied that number by the way, because I'm actually too busy-ish right now to check your maths.

So also, as a heads up: The below methods are not fully thought out, as I would normally do (and waste half a day or more), but lightly explained ideas.

They need feasibility checks and cost estimations as well as more maths, which I'm leaving out due to lack of time.

So treat this as "a way to look at some options I manage to present to you before I need to be back to being useful", rather than a full and complete design guide to exact components and schematics.

Your options (the equations are assuming perfect analogue and/or digital pathways):

  1. Scan 12 pins, as you point out yourself.
  2. Use ADC tricks to achieve (ADC granularity)^n = 140152 levels of detection.
  3. Use timer+ADC tricks to achieve (n-1)x(Timer Granularity)x(ADC Granularity) = 140152+ levels of detection. (the maths here are a bit iffy around the n-value)
  4. Use timer+Comperator tricks to achieve (Timer Granularity)^n = 140152 levels of detection.
  5. Do weird shit with tonal filtering using RLC (your option 3) to achieve 140152+ levels using about (estimating heavily) 2 independent PWM pins and 1 or 2 ADC pins.
  6. Introduce diodes into the system and Charlieplex (this is probably the easiest one).

Where all options have n as being the number of pins you'd need minimally and granularity is just fancy speak for "number of different levels this object can express measured in least significant bits", or what I also refer to as "levels" when preceded by a number (often the number 140152).

Option 1: Scanning

We've been into that in comments and other answers. Not for here.

Option 2: ADC Trickery alone

Work out the pins... So... Your ADC is probably 1024 levels, so to get the number with pure ADC trickery you'd need only 2 ADC pins, but also some very extremely high grade analogue parts to be able to amplify 1/1024th of a response to full scale with only 10 LSB of error. You can also get a 24bit Audio ADC, by the way, probably easier to get that level of granularity.

Using carefully chosen resistive networks, possibly including some capacitances to make sure the mesh of wires and higher resistances doesn't become some resonant antenna for your local radio broadcasts, you can detect the "disappearance" of every single junction in a change in the analogue signal measured across a part of that network. Most common solutions include the "R-2R" series and "R-2R-4R-8R-....." series. I have no time to work it out exactly, but several paths to that exist.

Using a low input offset (JFET) op-amp that signal can be buffered to allow you to get near enough to a 19-ish bit accuracy, but you will need a metal box and proper grounding, as well as some wiring consideration. And when your nephew licks the contacts all kinds of lights and sounds could start playing, because licking is very noisy, electrically speaking.

Then you'd need a good enough ADC (>19 bit resolution, good differential and integral linearity, etc) to capture that, or create a 20 bit internal ADC with a 1 to 1024 voltage division and 1024 factor amplification on the lower response. That last bit, however, is quite tricky to get right over noise and thermal effects, but maybe if you over-sample you can get out 19 to 21 bits of accuracy on a lucky try. Messy though.

3. Timer + ADC tricks:

This one requires more post-maths than full text, but is pretty fun. Here you create a waveform on one pin. It can be a pulse or square wave or even PWM, it's all up to the person doing the maths.

You feed that through an array or network of capacitors that get bridged by wires plugged in using one known resistor. By again decisively choosing capacitances, like in the resistor network, you can get a full picture of gaps and shorts in it. All capacitors should have a voltage rated above the maximum voltage (5V, or 12V, or 3.3V, whatever your digital drive can generate and your analogue system can measure).

If you would use one 8 bit timer to create a variable pulse width, a 10bit ADC to measure the resulting voltage at a changeable interval using another 8 bit timer, I'd be amazed if you couldn't get near a million levels of capacitor measurement range. Change the signal generator to a 16bit timer and it'll easily be tens to hundreds of millions.

Using large capacitances you may need an output buffer, to more strongly force the signal to get reliable results. There's likely to be some driver/buffer chip under €1 that will drive 100mA or more into large-ish capacitances, but usually MCU pins don't like those and start generating more of a triangle or sine output, rather than square wave, making the maths all moot.

Option 4: Use timer and comperator tricks

This is basically the same as above, but rather than measuring the level at an interval, you set a comperator to measure (many Atmels, and as such 'duino's, have internal comperators) one precise, known threshold across the capacitor that is charged after you set an output pin high. By measuring the time it takes to get there, you can use the charge/discharge response of a capacitor to develop the maths to figure out how large the capacitor is, based on the time it takes to charge. By using a 16bit timer and some R/C tuning you get up to 30000+ levels of capacitor sensing.

Add an 8 bit timer (software or hardware) that increments one each time the 16bit one overflows and you can get more than 15 million levels of capacitor detection.

Usually the comperator is more stable than the ADC, so time-to-time and value-to-value will be more stable, but the detection resolution with the same number of timer bits will be quite a bit lower. Apart from that the comperator trick is a lot easier to write code for, as it doesn't include all kinds of moiré-like effects on the two timers.

Option 5: RLC tricks with tone generation

This one needs quite a bit of pen and paper to make really universal, so it'll stay even more conceptual (I hope - already out of time at this point).

PWM tones can possibly be a second (and third) audio channel, if that library works cleanly enough.

You can generate a tone, which then gets through several stages of filters that may stack and short depending on connections. Depending on which tone you make you also get overtones, since you'll create the tone digitally, unless you introduce audio DACs. For small currents the RLC filters needed to let through or filter out one single tone can be relatively small, even in the lower ranges of audio frequency.

If every connector has a band-stop into the connector and another band-pass from the connector to ground, I believe there is a way to do this with a very limited number of tone generators and ADCs, but I lack the time to properly work it out. Just make a small peak-detector with a diode, capacitor and discharge resistor to turn the tone back into a DC signal.

Option 6:"Introduce diodes and charlieplex:

Here you can add diodes across some of the signal pins and ground rings of the connectors. Some in the one direction, some in the other. Again, time is running out, so this will have to keep it at the upper-upper theory level. You may then also need some resistors to make it work properly, but then you can simplify the digital drive and sense technique, you may even also be able to use an ADC more effectively using diodes and charlieplexed outputs with resistors.

But to see if and how that works you may have to take it from here. My thought basically was: If you have diode in one direction, and another one in the other, they combine and become a short to ground for both direction. If you combine two in the same direction they are short in only one direction. Throw in some resistors and possibly some more diode networks and you may end up with a 6 or 7 I/O purely digital way to sense all your possible combinations.

Here I stop.

\$\endgroup\$
6
  • \$\begingroup\$ Nice post, interesting ideas. You seem focused on cost. Although not really the issue, it is interesting to consider this question as it it was asked a few decades ago, when microcontrollers and IO were as cheap as they are now... IMO, the most interesting tricks are born out of necessity when working with limited resources. \$\endgroup\$
    – Jesuis
    Dec 30, 2015 at 0:19
  • \$\begingroup\$ One thing I still don't quite get regarding any solution involving a network (resistors, capacitors or otherwise) and then detecting which network elements have been bypassed... It seems that I can always think of indistinguishable pairing combinations by considering one short between two distant nodes. Any additional shorted node pair located "inside" of the first two, will not produce any change (therefore, not detectable), since the entire path was already shorted by the first pairing.... \$\endgroup\$
    – Jesuis
    Dec 30, 2015 at 0:26
  • \$\begingroup\$ @Jesuis The cost thing is more a convince other people to read it thing. Most people these days think "jeez, Arduino € 10,-, who cares", so I join in, to save from wasting 2 hours on that ^^ and nobody reading it. \$\endgroup\$
    – Asmyldof
    Dec 30, 2015 at 0:49
  • \$\begingroup\$ As for the networks, had I time (2AM now, bed time) I might make a small 4 pin example, but you're thinking of a single string, whereas with a network I do not mean "just a ladder" but an actual network, where side tracks will influence the overall characteristic, even when their envelopes are already combined out. Admittedly, with 12 pins, that becomes a bit of a pita to get right if it's your first attempt. \$\endgroup\$
    – Asmyldof
    Dec 30, 2015 at 0:51
  • \$\begingroup\$ Ah, of course... I'm an idiot. I actually was thinking about a 2D network, but decided it would have the same problem as a ladder. It doesn't... To convince myself I drew it up in Falstad circuit simulator: goo.gl/yJdchM All 4 combinations of switch postitions give a different voltage at the output, even though one cable is "inside" the other.. No way in hell I'm going to try to do this IRL... \$\endgroup\$
    – Jesuis
    Dec 30, 2015 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.