30. September 2012
Einstieg Zu beginn der Arbeit wollte ich durch einen Eigenbau mit Aluminiumfolie die Kapazitiven Sensoren eines Tochpad nachbauen. Jedoch war trotz des Imports der „Capacitive Sensing Library „ (http://arduino.cc/playground/Main/CapacitiveSensor?from=Main.CapSense) keine zufriedenstellende Umsetzung möglich. Erkenntnis Die von Arduino extrem schwankenden ausgelesenen kapacitiven Signalwerte, können trotz Smoothing und Eichungsfunktionen nur grob in folgende, einigermassen zuverlässige, Werte unterteilt werden: 1. Keine Hand in der Nähe der Folie 2. Hand nahe der Folie 3. Hand an der Folie 4. Folie nicht an Arduino angeschlossen Deswegen entschloss ich mich mein Lernprojekt auf einen Kapazitiven Sensor runter zu brechen. Produkt Entstanden ist der FoodReader 3000. Der offizielle Nachfolger des bekannten FoodReader 2000. Elektrisch leitende Esswaren können an ihn angeschlossen werden (Joghurt, Apfel etc.). In meinem Fall ist es ein „Schoggistängeli„. Den Nahrungsmitteln ist es dank dem „FoodReader 3000“ möglich, dem Nutzer ihre Sicht der Lage mitzuteilen. Aufbau 7 x 1 Mega Ohm Widerstände in Serie geschaltet. Funktionen Die Essensaussagen richten sich nach nähe der Hand zur Folie, Dauer der Interaktion und zum wievielten mal die Situation zu Stande kommt. Nachrichten Beispiel: 02_KontinuumVideo CODE://ARDUINO-------------------------------------------------------------------------------------------------------------------------------- #include <CapacitiveSensor.h> CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2); // 10 megohm resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foil void setup() { cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate on channel 1 - just as an example Serial.begin(9600); } void loop() { long start = millis(); long total1 = cs_4_2.capacitiveSensor(30); //delay(40); // arbitrary delay to limit data to serial port Serial.print(total1); // Anzeigen der Werte über Serial Monitor Serial.print(','); Serial.println(); } //PROCESSING-------------------------------------------------------------------------------------------------------------------------------- import fullscreen.*; FullScreen fs; // commenten für normal Window import processing.serial.*; Serial myPort; nichtBeruehrt nichtBeruehrtEingabe; naheKontakt naheKontaktEingabe; kontakt kontaktEingabe; klammerEntfernt klammerEntferntEingabe; int schoggiWert = 0; String textanzeige = "wait"; int i = 0; int schoggiWertDurchscnitt = 0; int schoggiWertGeeicht = 0; boolean startWert = false; int schoggiStartWert = 0; int zaehler = 0; int _schoggiWert00 = 0; int _schoggiWert01 = 0; int _schoggiWert02 = 0; int _schoggiWert03 = 0; int _schoggiWert04 = 0; int _schoggiWert05 = 0; int _schoggiWert06 = 0; int _schoggiWert07 = 0; int _schoggiWert08 = 0; int _schoggiWert09 = 0; int iNichtBeruert = 0; int iNaheKontakt = 0; int iKontakt = 0; int iKlammerEntfernt = 0; boolean runNichtBeruehrt = false; boolean runNaheKontakt = false; boolean runKontakt = false; boolean runKlammerEntfernt = false; int textanzeigeHoehe = 5; int textanzeigeBreite = 5; int textboxHoehe = 0; int textboxBreite = 0; int textGroesse = 0; boolean texteAnzeigen = false; // auf false ändern int letztenMal = 0; int delayZeit = 1000; boolean wach = false; boolean schlaf = true; void setup() { //size(1920, 800); //ENTcommenten für normal Window size(1920, 1200); //commenten für normal Window PFont font; font = loadFont("Monospaced-60.vlw"); textFont(font, 60); smooth(); println(Serial.list()); myPort = new Serial(this, "/dev/tty.usbmodemfd121", 9600); fs = new FullScreen(this); //commenten für normal Window fs.enter(); //commenten für normal Window nichtBeruehrtEingabe = new nichtBeruehrt(); naheKontaktEingabe = new naheKontakt(); kontaktEingabe = new kontakt(); klammerEntferntEingabe = new klammerEntfernt(); } void draw() { background(69, 93, 214); if (texteAnzeigen == true) { if (runNichtBeruehrt == true) { nichtBeruehrtEingabe.anzeigen(); //nichtBeruehrt(); } if (runNaheKontakt == true) { naheKontaktEingabe.anzeigen(); //naheKontakt(); } if (runKontakt == true) { kontaktEingabe.anzeigen(); //kontakt(); } if (runKlammerEntfernt == true) { klammerEntferntEingabe.anzeigen(); //klammerEntfernt(); } if (iNichtBeruert > 3) { beenden(); runNichtBeruehrt = true; } if (iNaheKontakt > 3) { beenden(); runNaheKontakt = true; } if (iKontakt > 3) { beenden(); runKontakt = true; } if (iKlammerEntfernt > 3) { beenden(); runKlammerEntfernt = true; } textbox(); } } void serialEvent(Serial myPort) { if (myPort.available() > 0) { //println(Daten sind da); String completeString = myPort.readStringUntil(10); //Println(completeString); if (completeString != null) { trim (completeString); String seperateValues[] = split(completeString, ","); //println(seperateValues[1]); schoggiWert = int(seperateValues[0]); //schoggiWert = 0; smoothing(0); eichen(); println("schoggiWertGeeicht = " + schoggiWertGeeicht); if (zaehler < 110) { zaehler = zaehler + 1; } //if (schoggiWertGeeicht < 20) { if (schoggiWertGeeicht >= -20 && schoggiWertGeeicht <= 20) { iNichtBeruert = iNichtBeruert + 1; println("iNichtBeruert = " + iNichtBeruert); iNaheKontakt = 0; iKontakt = 0; iKlammerEntfernt = 0; } if (schoggiWertGeeicht > 30 && schoggiWertGeeicht <= 80) { iNaheKontakt = iNaheKontakt + 1; println("iNaheKontakt = " + iNaheKontakt); iNichtBeruert = 0; iKontakt = 0; iKlammerEntfernt = 0; } if (schoggiWertGeeicht > 80) { iKontakt = iKontakt + 1; println("iKontakt = " + iKontakt); iNichtBeruert = 0; iNaheKontakt = 0; iKlammerEntfernt = 0; } if (schoggiWertGeeicht < -30) { iKlammerEntfernt = iKlammerEntfernt + 1; println("iKlammerEntfernt = " + iKlammerEntfernt); iNichtBeruert = 0; iNaheKontakt = 0; iKontakt = 0; } } } } void smoothing(int alterWert) { int aktuellerWert = schoggiWert; // Hier werden die Werte abgerufen aktuellerWert = int (0.6*alterWert + 0.4*aktuellerWert); // Smoothing Funktion alterWert = aktuellerWert; // Hier wird der aktuelle Wert als oldValue gespeichert schoggiWert = aktuellerWert; } void eichen() { int _schaltstufe = 9; if (startWert == false && zaehler >= 100) { if (zaehler == 110) { startWert = true; } switch(i) { case 0: _schoggiWert00 = schoggiWert; println("_schoggiWert00 = " + _schoggiWert00); break; case 1: _schoggiWert01 = schoggiWert; println("_schoggiWert01 = " + _schoggiWert01); break; case 2: _schoggiWert02 = schoggiWert; println("_schoggiWert02 = " + _schoggiWert02); break; case 3: _schoggiWert03 = schoggiWert; println("_schoggiWert03 = " + _schoggiWert03); break; case 4: _schoggiWert04 = schoggiWert; println("_schoggiWert04 = " + _schoggiWert04); break; case 5: _schoggiWert05 = schoggiWert; println("_schoggiWert05 = " + _schoggiWert05); break; case 6: _schoggiWert06 = schoggiWert; println("_schoggiWert06 = " + _schoggiWert06); break; case 7: _schoggiWert07 = schoggiWert; println("_schoggiWert07 = " + _schoggiWert07); break; case 8: _schoggiWert08 = schoggiWert; println("_schoggiWert08 = " + _schoggiWert08); break; case 9: _schoggiWert09 = schoggiWert; println("_schoggiWert09 = " + _schoggiWert09); break; default: break; } if (i <= _schaltstufe) { i = i + 1; } else { i = 0; } if (i > _schaltstufe) { println(i); schoggiWertDurchscnitt = (_schoggiWert00 + _schoggiWert01 + _schoggiWert02 + _schoggiWert03 + _schoggiWert04 + _schoggiWert05 + _schoggiWert06 + _schoggiWert07 + _schoggiWert08 + _schoggiWert09)/_schaltstufe; println(" schoggiWertDurchscnitt = " + schoggiWertDurchscnitt); fill(255, 0, 0); texteAnzeigen = true; } } schoggiWertGeeicht = schoggiWert - schoggiWertDurchscnitt; } void beenden() { runNichtBeruehrt = false; runNaheKontakt = false; runKontakt = false; runKlammerEntfernt = false; } void textbox() { textboxHoehe = textanzeigeHoehe + 20; textboxBreite = textanzeigeBreite + 20; translate(300, (height/2) - textboxHoehe); fill(255); rect(0, 0, textboxBreite, textboxHoehe); triangle(0, textboxHoehe, 0, textboxHoehe + 60, 60, textboxHoehe); noStroke(); fill(0); textSize(textGroesse); text(textanzeige, 20, 20, textanzeigeBreite, textanzeigeHoehe); } //class klammerEntfernt-------------------------------------------------------------------------------------------------------------------------------- class klammerEntfernt { //Globale Variablen //Konstruktor klammerEntfernt() { } // Funktionen void anzeigen() { textGroesse = 200; textanzeige = "WAHHHHH!!!"; textanzeigeBreite = 1300; textanzeigeHoehe = 400; } } //class kontakt-------------------------------------------------------------------------------------------------------------------------------- class kontakt { //Globale Variablen boolean runStufeKontakt = true; boolean runStufeKontakt00 = false; boolean runStufeKontakt01 = false; boolean runStufeKontakt02 = false; boolean runStufeKontakt03 = false; //Konstruktor kontakt() { } // Funktionen void anzeigen() { wach = true; if (runStufeKontakt == true) { textGroesse = 80; textanzeige = "Finger weg!"; textanzeigeBreite = 600; textanzeigeHoehe = 100; delayZeit = 3000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeKontakt = false; runStufeKontakt00 = true; } } if (runStufeKontakt00 == true) { textGroesse = 80; textanzeige = "Finger weg!"; textanzeigeBreite = 600; textanzeigeHoehe = 100; delayZeit = 3000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeKontakt00 = false; runStufeKontakt01 = true; } } if (runStufeKontakt01 == true) { textGroesse = 80; textanzeige = "Wie wär's wenn ich DICH mal da unten anfassen würde?"; textanzeigeBreite = 1300; textanzeigeHoehe = 200; delayZeit = 5000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeKontakt01 = false; runStufeKontakt02 = true; } } if (runStufeKontakt02 == true) { textGroesse = 60; textanzeige = "Pfuhhh... langsam wird mir echt warm..."; textanzeigeBreite = 1300; textanzeigeHoehe = 160; delayZeit = 3000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeKontakt02 = false; runStufeKontakt03 = true; } } if (runStufeKontakt03 == true) { textGroesse = 100; textanzeige = "!!@$¿@¥*§#‰!!"; textanzeigeBreite = 800; textanzeigeHoehe = 120; delayZeit = 3000; } } } //class naheKontakt-------------------------------------------------------------------------------------------------------------------------------- class naheKontakt { //Globale Variablen boolean runStufeNaheKontakt = true; boolean runStufeNaheKontakt00 = false; boolean runStufeNaheKontakt01 = false; boolean runStufeNaheKontakt02 = false; //Konstruktor naheKontakt() { } void anzeigen() { wach = true; if (runStufeNaheKontakt == true) { textGroesse = 60; textanzeige = "*GÄÄääähn schmatz schmatz* öhhmmm... was soll das werden?"; textanzeigeBreite = 1300; textanzeigeHoehe = 150; delayZeit = 6000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeNaheKontakt = false; runStufeNaheKontakt00 = true; } } if (runStufeNaheKontakt00 == true) { textGroesse = 60; textanzeige = "*GÄÄääähn schmatz schmatz* öhhmmm... was soll das werden?"; textanzeigeBreite = 1300; textanzeigeHoehe = 150; delayZeit = 5000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeNaheKontakt00 = false; runStufeNaheKontakt01 = true; } } if (runStufeNaheKontakt01 == true) { textGroesse = 60; textanzeige = "Wenn's Dir spass macht."; textanzeigeBreite = 900; textanzeigeHoehe = 75; delayZeit = 4000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); runStufeNaheKontakt01 = false; runStufeNaheKontakt02 = true; } } if (runStufeNaheKontakt02 == true) { textGroesse = 60; textanzeige = "..."; textanzeigeBreite = 130; textanzeigeHoehe = 75; } } } //class nichtBeruehrt-------------------------------------------------------------------------------------------------------------------------------- class nichtBeruehrt { //Globale Variablen boolean runStufeNichtBeruehrt01 = false; //Konstruktor nichtBeruehrt() { } // Funktionen void anzeigen() { if (schlaf == true) { textGroesse = 15; textanzeige = "Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz... Zzz Zzzzzz..."; textanzeigeBreite = 400; textanzeigeHoehe = 200; } if (wach == true) { textGroesse = 60; textanzeige = "Ja, geh weiter Du Freak."; textanzeigeBreite = 900; textanzeigeHoehe = 75; delayZeit = 7000; if (millis() - letztenMal > delayZeit) { letztenMal = millis(); wach = false; runStufeNichtBeruehrt01 = true; } } if (runStufeNichtBeruehrt01 == true) { textGroesse = 60; textanzeige = "..."; textanzeigeBreite = 130; textanzeigeHoehe = 75; } } }