Skip to content

Commit

Permalink
AVR support
Browse files Browse the repository at this point in the history
  • Loading branch information
arpruss committed Oct 17, 2017
1 parent d5985c8 commit ccabd92
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 110 deletions.
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
## ADCTouch
ADCTouchSTM is a library that allows users to create a capacitive sensor without ANY external hardware.
It is based on the ideas in https://github.com/martin2250/ADCTouch
## ADCTouchSensor
ADCTouchSensorSTM is a library that allows users to create a capacitive sensor without ANY external hardware.
It is based on the ideas and code in https://github.com/martin2250/ADCTouch but extended to work on hardware
other than AVR.

## Purpose
Most capacitive touch libraries require two pins and a large resistor to acquire precise readings.
This library inspired by the ADCTouch library makes use of internal wiring to get decent
resolution with just a single pin (plus on some MCUs one extra sacrificial pin, shared between allows
the touch sensors).
This library makes use of internal wiring to get decent resolution with just a single pin (plus on
some MCUs one extra sacrificial pin, shared between allows the touch sensors).

## Usage
`ADCTouch touchSensor = ADCTouch(int analogPin, int sacrificialPin = -1);`
`touchSensor.begin();`
`value = touchSensor.read(int samples=5);`
`value = touchSensor.readRaw(int samples=5);`
`ADCTouchSensor touchSensor = ADCTouchSensor(int analogPin, int sacrificialPin = -1, unsigned delaytime = [device dependent]);`
`touchSensor.begin(unsigned samples=500);`
`value = touchSensor.read(unsigned samples=5);`
`value = touchSensor.readRaw(unsigned samples=5);`

* analogPin: The pin to read data from

* sacrificialPin is grounded and used for internal purposes. It shouldn'tA
* sacrificialPin is grounded and used for internal purposes. It shouldn't
be connected to anything (beware of shorts). A single
sacrificialPin can be used for many ADCTouch instances. On the stm32f103c, you can omit
sacrificialPin can be used for many ADCTouchSensor instances. On the stm32f103c, you can omit
the sacrificial pin, and an internal grounded ADC channel
can be used. If your MCU has such a channel -- likely, the same one, namely 15 -- you can
can be used. If your STM32F1 MCU has such a channel -- likely, the same one, namely 15 -- you can
edit the library to support it (and email me)

* delayTime is the amount of extra time to allow for charging up the touch pin; the default value is
device dependent

* samples: number of samples to take

Expand Down
8 changes: 4 additions & 4 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name=ADCTouchSTM
name=ADCTouchSensor
version=0.0.1
author=Alexander Pruss
maintainer=arpruss <[email protected]>
sentence=Create Touch Sensors with a single analog pin without external Hardware
paragraph=This library uses the internal wiring of STM microcontrollers to measure capacitance sort of as described here <http://tuomasnylund.fi/drupal6/content/capacitive-touch-sensing-avr-and-single-adc-pin>
sentence=Create Touch Sensors with a single analog pin without external hardware
paragraph=This library uses the internal wiring of microcontrollers to measure capacitance much as described here <http://tuomasnylund.fi/drupal6/content/capacitive-touch-sensing-avr-and-single-adc-pin> and is based on <https://github.com/martin2250/ADCTouch>
category=Sensors
url=https://github.com/arpruss/ADCTouchSTM
architectures=STM32F1,STM32F2,STM32F3,STM32F4
architectures=STM32F1,STM32F2,STM32F3,STM32F4,avr,STM32
64 changes: 0 additions & 64 deletions src/ADCTouchSTM.cpp

This file was deleted.

29 changes: 0 additions & 29 deletions src/ADCTouchSTM.h

This file was deleted.

101 changes: 101 additions & 0 deletions src/ADCTouchSensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
ADCTouchSTM.cpp - Library for Capacittive touch sensors using only one ADC PIN
Created by Alexander Pruss. MIT license.
*/

#include "Arduino.h"
#include "ADCTouchSensor.h"

ADCTouchSensor::ADCTouchSensor(int pin, int sacrificialPin, unsigned delayTimeMicroseconds) {
touchPin = pin;
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
touchDigitalPin = pgm_read_byte(analog_pin_to_digital_pin + pin);
if ((uint8_t)touchDigitalPin == (uint8_t)NOT_A_PIN) {
valid=false;
return;
}
#else
touchDigitalPin = pin;
#endif
reference = 0;
groundedPin = sacrificialPin;
delayTime = delayTimeMicroseconds;
if (sacrificialPin < 0) {
#if defined(ADCTOUCH_STM32_GROUND_CHANNEL) || defined(ARDUINO_ARCH_AVR)
valid = true;
#else
valid = false;
#endif
}
else {
valid = true;
}
}

// connect the ADC input and the internal sample and hold capacitor to ground to discharge it
// also, delay to allow for charging of the touch pin
inline void ADCTouchSensor::groundPortable() {
pinMode(groundedPin, OUTPUT); // HARDWARE ISSUE: ensure no short occurs
digitalWrite(groundedPin, 0);
if (delayTime > 0)
delayMicroseconds(delayTime);
analogRead(groundedPin);
}

#if defined(ADCTOUCH_STM32_GROUND_CHANNEL)
inline void ADCTouchSensor::ground() {
if (delayTime>0)
delayMicroseconds(delayTime);
adc_read(ADCTOUCH_STM32_ADC, ADCTOUCH_STM32_GROUND_CHANNEL);
}

#elif defined(ARDUINO_ARCH_AVR)

inline void ADCTouchSensor::ground() {
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = (ADMUX & 0xF0) | 0b1101;
#else
ADMUX |= 0b11111;
#endif
if (delayTime>0)
delayMicroseconds(delayTime);

ADCSRA |= (1 << ADSC);
// ADSC is cleared when the conversion finishes
while((ADCSRA & (1 << ADSC))) ;
}
#endif

int ADCTouchSensor::readRaw(unsigned samples) {
if (!valid)
return -10000;
int32_t total = 0;
for (unsigned i=0; i<samples; i++) {
pinMode(touchDigitalPin, INPUT_PULLUP);
if (groundedPin >= 0) {
groundPortable();
}
else {
ground();
}
pinMode(touchDigitalPin, INPUT_ANALOG);
total += analogRead(touchPin);
}
return total / ADCTOUCH_DIVIDER / samples;
}

bool ADCTouchSensor::begin(unsigned samples) {
if (valid) {
reference = readRaw(samples);
return true;
}
else
return false;
}

int ADCTouchSensor::read(unsigned samples) {
if (valid)
return readRaw(samples) - reference;
else
return -10000;
}
51 changes: 51 additions & 0 deletions src/ADCTouchSensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
ADCTouchSensor.h - Library for Capacitive touch sensors using only one ADC PIN, with a second unconnected pin shared between sensors on some devices
Based on code that was created by martin2250, April 23, 2014 and released into the public domain.
*/
#ifndef ADCTOUCHSENSOR_h
#define ADCTOUCHSENSOR_h

#include "Arduino.h"

#if defined(ARDUINO_GENERIC_STM32F103C)
# define ADCTOUCH_STM32_GROUND_CHANNEL 15
# define ADCTOUCH_STM32_ADC ADC1
# define ADCTOUCH_INTERNAL_GROUNDING
#endif

#if defined(ARDUINO_ARCH_AVR)
# define ADCTOUCH_INTERNAL_GROUNDING
# define INPUT_ANALOG INPUT
#endif

#if defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F2) || defined(ARDUINO_ARCH_STM32F3) || defined(ARDUINO_ARCH_STM32F4)
# define ADCTOUCH_DEFAULT_DELAY 20
# define ADCTOUCH_DIVIDER 4
#elif defined(ARDUINO_ARCH_AVR)
# define ADCTOUCH_DEFAULT_DELAY 0
# define ADCTOUCH_DIVIDER 1
#endif

class ADCTouchSensor
{
private:
int32_t reference;
int groundedPin;
int touchPin;
int touchDigitalPin;
unsigned delayTime;
bool valid;

private:
void groundPortable();
#ifdef ADCTOUCH_INTERNAL_GROUNDING
void ground();
#endif

public:
ADCTouchSensor(int pin, int sacrificialPin=-1, unsigned delayTimeMicroseconds=ADCTOUCH_DEFAULT_DELAY);
bool begin(unsigned samples=500);
int read(unsigned samples = 5);
int readRaw(unsigned samples = 5);
};
#endif

0 comments on commit ccabd92

Please sign in to comment.