Hallo ich bin neu hier und das ist mein erster Thread im Arduino Forum. Ich hoffe ich mache alles soweit richtig. Ich verwende einen Arduino Uno R3 und die Arduino IDE.
Bei meinem aktuellen Projekt geht es mir darum mithilfe eines Magnetventils eine bestimmte Menge Wasser durch Schwerkraft aus einem zylindrischen Gefäß auszulassen.
Dafür habe ich mir für ein beispielhaftes Gefäß eine lineare Funktion gesucht, die der des Volumenstroms über die Zeit ausreichend genau entspricht.
In diesem Fall ist das: f(t) = -0,463t + 21,5.
Nun möchte ich das mir der Arduino für ein beliebiges Volumen, welches ich über den seriellen Monitor eingebe, mithilfe der Mitternachtsformel, den zweiten Grenzwert des Integrals und damit delta t ausgibt. Delta t möchte ich dann verwenden um das Magnetventil anzusteuern und die gewünschte Menge Wasser abzulassen.
Da die Mitternachtsformel jeweils zwei Ergebnisse hat muss der Arduino das richige wählen (b1 oder b2) und davon dann den ersten Grenzwert (t) abziehen.
Das funktioniert soweit auch halbwegs, nur gibt es zwei Probleme:
Das erste ist das ich im seriellen Monitor b1 und b2 ausgegeben bekomme und delta t, wenn t null ist keinem der beiden Werte entspricht. Ich denke es könnte eventuell ein Rundungsfehler sein, verstehe allerdings nicht wie das bei (b1-0) oder (b2-0) passiert.
Die Ausgabe sieht z.b. so aus:
Bitte auszugebendes Volumen eingeben:
Vol (ml): 499.19
A = -0.46
B = 43.00
C = -998.38
discriminant = 0.0
b1 = 46.42
b2 = 46.45
delta t: 46.31 s
gesamt t: 0.00 s
Das berechnete Ergebnis an dieser Stelle wäre 46.44 s.
Das zweite Probleme ist die Auswahl der korrekten Lösung im Moment prüft er nur ob b > t,
also der errechnete zweite Grenzwert größer als der erste Grenzwert ist. Bei größeren Eingaben sind die Werte sehr nah bei einander und er nimmt einfach den ersten.
Leider ist das für mich alles noch Neuland und mein Sketch sicher nicht toll. Bisher habe ich den Sketch in Tinkercad mit einer LED am Pin 9 getestet. Wenn mir jemand weiterhelfen kann freue mich sehr.
float inVol = 0.0; // Globale Variable zum Speichern der Eingabe
const int valvePin = 9; // Pin, an dem das Ventil angeschlossen ist
//f(t) = (-0.463)*t+21.5 lineare Annäherung des Volumenstroms
float t = 0.0; // Erster Grenzwert bzw. aktueller x-Wert der Funktion
float m = (-0.463); // Steigung der linearen Funktion
float c = 21.5; // y-Achsenabschnitt der linearen Funktion
float maxT = 46.436; // Nullstelle der Funktion
void setup() {
pinMode(valvePin, OUTPUT);
Serial.begin(9600); // Startet die serielle Kommunikation
Serial.println("Bitte auszugebendes Volumen eingeben:");
}
void loop() {
// Überprüfen, ob neue serielle Daten verfügbar sind
if (Serial.available() > 0 && t < maxT) {
String inputString = Serial.readStringUntil('\n'); // Lesen der Eingabe bis zum Zeilenende-Zeichen
inVol = inputString.toFloat(); // Konvertieren der Eingabe in einen float
Serial.print("Vol (ml): ");
Serial.println(inVol, 2); // Ausgabe mit 2 Nachkommastellen
float additionalTime = calculateDeltaT(calculate_b(inVol, t, m, c));
Serial.print("delta t: ");
Serial.print(additionalTime);
Serial.println(" s");
Serial.print("gesamt t: ");
Serial.print(t);
Serial.println(" s");
activateValve(additionalTime);
t += additionalTime;
Serial.println("Bitte auszugebendes Volumen eingeben:");
}
}
void activateValve(float duration) {
digitalWrite(valvePin, HIGH); // Ventil öffnen
delay(duration*1000); // Ventil für die berechnete Dauer offen halten
digitalWrite(valvePin, LOW); // Ventil schließen
}
float calculateDeltaT(float b) {
b-t;
}
float calculate_b(float i, float t, float m, float c) {
// Koeffizienten der quadratischen Gleichung
float A = m;
Serial.print("A = ");
Serial.println(A);
float B = 2.0 * c;
Serial.print("B = ");
Serial.println(B);
float C = -(2.0 * i + m * sq(t) + 2.0 * c * t);
Serial.print("C = ");
Serial.println(C);
// Diskriminante der quadratischen Gleichung
float discriminant = sq(B) - 4.0 * A * C;
Serial.print("discriminant = ");
Serial.println(discriminant, 1);
//if (discriminant < 0) {
// Serial.println("Keine reale Lösung vorhanden.");
// return NAN;
//}
// Lösungen der quadratischen Gleichung
float sqrtDiscriminant = sqrt(discriminant);
float b1 = (-B + sqrtDiscriminant) / (2 * A);
float b2 = (-B - sqrtDiscriminant) / (2 * A);
Serial.print("b1 = ");
Serial.println(b1);
Serial.print("b2 = ");
Serial.println(b2);
// Wähle die gültige Lösung (b muss größer als t sein)
if (b1 > t) {
return b1;
}
else if (b2 > t) {
return b2;
}
else {
Serial.println("Keine gültige Lösung gefunden.");
return NAN;
}
}