Interactive LED Table

Status
Not open for further replies.

kadamr

Member
Hi everyone, I was looking for guidance on a project I started some months ago. I am trying to make an interactive (touch-sensitive) LED table for my living room. I'm sure most of you are familiar with what I mean but for clarity this link isn't at all dissimilar to what I am trying to achieve. I am aiming to tackle this project in a series of steps, each more ambitious than the last. The first two steps I have a pretty good idea of how to tackle or have already addressed to some degree, however, I have no idea how to begin the last steps. Anyway, broadly speaking, this is the plan:

1. Table design and construction
2. Electronics installation for LEDs to be controlled via Teensy 3.1
3. Wifi control using something like a Raspberry Pi and coding for games etc.
4. Incorporation of touch-sensitivity using IR emitters and sensors (reflecting IR off hand for single pixel resolved 'touch' detection)

I have already progressed as far as beginning construction - a computer model of what it will look like is shown below. I've also used OctoWS2811 to program a strip of WS2812b LEDs successfully. Combining the LEDs with the completed table shouldn't be too hard, and I'm fairly confident with how to achieve this. However, to avoid complications later on I want to design the system in such a way that the IR LEDs and sensors can be easily incorporated into the existing electronics. As I have very little idea of how to do this I thought I should ask here.

LED Table.jpg

The carpentry isn't a problem at all. As for the RGB LEDs - I am using WS2812b 60 LED/m strips but cutting them into single LEDs (most cost efficient, and each 'pixel' must be 2 inches apart) and then I'll reconnect them with short lengths of wire. I had hoped to use something like very low profile copper tape instead but I don't think it will work or could handle the current - although it would have been much neater than bundles of wires! Then I will attach each strip (12 strips of 24 LEDs = 288 LEDs) to the Teensy. However, when I return to add the IR electronics later on I anticipate that I'll have to redo all the wiring, unless I plan for their future addition early on.

So what I would like help with is how to use IR sensors. Obviously there aren't 288 inputs on a Teensy for each IR sensor so presumably I have to do something like how the WS2812b LEDs work, but in reverse. I really don't know how to approach this but I imagine it's a fairly common thing in electronics. If you could describe how it's done or point me in the right direction it would be really appreciated! I would prefer being able to detect more than just ON or OFF - I would like a degree of touch between 0 and 255 for example (not touched to completely touched). My feeling is that each strip would have to be encoded into a digital data stream and then something... how...?

I would also like to code any games etc. in Java, so I thought the Teensy could take care of the pesky time-sensitive LEDs and interacting with the IR sensors while something like a Raspberry Pi could communicate with it and run the games, does this seem sensible?

A little background regarding myself: I frequently code in Java to produce software/games, however, although I understand electronics I haven't done anything like this before. Hopefully I'm not being ridiculously ambitious!

Finally, does this all seem okay or am I missing some quite fundamental/important points?

Thanks!
 
So what I would like help with is how to use IR sensors. Obviously there aren't 288 inputs on a Teensy for each IR sensor so presumably I have to do something like how the WS2812b LEDs work, but in reverse. I really don't know how to approach this but I imagine it's a fairly common thing in electronics. If you could describe how it's done or point me in the right direction it would be really appreciated! I would prefer being able to detect more than just ON or OFF - I would like a degree of touch between 0 and 255 for example (not touched to completely touched). My feeling is that each strip would have to be encoded into a digital data stream and then something... how...?

This page might help. Scroll down to "Connecting Many Buttons & Knobs/Sliders".

http://www.pjrc.com/teensy/td_midi.html

There are a lot of ways to do this. The 74HC4051 mux chips are probably the simplest and cheapest.

Another popular way is with "I/O expander" chips. Most of other interface using I2C, which you access with the Wire library. I know Adafruit, Sparkfun and others sell these on boards. I personally haven't used those I/O expander boards, but perhaps some else here has, and might recommend one?
 
I've used the MCP23017 i2c board that Adafruit sells: https://www.adafruit.com/search?q=mcp23017.

It is great for adding 16 digital inputs and/or outputs. It has 3 address pins, so you can have up to 128 inputs/outputs on the common i2c bus. With Teensy 3.1, you have the option of 2 i2c buses, so in theory you could hook up 16 MCP23017's for 256 pins. I suspect you will run into electrical problems if you have so many devices hung off of a single Teensy.

To hook up i2c devices on the Teensy 3.x, you need to add 4.7K ohm pull-up resistors (between the pins and power rail) to A4/A5, and connect A4 to the SDA pin, A5 to the SCL pin, and connect the 3.3v/ground wires. The MCP23017 will work with both 3.3 and 5 volts.

However, since you want the ability to have more than binary (on/off), it would not be appropriate for your task.
 
Last edited:
Thank you both for your advice. I may well end up going with binary touch detection but for now I will pursue using analogue chips instead. So that means the best (and simplest) option would be the 74HC4051 that you recommend. With 12 strips of 24 LEDs I will have already used up a lot of pins on the Teensy. If I need 3 more pins for controlling all the MUX chips and a further 36 or so for receiving the outputs from the MUX chips I won't have enough pins. I calculated that by 12 x 24 = 288 LEDs and then 288 / 8 for the MUX = 36 pins just for MUX outputs. This leaves me with a few questions:

1. Is there a 74HC4051 with 16 (or more) inputs rather than 8? I apologise that I'm not sure how to find this out for myself! If there was a 16 input version (therefore requiring 4 control pins instead of 3) I would need: 4 + 288 / 16 = 22 pins for the MUX chips which is not perfect but getting closer to the pin limit on the Teensy 3.1. Presumably if I used a 32 or more input MUX and didn't put each LED strip on it's own pin then I would be able to fit all the LEDs and IR sensors onto a single Teensy 3.1. Which I see as being a nice solution - but perhaps that's a bad idea? You mentioned some potential "electrical problems" - anything for me to worry about?

2. This brings me to the next question: is OctoWS2811 limited to 8 LED strips? I would prefer each of the 12 strips on their own pin for the sake of neatness/coding, however, they could all be connected to a single pin instead I guess - it would certainly give me some more pins to spare.

3. Is using the Teensy purely for controlling the LEDs and reading the IR sensors and using a separate microcontroller to run code for games/animations a sensible idea? And how does one go about getting different microcontrollers to talk to one another? If for example I used a Teensy with a Raspberry Pi (almost random choice...is there a better choice?) how do I make them communicate? This is where I show my inexperience clearly! Essential the Raspberry Pi would need to be able to say "Set pixel X, Y to this colour" and "To what degree has pixel X, Y been 'touched'?". Is this done just using regular pins or is there a clever protocol/method for this kind of thing? And is it even a good idea?

4. Lastly, I had to use a 74HC245 for my LEDs because they were flickering. I could only find a HC rather than HCT but it seems to work well. Is this okay? As I understand the only difference is the definition of voltage levels...

Cheers!
 
If you don't need extremely fast response, the i2c bus can be used to connect different chips. The standard i2c runs at 100 kHz. On the Teensy you can use the alternate i2c library to go at a higher speed. Normally, the microprocessor would run as the master and various sensors/devices run as the slave, but it should be doable to run the Teensy as a slave (I haven't done this myself). You would need to run both systems at the same voltage or use level shifting.

Alternatively, if it is just 2 processors, you could use a serial approach, connecting the UART on the pi to one of the 3 serial ports on the Teensy.

In terms of protocol, it depends. Typically you would need to define something that says for instance, if you send 'p', followed by 3 bytes to give the x, y coordinated, and then the color it would set the color. If possible you want to keep it fairly simple if you don't need the complexity. Generally after you send something, you would expect the slave to respond to say it got the data, and possibly provide more information like the touch status. If you are using serial connections, you may want to use printable characters only (on the Linux side, depending on the options, control-s/control-q can act as flow control, tabs might be expanded to spaces, etc.).
 
Thanks again for your response - really helpful! I've been thinking about using a digital approach instead of analogue and MUX chips after all. I was thinking if I could change the 0 to 5 V analogue signal from each IR sensor into 8 bits and put those into a shift register for each pixel I could then read all the 288 shift registers off for all 288 pixels with a single data and clock line. Furthermore, each pixel could have a 'touch detection level' between 0 and 255 not just ON or OFF. My concerns with this approach would be the maximum speed this could be done at. I would like to operate at 30+ frames per second for interactive games etc.. That would mean reading all 288 shift registers 30 times a second or more. I have no experience of doing this - is that an at all realistic speed?

The same speed concerns go for communicating with serial between the two microcontrollers. Could the Teensy and Raspberry Pi communicate 288 new LED colours and touch levels at 30+ fps while performing their other tasks, i.e. running animations/updating LEDs etc.? The Raspberry Pi would only have to send 3 or 4 bytes for setting a pixel colour or requesting its touch level - e.g. [MODE] [X] [Y] [COLOUR] to set pixel at x, y to whatever colour.

Finally, how can I go about changing the IR sensor's analogue signal to an 8 bit digital signal? I would want to calibrate 0 to refer to 'minimum touch' and 255 to 'maximum touch' - noting that the 'minimum touch' won't be no IR light, for example, as there is background light in the room etc. - although using modulated IR LEDs and sensors should help a lot.
 
Perhaps instead of using IR sensors you could use something like the touch (capacitive) sensors built into the Teensy. Trouble is there aren't 288 of them, but...

Consider laying out an X-Y grid of wires and small (1N914 or 1N4148) diodes at each intersection. Say 18 X and 16 Y. Now select one X column and drive it high, drive the others low. Read the logic level on all 16 Y (inputs). Drive the X low (so now all are low), and continue reading (looping) the Y lines and detect the first one to go low. That would be the one with the most capacitance on it. Loop over X to get the X position.

I don't know how well this would work in practice -- the additional touch capacitance might be too small to detect, and the results will also be noisy. You'll also have to calibrate the system (measure all X-Y points with 'hands off' and subtract that from the measurements above). YMMV

Might be best to user another Teensy for this and have the 2 communicate over I2C (although using a T3 as an I2C slave doesn't seems to work well); perhaps SPI or SCI ?

Teensy has 34 digital I/O's which is enough for this, but not for the I2C simultaneously -- but you can reuse the X lines (wouldn't want to add capacitance to the Y lines) for comms after each measurement by making the other Teensy ignore 'strange' signals.
 
It's a nice idea and I had considered using capacitive touch already but there were a few issues in addition to the ones you have mentioned. The top surface of this table is 5 mm thick glass - I can't think of a way of using a conductive material hidden behind the glass that could detect touch across the entire 2 by 2 inch pixel. If I used a thin wire it probably wouldn't detect any touch and I'd have to zigzag it across the square pixel so that it's sensitive to touch anywhere on the pixel. The colour LED shining up through the glass would silhouette the wire as well. The real killer is that I want it to be sensitive to objects as well as human touch, e.g. a dinner plate or pack of cards etc. which aren't conductive. Thanks for the idea though!

I feel the best way forward, given those limitations, is to use IR LEDs/sensors for each pixel and convert that to an 8 bit 'touch level' (0 to 255) locally (i.e. for each pixel) before sending all the data as a data stream from every pixel to the T3 (somehow??). If each sensor is immediately converted to 8 bit digital info using something like this (8 bit ADC) then I can read all the data using a shift register for each pixel and two pins on the T3. In my mind that makes sense but I'm not sure which components exist or are best. There may even be some analogue to digital 8 bit converters that go straight to an equivalent data stream as you would get using a shift register. Anybody have any ideas?
 
This might work - http://www.ti.com/general/docs/lit/getliterature.tsp?genericPartNumber=adc101c021&fileType=pdf 10-bit I2C ADC and can have 9 different addresses which simplifies connecting to the I2C bus.

If you drive the (16 ?) rows looping with only 1 on at a time, you can have 2*9 ADCs (say 9 left and 9 right, with 9 addresses in each group) on each row. They could be powered from the same signal that powers the IR LED, and all ADCs in a column (16*9) can share a single I2C channel on the Teensy as the unpowered ADCs won't interfere with the active ones on the same I2C bus. That's a lot of ADCs though, but it minimizes wiring.
 
I need to have 12 rows of 24 LEDs giving a total of 288 LEDs. I've looked around and it seems ADCs come in I2C format, like the one you found, and SPI or 'regular', i.e. 1 pin per bit versions, whatever that's really called. I don't pretend to completely understand I2C or SPI but as I understand it SPI wouldn't work because I think you need an additional pin to for each address and the T3 doesn't have 300 or so pins. However, I2C would be okay if there were enough addresses. I thought they come in 7-bit and 10-bit address versions giving 128 address (too few) or over a thousand addresses (plenty!). So I'm not sure I understand why you say these have only 9 addresses - definitely inexperience on my part, I'm sure! Anyway, I thought that each pixel (all 288) should have it's own ADC because each must have it's own IR sensor. In which case should I be looking for an 8-bit ADC with 10-bit addresses? Note: I don't really need 0 to 255 - I'd be happy with 0 to 10 but I would guess that 8-bit is as small as it gets for ADCs.

Is this a better (faster read speed or easier/cheaper) than just using 288 shift registers? I was thinking about having one 'regular' ADC connected directly into one shift register per pixel. Then the shift registers would effectively add up to a giant 8 x 288 (8 bit and 288 pixels) = 2304 shift register. I could then take the parallel data and read it off as serial chopping the 2304 bits up into groups of 8 and evaluating each of those 8 bits as a 'touch level' between 0 and 255. I'm not experienced enough to know which is better or more suitable a method. Thanks for the I2C idea - I guess the viability of that idea depends on the number of addresses being over 288? I'm not sure I understand what you meant by looping through different rows I'm afraid. But anyway, I will have more than 9 pixels per row or column unfortunately!
 
In the TI part, there are 9 different addresses to choose from. I2C does have 127 addresses, but most products can't be configured to have any arbitrary choice of those.

(Converting to your 12x24) My concept was to have 12 rows, and 24 columns on each with a set of LEDs and an ADC at each intersection. In each column there are 12 ADCs (one per row) configured with addresses 1..6 and one set of SDA&SCL lines, and 1..6, and another set of SDA&SCL. Connect the 1st pair of SDA&SCL to one T3's I2C port, and the other to another I2C port. Configure the system that when you select a column, all the ADCs on it get powered (each is < 1 mA). Your two I2C ports can now each scan the 6 addresses and read the conversions.

Here's the trick -- I think you can connect all I2C ADCs in single row with the same address, and shared SDA & SCL lines. ADCs on columns which are not selected (i.e. not powered) will not interfere with the I2C bus, so you can effectively have 24 ADCs, each with the same address, but only one powered at a time at a single address.

This is nonstandard and you'd have to confirm it works before investing too much in it. The I2C bus will be slower than normal because of all the capacitance on it.

If this 144-ADC idea doesn't work, you can still MUX the lines with port expanders, but that makes wiring and assembly more complex. Or look for 10- or 12-input ADCs, but be wary about the IR detectors picking up noise with long wires...
 
Thanks for the explanation. So the components can only choose from 9 fixed addresses so to solve that you'd use just 6 addresses for each 12-pixel column but using 2 I2C lines from the T3 to address all 12 pixels; essentially splitting the table in to an upper and lower half. To avoid accessing all the columns at once as they have the same address for a given row you would selectively power individual columns. I can see there an advantage over using shift registers as you could quickly read off a single pixel without having to go through them all one by one.

Nevertheless, I wondered what thoughts you (or anyone) have on using 288 daisy chained shift registers with a parallel to serial approach like this. I guess my thoughts are that if that worked it would be a little neater in terms of wiring and a bit more basic level (my level!). It would use a regular 8-bit output ADC rather than an I2C one.
 
I've just noticed a lot of the ADC converters are serial and I've found mention of daisy chaining them directly. That may prove the simplest solution - if anyone has any advice/knowledge regarding daisy chaining ADCs?
 
I expect the 288 shift registers could work, but perhaps you'll need care with signal integrity (ground shift, transients) over such a large area. Be sure to have decoupling caps (0.1 uF) at each of the 288 nodes. with 8-bit data, 288 nodes and 30 Hz, you'll need to clock at 70 kHz which is fine (these an probably go to over 1 MHz) -- you'll hear it on your AM radio though.

One problem is that you can't (reliably) drive 288 inputs in parallel from one wire. The edges will be relatively slow and this means the shift registers will tend to see multiple clocks per 'real' clock edge. In addition, the different shift registers will trigger at slightly different times (during the slow edge) which will mean that the data may also shift by multiple steps. A way around this is to regenerate the clock at each (of the 288) nodes with a non-inverting buffer and wire it in the opposite direction of data flow -- so if data is flowing from the last shift reg towards the first (which is feeding the T3), drive the clock from the T3 to the 1st shifter; regenerate it and drive the 2nd...

I haven't looked at the ADCs or the IR receivers -- do you also need to trigger the ADCs ? You may also need a couple of 'global' signals which will may have trouble with fast edges. One way to fix this is to use schmittt triggers -- something like 74LVC2G17 might work and the 2nd could be used as the clock regenerator above.
 
The IR sensor is just a photoresistor and the ADC samples at around 100 kHz and for the parallel 8-bit/8 pin output option updates at the same rate without triggers I think, if I understand you correctly. I see what you mean by the long lengths of wire and signal integrity, I could daisy chain the 24 pixel rows up to 12 pins on the T3 or even use a MUX to go through each row so there wouldn't be quite so many shift registers in a line. Or even do a MUX chip of 24 columns of 12 rows of shift registers instead of the other way around, i.e. many fewer shift registers daisy chained. I have seen exactly 12 daisy chained shift registers in a basic line without any extra components before for a digital clock kind of project, so it may well work okay.

I don't know if you spotted my second post just before yours - I found a site mentioning that you can daisy chain serial type ADCs (as opposed to SPI/I2C/parallel) to do almost exactly what I'm trying to; that is to say: take loads of inputs and produce one data stream. Those ADCs have a data and clock line just like shift registers - seems like what I was aiming for but already nicely packaged. Unfortunately I lost the link and can't find much more info about this method...
 
If you have ADCs just generating 8-bit digital outputs, you'll either need a trigger, or a conversion complete signal. Otherwise your shift register won't know when to latch the data. If it latches (i.e. transfers the data from its parallel inputs to its internal latches in preparation for shifting) while the ADC is changing (e.g. from 0111 to 1000), you will get corrupted data (1111 for example) that is a mix between old and new bits. Therefore you'll need a way to either control or know what's happening. The best way I can think is to trigger the ADC since the shift registers will all be latched at (approximately) the same time.
 
I don't have any experience with OctoWS2811 but I've done something vaguely similar (although simpler!) to your IR sensing problem so I thought I might offer my thoughts on how I might approach this.

Arrange the IR emitters so that each is individually addressed. Wiring as a matrix is probably easiest. Perhaps use ring counters to do this as it saves a lot of I/O.

Each 'cell' in the table has an IR detector. Use a TSL260 or similar - these have an integrated op amp which is useful.
By inserting a diode on the output of each TSL260 it should be possible to connect all of their outputs together and then to a single analogue input on your Teensy. I don't like the idea of using LDRs as detectors.

So, when you address a particular cell the analogue voltage you read should(!) correspond to the detector in that cell.
There will doubtless be issues concerning extraneous IR. It would also help if your IR sources are collimated so that light only fires upwards from your table and doesn't radiate in every direction. This might be tricky as you presumably want the visible light to be diffused. Similarly, making the cells deep with the detector at the bottom might protect against stray reflections, your hand (or whatever) will scatter the IR.

I guess I'd be inclined to build something & do some experiments! Perhaps a 4x4 arrangement would be suitably informative.
It's not obvious to me why you want analogue values from your IR sensors - a more conventional IR touch screen would be much easier to build.

The TSL260 I've cited is quite expensive if you need 288 of them :(
 
If you have ADCs just generating 8-bit digital outputs, you'll either need a trigger, or a conversion complete signal.

Yea I'm not sure how it's done but judging from a few quick tutorials on YouTube (I posted a link above) it seems pretty simple, at least for the parallel versions. However, consider the price for 288 of these ADCs and shift registers in addition to the colour LEDs and IR LEDs etc. it may not be feasible. I can buy the colour LEDs with in-built registers etc. (see OctoWS2811) for £0.31 ($0.52) each. So 300 (come as groups of 60) would cost just over £90 ($150) which is quite reasonable, especially as they are really simple to use with the OctoWS2811 library provided on here. However, the ADCs seem to be up to $5 each which would soon add up to a lot for so many. Part of the reason for looking at chainable serial ADCs was that they seem to be cheaper, easier and don't require additional components (i.e. shift registers = more money!).

There will doubtless be issues concerning extraneous IR.

So there seems to be a variety of IR sensors and LEDs. If I buy 38kHz modulated IR sensor/LED pairs then apparently most the extraneous IR from other sources will be eliminated - more expensive, however. Additionally, I had thought of a variety of ways to reduce background IR, the cell depth and shape for example, as you suggested, and even IR absorbent paint for the sides of the cells (crazy?) but this kind of stuff I will leave until I have a prototype to see how important it is. Going from what other people have done in the past it seems just using modulated IR is sufficient.

It's not obvious to me why you want analogue values from your IR sensors - a more conventional IR touch screen would be much easier to build.

The sensors seem to come in two types; they either give an analogue output, say between 0 to 5 V on a third pin, or a single digital output - either detected or not-detected. The latter is of course simplest but then each pixel can only be ON or OFF in terms of touch. I would prefer to detect different levels of touch for cells that are half covered, for example. That's why I initially wanted to use analogue signals. However, I now think that locally (each cell) changing the analogue signal to a digital 0 to 255 range would be better - so the microprocessor doesn't have to analyse 288 analogue signals. The question is then: how to do this best and, importantly, whether it's viable given the price. The only way I can see currently is using 288 serial ADCs that are daisy chained. Then the T3 would be fed 8 x 288 bits in serial. Each 8 bits represent the 'touch level/amount' for each cell. I just don't know how easy/feasible this is. Any ideas?

If it turns out that it's just too expensive, which it very well might be, then I will have to just use a binary ON/OFF touch system for each cell. In that case I would use the digital output IR sensors and just collect all 288 outputs somehow. Any ideas how to do this? I would probably try to do shift registers again but apparently the lengths of wire etc. might cause problems. In such a scenario one 24-bit shift register could collect all the digital outputs for a single row of 24 LEDs - if such a thing exists - and then they could be daisy chained (12 rows) to give 288 serial bits fed to the T3... is this okay or are there better ways?

I would still prefer the serial ADC method (for 0 to 255 touch levels) if it was possible but I can't seem to figure it out! I'd be happy with just 10 touch levels per cell!
 
Could you still use a sensor with a digit output to detect analog(ue) signals by changing the drive level on the transmitter ?
 
Could you still use a sensor with a digit output to detect analog(ue) signals by changing the drive level on the transmitter ?

I'm afraid I don't know! Someone told me a different method that I thought seemed pretty good. What do you think of using something like an ATtiny84. It says it has 12 A/D pins (all I need for one column). So I could use 24 of those (one for each row), right? And I was wrong about SPI, daisy chaining doesn't require an extra pin per address, that's only for regular multiple use. I'm not sure if I can use all the A/D pins if they are being used doing something else though (e.g. SPI)...? There must be a few different DIP microcontrollers that are cheap and have a number of A/D pins. Is there any with 24 A/D pins for example? If I use this method the price per cell is quite low. Would it be as simple as connecting each IR sensor analogue output to the ATtiny (or other DIP) and using Wire library and daisy chaining to get all the info.? Sounds like a decent solution - what am I missing?
 
That's a good idea. It can do SPI or I2C, although that takes away from the pins available in that particular part; is there on available with more I/O ? Or just use two per column. The Teensy 3.0 and 3.1 have 14 and 21 analog I/O pins - and still plenty more left for other I/O (driving the IR LED ?), but it much more expensive.
 
So using something like T3s would be far too expensive as I would need one for each column: 24 x T3s. These DIP microcontrollers are much cheaper and work fine for using just as a 12-channel 8-bit ADC with SPI/I2C. I don't know if there is one with more inputs.

Does anyone know if there is a DIP microcontroller (like an ATtiny84) with SPI capability and/or I2C (and enough available addresses, about 24) with 12 (or 24) A/D inputs after using up the SPI/I2C pins etc.?
 
Status
Not open for further replies.
Back
Top