Hallo Zusammen,
so, Hardware ist jetzt alles da. Welche ich einsetze weiß ich noch nicht. Ich hab auf jeden Fall mal die Transistoren mit Basiswiderständen und Freilaufdioden aufs Breadboard gesteckt.
Jetzt kam mir nur gerade die Idee das Sketch erstmal mit zwei LEDs zu testen.
Und siehe da: Ich bring es nicht hin.
Verwendete Hardware ist übrigens: Nano CH340, OLED 128x64 I2C mit SH1106 Treiber...
Aber wie gesagt jetzt soll's erstmal um die Software gehen.
Der Code ist überwiegend von Reichelt.de aus dem Füllstand sketch.
Hier habe ich nur von SSD1306 auf das SH1106 Display umgestellt.
Dann habe ich weiter versucht abhängig vom levelpercent (Füllstand in Prozent) die LEDs auf PIN 7 und 8 für eine bestimmte Zeit zu steuern. (Der Kugelhahn braucht ca. 5 Sekunden für einen Schaltvorgang von offen zu geschlossen und ist danach stromlos. deswegen will ich die PINs nach 6 Sekunden ausschalten.)
Ich habs mit If schleifen Probiert und mit switch-case...
ich bring es einfach nicht hin.
Das Problem scheint mir, dass ich einen Logikfehler habe so wie ich die millis() Funktion einsetze.
Wie kann ich mit millis() einen Vorgang einmalig ausführen lassen in Abhängigkeit von zwei Variablen (Füllstand% und Zustand Kugelhahn)?
Ich schaffe es die LEDs dauerhaft 6 Sekunden blinken zu lassen oder beim ersten Durchlauf des Loop einmalig 6s an und dann nie mehr....
hier der code:
#include <SPI.h>
#include <Wire.h> //fuer I2C Kommunikation
#include <Adafruit_GFX.h> //fuer OLED
#include <Adafruit_SH1106.h> //fuer OLED
#include <NewPing.h> //fuer Ultraschall-Sensor
#define LEVELFULL 100 //Hoehe Wassersaeule wenn voll (=100%) in cm
#define LEVELEMPTY 100 //Abstand Boden zu Sensor in cm
#define VOLUME 2000 //Volumen des zu messenden Mediums bei 100% in l
#define OLED_RESET -1 //Reset pin beim SH1106 nicht vorhanden
#define trigPin 2 //Trigger Pin
#define echoPin 3 //Echo Pin
#define MAX_DISTANCE 320 //Begrenzung fuer Ultraschallsensor
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
Adafruit_SH1106 display(OLED_RESET);
float duration;
int lefty, distance, levelact, levelpercent, volumeact;
long unsigned int currentMillis; //Startwert Zähler
long unsigned int previousMillis = 0; //
const long interval = 6000; //6 Sekunden Dauer für Vorgang Oeffnen oder Schliessen d. Kugelhahns
bool statusOpen; //aktueller Status Kugelhahn offen
bool statusClosed; //aktueller Status Kugelhahn geschlossen
bool offen; //Reserve für Erweiterung d. Funktion
bool geschlossen; //Reserve für Erweiterung d. Funktion
bool levelFull; //Grenzwert zum Auslösen des Schaltvorgangs
int Zustand; //var fuer switch-case
NewPing sonar(trigPin, echoPin, MAX_DISTANCE); // NewPing Setup
void setup() {
Serial.begin(9600); // nur fuer Debugzwecke
pinMode(8, OUTPUT); // fuer rotes Kabel Kugelhahn (schliessen)
pinMode(7, OUTPUT); // fuer blaues Kabel Kugelhahn (oeffnen)
// statusOpen=true;
// statusClosed=false;
display.begin(SH1106_SWITCHCAPVCC, 0x3C);
}
void loop() {
delay(50); // Wartezeit zwischen Pings (ca. 20 pings/sec). nicht kleiner als 29ms!
//Messung mit Mittelung
int iterations = 5;
duration = sonar.ping_median(iterations); //duration = sonar.ping() ohne Mittelung
distance = int((duration / 2) * 0.0343); //Abstand in cm
//Fuellstand berechnen
levelact = (LEVELEMPTY - distance);
//Fuellstand in Prozent berechnen
levelpercent = (levelact * 100 / LEVELFULL);
//Berechnung Volumen
volumeact = ((VOLUME / 100) * levelpercent);
//Steuerung Kugelhahn
if (levelpercent >= 95){ //um nur wahr oder falsch als Bedingung zu haben
levelFull = true;
}
else
levelFull = false;
if (levelFull == true && statusOpen == true){ //zur Definitionen der Cases
Zustand = 1;
}
if (levelFull == false && statusClosed == false){
Zustand = 2;
}
switch (Zustand){
case 1:
digitalWrite(8, HIGH); //öffnet den Hahn bzw LED rot geht an
currentMillis = millis(); //Startzeitpunkt
if (millis() - currentMillis >= interval){ //aktuelle Zeit - Startzeitpunkt sollte doch das sein was ich brauche um es mit dem Interval (6000ms) zu vergleichen
digitalWrite(8, LOW); //macht den Hahn wieder zu (LED rot aus)
statusOpen = false; //Marker ob Hahn offen oder geschlossen
statusClosed = true;
}
break;
case 2: //alles "seitenverkehrt"
digitalWrite(7, HIGH);
currentMillis = millis();
if (millis() - currentMillis >= interval){
digitalWrite(7, LOW);
statusOpen = true;
statusClosed = false;
}
break;
}
display.clearDisplay(); // Clear display buffer
//Ueberschrift
display.setTextSize(2); // Schriftgroesse
display.setTextColor(WHITE); // Textfarbe
display.setCursor(0, 0); // obere linke Ecke
display.print("Levelmeter");
//Fuellstand in Prozent
display.setTextSize(2); // Schriftgroesse
display.setTextColor(WHITE); // Textfarbe
display.setCursor(50, 24); // obere linke Ecke
display.print(levelpercent);
display.print(" %");
//Fuellstand in Litern
display.setTextSize(2);
display.setCursor(50, 48);
display.print(volumeact);
display.print(" l");
//Balkenanzeige
levelpercent = constrain(levelpercent, 0, 100); //um nur Werte zwischen 0 und 100 zu erhalten
lefty = map(levelpercent, 0, 100, 63, 16); //Hoehe des Balkens ermitteln
//aeusserer Rahmen zeichnen
display.drawRect(0, 16, 38, 48, WHITE);
//Balken zeichnen
display.fillRect(0, lefty, 38, 48, WHITE);
//Display anzeigen
display.display();
}
Habt Ihr einen Hinweis an welcher Stelle ich hänge?
Das würde mich sehr freuen.
Und wie kann ich das Problem mit den 49,.. Tagen umgehen? der Nano soll das ganze Jahr laufen und den Hahn steuern. (Winterschaltung ist noch in Planung...)
Und wie schließe ich bei Wellen (oder anderen schnellen Leveländerungen von 95% +/-) aus, dass beide Pins gleichzeitig HIGH werden?
Schonmal vorab danke für Eure Kommentare.
Ich hoffe ich habe diesmal keine relevanten Infos vergessen. (Schaltplan hab ich noch nicht)
Besten Gruß
Frank