#Include CapacitiveSensor library

@peekay123 Yes you need those and more stuff… to set the pin direction, pull-ups or not… etc… For reading inputs you do it a little differently.

These are basically direct port manipulation. I have some examples of that here on the Spark Core: https://gist.github.com/technobly/8342185 and here: https://gist.github.com/technobly/8573877

Looking at the library, it appears they are using the direct port manipulation on the Arduino to gain speed in setting the pins to various states. And waiting for the capacitance on the input to do it thing, charging/discharging. They are using a tight loop with a counter to determine some fast timing/calibration of the these inputs.

Really to be able to convert this, you are going to need to understand how it works on the Arduino first. Then you’ll have to determine the best way to do it on the Core. You might not have to use direct port manipulation… and you might be able to get away with digitalWrite, pinMode, etc… it’s unclear until their timing is understood.

This is obviously going to need to be changed:
loopTimingFactor = 310; // determined empirically - a hack

But to what? You won’t know until you see what the timing is on an Arduino. Got a scope or a logic analyzer?

@kennethlimcp also take a look at the Spark Wiring for how stuff is implemented low level:
https://github.com/spark/core-firmware/blob/master/src/spark_wiring.cpp

@BDub thanks for so much information!

I looked at the code that requires the portregister/portoutputregister etc and was thinking we can get away by using the functions to directly set the pins to high/low and their modes like PULLUP/PULLDOWN etc. like you mentioned

But i can’t tell if that’s the best way to port the library over?

I don’t own a scope but it’s available in my university :slight_smile:

Just trying to help out with my limited knowledge and learn along the way :spark:

OK, so I didn’t have enough coffee this morning and I missed some stuff! Ok, a lot of stuff!! :open_mouth:

1 Like

kennethlimcp, I looked at Paul Stoffregen’s code for the capacitance sensor and I believe he uses direct port manipulation to charge/discharge the intrinsic capacitance of the pins as quickly as possible. Is it necessary? The code was originally written for a 16MHz arduino so at 72MHz, the standard Spark library commands may work just fine.

I believe the loopTimingFactor value is based entirely on the capacitance of the Spark pins while in input mode. It affects the timeout of the sensor sampling loops. So if a sensor INPUT is not changing from low to high (ie. charging due to touch) then the loop times out and returns an error. The timeout var is called CS_Timeout_Millis but its value for F_CPU of 16000000 is 620,000! Looking at the code, it is a tight loop so the timeout must reflect the while() processing time * number of loops to get a delay of N milliseconds, where N is not explained by Paul. So you may have to increase that delay given the Spark processor speed, thus the “hack”. :smile:

@peekay123 That’s a good point to note!

I guess that’s gonna be a factor once i can get the code running the way it should (ie. changing from high to low and pullup/pulldown)

I’ll see how i can be change those stuff without touching the registers yet behaving the same way.

Really thankful for all the inputs! :smiley:

To me it seems wrong that it would take many many milliseconds to charge and discharge the parasitic capacitance on the inputs/flying wires… but the millis() does work it’s way into the loop max timing so it’s somewhere in the millisecond range for a timeout.

That said, you should play with capturing the timing of the functions on an Arduino to understand where everything stands.

BTW the digitalWrite() takes about 2us to execute on the Spark Core. I wanna say the last time I checked on the Arduino is was in the 5-6us range?

Don’t forget we have the micros() timer. It might also be possible to do something with attachInterrupt() but it’s limited to only so many pins.

BDub, the timeout loop is very tight and I suspect it takes about 15us or so. So with the numbers as they are, the timeout is 620,000 * 15us = 9ms, so it appears the timeout is about 10ms. It does seem long but, like I pointed out, the capacitance of the input pin is the key here. The point is that WITH a touch, it should never get there. I would use the micros() delay as you mentioned and use the 10ms timeout to start with.

Hi :spark:ies ,

I was just wondering if any progress has been made? I’m interested in playing with this library as well :open_mouth:
Thanks in advance!

The orignal poster did not pursue further and the slightly modified, not working code is saved in my IDE.

Haha! But thinking of it… I would like that this is working too :slight_smile:

1 Like

Has anybody made any more progress with this, or should I just consider getting the Adafruit touch sensor board?

I tried a bunch of stuff without any real success. Get the touch sensor board. It will save you a bunch of hassles :smile:

1 Like

Having given up hope on using the capSense library due to porting issues, I decided on getting a touch board as well. It also seemed more reliable, and since they’re I2C, easier to work with, consuming less of my precious I/O pins.
I ended up buying the MPR121 from aliexpress, which I’m very happy with. (available on eBay for ~$7 shipping included, Sparkfun for $10+shipping) Delivery was (surprisingly) fast, and the board works great. You can connect up to twelve electrodes with individually configurable sensitivity settings, as well as combining all twelve, thereby creating one huge sensitive 13th virtual sensor.
Having no coding experience, I thought porting the library would be hell. After some struggling, and some help from my (EE) dad, it turned out I just had to connect a wire to give it the proper I2C address. After that it worked like a charm.
Since I didn’t feel like permanently soldering wires to it, I just stuck a wire through the hole and twisted it, until they stuck, hoping for an electrical connection. Sluggish as that may have been, it miraculously worked, and I could do stuff by touching the wires.
Though that was fun, the whole idea behind capacitive touch is, that well, you don’t have to touch it. I then attached ~5x5cm (~2x2 inch) pieces of aluminum foil to the wires, just wrapping them around the wires lightly.
Being no great feat of electrical construction, this at first didn’t work. After messing around with it a bit, it turned out that I had to reboot the cap-board, since it initializes all sensors at power up, and thus had to reinitialize the changed capacitance of the added aluminum foil.
The board then worked great, and I’m able to sense my hand through my wooden desk, which is around ~5cm (~2inch) thick. Good enough for my purposes, since I’d like to stick it behind my wallpaper to create some hidden buttons :wink:

Money well spent on that board. 12 sensors, which can be used as LED drivers if unused. You can even use them as I/O pins I believe, but I’m not experienced enough to figure out how. All in all, I can certainly recommend the board :slight_smile:

2 Likes

Thanks @moors7, you answered my next question. I was wondering if those sensor boards could handle sensing at a distance like that. I’m thinking about some sort of color organ project, with patterns, colors, and intensity on a LED strip controlled by a combination of audio input and touch sensors.

1 Like

I implemented touch sensing using attachInterrupt() and micros() timer. Look here for a description of operation and here for demo code.

2 Likes

@Tangibit great work :slight_smile: I was wondering what the typical delta t was between not being touched and being touched in your example?

Do you find that microseconds granularity is sometimes not precise enough? If so there is another free-running counter in the Spark core you could use that runs at a 72th of a microsecond (13.89ps aka 1/72MHz aka the system clock)

You can see it used to generate the micros() output:

unsigned long micros(void)
{
	return (DWT->CYCCNT / SYSTEM_US_TICKS);
}

basically calling DWT->CYCCNT gives you the current timer count. SYSTEM_US_TICKS = 72.

Also when you subtract the previous UNSIGNED LONG count of DWT->CYCCNT from the current UNSIGNED LONG count of DWT->CYCCNT you naturally defeat (with coding wizardry) the case when the DWT->CYCCNT count wraps.

uint32 LAST_DWT = DWT->CYCCNT;
while( (DWT->CYCCNT - LAST_DWT) > 72 ) {
  // One microsecond has elapsed since LAST_DWT
  // DWT->CYCCNT can also wrap and it won't affect us 
  // if done as above using the power of subtraction :) 
  break;
}

Thanks! I’ve been running without the fixed capacitor (10pF in the schematic) and see a change of 100’s of usec. Using this technique on a shield I’m working on, there is more stray capacitance so the baseline delay is higher- but I still see 100’s of usec change. I had thought about trying a timer and some the bit banging techniques you posted if the micros() and digitalWrite() were too slow, but these seem sufficient (and make for easy code).

The bigger issue seems to be the impact of supply grounds. Running from a battery-powered laptop USB port is always fine. I’ve noticed that using the power adapter with certain circuits in the house (like with dimmer switches on them, etc.) can lead to flakier performance. My next step is to try a smaller resistor and put the fixed cap in place (this is discussed on the CapacitiveSense page to stabilize performance). This will reduce sensitivity to the touch condition, since the fixed cap will be in parallel with the capacitive loading when touched- but it has been noted to improve performance, so I will give it a try. This might lead to needing a finer timer. I need to get a scope on the node a see what is actually happening…

This is great.
I took the liberty of converting the code to a library and simplifying the API.

I’m hoping an update to the firmware will support C++ lambdas and allow multiple instances; I have this working locally:

#include "captouch.h"
CapTouch Touch(A0, A1);
CapTouch Touch2(D1, D4);
setup() {
  Touch.setup();
  Touch2.setup();
}
loop(){
  CapTouch::Event touchEvent = Touch.getEvent();
  if (touchEvent == CapTouch::TouchEvent) {
	digitalWrite(D7, HIGH);
  } else if (touchEvent == CapTouch::ReleaseEvent){
	digitalWrite(D7, LOW);
  }
  touchEvent = Touch2.getEvent();
  // more
}
1 Like

The description link has moved to
http://jvs.me/spark-core/touch-sensing-on-the-spark-core/

Hello guys,

after long time no one update this code. i’m trying to use the code of Captouch on spark core which is on the website:

http://jvs.me/spark-core/touch-sensing-on-the-spark-core/

some how it is not working for me. can any one help me to get this working. i’m always getting tEVENT_NONE.