Windrichtungserkennung mit Hall Sensor

OP #7314519
Lesenswert?

Hallo,

ich möchte für mein Windrad einen dezentralen Windrichtungsmesser bauen. Dieser soll schnell schwankende Richtungsänderungen per Software ausmitteln damit sich das Windrad nicht wie bei klassischer Fahne zur Drehung ständig hin und her bewegt. Dazu würde ich einen Zahnkranz und einen Getriebemotor an dieses anbringen. Der Windrichtungs-Sensor soll 36 Hall-Sensoren und eine drehbare Scheibe mit einem Magneten bekommen um die 'Richtung zu erkennen. Nun meine Frage: können Hall-Sensoren auch einen "stehenden" Magneten erkennen oder nur bewgte Magneten? Wenn so ein Hall Sensor (z.B. SI7211-B-00-IVR) ein stehendes Magnetfeld erkennt, würde ich eine PCB mit 36 Sensoren erstellen die mittels analog-Multiplexern dann von einem Controller ausgelesen werden und somit die grobe Windrichtung liefern. An optische erkennung mittel reflex-Lichtschranken habe ich auch schon gedacht, jedoch gefällt mir es nicht, wenn sich Insekten oder Spinnen da breit machen würden... Oder hat jemand noch eine bessere Idee?

Gast #7314550
Lesenswert?

Wolfram F. schrieb:

Der Windrichtungs-Sensor soll 36 Hall-Sensoren und eine drehbare Scheibe mit einem Magneten bekommen um die 'Richtung zu erkennen.

Warum nicht einen einzigen Sensor? TLE493, AS5147 oder wie sie alle heißen https://www.digikey.de/de/products/filter/positionssensoren-winkel-und-lineare-positionsmessung/549?s=N4IgjCBcpgDA7ANiqAxlAZgQwDYGcBTAGhAHsoBtERATgBZZFkSBmG%2BAVhZZFcQ7AcATLxAswbFiJIdYjFszESaieCAC6JAA4AXKCADKOgE4BLAHYBzEAF8SYABxhk0EOkjZ8xMpTEOHiA6iLP78ovBwdHRqrKHImiC6%2BkZmVrY2NkA

OP #7314557
Lesenswert?

Wolfgang schrieb:

Wolfram F. schrieb:

Der Windrichtungs-Sensor soll 36 Hall-Sensoren und eine drehbare Scheibe mit einem Magneten bekommen um die 'Richtung zu erkennen.

Warum nicht einen einzigen Sensor? TLE493, AS5147 oder wie sie alle heißen https://www.digikey.de/de/products/filter/positionssensoren-winkel-und-lineare-positionsmessung/549?s=N4IgjCBcpgDA7ANiqAxlAZgQwDYGcBTAGhAHsoBtERATgBZZFkSBmG%2BAVhZZFcQ7AcATLxAswbFiJIdYjFszESaieCAC6JAA4AXKCADKOgE4BLAHYBzEAF8SYABxhk0EOkjZ8xMpTEOHiA6iLP78ovBwdHRqrKHImiC6%2BkZmVrY2NkA

Der sieht ja super aus! Wenn ich das richtig verstehe, kann dieser die Richtung des Magneten wiedergeben?

Gast #7314694
Lesenswert?

Wolfram F. schrieb:

Ich habe einige ADXL203 noch rumliegen, das sind eigentlich ja Beschleunigungsmesser, ob die sich evt. auch dafür eignen würden?

Nicht nur eigentlich - das SIND 2-Achsen Beschleunigungssensoren.

Die Achse bei einer Windfahne steht allerdings eher lotrecht und mit der Windrichtung ändert sich dann an der Richtung des Schwerefeldes nichts - das steht immer parallel zu der Achse der Windfahne.

#7314701
Lesenswert?

Wolfram F. schrieb:

...schnell schwankende Richtungsänderungen per Software ausmitteln damit sich das Windrad nicht wie bei klassischer Fahne zur Drehung ständig hin und her bewegt. Dazu würde ich einen Zahnkranz und einen Getriebemotor an dieses anbringen.

Die Sollbruchstelle nicht vergessen, z.B. mit einem Zahnkranz aus dem 3D-Drucker oder so. Das könnte eine größere Reparatur sparen, wenn der Rechner beim nächsten Gewitter abstürzt.

Plattenspieler hatten am Plattenteller eine Wanne mit Silikonöl in die ein fest stehendes Paddel eintaucht. Die haben damit die Drehzahl-Feineinstellung gemacht. Hier könnte man etwas ähnliches zwecks Dämpfung verwenden.

#7314766
Lesenswert?

Zwei lineare Hallsensoren und ein Magnet genügen.

Das hab ich schon einmal gebastelt. Für meine Zwecke reichte eine Auflösung für 12 Richtungen (30°; durch Mittelwertbildung entsprechend genauer) Grundprinzip: Je ein Sensor für die "N-S"- und für die "O-W"-Komponente des Magnetfeldes. -Auswertung durch Tabelle oder Winkelfunktionen.

Für Auflösungen/Genauigkeiten im Bereich von wenigen Winkelgraden ist es viel einfacher einen fertigen Sensorchip anzuwenden.

#7314785
Lesenswert?

Wolfram F. schrieb:

ich möchte für mein Windrad einen dezentralen Windrichtungsmesser bauen. Dieser soll schnell schwankende Richtungsänderungen per Software ausmitteln damit sich das Windrad nicht wie bei klassischer Fahne zur Drehung ständig hin und her bewegt. Dazu würde ich einen Zahnkranz und einen Getriebemotor an dieses anbringen. Der Windrichtungs-Sensor soll 36 Hall-Sensoren und eine drehbare Scheibe mit einem Magneten bekommen um die 'Richtung zu erkennen. Nun meine Frage: können Hall-Sensoren auch einen "stehenden" Magneten erkennen oder nur bewgte Magneten?

Warum nimmst Du keinen Kompasssensor wie z.B. GY-271 (Kompassmodul)? Spart den ganzen mechanischen Aufwand mit Magneten etc. Kann man prima mit ESP, Arduino oder Raspi verwenden.

Steve

Gast #7314798
Lesenswert?

Hans schrieb:

Grundprinzip: Je ein Sensor für die "N-S"- und für die "O-W"-Komponente des Magnetfeldes. -Auswertung durch Tabelle oder Winkelfunktionen.

Wenn man einen der von Wolfgang genannten verwendet, braucht man nur ein IC. Solange die absolute Ausrichtung nicht interessiert (absolte Windrichtung wird nicht ausgewertet), braucht man auch keine Nord-Süd-Ausrichtung bestimmen.

Gast #7314802
Lesenswert?

Hans schrieb:

Zwei lineare Hallsensoren und ein Magnet genügen.

Das hab ich schon einmal gebastelt. Für meine Zwecke reichte eine Auflösung für 12 Richtungen (30°; durch Mittelwertbildung entsprechend genauer) Grundprinzip: Je ein Sensor für die "N-S"- und für die "O-W"-Komponente des Magnetfeldes. -Auswertung durch Tabelle oder Winkelfunktionen.

Für Auflösungen/Genauigkeiten im Bereich von wenigen Winkelgraden ist es viel einfacher einen fertigen Sensorchip anzuwenden.

Hast Du noch ein Photo vom Aufbau? Dann bitte posten.

Gast #7314911
Lesenswert?

Wolfram F. schrieb:

Steve L. schrieb:

Warum nimmst Du keinen Kompasssensor wie z.B. GY-271 (Kompassmodul)? Spart den ganzen mechanischen Aufwand mit Magneten etc. Kann man prima mit ESP, Arduino oder Raspi verwenden.

Steve

Das ist wohl die beste Lösung! Den werd ich mir mal bestellen! Danke für die Info!!

Genau - die mechanische Konstroktion wird damit maximal "einfach": Den Kompasssensor packst Du direkt auf die Windfahne. Dann brauchst du nur noch einen leichtgängigen Schleifring, um Betriebsspannung und Ausgangssignal(e) vom/zum Montagemast zu übertragen.

Bitte auch unbedingt Fotos posten!

OP #7314936
Lesenswert?

Ludwig schrieb:

Dann brauchst du nur noch einen leichtgängigen Schleifring, um Betriebsspannung und Ausgangssignal(e) vom/zum Montagemast zu übertragen.

ich würde eher eine Solarzelle montieren und 1-2 18650 Lipos mit draufsetzen, Datenübertragung dann per LoRa. Zusätzlich noch ein Mini Rotor an einem Festplattenmotor als Generator, wäre ja passend!

#7314949
Lesenswert?

Wolfram F. schrieb:

können Hall-Sensoren auch einen "stehenden" Magneten erkennen

Ja.

Wolfram F. schrieb:

Oder hat jemand noch eine bessere Idee?

Mir scheint dein Aufwand übertrieben.

Wenn eine dauerhafte Auswertung sichergestellt werden kann, tun es 2 Hallsensoren und ein Zahnkranz, wenn man analog kann reicht Sinus/Cosinusencoder, oder eben die speziellen Drehsensoren wie AS5132.

Bauform B. schrieb:

Plattenspieler hatten am Plattenteller eine Wanne mit Silikonöl in die ein fest stehendes Paddel eintaucht. Die haben damit die Drehzahl-Feineinstellung gemacht

Welche ?

Steve L. schrieb:

Warum nimmst Du keinen Kompasssensor wie z.B. GY-271 (

Na ja, in der Nähe von Metallmasten hat man schon mal 30 Grad Fehlweisung.

Gast #7314966
Lesenswert?

Warum immer so kompliziert mit Elektrik und so... Die eigentliche Anforderung lautet:

Wolfram F. schrieb:

Dieser soll schnell schwankende Richtungsänderungen [...] damit sich das Windrad nicht wie bei klassischer Fahne zur Drehung ständig hin und her bewegt.

Das geht ohne Probleme rein mechanisch.

1.) Das Windrad drehbar lagern

2.) Eine Fahne an einem ausreichend langen Arm zur Ausrichtung gegen den Wind

3.) Ein Rotationsdämpfer mit der Drehachse koppeln damit es nicht so herumzappelt.

So etwas gibt es in den verschiedensten Ausführungen für überschaubares Geld zu kaufen, z.B.

https://de.rs-online.com/web/c/konstruktionsmaterialien-und-industrielle-systemteile/vibrationsdampfungs-und-ausgleichkomponenten/drehbare-dampfer/

Kein Hall-Sensor, kein Getriebemotor, keine Steuerung --> keine Probleme.

Gast #7315023
Lesenswert?

Helmut -. schrieb:

Wenn du es mit den Gyro-, Kompass- oder Hallsensoren aufgebaut hast, wirst du merken, dass das nicht die beste Idee war.

Und was für ein Problem hast du damit?

Hast du vielleicht eine ungünstige Form der Windfahne gewählt und bist auf die Dämpfung durch das Leitplastik-Poti angewiesen?

OP #7315092
Lesenswert?

Das geht ohne Probleme rein mechanisch.

1.) Das Windrad drehbar lagern ist es sowieso 2.) Eine Fahne an einem ausreichend langen Arm zur Ausrichtung gegen den Wind was wäre ausreichend? 3.) Ein Rotationsdämpfer mit der Drehachse koppeln damit es nicht so herumzappelt. Und warum wird sowas bei den großen Windrädern nicht gemacht?

Meins hat einen Flügeldurchmesser von 3.60m und wird in 15m Höhe stehen, da möchte ich nicht das es ständig bei jeder Böhe hin und her wandert.

Gast #7315161
Lesenswert?

Wolfram F. schrieb:

Ludwig schrieb:

Dann brauchst du nur noch einen leichtgängigen Schleifring, um Betriebsspannung und Ausgangssignal(e) vom/zum Montagemast zu übertragen.

ich würde eher eine Solarzelle montieren und 1-2 18650 Lipos mit draufsetzen, Datenübertragung dann per LoRa. Zusätzlich noch ein Mini Rotor an einem Festplattenmotor als Generator, wäre ja passend!

Genau - das macht die Konstruktion noch "vieeeeeeel einfacher"...

Gast #7315169
Lesenswert?

Wolfram F. schrieb:

Steve L. schrieb:

Na ja, in der Nähe von Metallmasten hat man schon mal 30 Grad Fehlweisung.

wird auf Holz montiert, ca. 10m vom eigentlichen Mast entfernt

So ein Mickymaus-Ausleger mit gerade mal 10m - natürlich auch aus Holz - ist ja wirklich ein Klacks. 2-3 amtliche Spax-Schrauben, das hält dann schon. Ich hatte das ja immer schon gesagt: Baustatik wird total überbewertet!

OP #7315182
Lesenswert?

Ludwig schrieb:

Wolfram F. schrieb:

Steve L. schrieb:

Na ja, in der Nähe von Metallmasten hat man schon mal 30 Grad Fehlweisung.

wird auf Holz montiert, ca. 10m vom eigentlichen Mast entfernt

So ein Mickymaus-Ausleger mit gerade mal 10m - natürlich auch aus Holz - ist ja wirklich ein Klacks. 2-3 amtliche Spax-Schrauben, das hält dann schon. Ich hatte das ja immer schon gesagt: Baustatik wird total überbewertet!

Quatsch, da hast du wohl sehr viel falsch verstanden! Der Windrichtungsmesser wird in ca. 10m Entfernung vom eigentlichen Windrad-Mast auf einem Holzschuppen montiert, also keine metallischen Gegenstände in der Nähe die den Kompass-Sensor beeinflussen würden.

Gast #7315186
Lesenswert?

Ok - bei der Größe ist eine frei (wenn auch gedämpft) drehende Variante wahrscheinlich nicht so gut. Muss es denn sein dass du den Windrichtungssensor selber bauen willst? Die gibt es mit einem Analogausgang 0-10V bzw. 4-20mA fertig zu kaufen. Das Signal dann mit einem kleinen Controller erfassen / mitteln und damit den Rotor passend drehen.

Und für die Erfassung der Rotorposition würde ich eine Reflexlichtschranken und eine passende Scheibe mit Gray-Codierung wählen, dann sind auch die Übergänge kein großes Problem mehr.

Zu meiner Jugend gab es mal eine Wetterstation in der ELO - die hatte die Windrichtung mit einer solchen Scheibe erfasst (und mit LED dargestellt). Leider habe ich keine Ahnung aus welchem Heft die war...

Gast #7315197
Lesenswert?

Wolfram F. schrieb:

Quatsch, da hast du wohl sehr viel falsch verstanden! Der Windrichtungsmesser wird in ca. 10m Entfernung vom eigentlichen Windrad-Mast auf einem Holzschuppen montiert, also keine metallischen Gegenstände in der Nähe die den Kompass-Sensor beeinflussen würden.

Dann kann man die Dämpfung auch per Software erledigen. Das hätte den Vorteil, dann bei die schwachem Wind das Windrad schneller in den Wind dedreht werden kann.

Icke schrieb:

Und für die Erfassung der Rotorposition würde ich eine Reflexlichtschranken und eine passende Scheibe mit Gray-Codierung wählen, dann sind auch die Übergänge kein großes Problem mehr.

oder per Magnetfeldsensor (weniger Schmutzprobleme).

Moderator (Firma: Titel) Persönliche Seite #7315206
Lesenswert?

Wolfram F. schrieb:

Hast du da mal eine Typenbezeichnung?

Ein Piher A15-3P kann das.

Und ein APLS RDC80 auch: https://tech.alpsalpine.com/e/products/detail/RDC803101A/

Und geht das Poti tatsächlich um 360grad ohne Lücke?

Ja. Im Piher ist eine durchgehende Potibahn mit 3 Abgriffen im 120° Winkel drin. Mit geschickter Ansteuerung kann man die absolute Lage ermitteln.

Im ALPS wird die Lücke mit 2 um 180° gedrehten Schleifer überbrückt.

#7315221
Lesenswert?

Joachim schrieb:

Hast Du noch ein Photo vom Aufbau? Dann bitte posten.

Kein Foto gefunden aber s. Beilage. Zwei der Hallsensoren sind senkrecht stehend positioniert. (bei 12 Uhr und bei 3 Uhr) An der Achse der Windfahne ein kleiner Stabmagagnet. Auswertung durch 2 x ADC im PIC Es wurden nur 12 Richtungen ausgewertet und per rs232 (aber 0V / 3V) ausgegeben.

Angehängte Dateien:
Gast #7315251
Lesenswert?

Wolfram F. schrieb:

Quatsch, da hast du wohl sehr viel falsch verstanden! Der Windrichtungsmesser wird in ca. 10m Entfernung vom eigentlichen Windrad-Mast auf einem Holzschuppen montiert, also keine metallischen Gegenstände in der Nähe die den Kompass-Sensor beeinflussen würden.

Ich „wollte“ dich falsch verstehen - um drauf aufmerksam zu machen, in welch übertrieben aufwendige Richtung du steuerst. Ganz entgegen dem Credo KISS.

Die Windrichtung misst man vorteilhafterweise auf und relativ zur „Generatorgondel“ und führt die Gondel so nach, dass der Wind immer von vorne kommt.

Dazu eignet sich ein z.B. kleines Hilfs-Windrad, entweder quer zur Windrichtung und anströmbar von beiden Seiten oder ein Rad vom Typ „Drehkreuz“ mit Teilabdeckung von vorne. Bei Beiden wertet man (vorrangig) die Laufrichtung aus. Das geht im Prinzip mit 2 Reedkontakten, oder auch optisch, oder oder oder...

Oder man vermeidet die Mechanik und denkt sich was aus mit 2 (selbst)-beheizten Temperatursensoren, links und rechts einer in Windrichtung stehender Trennwand.

Aber macht mal selbst ...

#7315393
Lesenswert?

Wolfram F. schrieb:

Hast du da mal eine Typenbezeichnung? Und geht das Poti tatsächlich um 360grad ohne Lücke?

Eine kleine Lücke ist immer gegeben. Das ist bei mir verbaut: https://www.mouser.de/datasheet/2/427/model357-1764384.pdf

Aber meine Vorredner haben ja auch Vorschläge gemacht. Verwende die Dinger schon seit 20 Jahren in meiner Wetterstation.

Die Lücke hat auch den Vorteil, dass deine Steuerung nicht immer hin- und zurück fährt, wenn der Wind genau aus der Richtung kommt, wo der Endanschlag des Motors ist.

#7315489
Lesenswert?

für die Wetterstationen von La Crosse gibt es die Windmesser TX20 mit Windfahne. Die Stellung der Windfahne wird über 4 LEDs und eine spezielle Lochscheibe ermittelt. Das Prinzip kann man hier erkennen: https://www.john.geek.nz/2011/07/disassembling-a-la-crosse-tx20-wind-anemometer/ Die Winkelauflösung beträgt 22,5 Grad (360/16). Ist nicht direkt eine Profilösung funktioniert aber, da bis auf die Lagerung verschleißfrei, bei mir seit vielen Jahren. Den Windmesser TX20 kann man evtl. als Ersatzteil noch irgendwo kaufen.

Gast #7315749
Lesenswert?

Kutte R. schrieb:

Die Stellung der Windfahne wird über 4 LEDs und eine spezielle Lochscheibe ermittelt.

Der Code, der mit der Lochscheibe erzeugt wird, ist ein ganz gewöhnlicher 4-Bit Gray-Code. Dies ergibt die schon genannte Auflösung von 1/16 Vollkreis oder eben die 22.5° (2 naut. Strich).
Wenn man diese Werte bei ausreichenden Fluktuationen der Windrichtung zeitlich mittelt, bekommt man damit auch auf eine deutlich höhere Auflösung (Erhöhung der Auflösung durch Überabtastung), was für das Windrad erstrebenswert ist.

Wolfram F. schrieb:

Der Windrichtungsmesser wird in ca. 10m Entfernung vom eigentlichen Windrad-Mast auf einem Holzschuppen montiert

Bist du sicher, dass der Holzschuppen den Wind nicht lokal ablenkt und zu Verwirbelugen führt?

STK500-Besitzer schrieb:

Das hätte den Vorteil, dann bei die schwachem Wind das Windrad schneller in den Wind dedreht werden kann.

Und dann? Bei schwachem Wind liefert das sowieso keine rechte Leistung - bringt also nicht viel.

Gast #7315755
Lesenswert?

Wolfgang schrieb:

Bei schwachem Wind liefert das sowieso keine rechte Leistung - bringt also nicht viel.

Würde den Wirkungsgrad erhöhen. Ist aber auch nur eine theoretischer Vorschlag. Es ging mir und die Dämpfung, da die Ausrichtung des Windrads ja elektrisch erfolgen soll.

Gast #7315768
Lesenswert?

Wolfgang schrieb:

... wohl eher verringern, wenn man den Aufwand für die aktive Ausrichtung in der Rechnung berücksichtigt ;-)

Um die Ausrichtung geht es hier doch ("Kundenanforderung"). Der beste Wirkungsgrad wäre eh, wenn das Ding passiv in den Wind gedreht wird. Dann wäre eine mechanische Dämpfung aber auch ratsam.

Beitrag #7315773 wurde von einem Moderator gelöscht.
OP #7324962
Lesenswert?

Moin Leute,

habe inzwischen das Mini-Windrad zum messen der Windrichtung und der Windgeschwindigkeit sogut wie fertig. Zur Verwendung sind ein Festplattenmotor zum messen der Geschwindigkeit (noch nicht im Code drin) und zum zusätzlichen laden der LiPo Zelle zum Einsatz gekommen. An diesem Festplattenmotor ist auch der mit 48cm Durchmesser kleine Rotor aus 50er Kanalrohren montiert. Die Berechnung der Flügel erfolgte mittels dem RoWi-Tool, (siehe https://www.kleinwindanlagen.de/Forum/cf3/topic.php?t=3502 ) sehr zu empfehlen um Flügel aus Kanalrohren herzustellen! Das Ganze ist auf einer CNC-gefrästen 6mm Aluplatte montiert welche wiederum auf einem Festplattenmotor drehbar montiert ist. Dieser dient aber nur als mechanische Lagerung. (Ja, habe kürzlich etliche alte Festplatten geschlachtet :-) ) Die Flügel sind auch bereits feingewuchtet. Halten bis zu 3000U/min problem- und vibrationslos aus. Getestet mit einem 3Phasen Generator auf 12V direkt auf den Festplattenmotor. Macht ganz schön Wind in der Werkstatt! endlich mal alles wieder Staubfrei ;-)

Die PCB ist ein altes Vero-Board, ideal für sowas. Drauf ist eine 18650 Samsung LiPo Zelle (mit der die Elektronik bereits ca. 5-6Tage ohne laden läuft!) , ein Arduino Nano, 2 StepDownwandler (1Mhz) für Solarzelle und Wind sowie der GY-271. Es fehlen noch das 433Mhz LoRa Funkmodul, ein INA3221 Modul zum messen der Solarzelle und des Windrad-Generator sowie die "Fahne" am Windrad.. Ich habe auch schon eine kleines Programm zum "mitteln" der Richtung im Arduino drin, es liefert ca. alle 30Sekunden einen Wert der Richtung. Das funktioniert schonmal super, Probleme wird es wohl geben, wenn der Wind von Norden kommt (=0Grad) und die Richtung sich etwas gegen den Uhrzeigersinn sich dreht, dann wären die gemittelten Werte ja zwischen 0 und 360 Grad, oder sehe ich das falsch? Hier mal der Code:

1
// Windrichtungs Messmodul
2
// 22.01.2023 W.Fischer
3
//
4
// liefert den Azimut in Grad
5
// 0 Grad = Norden
6
// 90 Grad = Osten
7
// 180 Grad = Süden
8
// 270 Grad = Westen
9
// https://de.wikipedia.org/wiki/Azimut
10
// es werden x mal die Richtung gemessen, addiert und 
11
// danach durch x wieder geteilt um den Mittelwert zu erhalten.
12

13
#include <QMC5883LCompass.h>
14
QMC5883LCompass compass;
15

16
void setup() 
17
{
18
  Serial.begin(9600);
19
  compass.init();
20
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
21
  compass.setSmoothing(10,true);  
22
  Serial.println(" Kompass ready");
23
}
24

25
void loop() 
26
{
27
  long a;
28
  int x;
29
  a = 0;
30
  for (x = 0; x < 16384; x++)
31
  {
32
    compass.read();
33
    a += compass.getAzimuth();
34
  }  
35
  a = a / x;
36
  Serial.print(a);
37
  Serial.println(" Grad");
38
}

################################ Wie würdet Ihr das "mitteln" ? ################################ PS: auch wenn manche meinen dies wäre alles viel zu aufwändig, bis jetzt hat es viel Spass gemacht und hat ja auch fast nix gekostet! Schöner wäre natürlich, wenn man das Signal was die großen Windräder als Richtung bekommen, "anzapfen" könnte...

Angehängte Dateien:
#7325033
Lesenswert?

....kann deinen code nicht sicher analysieren weil ich nur in assembler programmiere - aber angenommen es gibt 3 Richtungsmessungen: 0° 0° 350° Summe = 350 Durchschnitt (:3) ist dann 116,6° und falsch. Liefert dein Code in so einem Fall ein korrektes Ergebnis? Ja? -dann ist es OK.

OP #7325054
Lesenswert?

Max M. schrieb:

Ich hätte so gerne die 36 hall sensoren gesehen. Aber nein, er baut einen popel-kompass ein. Gleich über dem permanenterregten generator nehm ich an.

Zeig bitte wie das läuft !

ist noch nicht montiert, aber in der nähe von dem festplattenmotor ändert sich so gut wie nix am kompass signal>! Scheint gut magnetisch abgeschirmt zu sein.

OP #7325058
Lesenswert?

Wolfram F. schrieb:

Max M. schrieb:

Ich hätte so gerne die 36 hall sensoren gesehen. Aber nein, er baut einen popel-kompass ein. Gleich über dem permanenterregten generator nehm ich an.

Zeig bitte wie das läuft !

ist noch nicht montiert, aber in der nähe von dem festplattenmotor ändert sich so gut wie nix am kompass signal>! Scheint gut magnetisch abgeschirmt zu sein.

Getestet mit ner Kompass-App auf dem Handy direkt hinter dem Festplattenmotor.

#7325062
Lesenswert?

Du musst die einzelnen Messwerte erst so aufbereiten

wind_raw=get_winddir(); real[wind_i]=cos((float)(wind_raw/180.0M_PI)); imag[wind_i]=sin((float)(wind_raw/180.0M_PI));

und dann die gespeicherten Werte wieder so umrechnen

for(int i=0; i<20; i++){ vect_real+=real[i]; vect_imag+=imag[i]; } dir_rad=atan2(vect_imag, vect_real); wind_dir=(int)(dir_rad/M_PI*180.0);

#7325066
Lesenswert?

Max M. schrieb:

Wie würdest du das lösen?

Helmut, dein ansatz ist krass kompliziert. Aber plausibel.

Ansatz:

Man bildet die differenz zwischen den messungen. Die differenz normiert man auf -180 .. +180 grad.

1
If (x> 180) x-=360; 
2
If (x<-180) x+=360;

Die normierten differnzen werden aufsummiert und durch anzahle messungen geteilt. Das resultat wird zur erstem messung addiert.

OP #7325068
Lesenswert?

Helmut -. schrieb:

Du musst die einzelnen Messwerte erst so aufbereiten

wind_raw=get_winddir(); real[wind_i]=cos((float)(wind_raw/180.0M_PI)); imag[wind_i]=sin((float)(wind_raw/180.0M_PI));

und dann die gespeicherten Werte wieder so umrechnen

for(int i=0; i<20; i++){ vect_real+=real[i]; vect_imag+=imag[i]; } dir_rad=atan2(vect_imag, vect_real); wind_dir=(int)(dir_rad/M_PI*180.0);

Verstehe ich noch nicht ganz, was ist

1
*M_PI

?

Beitrag #7325072 wurde von einem Moderator gelöscht.
#7325096
Lesenswert?

Max M. schrieb:

Hans schrieb:

0° 0° 350° Summe = 350 Durchschnitt (:3) ist dann 116,6° und falsch.

Wie würdest du das lösen?

Ich würde jede Einzelmessung in einen Vektor umrechnen. -in der Ausgabeform delta x und delta y. (x und y mit Vorzeichen f. nach li./re bzw. nach oben/unten; -normales Koordinatensystem) Dann sämtliche x werte addieren und sämtliche y werte addieren. Das gibt den Summenvektor. Dividiert man den durch die Anzahl der Messungen (x dividieren; y dividieren) erhält man den durchschnittlichen vektor der die Richtung und Windstärke darstellt. Mit Phytagoras und Winkelfunktion erhält man dann die gewünschte Durchschnittsgeschwindigkeit und die Durchschnittsrichtung. Skizze zeichnen sollte das grundprinzip klarmachen.

#7325115
Lesenswert?

Max M. schrieb:

Hans schrieb im Beitrag #7325096: Das ist das gleiche wie der Helmut vorgeschlagen hat. Dazu braucht es pro messung ein sin() und ein cos().

Ja, ist mir klar - hab versucht das Grundprinzip darzustellen (das man sich als graphische Lösung gut vorstellen kann) ohne vielleicht "mit Formeln und unbekannten Symbolen" zu verwirren. (Wenn das mathematische Prinzip verstanden ist, muss man ja nur mehr rechnen....)

#7325158
Lesenswert?

Die differenzmethode sähe mit processing dann so aus:

1
int maxmeas = 4;
2
float[] meas = new float[maxmeas]; ;
3

4
void setup() 
5
{
6
  noLoop();
7
  meas[0] = 10;
8
  meas[1] = 350;
9
  meas[2] = 20;
10
  meas[3] = 40;
11
}
12

13
float dsum;
14
float res;
15

16
void draw() 
17
{
18
  float d;
19
  dsum = 0.0;
20
  for (int i = 1; i < maxmeas; i++) 
21
  {
22
    d = meas[i] - meas[0];
23
    if (d >  180.0) d-=360.0;
24
    if (d < -180.0) d+=360.0;
25
    print(d); print("  ");
26
    dsum += d;
27
  }
28
  println(); 
29
  println(dsum); 
30
  res = meas[0] + (dsum / maxmeas);
31
  print("Result "); 
32
  println(res);  
33
}

Soweit ich das getestet habe läuft das.

OP #7325730
Lesenswert?

habe mein Listing mit Deinem Code angepasst, nun bekomme ich Werte von -180 bis +180, aber auch da ist ein großer Sprung zwischen -180 und +180 drin!

1
#include <QMC5883LCompass.h>
2
QMC5883LCompass compass;
3
float dsum;
4
float res;
5
float maxmeas = 40;
6
float meas[40];
7

8
void setup() 
9
{
10
  meas[0] = 10;
11
  meas[1] = 350;
12
  meas[2] = 20;
13
  meas[3] = 40;
14
  Serial.begin(9600);
15
  compass.init();
16
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
17
  compass.setSmoothing(10,true);  
18
  Serial.println(" Kompass ready");
19
}
20

21
void loop() 
22
{
23
  int i;
24
  float d;
25
  dsum = 0.0;
26
  for (i = 1; i < maxmeas; i++)
27
  {
28
    compass.read();
29
    meas[i]= compass.getAzimuth();
30
    d = meas[i] - meas[0];
31
    if (d >  180.0) d-=360.0;
32
    if (d < -180.0) d+=360.0;
33
    Serial.println(d);
34
    dsum += d;
35
  }  
36
  Serial.println(); 
37
  Serial.println(dsum); 
38
  res = meas[0] + (dsum / maxmeas);
39
  Serial.print("Result "); 
40
  Serial.print(res);  
41
  Serial.println(" Grad");
42
}
OP #7325744
Lesenswert?

nochmal etwas angepasst:

1
#include <QMC5883LCompass.h>
2
QMC5883LCompass compass;
3
int dsum;
4
int res;
5
int maxmeas = 40;
6
int meas[40];
7

8
void setup() 
9
{
10
  meas[0] = 10;
11
  meas[1] = 350;
12
  meas[2] = 20;
13
  meas[3] = 40;
14
  Serial.begin(9600);
15
  compass.init();
16
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
17
  compass.setSmoothing(10,true);  
18
  Serial.println(" Kompass ready");
19
}
20

21
void loop() 
22
{
23
  int i;
24
  int d;
25
  dsum = 0;
26
  for (i = 1; i < maxmeas; i++)
27
  {
28
    compass.read();
29
    meas[i]= compass.getAzimuth();
30
    d = meas[i] - meas[0];
31
    if (d >  180) d-=360;
32
    if (d < -180) d+=360;
33
    Serial.println(d);
34
    dsum += d;
35
  }  
36
  Serial.println(); 
37
  Serial.println(dsum); 
38
  res = meas[0] + (dsum / maxmeas);
39
  Serial.print("Result "); 
40
  Serial.print(res);  
41
  Serial.println(" Grad");
42
}

Da der Sensor keine Nachkommastellen ausgibt, brauchen wir auch kein float...

#7325760
Lesenswert?

ääähhhhh... das war nicht die idee.

1
  for (i = 1; i < maxmeas; i++)
2
  {
3
    compass.read();
4
    meas[i]= compass.getAzimuth();

So ist besser

1
  compass.read();
2
  meas[3] = meas[2];
3
  meas[2] = meas[1];
4
  meas[1] = meas[0];
5
  meas[0]= compass.getAzimuth();
6
  for (i = 1; i < maxmeas; i++)
7
  {

da ist ein großer Sprung zwischen -180 und +180

überleg das nochmal.

OP #7325771
Lesenswert?

1
void loop() 
2
{
3
  int i;
4
  int d;
5
  dsum = 0;
6
  compass.read();
7
  meas[3] = meas[2];
8
  meas[2] = meas[1];
9
  meas[1] = meas[0];
10
  meas[0]= compass.getAzimuth();
11
  for (i = 1; i < maxmeas; i++)
12
  {
13
    d = meas[i] - meas[0];
14
    if (d >  180) d-=360;
15
    if (d < -180) d+=360;
16
    dsum += d;
17
  }  
18
  res = meas[0] + (dsum / maxmeas);
19
  Serial.print("Result "); 
20
  Serial.print(res);  
21
  Serial.println(" Grad");
22
}

Ahh, ok, sieht schon besser aus, aber es wird nicht genug "geglättet" Das ganze muss dann wohl nochmals in eine for-schleife um den Mittelwert der Richtung zu bekommen. Wenn ich den Sensor drehe sind die Werte sofort da.

#7325790
Lesenswert?

Max M. schrieb:

Helmut, dein ansatz ist krass kompliziert. Aber plausibel.

Das ist nicht krass kompliziert, sondern normale Vektorrechnung. Sin und Cos machen Imaginär- und Realteil, welche dann getrennt voneinander aufsummiert werden. Dadurch entsteht die Glättung. Das Dividieren durch die Anzahl kannst du dir schenken, denn Re und Im sind ja skaliert. Und der ATAN2 macht dann die Umwandlung in eine Richtung. Schau dir mal die Math.h in C an. Dort ist auch die Konstante Pi definiert, da die Funktionen Bogenmaß wollen, ich aber Ein- und Ausgabe in Grad habe. Alles keine Hexerei, nur Oberstufenmathematik.

OP #7325901
Lesenswert?

es ist ein GY-217 mit QMC5883L Chip

Habe das Programm nun zufriedenstellend am Laufen, es wird nun nur alle 5Sek. aufgerufen , die Werte sind schön gerundet, getestet mit regelmäßigen hin und her Bewegungen der ganzen Platine.

1
#include <QMC5883LCompass.h>
2
QMC5883LCompass compass;
3
int dsum;
4
int res;
5
int maxmeas = 256;
6
int meas[256];
7
unsigned long previousMillis = 0;
8
void setup() 
9
{
10
  meas[0] = 10;
11
  meas[1] = 350;
12
  meas[2] = 20;
13
  meas[3] = 40;
14
  Serial.begin(9600);
15
  compass.init();
16
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
17
  compass.setSmoothing(10,true);  
18
  Serial.println(" Kompass ready");
19
}
20

21
void loop() 
22
{
23
  unsigned long currentMillis = millis();
24
  if (currentMillis - previousMillis > 5000)
25
  {
26
    previousMillis = currentMillis;
27
    read_compass();
28
  }
29
}
30

31
void read_compass()
32
{
33
  int i;
34
  int d;
35
  dsum = 0;
36
  for (i = 1; i < maxmeas; i++)
37
  {
38
    compass.read();
39
    meas[i] = meas[i-1];
40
    meas[0]= compass.getAzimuth();
41
    d = meas[i] - meas[0];
42
    if (d >  180) d-=360;
43
    if (d < -180) d+=360;
44
    dsum += d;
45
  }  
46
  res = meas[0] + (dsum / maxmeas);
47
  Serial.print("Result "); 
48
  Serial.print(res);  
49
  Serial.println(" Grad");
50
}

Vielen Dank für die Hilfen!

#7325912
Lesenswert?

Das hier macht keinen sinn.

1
for (i = 1; i < maxmeas; i++)
2
  {
3
    compass.read();
4
    meas[i] = meas[i-1];
5
    meas[0]= compass.getAzimuth();

Du musst pro main loop nur ein mal lesen, 39 mal verschieben, und die differenzrechnung kommt später im eigenen for loop.


Die getazimuth sieht so aus:

1
int QMC5883LCompass::getAzimuth(){
2
  int a = atan2( getY(), getX() ) * 180.0 / PI;
3
  return a < 0 ? 360 + a : a;
4
}

Nun könntest du die getY() und getX() rufen, diese separat filtern, und dann den atan machen.

Oder: Du initialisierst die eingebaute smoothing funktion

1
void setSmoothing(byte steps, bool adv);

und bekommst mit getAzimuth() gleich die geglätteten werte. Die source deines sensor drivers kannst du hier ansehen: https://github.com/mprograms/QMC5883LCompass/tree/master/src

OP #7332165
Lesenswert?

Moin moin, ich bin ein großes Stück weiter und kurz davor, das Mini Windrad mit der Elektronik zu montieren!

Heute habe ich das LoRa RA-01 Modul eingebaut und angeschlossen. Das Programm funktioniert prima und der Akku ist ohne nachladen noch immer bei 3.85V ! Dank Sleep-Modus verbraucht die Elektronik ganz wenig. Tests mit der Reichweite des LoRa Moduls haben nur positives ergeben (wie ich aber schon früher festgestellt habe) Selbst wenn die Windrad-Elektronik sich beim Nachbarn befindet mit 8 Wänden und 2 Garagentore in Sichtweite gibt es null fehlerhafte Übertragungen! Ich muss dazu sagen, es ist auf jeden Fall empfehlenswert die 433Mhz Variante anstatt die 868Mhz zu verwenden! Die 868Mhz Variante ist viel mehr anfällig gegen Wände oder sonstige Hindernisse! Je höher die Frequenz desto höher die Fehler. Da wir eine Senioren-WG betreiben, habe ich bereits vor ca. 4Jahren 10 Handsender und eine Station basierend auf dem 433Mhz LoRa Modul gebaut und diese funktionieren im Vergleich zu "kaufbaren" Lösungen fast egal, wo sie sich befinden. (innerhalb des Hauses überall, draussen noch in etwa 80m) Die Station empfängt "nebenbei" auch noch die NTP Uhrzeit und zeigt diese auf einem TFT Display an. Da ich noch eine Prototyp Variante der Station hier in der Werkstatt am laufen habe, habe ich zum testen einfach die Uhrzeitdaten mit denen des Windrades getauscht. So sehe ich nun auf dem Display die gemittelte Grad Zahl, die Akku Spannung und die PV und Windrad Spannung. Daher im Listing auch ein paar Daten die später anders aussehen werden. Geplant ist noch ein LoRa-2-Wifi-2-MQTT Wandler, so daß ich die Daten auch in HomeAssistant weiterverwenden oder kontrollieren kann.

Und nun das aufgeräumte Listing... (es wurden alle serielle Ausgaben entfernt, die braucht man ja nur zum debuggen sowie einige Kommentare auf Deutsch hinzugefügt.) Vielleicht gibt es ja für den ein oder anderen Anregungen oder Lösungen...

1
// Windrichtungs Messmodul
2
// 29.01.2023 W.Fischer
3
//
4
// liefert die Windrichtung in Grad
5
// 0 Grad = Norden
6
// 90 Grad = Osten
7
// 180 Grad = Süden
8
// 270 Grad = Westen
9
// https://de.wikipedia.org/wiki/Azimut
10
// es werden x mal die Richtung gemessen, addiert und 
11
// danach durch x wieder geteilt um den Mittelwert zu erhalten.
12
// an IO2 ist ein 47µF Elko mit 10MOhm Entladewiderstand als Timer für den IRQ verbunden
13

14
#include <SPI.h>
15
#include <LoRa.h>
16
#include <Wire.h>  
17
#include <avr/sleep.h>
18
#include <QMC5883LCompass.h>
19
QMC5883LCompass compass;
20
int keep_ADCSRA;              // ADC Settings sichern
21
unsigned int i;
22
unsigned int ii;
23
int dsum;
24
unsigned int loop_counter;
25
int res;
26
int middle_res;
27
int maxmeas = 50;             // Anzahl der Messungen / Oversampling
28
int meas[50];
29
unsigned long previousMillis = 0;
30
float pv = 0.0;
31
float wind = 0.0;
32
float bat = 0.0;
33
byte localAddress = 199;     // address of this device
34
byte destination = 100;      // destination to send to
35
String outgoing;             // outgoing message
36
String lorasendstring = "*20:00  29.01.2023*";
37
#define LED   4               // Sende-LED, leuchtet in eine Kuppel auf dem Windrad zur optischen Kontrolle    
38
#define SS   10               // LoRa SX1278's CS
39
#define RST   9               // LoRa SX1278's RESET
40
#define DI0   3               // LoRa SX1278's IRQ(Interrupt Request)
41
#define BAND  433E6           // LoRa Frequenz
42

43
void setup() 
44
{
45
  pinMode(LED, OUTPUT);
46
  digitalWrite(LED, LOW);
47
  analogReference(INTERNAL);  // ADC Referenz auf interne 1.1V
48
  keep_ADCSRA = ADCSRA;
49
  loop_counter = 0;
50
  digitalWrite (2, HIGH);     // PullUp einschalten, Timer-Elko aufladen
51
  meas[0] = 10;
52
  meas[1] = 350;
53
  meas[2] = 20;
54
  meas[3] = 40;
55
  compass.init();
56
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
57
  compass.setSmoothing(10000,true);  
58
}
59

60
void loop() 
61
{
62
  unsigned long currentMillis = millis();
63
  if (currentMillis - previousMillis > 5000)
64
  {
65
    previousMillis = currentMillis;
66
    read_voltages();
67
    res = middle_res / loop_counter;
68
    send_LoRa();
69
    middle_res = 0;
70
    loop_counter = 0;
71
    go_sleep();
72
  } 
73
  read_compass();
74
}
75

76
void read_compass()
77
{
78
  int d;
79
  dsum = 0;
80
  for (i = 1; i < maxmeas; i++)
81
  {
82
    compass.read();
83
    meas[i] = meas[i-1];
84
    meas[0] = compass.getAzimuth();
85
    d = meas[i] - meas[0];
86
    if (d >  180) d-=360;
87
    if (d < -180) d+=360;
88
    dsum += d;
89
  }  
90
  res = meas[0] + (dsum / maxmeas);
91
  middle_res += res;
92
  loop_counter++;
93
}
94

95
void go_sleep()
96
{
97
  ADCSRA = 0;  
98
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
99
  sleep_enable();
100
  noInterrupts ();
101
  digitalWrite (2, LOW);              // LOW schalten, um geladenen Elko langsam zu entladen
102
  attachInterrupt (0, wake, FALLING);
103
  EIFR = bit (INTF0);  // clear flag for interrupt 0
104
  MCUCR = bit (BODS) | bit (BODSE);
105
  MCUCR = bit (BODS); 
106
  interrupts ();  // one cycle
107
  sleep_cpu ();   // one cycle
108
}
109

110
void wake ()
111
{
112
  sleep_disable();
113
  detachInterrupt (0);                // Interrupt wieder deaktivieren
114
  digitalWrite (2, HIGH);             // PullUp für Elko wieder einschalten
115
  ADCSRA = keep_ADCSRA;               // ADC Settings wiederherstellen
116
  analogRead(A0);                     // dummy read, nach sleep nötig
117
} 
118

119
void send_LoRa()
120
{
121
  if (res >= 0 && res < 361)  // sicherheitshalber den Bereich eingrenzen, falls es beim ausmitteln falsche Werte gibt
122
  {
123
    digitalWrite (LED, HIGH);         // Sende LED einschalten
124
    SPI.begin(); //SCK,MISO,MOSI,SS);
125
    LoRa.begin(BAND);
126
    LoRa.setPins(SS,RST,DI0);
127
    LoRa.setTxPower(20);              // 2 - 20  Sendeleistung einstellen
128
    LoRa.enableCrc();                 // Prüfsumme einschalten
129
    LoRa.setSpreadingFactor(9);       // 6 - 12
130
    LoRa.setSignalBandwidth(125E3);   // Bandbreite einstellen
131
    LoRa.setFrequency(433000000-3250);// Feintuning der Sende-/Empfangsfrequenz
132
    outgoing = "UHRZEIT";             // Kennwort für Empfangsstation (vorübergehend) 
133
    lorasendstring = "*" + String(res) + " " + String(bat) + " " + String(pv) + " " + String(wind) + "*";
134
    LoRa.beginPacket();
135
    LoRa.write(destination);          // Empfänger Adresse (z.Z. noch Station)
136
    LoRa.write(localAddress);         // Sender Adresse (Dieser Sender)
137
    LoRa.write(outgoing.length());    // Länge von "outgoing" senden
138
    LoRa.print(outgoing);             // Kennwort zur Station senden
139
    LoRa.print(lorasendstring);       // String mit Grad, Bat/PV/Wind Volt senden         
140
    LoRa.endPacket();                 // Paket beenden und senden
141
    LoRa.end();                       // LoRa beenden um Strom zu sparen
142
    SPI.end();                        // SPI beenden um Strom zu sparen
143
    digitalWrite (LED, LOW);          // Sende-LED ausschalten
144
  }
145
}
146

147
void read_voltages()
148
{
149
  bat = 0.0;
150
  pv = 0.0;
151
  wind = 0.0;
152
  
153
  for (ii = 0; ii < 10; ii++)
154
  {
155
    bat += analogRead(A0);
156
    delay(50);
157
    pv += analogRead(A1);
158
    delay(50);
159
    wind += analogRead(A2);
160
    delay(50);
161
  }
162
  ii = bat / 10;
163
  bat = map(ii, 0, 1023, 0 , 1694)/100.00;
164
  ii = pv / 10;
165
  pv = map(ii, 0, 1023, 0 , 1694)/100.00;
166
  ii = wind / 10;
167
  wind = map(ii, 0, 1023, 0 , 1694)/100.00;
168
}

Was ich noch suche: Gibt es irgendwas was man gut als Drehantrieb für das große Windrad nehmen könnte? Ein Getriebemotor mit Schneckenantrieb habe ich bereits, aber wo bekommt man ein großes ca. 250mm dm Zahnrad oder Zahnriemenrad her? Wenn es sowas nicht gibt, muss ich es wohl selber fräsen.

Schönen Abend noch, Gruß, Wolfram

´

Gast #7332373
Lesenswert?

Wolfram F. schrieb:

Moin moin, ich bin ein großes Stück weiter und kurz davor, das Mini Windrad mit der Elektronik zu montieren!

Ja - so kann man das auch machen...
[viel mehr oder weniger unnützen Programmcode gelöscht ...]

Eigentlich setzt man eine Windfahne AUF die Generatorgondel. Also auf das Teil, das man eigentlich in Windrichtung ausrichten will.

Die Windfahne muss dann nur noch entscheiden, ob sie von rechts oder links angeströmt wird. Entsprechend dreht man die Gondel in die richtige Richtung: Bei Meldung "Wind von rechts" dreht man nach rechts, und vice versa.

Und voilà, das Windrad dreht in den Wind, ganz egal wo dieser im Moment her kommt. Und das Ganze ohne SINUS, COSINUS, ATAN2 und so'n Quatsch.

Entsprechendes Equipment (oft rein mechanisch - und hält trotzdem tonnenschwere Schiffe auf Kurs) ist seit mindesten 100 Jahren auf Segelyachten verbaut: https://img.nauticexpo.de/images_ne/photo-mg/22019-235407.jpg

Hier die Version mit Hilfspropeller und landgestützt: https://de.wikipedia.org/wiki/Windrichtungsnachf%C3%BChrung

Aber das hatte meine Namenvetter (HI BRO!) vor Wochen schon vorgeschlagen: Beitrag "Re: Windrichtungserkennung mit Hall Sensor"

OP #7342523
Lesenswert?

wie schon im Thread Beitrag "Langzeittimer per RC-Glied?" beschrieben, habe ich auch hier bei der Windrichtungsmessung die Lösung des Sleep-Modus mit externen IRQ per RC-Glied verworfen und es nur per Software gelöst, da der µC so wenig Strom im Sleep-Modus verbraucht hätte ich nicht erwartet. Natürlich ist das Laden des Elkos auch eine erhebliche Stromverschwendung, soviel habe ich schon feststellen können.

Das Mess-Windrad ist nun am richtigen Platz montiert und sendet fleissig alle 48Sek. seine gemittelten Windrichtungsdaten in Grad. Problem ist nur, trotz mittelung sind die Werte doch noch sehr stark abweichend, Beispiel: eigentlich gleiche Windrichtung, aber durch Leichtgängikeit des Mess-Windrades bekomme ich derzeit Werte zwischen 25 und 47 Grad. Wäre Blödsinn später das große Windrad diesen Werten nachzuführen. Daher habe ich eine weitere Filterroutine eingebaut (Siehe auch https://forum.arduino.cc/t/mittelwert-von-meinen-sensorwerten/419980/32, Filterroutine von GuntherB) . Getestet erstmal mit Random-Werten zwischen 0 und 360, Ergebnis nach 5min ungefähr 180! Sieht sehr gut aus wie gemacht dafür! Werde morgen das Mess-Windrad nochmal demontieren und den Controller mit den Änderungen programmieren. Hier das komplette Listing:

1
// Windrichtungs Messmodul
2
// 08.02.2023 W.Fischer
3
//
4
// liefert die Windrichtung in Grad
5
// 0 Grad = Norden
6
// 90 Grad = Osten
7
// 180 Grad = Süden
8
// 270 Grad = Westen
9
// https://de.wikipedia.org/wiki/Azimut
10
// #######!!! als Board MiniCore wählen und BOD disabled!
11
// ####### Bootloader mit STK500 brennen!
12
// ####### Power Led vom Board ablöten
13
//
14
#include <SPI.h>
15
#include <LoRa.h>
16
#include <Wire.h>  
17
#include "LowPower.h"
18
#include <QMC5883LCompass.h>
19
QMC5883LCompass compass;
20
unsigned int i;
21
unsigned int ii;
22
int dsum;
23
unsigned int loop_counter = 0;
24
unsigned int sample_counter = 0;
25
unsigned int sleep_time = 5; // 5=40sek, 1880 = 4 Std.
26
float Val = 0;
27
int res = 0;
28
unsigned int maxmeas = 50;             // Anzahl der Messungen / Oversampling
29
unsigned int max_sample = 10;          // Anzahl der Filterdurchläufe
30
int meas[50];
31
byte count = 0;
32
float pv = 0.0;
33
float wind = 0.0;
34
float bat = 0.0;
35
byte localAddress = 199;     // address of this device (normalerweise NTP-ESP in der WG)
36
byte destination = 100;      // destination to send to (station)
37
String outgoing;             // outgoing message
38
String lorasendstring = "*20:00  29.01.2023*";
39
#define LED   4               // Sende-LED, leuchtet in eine Kuppel auf dem Windrad zur optischen Kontrolle    
40
#define SS   10               // LoRa SX1278's CS
41
#define RST   9               // LoRa SX1278's RESET
42
#define DI0   3               // LoRa SX1278's IRQ(Interrupt Request)
43
#define BAND  433E6           // LoRa Frequenz
44

45
void setup() 
46
{
47
  pinMode(LED, OUTPUT);
48
  digitalWrite(LED, LOW);
49
  analogReference(INTERNAL);  // ADC Referenz auf interne 1.1V
50
  loop_counter = 0;
51
  meas[0] = 10;
52
  meas[1] = 350;
53
  meas[2] = 20;
54
  meas[3] = 40;
55
  compass.init();
56
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
57
  compass.setSmoothing(10000,true);  
58
}
59

60
void loop() 
61
{
62
  if (loop_counter >= sleep_time)
63
  {
64
    loop_counter = 0;    
65
    read_voltages();
66
    read_compass();
67
    if (sample_counter >= max_sample)
68
    {
69
      sample_counter = 0;
70
      send_LoRa();
71
    }
72
    else
73
    {
74
      sample_counter++;
75
    }
76
  }
77
  else
78
  {
79
    sample_counter++;
80
    loop_counter++;
81
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
82
  }
83
}
84

85

86
void read_compass()
87
{
88
  for (ii = 1; ii < 20; ii++) //20fach oversampling
89
  {
90
    int d;
91
    dsum = 0;
92
    for (i = 1; i < maxmeas; i++)
93
    {
94
      compass.read();
95
      meas[i] = meas[i-1];
96
      meas[0] = compass.getAzimuth();
97
      d = meas[i] - meas[0];
98
      if (d >  180) d-=360;
99
      if (d < -180) d+=360;
100
      dsum += d;
101
    }  
102
    res += meas[0] + (dsum / maxmeas);
103
  }
104
  res = res / 20; // Oversampling ende
105
  Filtern(Val, res, 1000);
106
  res = Val;
107
}
108

109
void send_LoRa()
110
{
111
  if (res >= 0 && res < 361)  // sicherheitshalber den Bereich eingrenzen, falls es beim ausmitteln falsche Werte gibt
112
  {
113
    digitalWrite (LED, HIGH);         // Sende LED einschalten
114
    SPI.begin(); //SCK,MISO,MOSI,SS);
115
    LoRa.begin(BAND);
116
    LoRa.setPins(SS,RST,DI0);
117
    LoRa.setTxPower(20);              // 2 - 20  Sendeleistung einstellen
118
    LoRa.enableCrc();                 // Prüfsumme einschalten
119
    LoRa.setSpreadingFactor(9);       // 6 - 12
120
    LoRa.setSignalBandwidth(125E3);   // Bandbreite einstellen
121
    LoRa.setFrequency(433000000-3250);// Feintuning der Sende-/Empfangsfrequenz
122
    outgoing = (F("UHRZEIT"));             // Kennwort für Empfangsstation (vorübergehend) 
123
    lorasendstring = "*" + String(res) + " " + String(bat) + " " + String(pv) + " " + String(wind) + "*";
124
    LoRa.beginPacket();
125
    LoRa.write(destination);          // Empfänger Adresse (z.Z. noch Station)
126
    LoRa.write(localAddress);         // Sender Adresse (Dieser Sender)
127
    LoRa.write(outgoing.length());    // Länge von "outgoing" senden
128
    LoRa.print(outgoing);             // Kennwort zur Station senden
129
    LoRa.print(lorasendstring);       // String mit Grad, Bat/PV/Wind Volt senden         
130
    LoRa.endPacket();                 // Paket beenden und senden
131
    LoRa.end();                       // LoRa beenden um Strom zu sparen
132
    SPI.end();                        // SPI beenden um Strom zu sparen
133
    digitalWrite (LED, LOW);          // Sende-LED ausschalten
134
  }
135
}
136

137
void read_voltages()
138
{
139
  bat = 0.0;
140
  pv = 0.0;
141
  wind = 0.0;
142
  
143
  for (ii = 0; ii < 10; ii++)
144
  {
145
    bat += analogRead(A0);
146
    delay(50);
147
    pv += analogRead(A1);
148
    delay(50);
149
    wind += analogRead(A2);
150
    delay(50);
151
  }
152
  ii = bat / 10;
153
  bat = map(ii, 0, 1023, 0 , 1725)/100.00;
154
  ii = pv / 10;
155
  pv = map(ii, 0, 1023, 0 , 1725)/100.00;
156
  ii = wind / 10;
157
  wind = map(ii, 0, 1023, 0 , 1725)/100.00;
158
}
159

160
void Filtern(float &FiltVal, int NewVal, int FF)
161
{
162
  if (count < FF)   //
163
  {                 // 
164
    FF = count++;   // 
165
  }                 // 
166
  FiltVal= ((FiltVal * FF) + NewVal) / (FF +1);
167
}

Die Filterroutine ist ganz unten...

Etwas Off Topic: Habe gesehen, daß jedes "große" Windrad auch eine Art SAT-Antenne hat, über diese werden anscheinend Telemetrie-Daten wie auch die Windrichtung übertragen. Weiss jemand zufällig, wie und wo diese gesendet/empfangen werden? Frequenz? Wäre doch cool, wenn man diese Funksignale "anzapfen" könnte... Dann wäre dies hier alles nicht mehr nötig.

OP #7342547
Lesenswert?

bereits gebaut aus 2x 200L Ölfässern. läuft auch ganz gut, aber wollte unbedingt mal so ein horizontales bauen weil jeder sagt, die Effizienz ist größer. Habe Platz und etwas Zeit, also probiere ich, bis ich das Optimalste gefunden ist. (Wer baggert mir einen Fluss durch mein Grundstück mit ständig fliessenden Wasser? :-) )

#7342968
Lesenswert?

Pendelnde Windkraftanlage ... das Problem hatt ich auch. Meine Lösung war, die Drehachse oben durch den Generator verlängert und von oben n kurzgeschlossenen Schrittmotor (2 Nm) als "Wirbelstrombremse" drauf. So kann sich die Anlage langsam in den Wind drehen, aber kurze schnelle Pendelbewegungen werden unterdrückt.

Gast #7343032
Lesenswert?

Darrieus-Rotor sollte eine Ecke besser sein. Das Mistding läuf halt nicht von alleine an. https://de.wikipedia.org/wiki/Darrieus-Rotor

Blattverstellung (zur Leistungsanpassung und für 'shutdown') geht damit (wie bei allen "vertical axis wind turbins") aber nicht.

Bei Starkwind werden Windkraftanlagen eh lustig. Eine Kleinanlage ist von einem versierten Flugmodellbauer - so er an ein paar grundsätzliche Dinge denkt - aber zumindest technisch zu schaffen.

#7343101
Lesenswert?

Ludwig schrieb:

Darrieus-Rotor sollte eine Ecke besser sein. Das Mistding läuf halt nicht von alleine an. https://de.wikipedia.org/wiki/Darrieus-Rotor

Blattverstellung (zur Leistungsanpassung und für 'shutdown') geht damit (wie bei allen "vertical axis wind turbins") aber nicht.

Bei Starkwind werden Windkraftanlagen eh lustig. Eine Kleinanlage ist von einem versierten Flugmodellbauer - so er an ein paar grundsätzliche Dinge denkt - aber zumindest technisch zu schaffen.

Blattverstellung ist bei kleinen Horizontalläufern auch eher die Ausnahme, die drehen meist proportional zu Windgeschwindigkeit und man regelt die Belastung abhängig zur dadurch variierenden Spannung.

OP #7343158
Lesenswert?

um den Stromverbrauch des Mess-Windrades mit Kompass noch weiter zu reduzieren wird nun alle 32 Sek. gemessen und alle 5min per Funk übertragen. Das fertige Listing:

1
// Windrichtungs Messmodul
2
// 09.02.2023 W.Fischer
3
//
4
// liefert die Windrichtung in Grad
5
// 0 Grad = Norden
6
// 90 Grad = Osten
7
// 180 Grad = Süden
8
// 270 Grad = Westen
9
// https://de.wikipedia.org/wiki/Azimut
10
// #######!!! als Board MiniCore wählen und BOD disabled!
11
// ####### Bootloader mit STK500 brennen!
12
// ####### Power Led vom Board ablöten
13
//
14
#include <SPI.h>
15
#include <LoRa.h>
16
#include <Wire.h>  
17
#include "LowPower.h"
18
#include <QMC5883LCompass.h>
19
QMC5883LCompass compass;
20
unsigned int i;
21
unsigned int ii;
22
unsigned int loop_counter = 0;
23
unsigned int sample_counter = 1;
24
unsigned int sleep_time = 4; // 4=32sek, 1880 = 4 Std.
25
unsigned int max_sample = 10; // 10 x sleep_time = 5.33min
26
float Val = 0;
27
int res = 0;
28
unsigned int maxmeas = 50;             // Anzahl der Messungen / Oversampling
29
byte count = 0;
30
float pv = 0.0;
31
float wind = 0.0;
32
float bat = 0.0;
33
byte localAddress = 199;     // address of this device (normalerweise NTP-ESP in der WG)
34
byte destination = 100;      // destination to send to (station)
35
String outgoing;             // outgoing message
36
String lorasendstring = "*20:00  29.01.2023*";
37
#define LED   4               // Sende-LED, leuchtet in eine Kuppel auf dem Windrad zur optischen Kontrolle    
38
#define SS   10               // LoRa SX1278's CS
39
#define RST   9               // LoRa SX1278's RESET
40
#define DI0   3               // LoRa SX1278's IRQ(Interrupt Request)
41
#define BAND  433E6           // LoRa Frequenz
42

43
void setup() 
44
{
45
  pinMode(LED, OUTPUT);
46
  digitalWrite(LED, HIGH);
47
  delay(100);
48
  digitalWrite(LED, LOW);
49
  analogReference(INTERNAL);  // ADC Referenz auf interne 1.1V
50
  loop_counter = 0;
51
  compass.init();
52
  compass.setCalibration(-1150, 1665, -1112, 1092, -1230, 1173);
53
  compass.setSmoothing(10000,true);  
54
}
55

56
void loop() 
57
{
58
  if (loop_counter >= sleep_time)
59
  {
60
    loop_counter = 0;    
61
    read_voltages();
62
    read_compass();
63
    if (sample_counter >= max_sample)
64
    {
65
      sample_counter = 0;
66
      send_LoRa();
67
    }
68
    else
69
    {
70
      sample_counter++;
71
    }
72
  }
73
  else
74
  {
75
    loop_counter++;
76
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
77
  }
78
}
79

80

81
void read_compass()
82
{
83
    for (i = 1; i < maxmeas; i++)
84
    {
85
      compass.read();
86
      res = compass.getAzimuth();
87
      Filtern(Val, res, 100);
88
    }  
89
  res = Val;
90
  digitalWrite(LED, HIGH);
91
  delay(10);
92
  digitalWrite(LED, LOW);
93
}
94

95
void send_LoRa()
96
{
97
  if (res >= 0 && res < 361)  // sicherheitshalber den Bereich eingrenzen, falls es beim ausmitteln falsche Werte gibt
98
  {
99
    digitalWrite (LED, HIGH);         // Sende LED einschalten
100
    SPI.begin(); //SCK,MISO,MOSI,SS);
101
    LoRa.begin(BAND);
102
    LoRa.setPins(SS,RST,DI0);
103
    LoRa.setTxPower(20);              // 2 - 20  Sendeleistung einstellen
104
    LoRa.enableCrc();                 // Prüfsumme einschalten
105
    LoRa.setSpreadingFactor(9);       // 6 - 12
106
    LoRa.setSignalBandwidth(125E3);   // Bandbreite einstellen
107
    LoRa.setFrequency(433000000-3250);// Feintuning der Sende-/Empfangsfrequenz
108
    outgoing = (F("UHRZEIT"));             // Kennwort für Empfangsstation (vorübergehend) 
109
    lorasendstring = "*" + String(res) + " " + String(bat) + " " + String(pv) + " " + String(wind) + "*";
110
    LoRa.beginPacket();
111
    LoRa.write(destination);          // Empfänger Adresse (z.Z. noch Station)
112
    LoRa.write(localAddress);         // Sender Adresse (Dieser Sender)
113
    LoRa.write(outgoing.length());    // Länge von "outgoing" senden
114
    LoRa.print(outgoing);             // Kennwort zur Station senden
115
    LoRa.print(lorasendstring);       // String mit Grad, Bat/PV/Wind Volt senden         
116
    LoRa.endPacket();                 // Paket beenden und senden
117
    LoRa.end();                       // LoRa beenden um Strom zu sparen
118
    SPI.end();                        // SPI beenden um Strom zu sparen
119
    digitalWrite (LED, LOW);          // Sende-LED ausschalten
120
  }
121
}
122

123
void read_voltages()
124
{
125
  bat = 0.0;
126
  pv = 0.0;
127
  wind = 0.0;
128
  
129
  for (ii = 0; ii < 10; ii++)
130
  {
131
    bat += analogRead(A0);
132
    delay(50);
133
    pv += analogRead(A1);
134
    delay(50);
135
    wind += analogRead(A2);
136
    delay(50);
137
  }
138
  ii = bat / 10;
139
  bat = map(ii, 0, 1023, 0 , 1725)/100.00;
140
  ii = pv / 10;
141
  pv = map(ii, 0, 1023, 0 , 1725)/100.00;
142
  ii = wind / 10;
143
  wind = map(ii, 0, 1023, 0 , 1725)/100.00;
144
}
145

146
void Filtern(float &FiltVal, int NewVal, int FF)
147
{
148
  if (count < FF)  
149
  {                 
150
    FF = count++;   
151
  }                 
152
  FiltVal= ((FiltVal * FF) + NewVal) / (FF +1);
153
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren