Richtig!
Der Messwert muss dann in die Zeile "Aktuelle Füllhöhe" eingefügt werden. Kann man das mit dem Arduino realisieren?
Und kann man anschließend die Werte aus der Excel Tabelle im z.B. WebIf Anzeigen lassen?
Richtig!
Der Messwert muss dann in die Zeile "Aktuelle Füllhöhe" eingefügt werden. Kann man das mit dem Arduino realisieren?
Und kann man anschließend die Werte aus der Excel Tabelle im z.B. WebIf Anzeigen lassen?
newpv:
Der Messwert muss dann in die Zeile "Aktuelle Füllhöhe" eingefügt werden. Kann man das mit dem Arduino realisieren?
Vielleicht. Aber es ergibt keinen Sinn.
Eine Excel-Datei kannst Du ja nur auf dem PC (oder Tablet) ansehen. Also müsstest Du eine gemeinsame Ablage für die Datei haben oder sie hin- und hertragen.
Deshalb für den Datentransport CSV nutzen und dann (am PC) in das Excel importieren.
Und kann man anschließend die Werte aus der Excel Tabelle im z.B. WebIf Anzeigen lassen?
Nicht trivial. Du müsstest dann ja die berechneten Werte aus Excel wieder zum Arduino schicken falls der die Webseite erzeugt.
Du solltest Dir mal eine Skizze machen, aus der hervorgeht, welches Datum wo entsteht bzw. verarbeitet und schließlich angezeigt wird.
Ich stimme Walter zu. In so einem Fall sind kritzeln und Listen machen angesagt.
Gruß
Gregor
Hallo,
Du kannst doch sicher in Excell ein Macro machen um die relevanten Daten aus der Tabelle "Messwerte" in die Tabelle "Berechnen" zu kopieren. Auch in Excell gibts eine Möglickeit das mit "Basic" auf Knopfdrück zu automatisieren.
Mal eine ganz andere Frage warum machst Du die Berechnung nicht im Arduino, so wie ich das sehe hast Du doch gar keine Messreihen.
Und kann man anschließend die Werte aus der Excel Tabelle im z.B. WebIf Anzeigen lassen?
was ist WebIf ?
Heinz
@TO: Was hast du eigentlich vor? Ich glaube du hast die falsche Vorstellung der Lösung und ich bin davon überzeugt, das es viel bessere Lösungen für deine Aufgabenstellung gibt.
Was willst du also machen?
Eine Volumenberechnung von einer Zisterne?
Oder / auch ein Logging des Füllstands? Wenn ja über welche Zeit mit welchem Intervall?
Oder ganz was anderes?
Ich glaube nicht, das Excel zu der Lösung gehört. Das ist viel zu umständlich.
Erzähl mal was dein Ziel ist.
Lieben Gruß,
Chris
Mein Ziel ein Reale Füllstandsanzeige, da die Zisterne nicht Rund ist sondern die Form aus dem Bild hat...
Habe mir bereits die Berechnung in Excel erstellt, deshalb wollte ich es in Excel machen, da es aber so nicht funktioniert, werde ich die Berechnung nun mit Hilfe der Excel Tabelle im Arduino Programm schreiben...das geht ja auch, man benötigt halt nur die "math.h" dann geht es auch mit Pi usw.
Mal eine Frage wie muss "ARCCOS" lauten? Wäre es so richtig "acos()"?
Log brauche ich erstmal nicht! Möchte erstmal "nur" eine Berechnung des Füllstands und eine Temperaturanzeige über WebIf und LCD Display haben.
Fange alles erst per Serielleausgabe an...wenn die Werte ok sind geht es mit dem Display weiter, dann WebIf und am Ende kommen ggf. noch Bilder als Hintergrund vom WebIf je nach Füllstand. Aber alles nach und nach...
Und wenn das alles läuft kommt evtl. noch ein Durchfluss Zähler, aber das ist zuweit in der Zukunft
Ah ja - hurra!
Jetzt sehen wir doch schon viel klarer.
Dein Weg ist dann auch der richtige:
Excel-Formel in C++ Code auf dem Arduino umsetzen, mit Testwerten füttern und berechneten Füllstand seriell ausgeben. Display und Webseite kommen später.
Sieht wie ein Plan aus!
Was acos() angeht: Ja!
Darf ich frecherweise fragen, wo Du später die aktuelle Füllhöhe herbekommst? Im Plan fehlt noch das Kapitel "Sensorik".
Meine Empfehlung dazu:
ESP8266 und epaper Display.
Oder auch ESP32, den braucht es aber nicht wirklich, der 8266 reicht dafür auch 100x aus.
Die ESPs haben WLAN gleich mit an Board, damit kannste dann auch kabellos loggen wenn du willst.
Das epaper Display braucht nur kurz Strom, wenn sich die Anzeige ändern soll.
Dann kannste auch nur alle 5 oder 15min messen und bei Bedarf loggen.
Und in der Zwischenzeit kannst du das alles wieder in den Tiefschlaf versetzen. Das ganze funktioniert auch mit Solarzelle als Stromversorgung.
Du kannst auch ein OLED oder LCD oder TFT Display benutzen, aber die brauchen dauernd Strom.
Wenn du loggen und auswerten willst kann ich dir volkszaehler.org sehr empfehlen.
Lieben Gruß,
Chris
wno158:
Darf ich frecherweise fragen, wo Du später die aktuelle Füllhöhe herbekommst?
Natürlich, die Füllhöhe soll über einen Ultraschallsensor kommen!
@themanfrommoon
Danke für den Hinweis, aber in der Ecke habe ich eh LAN, wo der Arduino hin kommt. Habe einen Uno r3 Clone...
Ich habe ja bereits angefangen die Formel zur Berechnung zu schreiben. Jetzt hänge ich aktuell bei der Wurzel!
Wie kann ich diese Berechnen?
Zu faul zum googeln?
https://www.google.com/search?ie=UTF-8&client=ms-android-vf-de-revc&source=android-browser&q=arduino+wurzel
newpv:
...Jetzt hänge ich aktuell bei der Wurzel!
Wie kann ich diese Berechnen?
Sachma, was passiert beim Druck auf F1? Schon mal etwas von einer Online-Hilfe oder einem Handbuch gehört? Sowas kann man lesen, man kann darin nachschlagen ...
Gruß ![]()
Gregor
Hallo,
ich habe mal die Formeln von Excel in Arduino geschrieben, leider kommen da falsche Ergenisse heraus, woran liegt es?
// Tank Füllstandsanzeige v1.0
#include <math.h> //Mathe Bibliothek
#define PI 3.1415926535897932384626433832795
void setup()
{
Serial.begin(9600); // Serielle Schnittstelle intialisieren
}
void loop()
{
// Aktueller Füllstand
int Fuellstand = 1000; // Füllhöhe im mm
// Zylindervolumenberechnung
int Zylinderraduis = 875; // Zylinder Gesamt Raduis in mm
int Zylinderhoehe = 2380; // Zylinder Länge/Höhe Gesamtgröße in mm
int Zylinderverlust = 95; // Zylinder Überlaufverlust Höhe in mm
int Zylinderfuellhoehe = (Fuellstand / 2); // Aktuelle Füllhöhe (Radius) in mm
int VZ1 = ((PI * sq(Zylinderraduis) * Zylinderhoehe) / 1000000); // Zylindervolumengesamt ohne Überlauf im dm³
int VZ2 = (sq(Zylinderraduis) * Zylinderhoehe * (acos(1 - Zylinderverlust / Zylinderraduis)) * sqrt((Zylinderverlust / Zylinderraduis) * ((2 - Zylinderverlust) / Zylinderraduis))) / 1000000; // Zylindervolumen Überlaufverlust im dm³
int VZ3 = VZ1 - VZ2; // Maximal Nuztbares Volumen im dm³
int VZ4 = (sq(Zylinderraduis) * Zylinderhoehe * (acos(1 - Zylinderfuellhoehe / Zylinderraduis)) * sqrt((Zylinderfuellhoehe / Zylinderraduis) * ((2 - Zylinderfuellhoehe) / Zylinderraduis))) / 1000000; // Zylindervolumen des aktuellen Füllstand im dm³
// Kugelvolumenberechnung
int Kugelraduis = 835; // Kugel Radius vorhandene Fläche in mm
int Kugelhoehe = 380; // Kugel Gesamthöhe in mm
int Kugelverlust = 95; // Kugel Überlaufverlust Höhe in mm
int Kugelfuellhoehe = (Fuellstand / 2); // Aktuelle Füllhöhe (Radius) in mm
int RK1 = (sq(Kugelraduis) + sq(Kugelhoehe)) / (2 * Kugelhoehe); // Radius der Kugel
int VK1 = ((PI / 3) * sq(Kugelhoehe) * (3 * RK1 * Kugelhoehe)) / 1000000; // 1/2 Kugelvolumengesamt ohne Überlauf in dm³
int VK2 = VK1 * 2; // Kugelvolumengesamt ohne Überlauf in dm³
int VK3 = ((PI / 3) * sq(Kugelverlust) * ((RK1 * RK1 * RK1) - Kugelverlust)) / 1000000; // 1/2 Kugelvolumen Überlaufverlust im dm³
int VK4 = VK3 * 2; // Kugelvolumen Überlaufverlust gesamt im dm³
int VK5 = VK2 - VK4; // Kugel maximales Wasservolumen
int VK6 = (((PI / 3) * sq(Kugelfuellhoehe)) * ((RK1 * RK1 * RK1) - Kugelfuellhoehe))) / 10000000; // Aktueller Füllstand 1/2 Kugel im dm³
int VK7 = VK6 * 2; // Aktueller Füllstand Kugel
// Gesamtwerteberechnung
int Tankvolumengesamt = VZ1 + VK2; // Gesamtvolumen des Tanks im dm³
int Tankvolumennutzbar = VZ3 + VK5; // Nutzbares Tankvolumen im dm³
int Tankinhalt = VZ4 + VK7; // Aktueller Tankinhalt nach Füllstand im dm³
int Tankinhaltprozent = Tankinhalt / Tankvolumennutzbar; // Aktueller Tankinhalt nach Füllstand in %
// Die 4 Helligkeitswerte, Berechnung der Helligkeitswerte, Relais und die Endschalterzustände zu Testzwecken an den PC übertragen
static unsigned long lastprint;
if (millis() - lastprint > 3000) // Testausgabe alle 3s
{
lastprint = millis();
Serial.print ("Füllhöhe im mm:"); Serial.println(Fuellstand); // Füllhöhe im mm
Serial.print ("Gesamtvolumen des Tanks im dm³:"); Serial.println(Tankvolumengesamt); // Gesamtvolumen des Tanks im dm³
Serial.print ("Nutzbares Tankvolumen im dm³:"); Serial.println(Tankvolumennutzbar); // Nutzbares Tankvolumen im dm³
Serial.print ("Aktueller Tankinhalt nach Füllstand im dm³:"); Serial.println(Tankinhalt); // Aktueller Tankinhalt nach Füllstand im dm³
Serial.print ("Aktueller Tankinhalt nach Füllstand in %:"); Serial.println(Tankinhaltprozent); // Aktueller Tankinhalt nach Füllstand in %
Serial.print ("VZ1:"); Serial.println(VZ1);
Serial.print ("VZ2:"); Serial.println(VZ2);
Serial.print ("VZ3:"); Serial.println(VZ3);
Serial.print ("VZ4:"); Serial.println(VZ4);
Serial.print ("RK1:"); Serial.println(RK1);
Serial.print ("VK1:"); Serial.println(VK1);
Serial.print ("VK2:"); Serial.println(VK2);
Serial.print ("VK3:"); Serial.println(VK3);
Serial.print ("VK4:"); Serial.println(VK4);
Serial.print ("VK5:"); Serial.println(VK5);
Serial.print ("VK6:"); Serial.println(VK6);
Serial.print ("VK7:"); Serial.println(VK7);
}
}
Es liegt an der leider falschen Annahme, das alles in normalen "int" rechnen zu können.
Hier geht es los:
int VZ1 = ((PI * (Zylinderraduis * Zylinderraduis) * Zylinderhoehe) / 1000000); // Zylindervolumengesamt ohne Überlauf im dm³
Alleine Zylinderraduis * Zylinderraduis ist bei einem Startwert von 875 schon 765625 und damit etwas über dem maximal positivem int von 32767.
Und wie kann man das Lösen?
Die härteste Tour wäre, alle Deine Werte auf float umzustellen. Das ist auf den Arduinos etwas laufzeit-intensiv, aber Du hast ja keine Schleusenkammer, sodaß sich der Wert nicht sooo schnell ändert.
Ansonsten würde ich versuchen, die Formeln so umzustellen und zusammenzufassen, dass Du alle Werte, die sich nie ändern (weil sich die Geometrie des Tanks ja auch nicht ändert), außerhalb berechnest und dann nur noch ein wenig beim Einrechnen der aktuellen Füllhöhe zu tun hast.
PI sollte übrigens in der math.h schon als M_PI definiert sein.
Moin,
Nutze die Zahlen und Variablen gut aus.
Was heisst das?
Du musst nicht unbedingt SI konform rechnen, du kannst auch mit anderen Einheiten rechnen damit zu z.B. rechenintensive float Operationen vermeiden kannst.
Dazu schreibe bitte mal die Formel auf und die zu erwartenden min-max Werte aller Eingabeparameter.
Dann schaust du dir an welche Zahlen dabei rauskommen.
Und dann schaust du dir an welche Variablen es für deinen Controller gibt und wie große deren Wertebereich sind.
Du dann baust du es so, dass es passt.
Daruf kann aber auch jeder selber kommen.
PI sollte übrigens in der math.h schon als M_PI definiert sein.
Bei Arduino ist auch PI schon definiert.
Und wenn man schon die Funktion sq(Zylinderraduis) aufruft, sollte man natürlich mit dem double (oder float) Ergebnis weiterrechnen.
Selbst bei einer Schleusenkammer wäre eine float-Rechnung noch schnell genug ![]()
Und außerdem:
int VZ1 = ((PI * sq(Zylinderraduis) * Zylinderhoehe) / 1000000); // Zylindervolumen
Das ist eine Konstante, die nicht bei jedem loop-Durchlauf ausgerechnet werden muss, sondern die du aus deiner Excel Tabelle abschreiben könntest. Oder zumindest einmal in setup, weil der Compiler leider kein SQRT kann. (Nur als Beispiel)
Formeln:
VZ1 = PI*r²*h1 = 5724,57dm³
VZ2 = (r²*l*(ARCCOS(1-h2/r)-(1-h2/r)*WURZEL(h/r*(2-h2/r)))) = 120,90dm³
VZ3 = VZ1 - VZ2 = 5603,67
VZ4 = V=(r²*l*(ARCCOS(1-h3/r)-(1-h3/r)*WURZEL(h3/r*(2-h3/r)))) = min. 1,00dm³ - max. ca. 2736dm³
RK1 = (a²+ h²)/(2*h) = 1107,40dm³
VK1 = (PI/3)*h²*(3*r-h) = 444,92dm³
VK2 = VK1 * 2 = 889,84
VK3 = (PI/3)*h²*(3r-h) = 30,50dm³
VK4 = VK3 * 2 = 61,00dm³
VK5 = VK2 - VK4 = 828,84dm³
VK6 = PI/3*h²*(3r-h) = min. ca. 0,00dm³ - max. ca.1850,45dm³
VK7 = VK6 * 2 = min. 0,00dm³ - max. 3700,90dm³
@michael_x
Mit den Konstanten hast du recht. Die könnte man doch unter VOID SETUP setzen oder? Konstant sind:
VZ1, VZ2, VZ3, RK1, VK1, VK2, VK3, VK4, VK5
newpv:
@michael_x
Mit den Konstanten hast du recht. Die könnte man doch unter VOID SETUP setzen oder? Konstant sind:
VZ1, VZ2, VZ3, RK1, VK1, VK2, VK3, VK4, VK5
Bin zwar nicht Michael, aber: Ja.
Konstant sind:
VZ1, VZ2, VZ3, RK1, VK1, VK2, VK3, VK4, VK5
Wenn Du nun drauf bestehst, mit exakt diesen Variablen zu arbeiten, würde das schon weiterhelfen (allerdings auch diesmal in float statt int).
int Tankvolumengesamt = VZ1 + VK2; // Gesamtvolumen des Tanks im dm³
int Tankvolumennutzbar = VZ3 + VK5; // Nutzbares Tankvolumen im dm³
int Tankinhalt = VZ4 + VK7; // Aktueller Tankinhalt nach Füllstand im dm³
Von diesen sind die ersten beiden ebenfalls konstant. Tankvolumengesamt brauchst Du für die Funktion selbst nirgendwo - die Prozentangabe speist sich ja aus dem nutzbaren Volumen.