Cube contact detection

Hi!

I’m developing some smart cubes with an ESP-07 enabling wireless communication with a server, but the question fits also for arduino.

I need to sense when one cube is touching another one. These are the rules:

1- I can just use the only analog input in the ESP-07. This means I only have one analog pin to do the magic.

1- One cube could be joined with other cube by any of the sides.

2- There is no need to detect which is the specific side where another cube was attached, I just need to detect an “attached” event

I have an idea but I can’t build it yet, probably because my limited knowledge of electronics. I designed a circuit with 7 resistors and for each resistor a switch that jump the resistor. So, initially all the resistors are “on” , i.e., the switches are opened. When I close a switch I can sense it because there is a voltage drop that I can detect reading A0 (see the file attached!). The big question is, how to close that switches just by proximity!

I hope I had explained myself, any ideas are very welcomed!!!

The big question is, how to close that switches just by proximity!

Make the switch a reed switch and put a magnet in the other cube. When they are joined the magnet will trigger the switch. You might have to use ore than one switch and magnet to cover the whole of the side of the cube.

Their is no point in all those resistors the way you have wired them because any single closure will produce the same drop. Just wire all of the switches in parallel.

Yes, reed switch. Will do the job.

As added bonus: if you add resistors in series with the reed switch, you can actually even tell which side is touched by the different analog value!

Be aware that the ESP's ADC can read only 0-1V, not 0-3.3V as you may expect.

The easiest is to wire your reed contacts high side in that case.

1k resistor between ADC and GND.
2k3 resistor + reed between Vcc and ADC for the first side (ADC about 1024).
3k for the second side, ADC about 676
4k third side, ADC 520
5k5 fourth side, ADC 375
12k fifth side, ADC 260
24k sixth side, ADC 135

That idea. Use convenient resistor values. First must be at least 2k3 to bring the ADC voltage down to 1V.

Thanks both for your answers! Indeed I had already considered the reed switch option, actually an alternative of it because I need to sense the "join" event from both cubes at the same time... this means that I might put the reed switch and a magnet (to activate the other's cube switch) next to it. This could be a mess right? The alternative that I considered is this one: How to Make a Reed Switch - YouTube

Basically is a reed switch that get activated with the repulsion force of a magnet, and putting one of these in each side of the blocks might trigger the events exactly at the same time. This event is sent via wifi to a server where I can synchronize events by time and deduct which were the joined cubes.

The only drawback of this approach is that when users try to join the blocks they might experience an small repulsion force that could feel a bit contradictory and non intuitive. However I'm planning to overcome this issue using adhesive tapes on the the contours of the sides in order to make the cubes stay attached rather than getting away of each other as a result of the repulsion force. I could also use more magnets in the corners and make the blocks attract each other (opposite polarities) but is imposible to find a configuration where all sides could be joined with all sides of any of the blocks... isn't it? I uploaded a new drawing (
circuit-switches-blocks-.jpg ) explaining the circuit and the switches

Grumpy_Mike:
Their is no point in all those resistors the way you have wired them because any single closure will produce the same drop. Just wire all of the switches in parallel.

I put 6 resistor with 6 switches in order to detect each side and cover the case where the cube has more than one joined cube (see the drawing attached).

wvmarle:
Be aware that the ESP's ADC can read only 0-1V, not 0-3.3V as you may expect.

The easiest is to wire your reed contacts high side in that case.

1k resistor between ADC and GND.
2k3 resistor + reed between Vcc and ADC for the first side (ADC about 1024).
3k for the second side, ADC about 676
4k third side, ADC 520
5k5 fourth side, ADC 375
12k fifth side, ADC 260
24k sixth side, ADC 135

That idea. Use convenient resistor values. First must be at least 2k3 to bring the ADC voltage down to 1V.

Good, but this only works when we assume that the cube has only one cube joined. What happens when there are many cubes joined to a single one? I.e., when many of the switches are activated at the same time...For sure there is a way to calculate the voltage for each switches combination, but the math there is not that easy... right?

To wrap up, the alternative reed switch in theory is fine, but I'm not yet sure because I'm not sure about the precission I could get from these home made switches. And also the repulsion feeling make me have some doubts about this solution...

thank you so much again!!!

smarichal:
I put 6 resistor with 6 switches in order to detect each side and cover the case where the cube has more than one joined cube (see the drawing attached).

No attachment.

Good, but this only works when we assume that the cube has only one cube joined. What happens when there are many cubes joined to a single one? I.e., when many of the switches are activated at the same time...For sure there is a way to calculate the voltage for each switches combination, but the math there is not that easy... right?

The maths is not hard at all - you'd do that in a spreadsheet and provide a lookup table as the values are fixed anyway.
Choosing suitable resistor values is a lot harder, as you have to make sure no two combinations end up being identical. I don't know if this is even possible, I assume it is.
Distinguishing all 720 options is practically impossible. You have only 1024 values in the ADC so its inherent inaccuracy causes overlap, your resistor values are also never exact, even at 0.5% tolerance you probably totally mess up your lookup table. A 16-bit ADC may be able to do this.
I assumed no more than one contact at a time - if you may have up to 6 contacts it's a whole different story. Then at best you can tell how many contacts you make, by using the same resistor values in all six faces.

What may work is a magnetic sensor which can sense field strengths. Place magnets in both faces, the moment two magnets start to attract each other (especially when they're very close together) the magnetic field around them - especially behind them, i.e. towards the inside of the cube - should change drastically. That you should be able to sense. Then you're just left with the problem of multiplexing that onto a single analog pin.

I put 6 resistor with 6 switches in order to detect each side and cover the case where the cube has more than one joined cube

Yes I know, but the way you wired them up meant that their is no way you could tell what side was connected only that a side was connected.

Just noticed the second attachment that appeared at the OP. Hereby both, easier than downloading:

smarichal:
efaa1f05be5bd5f3c41b876a1db0d78c1547ce38.png
21e639a29a3e31daa17e39dd1757511f42dc6a47.jpg

smarichal: please don’t add attachments to an older post, they’re not noticed!

wvmarle:
Then at best you can tell how many contacts you make, by using the same resistor values in all six faces.

I agree, that's why I put the same resistor values, I just sense the "join event" regardles of the face of the cube.
Then, using the time tag of the event I'd be able to infeer which are the joined cubes.

wvmarle:
What may work is a magnetic sensor which can sense field strengths. Place magnets in both faces, the moment two magnets start to attract each other (especially when they're very close together)

But there isn't a magnet polarity settings where the cubes always attract each other... magnets will attract and sometimes repeal, depending on the polarities!

Grumpy_Mike:
Yes I know, but the way you wired them up meant that their is no way you could tell what side was connected only that a side was connected.

No, I can't.. but I can sense contact in all the sides. Using a single resistor I would only be able to sense contact in one side at a time. That's the main difference and in this context it matters...

Well, I think that there is no simple solution using just the analog input. Maybe it's time to move forward and constraint the interaction a little bit. I think that I'll just enable the joining action of the cubes in 2 faces and I'll use the physical design of the cubes to highlight this fact, i.e., that the user could easily identify which are the faces that might be joined. Let's say that in this scenario I could use 2 digital pins (one for each attachable face). This might be much simpler.... in this scenario, which is the best solution for you?

thanks again!

Ps:

wvmarle:
Just noticed the second attachment that appeared at the OP. Hereby both, easier than downloading:
smarichal: please don't add attachments to an older post, they're not noticed!

Sorry, I couldn't find the option to attach a file in the response, so I had to edit the original post.

smarichal:
Sorry, I couldn't find the option to attach a file in the response, so I had to edit the original post.

You can do this if you click Preview first.

I'm starting to wonder where that "must use just the analog pin" requirement comes from, as you now seem to have dropped this already. Use five digital pins and you can sense very easily which face makes contact.

No, I can't.. but I can sense contact in all the sides. Using a single resistor I would only be able to sense contact in one side at a time. That's the main difference and in this context it matters...

You are spectacularly missing my point.

I said the way you wired it up you can't. Wire it up another way and you can.

You need a digital to analogue converter. Their are two basic ways of making one just using resistors, one is called a binary weighted resistor network, the other is called a R/2R ladder. It is the latter type you want and is easy to make. If you look at circuits on the net just replace the final op amp with your Arduino's analogue input.

wvmarle:
You can do this if you click Preview first.

Thanks!

wvmarle:
I'm starting to wonder where that "must use just the analog pin" requirement comes from, as you now seem to have dropped this already. Use five digital pins and you can sense very easily which face makes contact.

Why do you worry about the initial post constraints and why do you think that I would ask something different than I need? This is the project guidance forum, isn't it? It's starting to feel like an interrogation...

I can't use five digital pins because I need some of the digital pins for leds, vibration motors and a buzzer. But let's say that I could use 5 digital pins as you suggested... I still don't know which is the best way to sense proximity in a cube using 5 digital pins, can you please help me?

thank you!

This is the project guidance forum, isn’t it? It’s starting to feel like an interrogation.

This is because beginners often have no idea of the capability of the system. It is quite common for some one to come on and say they are running out of digital pins with no idea they can use the analogue input pins as digital input and output pins. So we ask about pecieved constraints. Sorry if it feels like interrogation but their are so many options unless we narrow them down you could be lead down the wrong path.

smarichal:
Why do you worry about the initial post constraints and why do you think that I would ask something different than I need? This is the project guidance forum, isn't it? It's starting to feel like an interrogation...

  1. the initial "must use just the ADC" sounds like a school assignment type of constraint. It makes the problem a lot harder, and puts other constraints on it.
  2. changing requirements seriously halfway makes me feel I'm wasting my time thinking about solutions to a non-existent problem.
  3. xy problem.

I can't use five digital pins because I need some of the digital pins for leds, vibration motors and a buzzer.

There you go: more info on the project. That's helpful, seriously. It's always helpful to fully outline the project as there may be other solutions than what you thought of.

But let's say that I could use 5 digital pins as you suggested... I still don't know which is the best way to sense proximity in a cube using 5 digital pins, can you please help me?

Wire them in a 2x3 switch matrix.

It may even be possible to do it in just three pins by charlieplexing them.

More explanation here.

You may also multiplex your LEDs using charlieplexing - by flickering them fast enough (a couple hundred times a second is no problem for an Arduino) your eyes can't tell the difference. May also save some more pins, but beware that coding gets more complex.

The ESP8266 is doing WiFi in the background, so multiplexing your LEDs may occasionally have glitches as the WiFi is active and halts the other code for a moment.

Grumpy_Mike:
can use the analogue input pins as digital input and output pins.

That's for Arduino.
The ESP's analog input can not be used as digital input - it's pure analog. Of course you can treat it as digital in, but it's still read through the ADC with it's voltage limits. Also it can not be used as output.

I know, I was just illustrating why we seem, to a beginner, to be asking a lot of questions.

wvmarle:

  1. the initial "must use just the ADC" sounds like a school assignment type of constraint. It makes the problem a lot harder, and puts other constraints on it.
    WiFi is active and halts the other code for a moment.

mmmm no, it isn't at all... I was just trying to save you some time doing a shorter post rather than the whole and large explanation.

wvmarle:
2) changing requirements seriously halfway makes me feel I'm wasting my time thinking about solutions to a non-existent problem.
3) xy problem.
There you go: more info on the project. That's helpful, seriously. It's always helpful to fully outline the project as there may be other solutions than what you thought of.

Well, requirements "changed" because there is not feasible solution, not because I want to. Actually I explained that I was limiting the user interaction :

smarichal:
Well, I think that there is no simple solution using just the analog input. Maybe it's time to move forward and constraint the interaction a little bit. I think that I'll just enable the joining action of the cubes in 2 faces and I'll use the physical design of the cubes to highlight this fact, i.e., that the user could easily identify which are the faces that might be joined. .

smarichal:
Wire them in a 2x3 switch matrix.

It may even be possible to do it in just three pins by charlieplexing them.

More explanation here.

You may also multiplex your LEDs using charlieplexing - by flickering them fast enough (a couple hundred times a second is no problem for an Arduino) your eyes can't tell the difference. May also save some more pins, but beware that coding gets more complex.

Good, the wiring is clearer now! Thanks!! I think that the matrix might work fine and as you mentioned the Wifi in the background could affect the performance if I use charlieplexing.

smarichal:
But let's say that I could use 5 digital pins as you suggested... I still don't know which is the best way to sense proximity in a cube using 5 digital pins, can you please help me?

I know how to wire the switches now, but I'm still not sure which type of switches should I use. The reed switch has the magnetic repulsion problem, that if it is possible I would like to avoid. I was thinking if it is not possible to use a kind of conductive surface that when touching the conducting surface of the other cube it close or open the switch.... for example using the built in pull up resistors in the digital pins and putting them to ground when the cubes make contact... It's an abstract idea.... but I do not know how to implement it.

smarichal:
I was thinking if it is not possible to use a kind of conductive surface that when touching the conducting surface of the other cube it close or open the switch.... for example using the built in pull up resistors in the digital pins and putting them to ground when the cubes make contact... It's an abstract idea.... but I do not know how to implement it.

Or maybe using LDR and LED, each cube will have a small hole with the LDR and a salient part with the LED, like a puzzle. Then each cube will use a different color LED and when it get close to the LDR of the other cube I think that it would be possible to detect the proximity and actually to detect which is the joined cube... This should work, right? Now I'm thinking that with this "puzzle" approach I could use the reed switch without the undesired repulsion effect. Sure, note that in this solution the cubes are not symmetric anymore....

Place that hole in the centre of the face, with a small shield between the LED and the LDR and you should be able to detect an LED shining into it, while not detecting it’s own LED. Instead of visible, you’d better use IR LEDs instead (may look better, too: no visible lights shining out, and not so sensitive to ambient light), and photodiodes that are sensitive to IR only instead of LDRs which are highly sensitive to visible light.

Of course LDRs are sensitive to ANY light putting it under a lamp will make it think it’s got another cube attached to it.

To continue on this path:

To stop it react to ambient light, usually modulated IR is used (typically 38 kHz). Now as you’re modulating, you get the option to actually identify which cube you’re connecting to. Every face of every cube can have a unique identifier (up to 42 cubes), which is broadcast via its LED. Then when you place two faces next to each other, you can see not only at which face you have a neighbour, but also which face of which neighbour.
When you detect your own code on a face, that face is either down (on the table) or misaligned, so it reflects its own signal back.

You will be running out of pins now. Each detector (e.g. a TSOP type receiver) needs its own pin, plus at least three pins to charlieplex your LEDs. That’s 9 pins out of the 11 available on the ESP8266 (plus the analog pin, and you should be able to free up GPIO9 and 10 by reconfiguring the internal flash, so you’d have five pins available of which one input only). Some kind of I/O extender may have to come in play.
</FEATURE CREEP ALERT>

This way of course you will be able to detect other cubes at a distance, if aligned properly. You should be able to decrease the effective range of the LED by lowering their intensity, maybe so that you have to be aligned perfectly within a few cm distance for it to detect the other - or, of course, when touching.