5. Capsense

Capsense is een term die gebruikt wordt binnen het Arduino ecosysteem om capacitief uitgelezen knoppen te omschrijven. Dit principe is echter ook bruikbaar om naast knoppen, sliders, touch wheels, ook afstand tussen hand en knop uit te lezen (“proximity”), vloeistofniveaus te bepalen, etc. Het scherm van moderne touchscreen apparaten werkt nagenoeg altijd volgens dit principe, maar dan met een erg groot aantal capacitieve sensoren. Om het werkingsprincipe uit te leggen is het echter interessanter om te kijken naar de Arduino implementatie, aangezien deze hardware agnostisch is. De typische hardware layout ziet er zo uit:

Implementatie op de Arduino Uno (ATMEGA 328P), maar kan op 'alle' microcontrollers op deze wijze geïmplementeerd worden. Een ander principe wordt gebruikt op de ESP32, omdat deze specieke hardware aan boord heeft voor de meting!
Er zijn dus 2 pinnen nodig op onze microcontroller, waarvan we er één van rol moeten kunnen wisselen ("Send pin": input/output), de “Receive pin” mag input-only zijn. Let op, dit zijn dus “digitale pinnen”, we moeten dus geen analoge pinnen opofferen om gebruik te maken van deze functionaliteit. In de afbeelding hierboven kan je ook een condensator ontwaren: Csensed. Deze wordt gevormd door: een stukje metaal(-folie) enerzijds en je lichaam anderzijds. Wanneer er geen lichaam in de buurt is, dan zal je de capaciteit meten naar de aarde, wanneer je in de buurt komt, dan zal de capaciteit sterk wijzigen. Klimatologische omstandigheden zoals variaties in de luchtvochtigheid en luchtdruk hebben bijgevolg een grote invloed op de gemeten waarde. Daarom is het nodig om regelmatig te her-kalibreren. Hoe wordt deze capaciteit nu gemeten: De Send pin wordt hoog gemaakt, dan wordt er een tellertje gestart. Het duurt enige tijd (enkele ms) totdat de Receive-pin ook hoog wordt, omdat de Csensed condensator opgeladen moet worden. De laadstroom wordt beperkt door de weerstand R. Wanneer beide pinnen dezelfde toestand aangeven, dan wordt de Send-pin laag-impedant gemaakt zodat Csensed hierover kan ontladen. Opnieuw wordt er gekeken hoe lang het duurt totdat de ze beide dezelfde toestand hebben aangenomen.
De Arduino geeft dus een een arbitraire “counts” waarde aan (= status van de teller), welke gerelateerd is aan de grootte van de capaciteit.
Als touch sensor kan je best een kabeltje met tape op een stukje aluminiumfolie tapen, stop de andere zijde van het kabeltje in je development board, op een GPIO33 = Touch8 in overzicht van het development board. Je kan de pinnamen terugvinden op de INFO-pagina.
Pas de onderstaande code aan, zodat je een capacitieve meting kunt doen op GPIO33. De capaciteit wordt in arbitraire waarden geprint in de Serial Console, maar het is vaak beter om de Serial Plotter te gebruiken om naar dergelijke data te kijken. Deze code is een trouwens een voorbeeld van een Arduino-achtige implementatie op de ESP32 qua software, maar maakt wel gebruik van de specifiek ESP32 capacitieve hardware.
#include <Arduino.h>
#include <TFT_eSPI.h>
void printTitel(void);
TFT_eSPI tft = TFT_eSPI(); // Constructor for the TFT library
#define DISPLAYTEXT "Labo 2 - CAPSENSE"
void setup() {
printTitel();
Serial.begin(115200);
}
void loop() {
Serial.println(touchRead(...)); // get value of Touch8 pin = GPIO 33
delay(10);
}
void printTitel(){ // Print titel
tft.init();
tft.setRotation(3); //setRotation: 1: Screen in landscape(USB to the right)
tft.fillScreen(TFT_BLACK); //Fill screen with random colour
tft.setCursor(0, 0, 4); //cursor at 0,0;font 4,println sets cursor on next line
tft.setTextColor(TFT_BLACK, TFT_YELLOW); // Textcolor, BackgroundColor
tft.println(DISPLAYTEXT); //Print on cursorpos 0,0
}

Schema
Je zal merken dat de het signaal op Serial Plotter al wijzigt wanneer je met je hand in de buurt van de sensor komt. Zoveel te groter het oppervlak dat je bedekt, zoveel te groter de uitwijking. Wanneer je de sensor aanraakt, dan zie je een erg grote response! Helaas is er standaard erg weinig aan te passen aan het gedrag van de capacitieve uitlezing. Daarvoor moeten we iets dieper graven in de ESP32. Op de ESP32 ziet de “volledigere implementatie” er iets anders uit, aangezien deze specifieke hardware aan boord heeft welke de capacitieve knoppen kan uitlezen. Waardoor je veel meer mogelijkheden hebt, die via software aanstuurbaar zijn. Zoals je onder andere in de afbeelding hierboven kunt zien, zijn er veel parameters aanpasbaar, welke niet in te stellen zijn in de standaard Arduino implementatie. Meer informatie over de ESP32 implementatie van Capsense (“Touch Sensor” genoemd), kan je terugvinden in de specifieke design guide of programming guide. Vul de code hieronder aan, door de nodige informatie op te zoeken in de programming guide (v4.4.1)(PDF Backup), deze versie van de driver is al wat ouder, maar je hebt veel meer controle dan met de meest recente versie van de driver (Meest recente programming guide).
#include <Arduino.h>
#include <TFT_eSPI.h>
#include "driver/touch_sensor.h" //Old driver, still available for backward compatibility, but not recommended for new projects.
//#include "driver/touch_sens.h" //New driver, recommended for new projects, but the available configuration options are very limited.
#define DELAYTIME_MS 10
#define TOUCH_PIN 2 // GPIO 2 is Touch Channel 2 on ESP32 classic
#define DISPLAYTEXT "Labo 2 - CAPSENSE V2"
uint16_t rawValue = 0;
uint16_t filteredValue = 0;
unsigned long lastMillis = 0;
TFT_eSPI tft = TFT_eSPI();
void setup() {
Serial.begin(115200);
delay(100); // Give serial time to start
//touchAttachInterrupt(TOUCH_PIN, NULL, 40); // 1. Initialize the touch system, Optional
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); // 2. Example to show Configuration of the voltages
touch_pad_filter_start(10); // 3. Configure+Start the Hardware Filter: 10ms is a standard choice.
Serial.println("\nInitionalisation Ready.\n\n");
}
void loop() {
if (millis() - lastMillis >= DELAYTIME_MS) { // Non-blocking delay
lastMillis = millis();
touch_pad_...((touch_pad_t)TOUCH_PIN, &rawValue); // Read Raw Data
touch_pad_...((touch_pad_t)TOUCH_PIN, &filteredValue);// Read Filtered Data
Serial.printf("Raw: %d, Filtered: %d/n",rawValue,filteredValue);
}
}
void printTitel(){ // Print titel
tft.init();
tft.setRotation(3); //setRotation: 1: Screen in landscape(USB to the right)
tft.fillScreen(TFT_BLACK); //Fill screen with random colour
tft.setCursor(0, 0, 4); //cursor at 0,0;font 4,println sets cursor on next line
tft.setTextColor(TFT_BLACK, TFT_YELLOW); // Textcolor, BackgroundColor
tft.println(DISPLAYTEXT); //Print on cursorpos 0,0
}
Roep de docent, demonstreer de functionaliteit van de schakeling.
ANS vraag 5a, 5b, 5c, 5d
Dit was de laatste oefening van Labo 2, breek je schakeling af, en berg alles weer op. Vergeet je ANS lijst niet in te dienen!