ADCTouch capacitive touch implementation for STM32F103 development board

Can someone help me port this library?
arpruss
Posts: 19
Joined: Sat Sep 30, 2017 3:34 am

Re: ADCTouch capacitive touch implementation for STM32F103 development board

Post by arpruss » Thu Oct 12, 2017 12:57 pm

fpiSTM wrote:
Fri Aug 04, 2017 12:20 pm
I've just replaced

Code: Select all

 
    ADMUX |=   0b11111;
    ADCSRA |= (1<<ADSC); //start conversion
    while(!(ADCSRA & (1<<ADIF))); //wait for conversion to finish
    ADCSRA |= (1<<ADIF); //reset the flag
by

Code: Select all

    analogRead(ADCChannel);
That's not equivalent, though. I've spent some time looking over AVR information, and the AVR code above does an ADC conversion on ground (ground is the input channel selected by the ADMUX line), presumably in order to discharge the ADC's internal capacitor to ground. Your code does an ADC conversion on the input pin.

(Actually, on the AVR, one doesn't even need the conversion. All one needs is the ADMUX |= 0b11111 to connect ground to the sample-and-hold capacitor and then a pause of about 100 microseconds for (a) the sample-and-hold capacitor to discharge and (b) the earlier pull-up to charge the target pin. The conversion just happens to provide a pause of the right length.)

I don't know if it's possible to select ground as the source for ADC on the stm. But if not, one could just sacrifice one input pin and ground it, and do an ADC conversion on it. And one pin is all one would need for all the touch detection. The stm32f1's sample and hold capacitor is 8pF versus the 14pF for the AVR, so things should happen a bit faster.

arpruss
Posts: 19
Joined: Sat Sep 30, 2017 3:34 am

Re: ADCTouch capacitive touch implementation for STM32F103 development board

Post by arpruss » Fri Oct 13, 2017 3:13 am

Rather than port the ADCTouch code itself, I tried to duplicate how I understand the ADCTouch code to work. Since I didn't know how to pull the ADC to ground, I just sacrificed PA6, wrote 0 to it, and did an ADC conversion on PA6. The code (see below) then measures touch on PA7.

Currently there is a 4.7K resistor between the pin and the alligator clip I am touching, because my STM32 is encased in a hard to open project case, and my PA7 pin happens to have a 4.7K on it.

The results are gratifying. Without touch, I am getting output values in the single digits, and when I touch the alligator clip, I am getting around 200. When I attached the alligator clip to an orange at startup (it's important that whatever one has attached to the pin be there at bootup, so the reference value can take it into account), upon touching the orange, I would get values of around 19 with a light touch and around 30 with a firmer touch. In theory, it should be possible to make a MIDI piano with oranges for keys and variable velocity dependent on how hard one presses!

It seems to work both indoors and outdoors (though I only checked with larger delayMicroseconds() outdoors; I doubt this makes a difference). There is probably quite a bit more to tweak for optimal use, and one should really do this on a pin without a resistor.

Here is my sketch:

Code: Select all

int32_t measure(int pin, int samples) {
  uint32_t total = 0;
  for (int i=0; i<samples; i++) {
    pinMode(pin, INPUT_PULLUP);
    pinMode(PA6, OUTPUT);
    digitalWrite(PA6, 0);
    delayMicroseconds(50);
    analogRead(PA6);
    pinMode(pin, INPUT_ANALOG);
    total += analogRead(pin);
  }
  return total/samples;
}

int32_t base;

void setup() {
  delay(2000);
  base = measure(PA7, 500);  
  Serial.println("Start "+String(base));
}

void loop() {
  Serial.println(String(measure(PA7, 10)-base));
  delay(50);
}

arpruss
Posts: 19
Joined: Sat Sep 30, 2017 3:34 am

Re: ADCTouch capacitive touch implementation for STM32F103 development board

Post by arpruss » Sun Oct 15, 2017 5:04 pm

I got a new stm32f103c8 in the mail. The sample code I posted works fine, but I wrapped it into a library with an example:
https://github.com/arpruss/ADCTouchSensor
The library works on STM32, AVR and probably any MCU whose internal ADC workings are similar.

On the STM32F103C, it uses the fact that ADC channel 15 appears to be always grounded (it doesn't connect to a pin), and so it doesn't require any extra pin. On other devices, you need to specify a sacrificial analog pin which is grounded, and which shouldn't be connected to anything.

My experience suggests that no debouncing is needed.

Here's how to use:

Code: Select all

#include <ADCTouchSensor.h>
...
ADCTouch button0 = ADCTouchSensor(PA0); // add a sacrificial pin number if needed
ADCTouch button1 = ADCTouchSensor(PA1);
...
button0.begin(); // calibrate touch sensors at startup
button1.begin();
...
if (button0.read() > 40) {
  ... button pressed ...
}

if (button1.read() > 40) {
  ... button pressed ...
}

arpruss
Posts: 19
Joined: Sat Sep 30, 2017 3:34 am

Re: ADCTouch capacitive touch implementation for STM32F103 development board

Post by arpruss » Tue Oct 17, 2017 2:31 am

If you want more demo code, here is a simple but working capacitive MIDI piano keyboard ( use this core for MIDI USB: https://github.com/arpruss/Arduino_STM3 ... addMidiHID ):
https://github.com/arpruss/capacitive-piano-Arduino

Post Reply