Pages: 1 2 3 [4] 5 6   Go Down
Author Topic: Auswertung Impulse Volkswindmesser  (Read 8738 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mein ganzer Fehler lag wohl darin, in der Rechnung frequenz = 1000000 / periode zu schreiben: frequenz = 1000000.0 / periode smiley-grin.

Gibt es denn eine Möglichkeit festzulegen, wie viele Nachkommastellen man angezeigt bekommen möchte, wenn man solch eine Float-Division durchführt?
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Gibt es denn eine Möglichkeit festzulegen, wie viele Nachkommastellen man angezeigt bekommen möchte
Ja, mehrere.
Ist ausserdem keine Frage der Division, sondern der Anzeige.
Schau dir mal Serial.print an
Logged

Offline Offline
Edison Member
*
Karma: 39
Posts: 1173
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Float hat beim Arduino meist 6 bis 7 Stellen, also z.B. 1.23456 *10^-4
Du kannst dir natürlich mehr Stellen anzeigen lassen (z.B. mit Serial.println(frequenz, 18), aber die machen keinen Sinn.
mehr als die 6-7Stellen genauigkeit wirst du nicht bekommen,  und das reicht ja meist auch.
Logged

Grüße
Gunther

Offline Offline
God Member
*****
Karma: 12
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich komme aus Delphi/Pascal Welt, deshalb wundere ich ab und an schon was ein C-Compiler so macht

Code:
frequenz = 1000000 / periode

Bei Delphi - Wenn frequenz eine Integer Variable wäre wurde der Compiler sofort meckern.
Er will das dies in einer Gleitkomma Variable gespeichert werden soll, weil das Ergebnis ein Gleitkomma sein wird.
Wenn zwei ganze Zahlen dividiert werden ist das meist der Fall

Wenn ich nun in C frequenz expliziert als float definiere muß ich dies dann wirklich so schreiben,
damit auch eine Float-Division durchgeführt wird.
Code:
frequenz = 1000000.0 / periode

Ich wäre genauso wie BigBangTheory in diese Falle getappt.

Ist zwar etwas OT sorry dafür, aber dieses Beispiel passte genau für meine Frage
« Last Edit: June 05, 2013, 11:57:19 am by rudirabbit » Logged

Arduino UNO,MEGA  Fremdgänger mit dem  Nucleo L152RE   
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
...weil das Ergebnis ein Gleitkomma sein wird.

Der Fehler liegt erstmal im "weil", dann konkret daran dass in c Integer/Integer als Ergebnis immer ein Integer ist.   Was sonst smiley-wink

Ganz fies wird es übrigens, wenn z.B. 1000 und 1000L einen Unterschied macht.
( z.B. wenn man es mit int i = 100 multipliziert und das Ergebnis in einem long ablegt. )

Code:
int i = 100;
long l = 1000 * i;
Serial.print(l);
if ( l == -31072) Serial.println (" ist ein erstaunliches Ergebnis");

Bei c für MicroController sollte man übrigens auch immer überlegen, ob man tatsächlich den Datentyp float braucht. 
Logged

Offline Offline
God Member
*****
Karma: 12
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bei c für MicroController sollte man übrigens auch immer überlegen, ob man tatsächlich den Datentyp float braucht.  

Schon klar, immer schön die ressourcen schonen.

Code:
int i = 100;
long l = 1000 * long( i);
Serial.print(l);
if ( l == -31072) Serial.println (" ist ein erstaunliches Ergebnis");

Dann müsste man in diesen Fall einen typecast machen  smiley-cry   oder i gleich als long denfinieren
Danke für solche Hinweise, als Delphi Mensch hätte so einen Fehler nie gesehen.
Ich möchte jetzt keine Diskussion über Programmiersprachen lostreten, weil obsolet ..... C++ hat sich durchgesetzt.  smiley-confuse

Ob C++ zu Objekt Pascal wirklich besser ist  ??  

Das obigen Beispiel ist ganz simples C und selbst dort gibt es Dinge die in meinen Pascal Augen gar nicht gehen dürften.
« Last Edit: June 07, 2013, 01:16:10 am by uwefed » Logged

Arduino UNO,MEGA  Fremdgänger mit dem  Nucleo L152RE   
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C und C++ ist für Masochisten, sagen die einen.

Basic, C# , Java und dein Pascal ist für Weicheier, sagen die anderen.
Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

C und C++ ist für Masochisten, sagen die einen.

Basic, C# , Java und dein Pascal ist für Weicheier, sagen die anderen.

Dann oute ich mich hier mal als masochistisches Weichei  smiley-lol
Logged

_______
Manfred

Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Leute,

nachdem mein Windmesser unter "Laborbedingungen  smiley-lol" super funktioniert und gute Werte angezeigt hat, dachte ich mir als ein Gewitter aufzog, dass ich ihn mal in "freier Wildbahn" testen werde. Ich habe ihn also auf dem Geländer meines Balkons installiert, Y-Draht in die Wohnung gezogen, alles angeschlossen und los gings. Am Anfang kamen super Werte, dann zog das Gewitter über uns hinweg und ich bekam Windgeschwindigkeiten die jenseits von Gut und Böse lagen (über 1000 m/s) und als das Gewitter wieder weg war, waren die Werte wieder okay.

Desweiteren habe ich versucht, den Arduino per Netzteil zu betreiben, wobei ich dabei auch teilweise sehr sehr wilde Werte angezeigt bekam. Ohne Netzteil war dies jedoch nicht der Fall.

Kann es sein das dies daran liegt, weil der Y-Draht nicht abgeschirmt ist?

Oder hat jemand noch eine bessere Idee dazu?

Gruß
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 160
Posts: 3163
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Kann es sein das dies daran liegt, weil der Y-Draht nicht abgeschirmt ist?

Oder hat jemand noch eine bessere Idee dazu?

Ja, nicht abgeschirmte Kabel, oder welche an denen die Abschirmung nicht geerdet ist, wirken als Antenne und nehmen Funkwellen auf, auch die bei einem Gewitter entstehenden. Da kommt es darauf an, wie stark Deine PullUp- oder PullDown-Widerstände sind, inwieweit die entgegenwirken.

Ich bin jetzt in diesem vierseitigen Thread nicht drin, was verwendest Du denn zur Auswertung des Reed-Signals am Pin:
- den internen PullUp-Widerstand?
- einen externen PullUp- oder PullDown-Widerstand? Welchen Wert hat der Widerstand?

Im Zweifelsfall mal einen niedrigeren Wert probieren, also z.B. 1K statt 10K Pulldown-Widerstand.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das mit den Funkwellen dacht ich mir schon fast. Wenn früher bei nem alten Radio die Antenne ab war, haben wir auch nen Stück blanken Kupferdraht genommen und den zu ner Antenne gebogen smiley.

Ich hab da momentan nen 12K Widerstand dran.

Wieso würde denn ein kleinerer Widerstand hier helfen?
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 270
Posts: 21842
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Es könnte aber auch ein Überlauf sein, weil das WindRad zu schnell dreht.
Ich habe jetzt nicht den Code im Kopf oder unter der Hand um ihn analysieren zu können.

Grüße Uwe
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 160
Posts: 3163
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich hab da momentan nen 12K Widerstand dran.

Wieso würde denn ein kleinerer Widerstand hier helfen?

Wenn durch den PullDown-Widerstand höhere Ströme fließen müssen, um zu einer Spannungsänderung am Arduino-Pin zu führen, dann ist für Störungen eine höhere eingekoppelte Energie notwendig, damit der Arduino-Pin auf HIGH gezogen wird.

Ein kleinerer PullDown-Widerstand wirkt also eingekoppelten Störungen auf der Zuleitung entgegen. Je länger eine Zuleitung ist, desto mehr Störungen fängt sie auf. Und daher verwendest Du bei einer längeren Zuleitung besser 1K Pulldown-Widerstände als 12K.

Wie Uwe schreibt, kann aber auch die Software-Auswertung fehlerhaft sein.
Welchen Sketch verwendest Du denn jetzt dafür?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Leute,

momentan verwende ich folgenden Sketch:

Code:
#include <SPI.h>
#include <SD.h>

const int chipSelect = 4; // Chip Select, Signal SS (Slave Select)
unsigned long kimpuls = 0;
unsigned long limpuls = 0;
unsigned long periode = 0;
unsigned long Zeitscheibe = 0;
unsigned long i = 0;
unsigned long j = 0;
unsigned long abstand = 0;
int Sekunden = 00;
int Minuten = 54;
int Stunden = 16;
float wind = 0;
float frequenz = 0;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  //-------------------------------------------------SD-Card - Anfang
  Serial.print("Initialisierung SD-Card...");
  pinMode(10, OUTPUT); // SPI Chip Select als Ausgang setzen, auch wenn nicht genutzt
  if (!SD.begin(chipSelect)) { // Prüfen, ob SD-Card bereit für Initialisierung
    Serial.println("SD-Card nicht bereit oder fehlend");
    return; // nichts weiter zu tun
  }
  Serial.println("SD-Card initialisiert");
//-------------------------------------------------SD-Card - Ende
//  Serial.println("hh:mm:ss;   Windgeschwindigkeit");
 
 
  attachInterrupt(0,Interrupt,RISING);
}

void Interrupt()
{
  noInterrupts(); 
  i = micros();
  interrupts();
}

void loop()
{
  abstand = i-j;
  j=i;
  if (abstand >= 1000)
  {
   limpuls=abstand;
  }
  else
  {
   kimpuls=abstand;
  }
  periode = kimpuls + limpuls;
  frequenz = 1000000.0 / periode;
  wind = 2.58 * (pow(frequenz,0.8927));
 
  if (millis() > Zeitscheibe )   
  {
    detachInterrupt(0);
    Zeitscheibe  = millis()+1000;
    Sekunden++;
//-------------------------------------------------Zeit Berechnung - Anfang 
  if (Sekunden==60){
   Minuten++;
   Sekunden=0;
  }
  if (Minuten==60){
    Stunden++;
    Minuten=0;
  }
  if (Stunden==24){
    Stunden = 0;
  }
//-------------------------------------------------Zeit Berechnung - Ende   
    if (micros()-i > 4311965 )
    {
     wind = 0;
    }
    if (periode == 0){
      wind = 0;
    }
   
//-------------------------------------------------Speicherung auf SD-Karte - Anfang   
 File dataFile = SD.open("wind.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.print(Stunden);
    dataFile.print(" ; ");
    dataFile.print(Minuten);
    dataFile.print(" ; ");
    dataFile.print(Sekunden);
    dataFile.print(" ;   ");
    dataFile.print(wind);
    dataFile.print(" ; m/s;   ");
    dataFile.print(i);
    dataFile.println(" ;   Zeitpunkt des Interrupts in Mikrosekunden");
    dataFile.close();
    } 
  // kann die Datei auf der SD-Karte nicht geöffnet werden, wird folgende Fehlermeldung angezeigt
  else {
    Serial.println("error opening wind.csv");
  }
//-------------------------------------------------Speicherung auf SD-Karte - Ende
// Ausgabe der Werte auch auf dem Serialmonitor:

    Serial.print(Stunden);
    Serial.print(" ; ");
    Serial.print(Minuten);
    Serial.print(" ; ");
    Serial.print(Sekunden);
    Serial.print(" ;   ");
    Serial.print(wind);
    Serial.println(" ; m/s;   ");
//    Serial.print(i);
//  Serial.println(" ;   Zeitpunkt des Interrupts in Mikrosekunden");

    attachInterrupt(0,Interrupt,RISING);
  }
}

Ich habe, auch wenn das Windrad stand, beim Gewitter, aber auch wenn ich ein Netzteil an den Arduino angeschlossen habe, sehr große Werte bekommen. Ich tippe da dann doch eher auf die Störsignal-Variante.

Ich würde auch gern zur festen Installation des Windmessers ein Koaxialkabel verwenden, welches ja abgeschirmt sein müsste, oder?

Mir stellt sich da nun jedoch die Frage, wie ich es an den Arduino anschließen kann. Der Innenleiter ist ja easy, aber wie mach ich es mit dem Außenleiter? Ich Stück vom Kabel zurückschneiden und den Außenleiter verdrillen zum anschließen?

Werd das ganze mal mit nem kleineren Widerstand ausprobieren smiley.
Logged

Offline Offline
God Member
*****
Karma: 12
Posts: 513
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Habe den Code nur kurz angesehen.

Du hast in der main Loop dies:
Code:
attachInterrupt(0,Interrupt,RISING);


Im Setup auch, so soll es auch sein, aber warum auch in der main Loop ?
Logged

Arduino UNO,MEGA  Fremdgänger mit dem  Nucleo L152RE   
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

Pages: 1 2 3 [4] 5 6   Go Up
Jump to: