ich versuche gerade, kapazitive Sensoren (jeweils Kupferfolie, verbunden mit Arduino Mega), zu kalibrieren. Bevor ich das mit mehreren versuche, probiere ich es gerade mit einem einzelnen Sensor aus.
Die Idee ist Folgende:
Kalibrierungsphase --> LED leuchtet 5 Sekunden lang auf
Während dieser Zeit wische ich über den Sensor hin und her, sodass Min- und Max-Werte festgestellt werden
Dann ist die Kalibrierungsphase vorbei --> LED geht aus
Dann werden die kalibrierten Werte ausgegeben (in meinem Test zwischen 0 und 127)
Leider will das so nicht klappen. Die Werte gehen in meinem Fall auf über 300 hoch, das heißt, die Kalibrierung funktioniert nicht. Hier ist der Code:
#include <CapacitiveSensor.h>
#include <elapsedMillis.h>
float max = 0;
float min = 100000;
void calibrate (float v) {
if (v > max) max = v;
if (v < min) min = v;
}
float get (float v) {
return map(v, min, max, 0, 127);
}
int ledPin = 13;
elapsedMillis timer;
CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2);
void setup() {
pinMode(ledPin, OUTPUT);
cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
Serial.begin(9600);
digitalWrite(ledPin, HIGH);
while(timer < 5000) {
calibrate(cs_4_2.capacitiveSensor(30));
}
digitalWrite(ledPin, LOW);
}
void loop() {
float sensorValue1 = cs_4_2.capacitiveSensor(30);
float total1 = get(sensorValue1);
Serial.println(total1);
delay(10);
}
Vermutlich habe ich irgendwo einen Denkfehler drin und die Lösung ist ganz simpel aber anscheinend stehe ich grad gehörig auf dem Schlauch.
Wenn jemand u. U. einen Fehler sieht, wäre ich über jede Hilfe sehr dankbar.
Danke euch Hab jetzt die floats in ints geändert (+ aus dem Grund den min-Wert von 100000 auf 10000 reduziert) mit dem Ergebnis, dass das Programm so, sagen wir mal, 90% funktioniert. Die Kalibrierung funktioniert vom Prinzip her, allerdings habe ich festgestellt, dass ich, obwohl ich nur bis 127 mappe, trotzdem zum Teil Werte um 200 rum bekomme. Wenn ich bis 511 mappe, erhalte ich zum Teil Werte um 600 rum etc.
An was liegt das?
Hier ist der geänderte Code:
#include <CapacitiveSensor.h>
#include <elapsedMillis.h>
int max = 0;
int min = 10000;
void calibrate (int v) {
if (v > max) max = v;
if (v < min) min = v;
}
int get (int v) {
return map(v, min, max, 0, 127);
}
int ledPin = 13;
elapsedMillis timer;
CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2);
void setup() {
pinMode(ledPin, OUTPUT);
cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
Serial.begin(9600);
digitalWrite(ledPin, HIGH);
while(timer < 5000) {
calibrate(cs_4_2.capacitiveSensor(30));
}
digitalWrite(ledPin, LOW);
}
void loop() {
int sensorValue1 = cs_4_2.capacitiveSensor(30);
int total1 = get(sensorValue1);
Serial.println(total1);
delay(10);
}
void calibrate (int v) {
if (v > max) max = v;
if (v < min) min = v;
}
int get (int v) {
return map(v, min, max, 0, 127);
}
Habt ein schönes Wochenende!
Wenn Du rausliest, wie gross die Werte v, min, max, etc. sein dürfen und Du das ausnutzt, ist mein WE gerettet! Danke schonmal dafür - Ich weiss Du machst das
map() limitiert sich nicht auf den angegebenen Werte. Die angegebenen Werte sind nur jeweils 2 Punkte auf 2 Geraden. Da die Geraden unendlich lang sind (außer durch den Wertebereich der verwendeten Variablen begrenzt), sind auch Werte außerhalb des Eingabebereichs definiert. Darum kann auch 200 herauskommen.
So, nach längerem Überlegen bin ich auf dieselbe Vermutung gekommen, die sich dann durch uwefed's Beitrag zum Glück bestätigt hat, nämlich, dass die map-Funktion ein Problem macht, wenn NACH der Kalibrierung noch ein höherer "v"-Wert entsteht, als WÄHREND der Kalibrierung. Dann ist v > max, also klappt das mit der map-Funktion dann nicht.
Ich habe das jetzt folgendermaßen gelöst:
int get (int v) {
if (v > max) max = v; // <-- !!!
return map(v, min, max, 0, 127);
}
Das heißt, ich setze jetzt v auf den max-Wert, wenn nachträglich (nach der Kalibrierung) noch ein höherer v-Wert entsteht.
Scheint soweit zu klappen.
Als nächstes versuche ich jetzt, das mit mehreren Sensoren zu machen
Das 'Nachführen' Deiner Werte nach der Kalibrierung halte ich für gefährlich.
So können Dir zwei Ausreißer den Wertebereich so auseinander drücken, daß die normalen Messwerte 'ziemlich genau in der Mitte' - aber eben Beide nahezu identisch - sind.
Das kann Dir auch erst in drei Wochen passieren - dann ist plötzlich einer der Sensoren 'taub' geworden.
Siehe constrain
Das begrenzt den Variablenwert auf Unter/Obergrenze bzw. gibt den Wert zurück, wenn Er innerhalb der Grenzen liegt.
Bei mir sind die Sensoren unter einer Gipsschicht. Um zu verhindern, dass die Werte nach der Kalibrierung höher sind, als während der Kalibrierung, könnte ich natürlich während der Kalibrierung auch einfach ganz fest auf die ganzen Sensoren drücken aber das mit der constraint-Funktion hört sich besser an