.. index:: touch sensor,touch,tsc,tsc peripheral .. _touch-sensor: STM32 TOUCH SENSOR (TSC) DEMO BINARY ==================================== This project supplies a binary file ready to run on a STM32F0 Discovery Board. It provides a fully configured Touch Sensor and Menu so that various user created touch sensors may be tested and calibrated. .. _tsc-binary: **NEW!** Download this project in a tarball with everything, including sourcecode, binary, readme etc. My new Tarball Release format contains *everything* you need to develop this project. URL: https://sourceforge.net/projects/mecrisp-stellaris-folkdoc/files/STM32F0-Discovery-TouchSensor-377b5b56c2.tar.gz Download the OLD binary only: https://sourceforge.net/projects/mecrisp-stellaris-folkdoc/files/STM32F0-Discovery-TouchSensor-Demo.bin STM Technical Manual Description -------------------------------- The touch sensing controller provides a simple solution for adding capacitive sensing functionality to any application. Capacitive sensing technology is able to detect finger presence near an electrode which is protected from direct touch by a dielectric (for example glass, plastic). The capacitive variation introduced by the finger (or any conductive object) is measured using a proven implementation based on a surface charge transfer acquisition principle. Schematic --------- Figure 1. modified with the component values and GPIO Pins I have used in this project. .. image:: projects/touch-sensor/pics/charge-transfer-principle-1.jpg Documentation ------------- * *STM32F051 Technical Manual*: RM0091 * *Getting started with touch sensing control on STM32 microcontrollers*: AN5105 * *Mecrisp-Stellaris Forth*: This site! Instructions ------------ * Download the binary and :ref:`flash` it to your F0 Discovery board. * Connect a :ref:`serial terminal` as shown in the wiring chart below * Connect the 47 nF capacitor and a touch pad of some kind. A coin with a wire attached and wrapped in stickytape should work fine. * When the board is powered up you should see the 'Main Menu'. If not, enter "?" to start the menu. * Select 's' and scanning should begin ready for touch experiments. Connection Information ---------------------- STM32F0 Discovery Board ^^^^^^^^^^^^^^^^^^^^^^^ :ref:`Information` .. image:: stm32-disco.jpg USB-3.3 Volt Dongle ^^^^^^^^^^^^^^^^^^^ :ref:`Information` .. image:: pics/usb-ttl-6pin-cp2102.jpg Wiring ^^^^^^ .. image:: projects/touch-sensor/pics/wiring.jpg Wiring Chart ~~~~~~~~~~~~ ===================== ============== ================ ============== ========= STM32F0 Discovery Description USB-3.3v dongle 47nF Capacitor Electrode ===================== ============== ================ ============== ========= \+5V (input) +5 volts +5V (output) GND 0 volts GND PA9 (TX) serial data RX PA10 (RX) serial data TX PA11 (CTS) handshaking RTS (not used) PA12 (RTS) handshaking CTS PA7 47 nf Cap * GND 47 nf Cap * PA6 Electrode * ===================== ============== ================ ============== ========= Notes ~~~~~ * The ELECTRODE has only ONE wire * The 47 nanoFarad capacitor is non-polarised Serial ~~~~~~ * 460800 baud, N,1 * Handshaking isn't essential if you only want to read data from the board (test different electrodes etc). It's only ESSENTIAL if you want to upload Forth Source. * CTS/RTS handshaking works but isn't needed so PA11 can connect to GND instead of the USB-3.3v dongle if you like. DON'T leave PA11 FLOATING or serial comms won't work! Development Binary Menu ----------------------- Main Menu ^^^^^^^^^ .. image:: projects/touch-sensor/pics/menu-main.jpg Information Menu ^^^^^^^^^^^^^^^^ .. image:: projects/touch-sensor/pics/menu-information.jpg Extra Menu ^^^^^^^^^^ .. image:: projects/touch-sensor/pics/menu-extra.jpg The menu contains most of the functions one needs to test various capacitive sensor designs including the 'counter' values which change with sensor size,shape and touch. A LED on the Discovery Board also lights when a finger 'press' is detected. Menu "s" example ---------------- The change in 'count value' can be seen in the example below as my finger is placed on and off the touchpad. Readings followed by a "*" mean this was detected as a "touch". The ratio of not-touched to touched can be as high as 10.8:1. :: 4921 5067 5068 975 * 863 * 1149 * 1149 * 5038 5065 942 * 942 * 5068 5071 5075 5073 5072 5065 5069 5050 998 * 915 * 892 * 884 * 898 * 898 * 4235 5026 Touchkey Sensor Electrodes -------------------------- These are some of my prototypes made from single sided copper coated scrap pcb material. Touch Pad Stats ^^^^^^^^^^^^^^^ All pads are insulated by tape (even if it isn't visible), the finger can't electrically touch anything. =========== ================ ============= ========= ======= ================== PCB Number PCB Material Insulation Untouched Touched Signal/Noise Ratio =========== ================ ============= ========= ======= ================== 1 Teflon Composite stickytape 5390 500 10.8 2 Fibreglass stickytape 5850 800 10.8 3 Fibreglass Kapton 5200 550 9.45 =========== ================ ============= ========= ======= ================== .. note:: The use of Kapton resulted in slightly less signal/noise ratio. touched = finger firmly pressing on the copper pad. Scale shown in pictures is in mm #1 Teflon Composite ^^^^^^^^^^^^^^^^^^^ .. image:: projects/touch-sensor/pics/touchsensor-5390-500.jpg #2 Fibreglass ^^^^^^^^^^^^^ Insulation: stickytape .. image:: projects/touch-sensor/pics/touchsensor-5850-800.jpg #3 Fibreglass ^^^^^^^^^^^^^ Insulation: Kapton .. image:: projects/touch-sensor/pics/touchsensor-5200-550.jpg Fault Outputs ------------- No Electrode connected ^^^^^^^^^^^^^^^^^^^^^^ "s" output: :: 9235 9235 9240 9235 9238 9239 9234 9236 9236 No Capacitor connected ^^^^^^^^^^^^^^^^^^^^^^ "s" output: :: 1 * 1 * 1 * 1 * 1 * 1 * 1 * No Capacitor or Electrode connected ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "s" output: :: 1 * 1 * 1 * 1 * 1 * 1 * 1 * The TSC Peripheral ------------------ This peripheral is available on many STM32F/L0, and STM32F/L4's but not all STM's including the STM32F1xx, eg the 'Blue Pill'. The table below lists the number of touch sensors available on various STM32F models. .. image:: projects/touch-sensor/pics/stm32-touch-channels.jpg Summary ------- Initially I thought that the TSC results might be a bit flaky or not work at all on a standard low cost "F0 Discovery" board where the lead capacitances are 'whatever' and there is a lot of electrical noise. I couldn't have been more wrong! Instead I found that the TSC is highly robust and repeatable. I intend to use it in further projects, some of which I only saw the possibilities after playing with this kit. For Developers -------------- Binary, Brief Description ------------------------- This project uses Mecrisp-Stellaris Forth on a FO Discovery Board containing a STM32F051 MCU overclocked to 75 MHz (via the Disco 8MHz xtal) and running a simple task scheduler consisting of Task 1 which occurs every 100 milliseconds and triggers a TSC 'acquisition' interrupt. Five milliseconds after the acquisition, Task 2 runs displaying the results. The controlling serial terminal response is the same whether scanning or not. After quitting out of the menu, the Forth system is available, type "words4" to see a list of all the Words (subroutines) available in the binary. Interesting Words ^^^^^^^^^^^^^^^^^ * gpioa. * rcc. * free * nvic. * 2 2 + . * 200 200 * . * 0 207 0 305 f/ f. * ." Hello World" cr * green-on * green-off Development History ^^^^^^^^^^^^^^^^^^^ Developing this Forth bootable binary took a few days as I attempted to learn about the TSC peripheral, understand the STMicro TSC configuration 'C' code example and port it to Forth whilst testing on a STMicro F0 Discovery board. Whilst very helpful, the 'code example' is incomplete because it doesn't contain enough information to actually build a working prototype. This may explain why there are so few projects using the STM32 TSC on the Internet? STMicro C TSC code example ^^^^^^^^^^^^^^^^^^^^^^^^^^ Copied from the "STM32F0x1/STM32F0x2/STM32F0x8 advanced ARM®-based 32-bit MCUs Reference Manual RM0091" dated January 2017. :: A.18.1 TSC configuration code example /* Configure TCS */ /* With a charge transfer around 2.5 µs */ /* (1) Select fPGCLK = fHCLK/32, Set pulse high = 2xtPGCLK,Master Set pulse low = 2xtPGCLK Set Max count value = 16383 pulses Enable TSC */ /* (2) Disable hysteresis */ /* (3) Enable end of acquisition IT */ /* (4) Sampling enabled, G2IO4 */ /* (5) Channel enabled, G2IO3 */ /* (6) Enable group, G2 */ TSC->CR = TSC_CR_PGPSC_2 | TSC_CR_PGPSC_0 | TSC_CR_CTPH_0 | TSC_CR_CTPL_0 | TSC_CR_MCV_2 | TSC_CR_MCV_1 | TSC_CR_TSCE; /* (1) */ TSC->IOHCR &= (uint32_t)(~(TSC_IOHCR_G2_IO4 | TSC_IOHCR_G2_IO3)); /* (2) */ TSC->IER = TSC_IER_EOAIE; /* (3) */ TSC->IOSCR = TSC_IOSCR_G2_IO4; /* (4) */ TSC->IOCCR = TSC_IOCCR_G2_IO3; /* (5) */ TSC->IOGCSR |= TSC_IOGCSR_G2E; /* (5) */ A.18.2 TSC interrupt code example /* End of acquisition flag */ if ((TSC->ISR & TSC_ISR_EOAF) == TSC_ISR_EOAF) { TSC->ICR = TSC_ICR_EOAIC; /* Clear flag */ AcquisitionValue = TSC->IOGXCR[1]; /* Get G2 counter value */ } What's Missing From The C Code Example? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. GPIO Alternate Function selection code. Touch requires a minimum of two GPIO pins to be useful. 2. Starting an 'acquisition' by setting the 'START' BIT (1) of TSC_CR. Without this, nothing happens! A more recent STMicro 'Touch Sensor' example I found was a series of GUI window pictures using Eclipse, HAL and STM32cube etc. There was no real code in this article, is this the dumbed-down future of embedded design? Forth Code ---------- This code excerpt from :ref:`the touch demo binary` shows the TSC peripheral config and interrupt code. :: 8 bit constant TSC-INTERRUPT \ bitposn 8 settable TSC Touch sensing interrupt 0 variable task1-time 0 variable task1b-flag 6000 variable g2-counter 0 variable touched-flag 2500 variable sensitivity \ ------------------------------------- Config Words ------------------------------------------- \ : RCC_AHBENR_TSCEN ( -- x addr ) 24 bit RCC_AHBENR ; \ RCC_AHBENR_TSCEN, Touch sensing controller clock enable : NVIC_ISER_SETENA ( %bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb -- x addr ) NVIC_ISER ; \ NVIC_ISER_SETENA, SETENA : GPIOA_AFRL_AFRL7 ( %bbbb -- x addr ) 28 lshift GPIOA_AFRL ; \ GPIOA_AFRL_AFRL7, Alternate function selection : GPIOA_AFRL_AFRL6 ( %bbbb -- x addr ) 24 lshift GPIOA_AFRL ; \ GPIOA_AFRL_AFRL6, Alternate function selection : GPIOA_MODER_MODER7 ( %bb -- x addr ) 14 lshift GPIOA_MODER ; \ GPIOA_MODER_MODER7 : GPIOA_MODER_MODER6 ( %bb -- x addr ) 12 lshift GPIOA_MODER ; \ GPIOA_MODER_MODER6, : TSC_CR_TSCE ( -- 1 addr ) 0 bit TSC_CR ; \ TSC_CR_TSCE, Touch sensing controller enable : TSC_CR_START ( -- x addr ) 1 bit TSC_CR ; \ TSC_CR_START, Start a new acquisition : TSC_CR_MCV ( %bbb -- x addr ) 5 lshift TSC_CR ; \ TSC_CR_MCV, Max count value : TSC_CR_PGPSC ( %bbb -- x addr ) 12 lshift TSC_CR ; \ TSC_CR_PGPSC, pulse generator prescaler : TSC_CR_CTPH ( %bbbb -- x addr ) 28 lshift TSC_CR ; \ TSC_CR_CTPH, Charge transfer pulse high : TSC_CR_CTPL ( %bbbb -- x addr ) 24 lshift TSC_CR ; \ TSC_CR_CTPL, Charge transfer pulse low : TSC_IOHCR_G2_IO4 ( -- x addr ) 7 bit TSC_IOHCR ; \ TSC_IOHCR_G2_IO4, G2_IO4 Schmitt trigger hysteresis mode : TSC_IOHCR_G2_IO3 ( -- x addr ) 6 bit TSC_IOHCR ; \ TSC_IOHCR_G2_IO3, G2_IO3 Schmitt trigger hysteresis mode : TSC_IER_EOAIE ( -- 1 addr ) 0 bit TSC_IER ; \ TSC_IER_EOAIE, End of acquisition interrupt enable : TSC_IOSCR_G2_IO4 ( -- x addr ) 7 bit TSC_IOSCR ; \ TSC_IOSCR_G2_IO4, G2_IO4 sampling mode : TSC_IOCCR_G2_IO3 ( -- x addr ) 6 bit TSC_IOCCR ; \ TSC_IOCCR_G2_IO3, G2_IO3 channel mode : TSC_IOGCSR_G2E ( -- x addr ) 1 bit TSC_IOGCSR ; \ TSC_IOGCSR_G2E, Analog I/O group 1 enable : TSC_ICR_EOAIC ( -- 1 addr ) 0 bit TSC_ICR ; \ TSC_ICR_EOAIC, End of acquisition interrupt clear : TSC_IOG2CR_CNT? ( %bbbbbbbbbbbbbb -- x ) TSC_IOG2CR @ ; \ TSC_IOG2CR_CNT, Counter value \ ------------------------------------- Config Words ------------------------------------------- \ : tsc-config ( -- ) \ Init and configure the TSC peripheral ready for use RCC_AHBENR_TSCEN bis! \ GPIO: Alternate Function Mode: PA6 & PA7 AF GPIOA_MODER_MODER7 bis! AF GPIOA_MODER_MODER6 bis! \ GPIO: AF3: PA6 & PA7 AF3 GPIOA_AFRL_AFRL6 bis! \ PA6 = TSC_G2_IO3 AF3 GPIOA_AFRL_AFRL7 bis! \ PA7 = TSC_G2_IO4 \ 1. CONFIGURE TCS With a charge transfer around 2.5 µs %101 TSC_CR_PGPSC bis! \ a. Select fPGCLK = fHCLK/32, 101: fHCLK /32 %1 TSC_CR_CTPH bis! \ b. Set pulse high = 2xtPGCLK,Master. CTPH: 0001: 2x tPGCLK %1 TSC_CR_CTPL bis! \ c. Set pulse low = 2xtPGCLK. CTPL: 0001: 2x tPGCLK %110 TSC_CR_MCV bis! \ d. Set Max count value = 16383 pulses. 110: 16383 TSC_CR_TSCE bis! \ e. Enable TSC. TSC_CR_TSCE, Touch sensing controller enable \ 2. DISABLE HYSTERESIS 0: Schmitt trigger hysteresis disabled TSC_IOHCR_G2_IO4 bic! \ disable G2_IO4 Schmitt trigger hysteresis TSC_IOHCR_G2_IO3 bic! \ disable G2_IO3 Schmitt trigger hysteresis \ 3. ENABLE END OF ACQUISITION INTERRUPT TSC_IER_EOAIE bis! \ End of acquisition interrupt enable \ 4. SAMPLING ENABLED, G2IO4. 1: G2_IO4 used as sampling capacitor \ These bits are set and cleared by software to configure the G2_IO4 as a sampling capacitor \ I/O. Only one I/O per analog I/O group must be defined as sampling capacitor. TSC_IOSCR_G2_IO4 bis! \ G2_IO4 = sampling mode \ 5. CHANNEL ENABLED, G2IO3. 1: G2_IO3 used as channel TSC_IOCCR_G2_IO3 bis! \ G2_IO3 = channel mode \ 6. ENABLE GROUP, G2. TSC_IOGCSR_G2E bis! \ TSC_IOGCSR_G2E = Analog I/O group ; : g2-counter? ( -- x ) g2-counter @ ; \ This is the value of the sensor read, high values around 5000 mean no touch : acquire ( -- ) \ TSC_CR_START, Start a new acquisition TSC_CR_START bis! \ start acquisition, it finishes with a interrupt by the irq-tsc ; \ which updates g2-counter within about 5 milliseconds. : tsc-handler ( -- ) \ Interrupt occurs because voltage across CS has reached the threshold TSC_ICR_EOAIC bis! \ TSC_ICR_EOAIC, Clear "End of acquisition interrupt flag" TSC_IOG2CR_CNT? g2-counter ! \ count = number of charge transfer cycles generated to complete acquisition ; : tsc-init ( -- ) ['] tsc-handler irq-tsc ! \ tie handler to interrupt TSC-INTERRUPT NVIC_ISER_SETENA ! \ enable TSC interrupt ;