mit Hilfe des Codes aus fogendem Post Sonnen Tracker Arduino konnte ich meinen eigenen Windsensor Code basteln, wo bei Erreichen der Windschwelle ein Ausgang geschalten wird, den ich in mein Homekit exportiere und zur Wintergartensteuerung nutzen möchte.
Außerdem habe ich noch ein Potentiometer eingebaut, mit dem man die Windschwelle etwas nach oben oder nach unten korrigieren kann (so war es auch bei meiner 20 Jahre alten Wintergartensteuerung, was meist sehr hilfreich war).
// Begin Variablen Wind
bool windAusgeloest = false;
const byte AnemometerPin = 2; //Definierter Interrupt Pin
const byte WindPin = 7; // Ausgang der geschalten wird, wenn Wind ausgelöst ist
const byte PotentiometerPIN = A0; // Analoger Eingang des Potentiometers
volatile unsigned long windCounter;
float Windgeschwindigkeit;
float Faktor;
const unsigned long messZeit = 2000; //Messzeit in ms
const byte windSchwelle = 30; // km/h
const byte sturmSchwelle = 40; // km/h
const unsigned long umlaufZeit = 10000; // 10 Sekunden
byte umlaufMerker[umlaufZeit / messZeit]; // Anzahl der benötigten Elemente des Array errechnet sich aus den Zeiten
// End Variablen Wind
void setup ()
{
// Setup Wind
pinMode(AnemometerPin, INPUT_PULLUP);
pinMode(WindPin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(AnemometerPin), countup, RISING);
Windmessung(messZeit);
}
void loop ()
{
//Einlesen der Potiwerte
int data = analogRead(PotentiometerPIN);
int Potistellung = map(data, 0, 1023, 1, 16); // Mapping der Potistellung von 1 bis 15
Faktor = Potistellung * 0.1; // Potistellung mit 0,1 multipliziert für sinnvollen Faktor
Serial.print("Potentiometer bei Faktor ");
Serial.print(Faktor);
Serial.print("\t aktuelle Windschwelle: ");
Serial.print(windSchwelle*(Faktor));
Serial.println(F(" Km/h"));
delay(messZeit);
//Ausgabe der Windwerte
static unsigned long lastprint;
static unsigned long lastausloeser = 0;
const unsigned long sperrZeit = 10000; // Wind Sperrzeit 10 Sek.
if (millis() - lastprint >= messZeit)
{
lastprint = millis();
Serial.print(F("Windgeschwindigkeit: "));
Serial.print(Windgeschwindigkeit); // Ausgabe der Windgeschwindigkeit in Km/h
Serial.println(F(" Km/h"));
}
Windmessung(messZeit);
if (Auswertung(umlaufZeit))
{
Serial.println(F("Wind ausgelöst"));
// Hier merken, das ausgelöst wurde:
windAusgeloest = true;
lastausloeser = millis();
Serial.println(F("Auslöser gemerkt"));
}
if (windAusgeloest)
{
if (millis() - lastausloeser >= sperrZeit)
{
windAusgeloest = false;
Serial.println(F("Ausloeser geloescht"));
}
}
if (windAusgeloest == true) {
digitalWrite(WindPin, HIGH); //Ausgang geschalten, wenn Wind ausgelöst
} else {
digitalWrite(WindPin, LOW); //Ausgang aus, wenn Wind ausgelöst falsch
}
}
bool Auswertung(unsigned long intervall)
{
static unsigned long lastmillis = 0;
unsigned int wind = 0;
unsigned int sturm = 0;
bool ausloeser = false;
if (millis() - lastmillis >= intervall)
{
Serial.println(F("Werte durchzaehlen:"));
for (byte i = 0; i < sizeof(umlaufMerker); i++)
{
if (umlaufMerker[i] >= windSchwelle*(Faktor)) wind++;
if (umlaufMerker[i] >= sturmSchwelle) sturm++;
Serial.print(umlaufMerker[i]);
Serial.print(F("\t"));
}
Serial.println();
lastmillis = millis();
}
if ((wind >= 3) || (sturm >= 2))
{
ausloeser = true;
}
return ausloeser;
}
void Windmessung(unsigned long intervall) // Initalisierung und Berechnung für die Windgeschwindigkeit
{
static unsigned long lastMessung = 0;
static unsigned int elementeZaehler = 0;
if (millis() - lastMessung >= intervall)
{
detachInterrupt(digitalPinToInterrupt(AnemometerPin));
Serial.println(windCounter);
Windgeschwindigkeit = (float)(windCounter * 1.2) / (float)((millis() - lastMessung) / 1000);
windCounter = 0;
lastMessung = millis();
attachInterrupt(digitalPinToInterrupt(AnemometerPin), countup, RISING);
umlaufMerker[elementeZaehler] = (int)Windgeschwindigkeit;
elementeZaehler++;
if (elementeZaehler > (sizeof(umlaufMerker))) elementeZaehler = 0;
}
}
void countup() // Zähler für die Impulse des Reed Kontakt
{
windCounter++;
}
(Eventuell kann der Code noch ausgedünnt werden und unnötige Codezeilen entfernt werden.)
Da der Code soweit funktioniert, wollte ich den nächsten Schritt wagen und mir die aktuelle Windgeschwindigkeit und Windschwelle über einen Webserver ausgeben lassen.
Leider verzweifle ich schon daran, den obigen Code auf einem ESP8266 zum Laufen zu bekommen. Der serielle Monitor gibt mir nur ungewöhnliche Werte aus.
im Serial Monitor zählt er jetzt von 10 auf 1 runter und dann schlägt wieder der Watchdog zu.
Hast noch einen Tip welche seriellen Ausgaben zum überprüfen sinnvoll sind?
Gruß
Martin
Das Problem liegt vermutlich in der loop, also auch serielle Ausgaben einbauen.
Das müssen keine Zählschleifen sein, nur einfache Textausgaben, an denen du anschließend den Fehler festmachen kannst.
Dann ist die Ursache später. Weiter suchen.
Gib doch erst mal an markanten Punkten Deines Sketches eine Ausgabe aus (die alten wieder entfernen), damit Du einen groben Überblick bekommst, wo er überall durch läuft.
es scheint wirklich im Loop ein Problem zu sein, im Setup kann ich noch alles in die serielle Ausgabe schreiben, das wird auch angezeigt.
Ich habe im loop an die erste Stelle eine serielle Ausgabe gestellt, doch da startet der ESP schon neu. Ich werd morgen Abend nochmal drauf schauen und hoffen mit meinem Anfängerwissen etwas herauszufinden.
Gruß
Martin
Was mich verwundert ist die PinAngabe.
Wie sieht denn die Zuordnung zu den GPIO aus? @HotSystems kannst Du da evtl. mal drauf schaun?
Und was ist da noch so alles beschaltet und ggfls. nicht in Gebrauch?
Das war ne gute Idee.
Der GPIO7 (7) ist garnicht herausgeführt und kann durchaus das Problem am ESP8266 auslösen, da dieser intern genutzt wird.
Somit sollte @Hanimaniac dafür einen anderen GPIO wählen. Hier kann man nachlesen, welcher GPIO geeignet ist.
Gib uns Fehlerausgaben bitte auch als Text in Codetags, nicht als Bild.
Dein Code stimmt nicht mit der Fehlermeldung überein, da es in Deinem Code keine TEST1ISR gibt. Willst Du uns veralbern (vorsichtig ausgedrückt)?
Du solltest schon den Quelltext liefern, der die Fehlermeldung erzeugt hat, sonst ist Hilfe unmöglich.
Für den Anfängerfehler mit dem Screenshot möchte ich mich entschuldigen und nichts liegt mir ferner als die Sehenden hier veralbern zu wollen.
Hier der aktuelle Code.
// Begin Variablen Wind
bool windAusgeloest = false;
const byte AnemometerPin = 4; //Definierter Interrupt Pin
const byte WindPin = 5; // Ausgang der geschalten wird, wenn Wind ausgelöst ist
const byte PotentiometerPIN = A0; // Analoger Eingang des Potentiometers
volatile unsigned long windCounter;
float Windgeschwindigkeit;
float Faktor;
const unsigned long messZeit = 2000; //Messzeit in ms
const byte windSchwelle = 30; // km/h
const byte sturmSchwelle = 40; // km/h
const unsigned long umlaufZeit = 10000; // 10 Sekunden
byte umlaufMerker[umlaufZeit / messZeit]; // Anzahl der benötigten Elemente des Array errechnet sich aus den Zeiten
// End Variablen Wind
void setup ()
{
Serial.begin(115200);
for (int i=10; i>0; i--) {
Serial.print(i); Serial.print(' '); delay(500);
}
Serial.println();
Serial.print("TEST1");
// Setup Wind
pinMode(AnemometerPin, INPUT_PULLUP);
pinMode(WindPin, OUTPUT);
attachInterrupt(digitalPinToInterrupt(AnemometerPin), countup, RISING);
Windmessung(messZeit);
}
void loop ()
{
Serial.print("TEST2");
//Einlesen der Potiwerte
int data = analogRead(PotentiometerPIN);
int Potistellung = map(data, 0, 1023, 1, 16); // Mapping der Potistellung von 1 bis 15
Faktor = Potistellung * 0.1; // Potistellung mit 0,1 multipliziert für sinnvollen Faktor
Serial.print("Potentiometer bei Faktor ");
Serial.print(Faktor);
Serial.print("\t aktuelle Windschwelle: ");
Serial.print(windSchwelle*(Faktor));
Serial.println(F(" Km/h"));
delay(messZeit);
//Ausgabe der Windwerte
static unsigned long lastprint;
static unsigned long lastausloeser = 0;
const unsigned long sperrZeit = 10000; // Wind Sperrzeit 10 Sek.
if (millis() - lastprint >= messZeit)
{
lastprint = millis();
Serial.print(F("Windgeschwindigkeit: "));
Serial.print(Windgeschwindigkeit); // Ausgabe der Windgeschwindigkeit in Km/h
Serial.println(F(" Km/h"));
}
Windmessung(messZeit);
if (Auswertung(umlaufZeit))
{
Serial.println(F("Wind ausgelöst"));
// Hier merken, das ausgelöst wurde:
windAusgeloest = true;
lastausloeser = millis();
Serial.println(F("Auslöser gemerkt"));
}
if (windAusgeloest)
{
if (millis() - lastausloeser >= sperrZeit)
{
windAusgeloest = false;
Serial.println(F("Ausloeser geloescht"));
}
}
if (windAusgeloest == true) {
digitalWrite(WindPin, HIGH); //Ausgang geschalten, wenn Wind ausgelöst
} else {
digitalWrite(WindPin, LOW); //Ausgang aus, wenn Wind ausgelöst falsch
}
}
bool Auswertung(unsigned long intervall)
{
static unsigned long lastmillis = 0;
unsigned int wind = 0;
unsigned int sturm = 0;
bool ausloeser = false;
if (millis() - lastmillis >= intervall)
{
Serial.println(F("Werte durchzaehlen:"));
for (byte i = 0; i < sizeof(umlaufMerker); i++)
{
if (umlaufMerker[i] >= windSchwelle*(Faktor)) wind++;
if (umlaufMerker[i] >= sturmSchwelle) sturm++;
Serial.print(umlaufMerker[i]);
Serial.print(F("\t"));
}
Serial.println();
lastmillis = millis();
}
if ((wind >= 3) || (sturm >= 2))
{
ausloeser = true;
}
return ausloeser;
}
void Windmessung(unsigned long intervall) // Initalisierung und Berechnung für die Windgeschwindigkeit
{
Serial.print("TEST3");
static unsigned long lastMessung = 0;
static unsigned int elementeZaehler = 0;
if (millis() - lastMessung >= intervall)
{
detachInterrupt(digitalPinToInterrupt(AnemometerPin));
Serial.println(windCounter);
Windgeschwindigkeit = (float)(windCounter * 1.2) / (float)((millis() - lastMessung) / 1000);
windCounter = 0;
lastMessung = millis();
attachInterrupt(digitalPinToInterrupt(AnemometerPin), countup, RISING);
umlaufMerker[elementeZaehler] = (int)Windgeschwindigkeit;
elementeZaehler++;
if (elementeZaehler > (sizeof(umlaufMerker))) elementeZaehler = 0;
}
}
void countup() // Zähler für die Impulse des Reed Kontakt
{
Serial.print("TEST4");
windCounter++;
}
Da ich heut eher weniger Zeit habe war das mit dem Screenshot eine schnelle aber unüberlegte Antwort.
Ich danke für die Hilfe und werde mich nochmal an den Code setzen.
Das hatte ich damals in dem Projekt, aus dem der Code ist, versucht. Das wird nix.
Der Umlauf müsste in 6,6 ms durch sein, was noch machbar wäre.
Der Aenometer hat zwei Auslöser (HIGH/LOW-Flanken) pro Umdrehung. Du musst zwingend beide erkennen.
Ok, soweit steck ich da nicht drin und ziehe meinen Tipp zurück.
Meine Idee wäre, das Projekt mit einem Arduino nachbauen. Wenn das läuft, auf anderen Controller umsetzen.
Ich komm auch mit dem Bildschirmbild von oben nicht klar.
Kannst Du mal die Ausgabe aus dem SerMon hier einfügen? - Die, die Du bekommst, wenn der Code auf dem Controller ist.
@HotSystems
Der Code zu Beginn meines Threads funktioniert problemlos auf einem Arduino Pro Mini.
Beflügelt durch meinen Erfolg, dachte ich, den Serial Monitor über ein WebServer abrufen zu können wäre ja auch ganz nett und wollte dann erstmal den Code auf dem ESP zum Laufen bringen, was mich zum Eröffnen dieses Post brachte.
Na ja Gut zu wissen Dann könnte man doch ein Teiler davor basteln zB auf TTL Basis, dem whre das danach auch egal ob die Signale Symmetrisch oder nicht sind, bei einer Umdrehung nur einmal H / L am Ausgang. Habe vor entweder einen Anemometer kaufen oder basteln