Windgeschwindigkeit messen

Fuzzy

Mitglied
09. Dez. 2008
60
0
6
Worfelden
Sprachen
Tach :),

da das mein 1. Beitrag ist folgendes Vorweg.

Einige beschweren sich dass so wenig gefragt wird usw. . Da in diesem Superforum ja schon fast alles drin steht, bleiben eigentlich fast keine Fragen mehr übrig :D

Ich hab jetzt aber doch noch ein paar und deshalb leg ich jetzt los :cool:

Vor einiger Zeit hab ich mir ein STK500 zugelegt und bin dabei mir eine Wetterstation zu bauen. Es gibt zwar jede Menge auf dem Markt, aber was mir bei denen nicht gefällt ist, dass man die Anzeige nicht über große Entfernungen ablesen kann und dass z.B. die Windgeschwindigkeit nur alle Minute mal gemessen wird.

Ich hab also vor Eine zu bauen die 7 Segment LED Anzeigen hat und die Windgeschwindigkeit misst, sobald Wind da ist.

Am Anfang wollte ich eigentlich alles in Assembler machen und hatte auch schon erste Erfolgserlebnisse, aber dann kam die Temperaturmessung mit einem DS18S20 und da hab ich das Timing nicht hinbekommen. Bin dann auf BASCOM umgeschwenckt und innerhalb kürzester Zeit hatte ich Temperatur auf dem LCD - Display stehen :). Mittlerweile hab ich es auch geschafft den Luftdruck noch anzuzeigen. Das LCD Display hab ich erstmal zu Testen drangehängt, weil ich noch nicht genau weiss wie ich die 7 Segmentanzeigen ansteuern soll, aber da steht ja auch einiges hier im Forum.

Achso, wenn's fertig ist soll Luftdruck, Temperatur und Wingeschwindigkeit gemessen und per Funk (RFM12) zur Anzeige gebracht werden.

Die Windgeschwindigkeit möchte ich so messen, dass ich die Anzahl der Impulse, die mir (ein noch zu bauendes) Windrad (Windsensor) am ICP1 Pin eines AtmegaX liefert, zähle und dann anhand der zugehörigen Daten (Durchmesser des Windrades usw.), in die Geschwindigkeit / Stunde umrechne.

Ich hab dafür jetzt ein Taster an ICP1 angeschlossen und mal folgenden Code eingeklappert:

------------------------------------------------------------------------
' ----------------------------------------------------------------
' Autor : Fuzzy
' Zeitmessung zwischen 2 Tastendrücken (Vorstufe für Windmesser)
' Signaleingang am ATmega8 = Pin PB.0 (ICP1)
' ----------------------------------------------------------------

$regfile = "m8def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 4000000
$baud = 9600


$crystal = 4000000 'Quarzfrequenz

On Icp1 Oncapture 'Interruptroutine für Timer1

Declare Sub Warten


Dim I As Word
Dim Wind As Bit


Ddrb.0 = 0 'PB.0 als Input
Portb.0 = 1 'Pullup ein


Tccr1a = &B00000000 'kein compare Modus
Tccr1b = &B10000010 '


Timsk.ticie1 = 1 'Interrupt enable

Sreg.7 = 1 'Interrupts global einschalten

I = 0
Wind = 0

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2

Config Lcd = 20 * 2

Cursor Off Noblink

Cls
Locate 1 , 1 : Lcd "*Geschwindigkeit*"

Main:

If Wind = 1 Then
Warten
End If

Goto Main


Oncapture:
I = I + 1
Wind = 1
Return

Sub Warten
Wait 2
Cls
Locate 2 , 1 : Lcd I
I = 0
Wind = 0
End Sub
----------------------------------------------------

Er zählt jetzt auch schön die Impulse wenn ich den Taster drücke, nur wenn jetzt kein Wind da ist, also Taster für z.B. 5 Sekunden NICHT gedrückt, dann bleibt natürlich die alte Anzeige dauerhaft im Display stehen. Kann mir jemand einen Tipp geben wie ich die Anzeige bei, z.B. 5 Sekunden kein Wind, auf 0 setzen kann. Ich probier schon den ganzen Nachmittag mir fehlt aber die richtige Idee.

Vielleicht könnte man auch den Inhalt des TCNT1 Registers in eine Variable lesen und damit die Zeit zwischen 2 Imulsen bestimmen, um die Geschwindigkeit zu messen. Vielleicht hat jemand so was schon mal gemacht?

Ich hab zwar vor Jahren mal ein bisschen Visual Basic programmiert aber so der Crack bin ich leider noch nicht :( .

Wäre schön wenn mir jemand auf die Sprünge helfen könnte.

Danke schon mal :)
 
erstmal würde ich "DO LOOP" (Endlosschleife) benutzen für deine main

Code:
Main:
Do

If Wind = 1 Then
Warten
End If

Loop

als nächstes kannst du dein LCD mit Leerzeichen Überschreiben

Code:
Main:
Do

If Wind = 1 Then
Warten
Else
Locate 2 , 1 : Lcd "    " 'ein Leerzeichen pro Ziffer
End If

Loop

oder halt mit CLS das Ganze LCD löschen


viel Glück
 
Hallo Fuzzy!

Ich wollte dich eigentlich nur mal schnell im Forum begrüßen! :ciao:


Auf Grund der späten Stunde, habe ich mir dein Programm noch nicht angesehen.... werde das aber gern in den nächsten Tagen mal nachholen. ;)

Das du nun von ASM zu BASCOM umgestiegen bist freut mich natürlich.
Mit BASCOM gelangt man als Anfänger doch etwas schneller ans Ziel. ;)

Vielleicht solltest du einfach mal auf den ein oder anderen Hinweis von Thomas-Knickohr warten. Der hat schon eine Wetterstation laufen und kann dir bestimmt noch ein paar Tipps geben.

Auf alle Fälle wünsch ich dir gutes Gelingen und wir freuen uns schon auf ein neues Wetterstation-Projekt.
Diesmal dann sogar mit 7-Segment Anzeigen! :)


Dann noch mal......
herzlich Willkommen im Forum und viel Spaß mit BASCOM und den Controllern.

Cassio
 
Hi Fuzzy,

ebenfalls herzlich willkommen.

- Dino

Am Anfang wollte ich eigentlich alles in Assembler machen und hatte auch schon erste Erfolgserlebnisse, aber dann kam die Temperaturmessung mit einem DS18S20 und da hab ich das Timing nicht hinbekommen. Bin dann auf BASCOM umgeschwenckt und innerhalb kürzester Zeit hatte ich Temperatur auf dem LCD - Display stehen :). Mittlerweile hab ich es auch geschafft den Luftdruck noch anzuzeigen.
:p:p


Grüsse,

Michael
 
Hi Michael,

- Dino

Am Anfang wollte ich eigentlich alles in Assembler machen und hatte auch schon erste Erfolgserlebnisse, aber dann kam die Temperaturmessung mit einem DS18S20 und da hab ich das Timing nicht hinbekommen. Bin dann auf BASCOM umgeschwenckt und innerhalb kürzester Zeit hatte ich Temperatur auf dem LCD - Display stehen :). Mittlerweile hab ich es auch geschafft den Luftdruck noch anzuzeigen.
:p:p
Bei mir läuft das 1-Wire-Interface mit Assembler ohne Probleme :D

Man muß nur eine Sache verstehen ... Die gesamte Kommunikation wird vom
Prozessor angeschoben. Auch beim Lesen wird die erste Flanke vom Prozessor
erzeugt und danach der Port vom Prozessor hochohmig geschaltet damit
der Slave antworten kann. Das hat mir am Anfang ne Stunde Zeit gekostet
bis ich die Signaldiagramme und Dokus soweit durch hatte.

Aber ich werde wohl auch auf einen Mischbetrieb aus Bascom und Assembler
umsteigen. Rechenklamotten in Bascom und die "guten" Sachen wo es
drauf ankommt in Assembler
. :p :p

Gruß
Dino
 
Vielen Dank für die freundliche Aufnahme hier im Forum :) .

@boeserkorn
Danke für den Tipp mit dem Löschen der 2. Zeile. Hab mich die ganze Zeit schon geärgert dass die obere Zeile bei "CLS" gelöscht wurde. Jetzt kann ich sie stehen lassen.

@dino03
Bei mir läuft das 1-Wire-Interface mit Assembler ohne Probleme

Man muß nur eine Sache verstehen ...

Ich glaub schon dass ich das verstanden habe, aber diese Wartecyclen müssen ja sehr genau sein und da ich das Ganze erstmal mit dem STK500 aufgebaut habe bin ich irgendwie mit den Fusebits zum Einstellen des externen 4 Mhz Quarzes nicht zurecht gekommen. Vielleicht probiere ich es dann mal wenn ich alles auf einer extra Platine aufgebaut habe.
Ich hab schon ein bisschen Erfahrungen mit Assembler (68Hc11) und hätt es auch gerne damit gemacht. Naja von Basic (Bascom) bin ich auch nicht abgeneigt. Muß mir nur bei Gelegenheit mal die Vollversion bestellen.

Leider hab ich mein Problem mit dem Rücksetzen des Zählers, wenn kein Interrupt mehr kommt immer noch :eek: . Hat jemand eine Idee wie ich das machen kann?
Nochmal zum Verständnis. Wenn ein externes Signal (Reedkontakt/Schalter) den Timerinterrupt auslöst, wird innerhalb der Interruptroutine eine Variable um 1 hoch gezählt. Nach 2 Sekunden wird dann geschaut welchen Wert die Variable hat und angezeigt. Wenn jetzt kein externes Signal mehr kommt, soll der Wert z.B. nach 5 Sekunden auf 0 zurückgesetzt werden.

Gruß
Roger
 
Hi Dino,

Aber ich werde wohl auch auf einen Mischbetrieb aus Bascom und Assembler
umsteigen. Rechenklamotten in Bascom und die "guten" Sachen wo es
drauf ankommt in Assembler
. :p :p
Ok, ok - auch ich werde früher oder später Assembler- Routinen einbinden...


:offtopic:
Was macht Deine Renovierung? Ich bin schon ein ganzes Stück vorangekommen.:)
Heute hat Cassio mein Haus bezüglich der Telefon/ - Netzwerkverteilung "inspiziert". Der Telefonanschluss ist dank des Vormieters an der richtigen Stelle, sein goldener Tip zum Netzwerk/ Internet: DLAN. Das erspart mir das elendige Strippenziehen.:D:D


Grüsse,

Michael
 
Hi Michael,

:offtopic:
Was macht Deine Renovierung? Ich bin schon ein ganzes Stück vorangekommen.:)
Heute hat Cassio mein Haus bezüglich der Telefon/ - Netzwerkverteilung "inspiziert". Der Telefonanschluss ist dank des Vormieters an der richtigen Stelle, sein goldener Tip zum Netzwerk/ Internet: DLAN. Das erspart mir das elendige Strippenziehen.:D:D
dann streu ich auch mal ein wenig OffTopic rein ... ;)

Sieht gut aus. Eß-/Küchenbereich ist zu 99,5% fertig (Grad noch schnell
aufgeräumt und saubergemacht). Jetzt fehlen noch Wohnzimmer, Flur und
1/3el vom Bad.
Bad wird als nächstes fertig. Flur ist nicht so wild, Wohnzimmer wird mit
dem Parkett (oder Laminat) und der Verkabelung noch viel Zeit kosten.
Außerdem wird das Wohnzimmer im Moment noch als "Materiallager" mißbraucht.
Aber ich bin im Großen und Ganzen mit dem Fortgang der Arbeiten zufrieden.
... OffTopic Ende ...

Gruß
Dino
 
Also ich hab's jetzt fast hinbekommen. Was noch nicht so schön ist, ist dass wenn die Anzeige 2 stellig wird dann löscht er nur die 1. Stelle, aber das bekomm ich bestimmt auch noch hin. Da ich ja noch am üben bin, bin ich natürlich für alternativ Vorschläge zur Erweiterung meines Know Hows dankbar. Hier der Code:

Code:
Do

While Wind = 1
   Warten
   If Wind = 0 Then
      Locate 2 , 1 : Lcd "00"
   End If
Wend

Wait 3

'Locate 2 , 1 : Lcd "0"

Loop


Oncapture:
    I = I + 1
    Wind = 1
Return

Sub Warten
      Wait 2
      Locate 2 , 1 : Lcd " "                                'ein Leerzeichen pro Ziffer
      Locate 2 , 1 : Lcd I
      I = 0
'      Wind = 0
End Sub

Danke schon mal ... ;)
 
Hallo Fuzzy,

spiel doch mal mit den Leerzeichen. Mach geb doch einfach mal
zwei statt eins aus :D Also nich "-" sondern "--" (die - sollen
Leerzeichen darstellen).

Wenn ich nicht genau weiß wie etwas formatiert auf der Anzeige erscheint
oder ob da noch vorlaufende oder nachlaufende Zeichen sind, dann pack
ich einfach ein "#" vor oder hinter die Ausgabe. Dann kann man die Zeichen
dazwischen wunderbar zählen ;)

Gruß
Dino
 
Bad wird als nächstes fertig. Flur ist nicht so wild, Wohnzimmer wird mit
dem Parkett (oder Laminat) und der Verkabelung noch viel Zeit kosten.
Außerdem wird das Wohnzimmer im Moment noch als "Materiallager" mißbraucht.
Aber ich bin im Großen und Ganzen mit dem Fortgang der Arbeiten zufrieden.
Jo, ebenso.

Ende Off- Topic.


Grüsse

Michael
 
Hi Fuzzy,

Die Windgeschwindigkeit möchte ich so messen, dass ich die Anzahl der Impulse, die mir (ein noch zu bauendes) Windrad (Windsensor) am ICP1 Pin eines AtmegaX liefert, zähle und dann anhand der zugehörigen Daten (Durchmesser des Windrades usw.), in die Geschwindigkeit / Stunde umrechne.
der Beitrag ist zwar schon ein paar Tage alt aber wenn Du das Windrad noch nicht fertiggestellt hast, kann ich Dir folgendes empfehlen:
http://cgi.ebay.de/Windgeber-0-10-V...werker_Sicherheitstechnik&hash=item255d2b16ea
Ich habe es aktuell in der 230V-Version verbaut und muss sagen, dass es super läuft. Das Teil ist gut durchdacht (Heizung für Winterbetrieb, Lagerung, Verarbeitung). Bei der Qualität empfinde ich den Preis auch als durchaus gut.
Falls es darum geht, schnelle und reproduzierbare Ergebnisse zu bekommen, wäre das Dein Ding. Wenn es Dir ums Basteln geht, kannst Du meinen Text natürlich gerne überlesen (möglichst viel selbermachen ist immer auch interessant).

Schönen Gruss
Markus
 
Hallo Markus,

ja das Thema ist noch aktuell, hab nur eine kleine Auszeit genommen weil mein Programmer nicht mehr geht, jetzt bin ich aber wieder dran.
Allerdings wollte ich den Windmesser erstmal selber versuchen zu bauen und erste Tests sind auch ganz zufriedenstellend verlaufen. Der Preis von 125 € ist mir auch eigentlich zuviel. Falls mein Eigenbau aber nicht so wie erwartet funktionieren sollte, werde ich mir das Teil mal ansehen. Vielen Dank auf jedenfall für den Tipp :flowers:

Gruß
Roger
 
zu Windgeschwindigkeit messen

ja ich messe die Wingeschwindigkeit schon eine Weile aber den Eintrag habe ich erst heute gesehen.
Als angefangen hat es vor 20 Jahren. Mit einem Propeller und einen kleinen Elektromotor wollt der Sohni Wind Messen. Das wurde nichts. Wir haben ein Schalenkreuzaneometer gebaut und mit einem Magneten und einem Reedkontakt die Pulse gemessen und mit einem Fahrradtacho ausgewertet. Den Faktor haben wir ermittelt indem wir mit dem Rad gefahren sind und die Fahrradgeschwindigkeit mit der Fahrtwindgeschwindigkeit verglichen haben.
Dann habe ich mit Microcontroller angefangen. Elektor 80C535 usw. Ich habe die Pulszeiten in Assembler nicht in den Griff bekommen, so habe ich mir etwas einfacheres überlegt. Da ich alle sechs Minuten meine Messwerte abspeicherte habe ich einfach alle Windimpulse die in sechs Minuten auflaufen gezählt und den sechs Minuten Mittelwert ausgerechnet. Mittlerweile war es die C_Control und nun ist es Atmel AVR aber die Pulszählung hat sich bewährt. Was mir fehlt ist der Maximalwert. Aber der wird ja in den meisten Fällen ja dann auch wieder gemittelt.
Ich hoffe es interessiert noch jemanden.
uli
 
Hallo Markus und Uli,

danke für Eure Beiträge. Den Windsensor bei ebay hab ich auch schon gesehen, ist mir aber schon etwas teuer. Ich werde erstmal selbst versuchen was zu bauen. Hab eineige Ideen gefunden und auch schon diverse 'Lager' hier liegen. Sollte das nicht so hinhauen werde ich mir vielleicht doch was fertiges zulegen.

@Uli, ja das mit den Imulsen pro Zeiteinheit hab ich als 1. Simulationsversion auch so gemacht. Hab die Tastendrücke in 4 sec gezählt und dann durch 4 getielt und in km/h umgerechnet. Leider bekommt man halt so die Windspitzen nicht so genau mit. Dehalb experimentiere ich gerade mit Timer0 und Timer1 beim Atmega. Ich messe die Zeit die von einem bis zum nächsten Impuls vergeht, bzw. lese den Wert von Timer1 zwischen 2 Impulsen aus und berechne daraus die Geschwindigkeit in km/h. Hab dazu auch gleich noch ein Frage die kommt dann im nächsten Posting :).

Gruß
Roger
 
Hallo,

wie bereits angekündigt habe ich eine Frage zum Timer1. Ich benutze den Atmega8 mit 8 Mhz Quartz. Wenn ich die Dokumentation richtig verstanden habe müsste ich doch bei einem Vorteiler von 1024 nach folgernder Rechnung:

8000000 / 1024 = 7812,5 und 65536 / 7812,5 = 8,39

so ca. alle 8 Sekunden einen Timer1 Overflow Interrupt erhalten.

Bei meinem kleinen Testprogrämmchen hier:

Code:
$regfile = "m8def.dat"
$framesize = 40
$swstack = 60
$hwstack = 60
$crystal = 8000000

'Unterprogramme:
'----------------

'VARIABLEN:
'---------

Dim Count As Byte


Timsk.ticie1 = 1                                            'Interrupt enable




Config Timer1 = Counter , Prescale = 1024 , Capture Edge = Rising

On Ovf1 Onoverflow1

Enable Icp1
Enable Ovf1

Enable Interrupts

Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , _
   Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5

Config Lcd = 20 * 2

Cls

Do

Loop


Onoverflow1:
   Count = Count + 1
   Locate 2 , 1
   Lcd "Count: " ; Count
Return

ändert sich aber der Wert von meinem 'Counter' schon so nach ca. 3 Sekunden. Kann mir jemand helfen meinen Denkfehler zu finden?

Danke!
Roger
 
Hallo Roger!

Frage zu Deinem Testprogramm:

Wenn Du nur einen Interrupt ausführen möchtest, warum verwendest Du Capture Edge = Rising?
=> Du verwendest doch nicht den Pin ICP und damit brauchst Du diesen Parameter auch nicht für den Timer.

Es reicht wenn Du den Timer wie folgt konfigurierst
Code:
Config Timer1 = Timer, Prescale = 1024

Ich glaube, dass Du schon nach 3 Sekunden eine Interrupt bekommst weil Du mit einem uninitialisierten Counter arbeitest und nicht weisst, welchen Inhalt dieser hat. Ich vermute auch, dass je nach Start und Vorgeschichte die Zeit variiert.

Um das zu umgehen arbeite ich IMMER mit sauberen Initialisierungen. Hier in meinem Beispiel Timerwert benannt

Hmmm, ich bin auch der Meinung, dass BASCOM ausreichend Funktion bietet, dass Du die register und Co. nicht von Hand setzten musst.

Ich würde die Funktion so programmieren:

Code:
$regfile = "m8def.dat"
$framesize = 40
$swstack = 60
$hwstack = 60
$crystal = 8000000

'Unterprogramme:
'----------------

'VARIABLEN:
'---------

Const Timerwert = 0 ' Startwert wenn Du den gesamten Counter ausnutzen möchtest um auf ca. 8 Sekunden zu kommen.

Dim Count As Byte

Config Timer1 = Counter , Prescale = 1024 , Capture Edge = Rising
On Timer1 Onoverflow1  ' Diese IrSr bei Overflow ausführen
Timer1 = Timerwert    ' Timer Vorinitialisieren !!!

Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5

Config Lcd = 20 * 2

Cls

Enable Timer1     ' Timer 1 freigeben
Enable Interrupts   ' und los :-)

Do
   ' Mache irgendwas
Loop


Onoverflow1:
   Timer1 = Timerwert  ' darauf kannst Du in Deinem speziellen all verzichten
   Count = Count + 1
   Locate 2 , 1
   Lcd "Count: " ; Count
Return

Ich hoffe es hilft Dir ein bissle weiter.

Grüße,
Markus
 
Hallo Markus,

danke für Deinen Vorschlag aber es hat sich nichts geändert. Vielleicht benutzt er den 16 Mhz anstatt dem 8 Mhz Quartz. Muß mir den Schaltplan nochmal genau ansehen, ich benutze das Pollin Board und da sind 2 Quartze drauf. Aber dann hätte mein Timing mit den 7 Segmentanzeigen eigentlich nicht funktionieren dürfen. Hab ich vielleicht einen Denkfehler bei der Berechnung der ca. 8 Sekunden für einen Timer Overflow? Mit Deinem folgendem Code zählt er im ca. 3 Sekunden Takt:

Code:
$regfile = "m8def.dat"
$framesize = 40
$swstack = 60
$hwstack = 60
$crystal = 8000000

'Unterprogramme: '----------------
'VARIABLEN: '---------

Const Timerwert = 0                                         ' Startwert wenn Du den gesamten Counter ausnutzen möchtest um auf ca. 8 Sekunden zu kommen.
Dim Count As Word

Config Timer1 = Counter , Prescale = 1024 , Capture Edge = Rising
On Timer1 Onoverflow1                                       ' Diese IrSr bei Overflow ausführen
Timer1 = Timerwert                                          ' Timer Vorinitialisieren !!!

Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5

Config Lcd = 20 * 2

Cls

Enable Timer1                                               ' Timer 1 freigeben

Enable Interrupts ' und los :-)

Do                                                          ' Mache irgendwas

Loop

Onoverflow1:
   Timer1 = Timerwert                                       ' darauf kannst Du in Deinem speziellen all verzichten
   Count = Count + 1
   Locate 2 , 1
   Lcd "Zaehler: " ; Count
Return

Gruß
Roger
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)