I want to use the CapacitiveSensor.h library to make an interactive mural using bare conductive paint as a sensor. I tested the library on my Arduino and it worked fine but my programming skills are not good enough to figure out how I can get it working with my Spark Core.
Is there anybody that can tell me how I can get this working?
marcapon, based on the bill of materials, the Spark uses the STM32F103CBT6 processor. The "103" describes:
103 = Cortex-M3 mainstream, 72MHz CPU, up to 1MB flash with motor control, USB and CAN
This processor does not have capacitive touch input compatible pins. To do capacitive touch, you could add a touch sensor breakout board like this one from Adafruit which can work with I2C or SPI and has 8 inputs. The I2C mode uses only 2 wires and I could help you adapt the arduino library.
Actually, Iâm pretty sure the Arduino doesnât have true touch-sensitive input pins either⌠Thatâs the point of the CapactiveSensor Library, it uses two input pins along with a massive resistor, along with the millis() function to time/measure the capacitance on a specified pin. Iâm using it in a project right now actually, (using a 25M ohm resistor). So⌠I feel like the library should work on the Spark Core, because it doesnât depend on built-in capacitive sensing ability.
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?
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
Just trying to help out with my limited knowledge and learn along the way
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â.
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.