Cap sense advice please!

I’m looking to make a cap slider that’s 800mm to 1m long on/in a curved pole. The effect I want to achieve is sliding a hand down the pole will cause LEDs within the pole to light up as the hand passes over them, so it’s a large contact area and a large gesture, but over a metre there could be 60 LEDs and I’d like the output to be sensitive enough for them to come on one at a time...but obviously 60 pins is a no-no!

Programming I can manage, just wondering the best design for the actual slider. The tube is composite, either carbon or glass fibre, 25mm diameter and should be invisible...the tube wall could be around 4mm thick too, so hope someone can advis3 on best resistor value to pick up contact through 4mm of resin composite.

All advice gratefully received.

GreyArea:
I’m looking to make a cap slider that’s 800mm to 1m long on/in a curved pole. The effect I want to achieve is sliding a hand down the pole will cause LEDs within the pole to light up as the hand passes over them, so it’s a large contact area and a large gesture, but over a metre there could be 60 LEDs and I’d like the output to be sensitive enough for them to come on one at a time...but obviously 60 pins is a no-no!

Programming I can manage, just wondering the best design for the actual slider. The tube is composite, either carbon or glass fibre, 25mm diameter and should be invisible...the tube wall could be around 4mm thick too, so hope someone can advis3 on best resistor value to pick up contact through 4mm of resin composite.

All advice gratefully received.

First let's look at your request. By "cap" are you referring to "capacitor" or "capacitance", or some type of cover?

Next, is a single hand involved or multiple hands, or other body parts?

Next, sliding of the hand, how fast? Is the hand wrapped around the tube?

And finally, you describe the tube as being invisible, how does that work.

I suggest you look at sensing the body acting as an antenna and a sensor picking up the change in level of the 50 or 60 cycle power that is always present in buildings. Probably don't need and Arduino for that.

Paul

I am not sure you understand how a capacitance sensor works.
Have a look here:- Atmel 42479 Capacitive Touch Long Slider

I think you will be hard pushed to get it that long or indeed that sensitive and accurate.

GreyArea:
The effect I want to achieve is sliding a hand down the pole will cause LEDs within the pole to light up as the hand passes over them, so it’s a large contact area and a large gesture, but over a metre there could be 60 LEDs and I’d like the output to be sensitive enough for them to come on one at a time...

Interesting problem !
As has been said by others, a large capacitive sensor is not going to work. A whole bunch of separate sensor areas may be ok, but I suspect you'll have a shift register full of LED's right next to 'em - which won't help at all.

I'd be tempted to look at making strips of hall effect sensors with a shift register, say thin PCBs each with 8 sensors spaced at 20mm and an 8-bit shift register. The 'performer' will have to wear some ornate ring with a big magnet in it.

Something like DRV5032

Yours,
TonyWilk

For some reason quote button not working on my iPad...having to do this manually so hope it’s not too confusing...

First let's look at your request. By "cap" are you referring to "capacitor" or "capacitance", or some type of cover? - sorry, I was thinking capacitive (capacitance), but how the effect is achieved is unimportant as long as it does the job.

Next, is a single hand involved or multiple hands, or other body parts? A single hand...the other hand may or may not be holding the tube, but if so there is room to have an area of the tube that is not acting as a sensor.

Next, sliding of the hand, how fast? Is the hand wrapped around the tube? - A range of speeds, from perhaps half a second to five seconds. If there is a limit to how fast it can respond that is acceptable. Yes, the hand could either encircle the tube or be pressed flat against it...but if one method is required for it to work, again that is acceptable.

And finally, you describe the tube as being invisible, how does that work. - Ha! It doesn’t, I’m an idiot...I meant the sensor should be invisible...although, depending on certain factors it may be possible to incorporate it as part of a design;I know it’s possible to use copper tape for capacative switches, I was wondering if inidividual parts of the sensor could be designed so that the whole sensor looks like a snake (for example). If not, would it be possible to have the sensor sufficiently responsive that it would work under 3 to 4 mm of fibre reinforced resin?

I suggest you look at sensing the body acting as an antenna and a sensor picking up the change in level of the 50 or 60 cycle power that is always present in buildings. Probably don't need and Arduino for that. - the rod needs to be portable and the whole system needs to use a5v DC power source. It may not always be used in a building. Does that change things?

In short, I’m looking for a method of turning on (and off) a line of 5v WS2812b LEDs in the centre of a 25mm OD, 17mm ID fibre reinforced resin tube by “stroking” them. If capacative sensors are not the best option, I’m open to suggestions...though it must be just a hand, no extra devices like rings etc please. Due to space restrictions for circuitry, I’ll be using a trinket style Arduino device, hence the need to limit both the number of pins used and the size of the sketch!

Yes I’m new at this, so if I’m asking for the moon, please let me know...!

For some reason quote button not working on my iPad...having to do this manually so hope it's not too confusing...

Is the quote icon not visible? If not then hold down the refresh icon in the URL window and a menu will appear saying “request desktop version”, kick that and the icons will appear.

I don’t thing your project is possible at all.

Grumpy_Mike:
Is the quote icon not visible? If not then hold down the refresh icon in the URL window and a menu will appear saying “request desktop version”, kick that and the icons will appear.

I don’t thing your project is possible at all.

Your forum operating advice is 100% accurate, thanks. Quote button was visible but didn’t respond until I requested desktop site.

Kind of hoping your Arduino advice isn’t as accurate :-).

It was this video that got me started...I just wondered how long the foil strip could be made...

I am not sure what you think that video is showing but it is not showing a reading of how far along the strip the hand is but how far above the strip the hand or grounding point is. So it is not related to your proposed project at all.

Kind of hoping your Arduino advice isn't as accurate

Sadly it is.

Grumpy_Mike:
I am not sure what you think that video is showing but it is not showing a reading of how far along the strip the hand is but how far above the strip the hand or grounding point is. So it is not related to your proposed project at all.

1:10 in the video. “As I touch the pad, the LEDs light up. As I move my finger to the right they progressively light more and more”

I hope you can at least see where my confusion arose given the above!

I see the confusion. The way that works is their is a diagonal cut in the masking tape and the A/D inputs are floating. The angle of this cut looks about 20 degrees. Even if you could, to extend this to a meter would require such a shallow angle that you would not get much resolution at all. This is the problem with demos like this, they simply do not scale up.

But that link I posted is the way to do a slider and it is a limited distance and not what you want. The cap sense example using no external components is not very reliable and stable anyway.

Edited because she woke up.

Grumpy_Mike:
I couldn’t have the sound on because I am in bed and my wife is sleeping. I see the confusion, I think the poster of the video is confused about what is happening as he has not even posted his code. Also I would never trust anyone who uses Solderless bread board for anything on a video.

But that link I posted is the way to do a slider and it is a limited distance and not what you want. The cap sense example using no external components is not very reliable and stable anyway.

Ah it’s hard to tell without the sound but it does become clear that what appears to be one bit of foil is actually two triangles, so he’s using a method the same as your link (which I’d found before you posted and is great, btw, but with my limited experience I couldn’t make out if there was a maximum length and sensitivity.

Thanks for the advice. I’ll try building a long one by the methods in your link and see what happens.

Well, I am sort of surprised...

Watched the linked YouTube video and thought, hmm, bet that's a) unreliable and b) running on mains pickup.

Anyhow, I built one.

For his application it's not bad, but it does rely on pickup (probably from mains electricity) because it stops working if you ground yourself. So it wouldn't work outdoors for example. It also depends a lot on the surface it is on. It only works when you press a finger on it - it has no range i.e. no effect from a few mm away. I also thought I'd damaged an analog input, which is a real possibility, but it seems ok now.

The real news is on a bit of an improvement - this is what I built:

The sensing strip is cut from copper foil tape, the central diagonal cut strips are about 10mm down to 1mm wide and about 300mm long, spaced by about 1mm. Around the outside is another strip roughly 5mm wide and spaced 3mm from the ones in the middle. Here's a closer view of each end:
CalStrip2.jpg
(if the images don't appear inline, they are attached)

The foil was laid on some thin plastic sheet (maybe mylar, about 0.2mm thick), wires soldered on and then covered with a layer of clear packing tape. I've taped it to a length of PVC pipe (about 30mm dia.)

The idea is to drive the outer strip so there is something to couple to the inner strips.
The mashed-together code is:

#define DEBOUNCE_TIME 20  //20mS per debounce step
const int calPin = 2;     // calibration button pin

// useful functions:
int debouncePin( uint8_t * pdebounce, int pin, int to_level );
void Sprint( char *fmt, ... );

//-----------------------------------
void setup() {
  Serial.begin(9600);
  pinMode(calPin, INPUT_PULLUP);// CAL button pin

  pinMode( A0, INPUT );
  pinMode( A1, INPUT );
  pinMode( 4, OUTPUT );
  digitalWrite( 4, LOW );
}

//-----------------------------------
static uint32_t time10mS=0;
static int count100mS= 0;
static int32_t a0,a1, total, b0, b1, cal0=0, cal1=0;
static uint8_t d_calPin= 0x7f;
int i;

void loop() {
  // run 10mS and 100mS loops:
  if( millis() > time10mS + 10 )
  {
    do_10mS_loop();
    if( ++count100mS > 10 )
    {
      do_100mS_loop();
      count100mS= 0;
    }
  }
}

// Executed every 10mS
//
void do_10mS_loop()
{
  if ( debouncePin( &d_calPin, calPin, LOW ) )
  {
    // do something useful...
    Serial.println("Calibrate!");
    cal0= b0;
    cal1= b1;
  }
}

// Executed every 100mS
//
void do_100mS_loop()
{
  a0= a1= 0;
  for( i=0; i<500; i++ )
  {
    digitalWrite( 4, LOW );
    digitalWrite( 4, HIGH );
    a0+= analogRead( A0 );
    digitalWrite( 4, LOW );
    digitalWrite( 4, HIGH );
    a1+= analogRead( A1 );
  }
  total= a0+a1;
  b0= (a0 * 1000)/ (total/2) - cal0;
  b1= (a1 * 1000)/ (total/2) - cal1;
 
  Sprint("a0= %ld, a1= %ld, b0= %ld, b1= %ld, diff= %ld\n", a0, a1, b0, b1, b1-b0 );
}


//----------------------------------------------------------------------
// debouncePin
// - debounces the given pin input
// passed:
//    debounce   - pointer to a byte used to debounce this pin
//    pin        - no. of the pin to read and debounce
//    to_level   - the level at which the input is 'active'; LOW or HIGH
// returns:
//    1 when pin has just transitioned to the 'active' state
//    otherwise 0
//
// usage:
//    static uint8_t pin3debounce= 0x7f;  // always initialise to 0x7f
//    if( debouncePin( &pin3debounce, 3, LOW ) )
//       \\ pin debounced LOW
// 
int debouncePin( uint8_t * pdebounce, int pin, int to_level )
{
  uint8_t levelFlip= (to_level == HIGH) ? 0 : 1;
  
  *pdebounce &= 0x7f;         // clear action bit
  *pdebounce= (*pdebounce & 0xc0) | ((*pdebounce & 0x3f) << 1) | (digitalRead(pin) ^ levelFlip);
  if( *pdebounce == 0x3f )
    *pdebounce= 0xff;         // is debounced '1', set state and action flags
  if( (*pdebounce & 0x3f) == 0 )
    *pdebounce= 0x00;         // is debounced '0', set state= 0;
  return (*pdebounce >> 7);   // return 'action' bit
}

//-----------------------------
// Serial.print helper function
// - a real cut-down printf()
//
void Sprint( char *fmt, ... )
{
  char c;
  va_list args;
  va_start( args, fmt );
  while( (c=*fmt) != 0 ){
    switch( c )
    {
    case '%':
      c= *(++fmt);
      if( c == 'l' ){  // lower case L for "%ld" or "%lu"
        c= *(++fmt) & 0xdf; // convert 'd', 'u' to 'D', 'U'
      }
      switch( c )
      {
      case 'd': Serial.print( va_arg(args,int16_t) ); break;
      case 'u': Serial.print( va_arg(args,uint16_t) ); break;
      case 'D': Serial.print( va_arg(args,int32_t) ); break;
      case 'U': Serial.print( va_arg(args,uint32_t) ); break;
      case 'f': Serial.print( va_arg(args,double) ); break;
      case 'h': Serial.print( va_arg(args,int), HEX ); break;
      case 'c': Serial.print( (char)va_arg(args,int) ); break;
      case 's': Serial.print( va_arg(args, char *) ); break;
      default:  break;
      }
      break;
    case '\\':
      c= *(++fmt);
      if( c == 'n' )
        Serial.println();
      else
        Serial.print( c );
      break; 
    default:
      Serial.print( c );
      break;
    }
    ++fmt;
  }
  va_end( args );
}

Analog inputs A0 and A1 are connected to the diagonal-cut strips and have 1Mohm resistors to ground.
Digital output D4 is connected to the outer strip. I've used D2 as an input for a 'Calibrate' button which removes offsets.

When calibrated it prints: (note the 'diff' value)

a0= 79048, a1= 69030, b0= 0, b1= 0, diff= 0
a0= 78969, a1= 69060, b0= -1, b1= 1, diff= 2
a0= 79093, a1= 68950, b0= 1, b1= -1, diff= -2

Hand gripping lower end:

a0= 111710, a1= 100892, b0= -17, b1= 17, diff= 34
a0= 111669, a1= 100791, b0= -16, b1= 16, diff= 32
a0= 111773, a1= 100860, b0= -16, b1= 16, diff= 32

Hand gripping upper end:

a0= 113945, a1= 128126, b0= -126, b1= 126, diff= 252
a0= 114930, a1= 129889, b0= -129, b1= 129, diff= 258
a0= 115349, a1= 130419, b0= -129, b1= 129, diff= 258

Surprisingly it seems to work ! However, you have to grip the tube for it to register well.

I may play with this some more and see if I can get anything out of a longer 'sensor'. It may help to have the 'driving strip' all the way around the tube so there's more area to couple into your hand.

Even this quick'n'nasty test piece lays nice and flat, so putting it around the outside of the tube and painting it may work.

Yours,
TonyWilk

P.S.
tip: cheap copper foil tape is sold as 'Slug Tape' - apparently garden slugs don't like sliming over copper, so you use it to protect plants.

CalStrip2.jpg

CapStrip.ino (3.66 KB)

I too have been busy and subject to reining in my ambitions, have something that may deliver what I need...not as elegant as Tony's solution, but functional and limited to only two pins.

The main thing I've sacrificed is the resolution...because why do I need to light up each LED one at a time when my great hulking fist will be covering five of them?

Also, I'm using the fact that I'm on a round pole to my advantage...I can make two interlocking touchpads, and though each will be on a common pin, if I am careful only to stroke (not wrap my hand around) the pole, I only contact the teeth where they interlock, as the "rail" they are on is below the touch plane because of the curve of the pole (I'll post a pic in a bit).

Getting a third contact in would give a direction...either 123123 or 321321...but I haven't figured out how to wire that yet, so I've jury rigged it. As long as the total number of "teeth" is even (from pad one AND pad two combined), then in one direction I always hit pad one first, in the other, pad two.

So far I've got an output of the ratio of the two signals in the graph monitor providing me quite a nice square wave (with noise, of course!). A ratio of 0.25 or less means pin one is on, 4 or more means pin two is on.

So now I have question about the code...

The "total1 = cs_4_2.capacitiveSensor(30);" line. This "adds up" readings from the pin I assume. Is the figure in brackets a period of milliseconds or a number of readings? I assume either way that a higher number would be a slower response?

Pic as promised...just need to work out code to do the magic with the lights...

...and I knew about slug tape, but to save myself a half hour trip to B and Q, decided I’d spend five hours faffing about with bacofoil and sellotape!

Well... :o

I apologise for pouring scorn on the idea of using a capacitive sensor earlier.

Went for gold this time, made an 800mm long version. This time using full width 'Slug Tape' (23mm) cut diagonally and applied directly to my bit of PVC pipe, then added the 'driving' strips around the rest of the tube. Works surprisingly well.

There is a bit of a knack to getting repeatable readings tho', the best being when your fingers wrap around the tube to equally cover the sensing strips. The worst is when you only cover one of the sense strips - I was wondering why it'd suddenly 'gone all funny' when I realised I had my extended thumb and palm over only one strip.

I didn't modify the code I posted earlier... (but there is a bug: the Calibrate bit only works the first time, thereafter it's using already-calibrated values.)

see attached pic.

Yours,
TonyWilk

P.S. 'Slug Tape' (look on eBay) comes in straight-edged and crinkly-edged (presumably to further deter the little beasties from eating your prize Delphiniums). The crinkly stuff is a pain.

GreyArea:
Getting a third contact in would give a direction...either 123123 or 321321...but I haven't figured out how to wire that yet, so I've jury rigged it. As long as the total number of "teeth" is even (from pad one AND pad two combined), then in one direction I always hit pad one first, in the other, pad two.

Ah, so you'll count your way up the pole... neat.
With just inputs to the A-D's you are relying on picking up mains 'hum' I think, so it may stop working when it's portable.

The "total1 = cs_4_2.capacitiveSensor(30);" line. This "adds up" readings from the pin I assume. Is the figure in brackets a period of milliseconds or a number of readings? I assume either way that a higher number would be a slower response?

Sorry... what code is that from ?

Yours,
TonyWilk

It's the example from the capacative sense library by Peter Badger...

Yours is superior of course as it allows a change in direction...my way you have to keep going left if you started left...once the lights are added with my method you'd be able to keep lighting them by going back and forth between contacts...your way it should sense a change of direction.

One advantage to my method though may be aesthetics if it's visible...instead of two toothed contact plates, imagine two sinusoidal "snakes", back to back...as long as the snakes are wide enough that there's no loss of contact "under" the same snake, the effect should be the same...

I do need it to work when "mobile" though...the grounding issue may become a pain...

If you tightly ran a a length of very thin ( ie high resistivity) nichrome wire along your pole, spaced off from a fixed contact plate by a few mm , and supplied +/- 5v to the nichrome wire, you'd get a voltage on the fixed contact proportional to where you pressed it to the fixed contact.....

I'd add a capacitor to cut out mains pickup.

Allan

allanhurst:
If you tightly ran a a length of very thin ( ie high resistivity) nichrome wire.... snip

Ah, yes... that could be very accurate.

You also just reminded me that these are a thing: SoftPot Membrane Potentiometer

Yours,
TonyWilk