Nettolaufzeit erfassen

Hallo zusammen.
ich baue zur Zeit eine Kleinwindkraftanlage, und habe eine Problem mit der Azimutregelung, also dem drehen des Rotors in die Windrichtung. Hierzu benutze ich eine Windfahne, die mit zwei Lichtschranken arbeitet. Wird die Windfahne z.B. nach rechts geweht, wird eine Lichtschranke verdeckt und nach einer kurzen Zeit wird der Motor des Azimutantriebs gestartet und dreht den Rotor in die entsprechende Richtung.

#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2);

int Lichtschranke1 =3; // Azimuthregelung
int Lichtschranke2 =6; // Azimuthregelung
int Lichtschrankenstatus1=0; // Azimuthregelung
int Lichtschrankenstatus2=0; // Azimuthregelung
int Azmr =9; //Azimuth rechts drehen
int Azml =10; //Azimuth links drehen
float Wartezeit1 =0; //Dauer Lichtschranke1 high
float Wartezeit2 =0; //Dauer Lichtschranke2 high
int Startzeit =1000; //Dauer bis Azimuthantrieb reagiert

void setup() {

// put your setup code here, to run once:
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode (Lichtschranke1,INPUT);
pinMode (Lichtschranke2,INPUT);
pinMode (Azmr, OUTPUT);
pinMode (Azml, OUTPUT);

}
void loop () {

// Azimutsteuerung

Lichtschrankenstatus1= digitalRead(Lichtschranke1);
if (Lichtschrankenstatus1 == HIGH){
Wartezeit1++;}
if (Lichtschrankenstatus1 ==LOW){
Wartezeit1=0;}

Lichtschrankenstatus2= digitalRead(Lichtschranke2);
if (Lichtschrankenstatus2 == HIGH){
Wartezeit2++;}
if (Lichtschrankenstatus2 ==LOW){
Wartezeit2=0;}

if (Wartezeit1> Startzeit) digitalWrite(Azmr, LOW);
if (Wartezeit1< Startzeit) digitalWrite(Azmr, HIGH);
if (Wartezeit2> Startzeit) digitalWrite(Azml, LOW);
if (Wartezeit2< Startzeit) digitalWrite(Azml, HIGH);

delay (1);

Dieser Sketch funktioniert so gut. Jetzt hatte ich das Problem, dass der Rotor zu oft in dieselbe Richtung gedreht wurde und meine beiden Kabel sich im Turm sehr stark aufgewickelt habe.

Um das zu verhindern möchte ich die Nettolaufzeit des Azimutantriebs erfassen. Die Zeit soll z.B. bei rechts herum drehen positiv gezählt werden und beim links herum negativ. Sobald dann ein wert von z.B. +200sec. oder -200sec erreicht ist soll der Rotor 200sec. in die andere Richtung gedreht werden um die Kabel wieder abzuwickeln. Wie kann ich das programmieren? Mein Hauptproblem ist die Erfassung der Nettolaufzeit, weil die Laufzeit sich in sehr viele kurze Abschnitte aufteilt.

Danke im Voraus für die Hilfe.

Das wird auf Dauer nicht funktionieren, da die Drehbewegung mit dem Anlaufen langsamer ist, als bei laufender Bewegung.
Wenn Du noch einen weiteren Sensor (Reed, Lichtschranke) verwenden könntest, um die tatsächliche Position nach einer Umdrehung festzustellen, würde das genauer werden.

Ansonsten wäre mein Ansatz:

#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int Lichtschranke1 = 3; // Azimuthregelung
int Lichtschranke2 = 6; // Azimuthregelung
int Lichtschrankenstatus1 = 0; // Azimuthregelung
int Lichtschrankenstatus2 = 0; // Azimuthregelung
int Azmr = 9; //Azimuth rechts drehen
int Azml = 10; //Azimuth links drehen
float Wartezeit1 = 0; //Dauer Lichtschranke1 high
float Wartezeit2 = 0; //Dauer Lichtschranke2 high
int Startzeit = 1000; //Dauer bis Azimuthantrieb reagiert
int32_t laufzeit = 0;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  //  lcd.init();
  lcd.backlight();
  pinMode (Lichtschranke1, INPUT);
  pinMode (Lichtschranke2, INPUT);
  pinMode (Azmr, OUTPUT);
  pinMode (Azml, OUTPUT);
}
void loop ()
{
  // Azimutsteuerung
  Lichtschrankenstatus1 = digitalRead(Lichtschranke1);
  if (Lichtschrankenstatus1 == HIGH)
  {
    Wartezeit1++;
  }
  if (Lichtschrankenstatus1 == LOW)
  {
    Wartezeit1 = 0;
  }
  Lichtschrankenstatus2 = digitalRead(Lichtschranke2);
  if (Lichtschrankenstatus2 == HIGH)
  {
    Wartezeit2++;
  }
  if (Lichtschrankenstatus2 == LOW)
  {
    Wartezeit2 = 0;
  }
  if (Wartezeit1 > Startzeit)
  {
    digitalWrite(Azmr, LOW);
  }
  if (Wartezeit1 < Startzeit)
  {
    digitalWrite(Azmr, HIGH);
  }
  if (Wartezeit2 > Startzeit)
  {
    digitalWrite(Azml, LOW);
  }
  if (Wartezeit2 < Startzeit)
  {
    digitalWrite(Azml, HIGH);
  }
  delay (1);
  erfassung();
  rueckstellen();
}
void erfassung()
{
  enum {stop, rechts, links};
  static byte richtung = stop;
  static uint32_t startBewegung = 0;
  if (digitalRead(Azmr) == HIGH && digitalRead(Azml) == HIGH)  // Antriebe sind aus
  {
    if (richtung == rechts)                                    // Vorher war Antrieb an
    { laufzeit += millis() - startBewegung; }                  // Richtung Zeit aufaddieren
    else if (richtung == links)
    { laufzeit -= millis() - startBewegung; }                  // Richtung Zeit abziehen
    richtung = stop;                                           // Richtung löschen
  }
  if (digitalRead(Azmr))                                       // Richtung Bewegung festgestellt
  {
    if (richtung == stop)                                      // und vorher keine Bewegung
    {
      startBewegung = millis();                                // Merken
      richtung = rechts;                                       // Bewegung merken
    }
  }
  if (digitalRead(Azml))
  {
    if (richtung == stop)
    {
      startBewegung = millis();
      richtung = links;
    }
  }
}

void rueckstellen()
{
  if (laufzeit > 200)                                          // aufgewickelt Richtung rechts?
  {
    digitalWrite(Azml, LOW);                                   // zurück drehen
    delay(laufzeit);                                           // solange aufgewickelt wurde
    digitalWrite(Azml, HIGH);
    laufzeit = 0;                                              // Wickelzeit zurücksetzen
  }
  else if (laufzeit < -200)
  {
    digitalWrite(Azmr, LOW);
    delay(laufzeit);
    digitalWrite(Azmr, HIGH);
    laufzeit = 0;
  }
}

vollkommen rudimentär und ohne Anspruch, das das funktioniert.

Danke für den Sketch und den Hinweis auf die Genauigkeit. Ich hatte mal geplant über einen Greycode die genaue Position zu ermitteln. Das Problem für mich war einmal der Einbau des Greycode im Windrad, und die Drehrichtungserkennung. Die Drehrichtungserkennung ist mit der Laufzeitmessung sehr einfach.

Vom Prinzip her könntest Du genauso wie oben die Laufzeit erfassen.
Aber dann, wenn die Laufzeit erreicht ist testen wann der Sensor auslöst und die Drehrichtung ändern, bis der Sensor erneut auslöst.

Spart Dir graycode udnirgendwelche Mimiken, aber Du bekommst immer den absoluten "Nullpunkt".

Nachtrag:
Das mit dem zusätzlichem Sensor zur Nullstellung könnte so aussehen:

#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int Lichtschranke1 = 3; // Azimuthregelung
int Lichtschranke2 = 6; // Azimuthregelung
int Lichtschrankenstatus1 = 0; // Azimuthregelung
int Lichtschrankenstatus2 = 0; // Azimuthregelung
int Azmr = 9; //Azimuth rechts drehen
int Azml = 10; //Azimuth links drehen
float Wartezeit1 = 0; //Dauer Lichtschranke1 high
float Wartezeit2 = 0; //Dauer Lichtschranke2 high
int Startzeit = 1000; //Dauer bis Azimuthantrieb reagiert
int32_t laufzeit = 0;
const byte nullSensor = 7;

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  pinMode (Lichtschranke1, INPUT);
  pinMode (Lichtschranke2, INPUT);
  pinMode (Azmr, OUTPUT);
  pinMode (Azml, OUTPUT);
}
void loop ()
{
  // Azimutsteuerung
  Lichtschrankenstatus1 = digitalRead(Lichtschranke1);
  if (Lichtschrankenstatus1 == HIGH)
  {
    Wartezeit1++;
  }
  if (Lichtschrankenstatus1 == LOW)
  {
    Wartezeit1 = 0;
  }
  Lichtschrankenstatus2 = digitalRead(Lichtschranke2);
  if (Lichtschrankenstatus2 == HIGH)
  {
    Wartezeit2++;
  }
  if (Lichtschrankenstatus2 == LOW)
  {
    Wartezeit2 = 0;
  }
  if (Wartezeit1 > Startzeit)
  {
    digitalWrite(Azmr, LOW);
  }
  if (Wartezeit1 < Startzeit)
  {
    digitalWrite(Azmr, HIGH);
  }
  if (Wartezeit2 > Startzeit)
  {
    digitalWrite(Azml, LOW);
  }
  if (Wartezeit2 < Startzeit)
  {
    digitalWrite(Azml, HIGH);
  }
  delay (1);
  erfassung();
  rueckstellen();
}
void erfassung()
{
  enum {stop, rechts, links};
  static byte richtung = stop;
  static uint32_t startBewegung = 0;
  if (digitalRead(Azmr) == HIGH && digitalRead(Azml) == HIGH)  // Antriebe sind aus
  {
    if (richtung == rechts)                                    // Vorher war Antrieb an
    { laufzeit += millis() - startBewegung; }                  // Richtung Zeit aufaddieren
    else if (richtung == links)
    { laufzeit -= millis() - startBewegung; }                  // Richtung Zeit abziehen
    richtung = stop;                                           // Richtung löschen
  }
  if (digitalRead(Azmr))                                       // Richtung Bewegung festgestellt
  {
    if (richtung == stop)                                      // und vorher keine Bewegung
    {
      startBewegung = millis();                                // Merken
      richtung = rechts;                                       // Bewegung merken
    }
  }
  if (digitalRead(Azml))
  {
    if (richtung == stop)
    {
      startBewegung = millis();
      richtung = links;
    }
  }
}

void rueckstellen()
{
  bool isStarted = false;
  if (digitalRead(nullSensor) == LOW)
  {
    if (laufzeit > 200)                                          // aufgewickelt Richtung rechts?
    {
      digitalWrite(Azml, LOW);                                   // zurück drehen
      isStarted = true;                                          // merken
    }
    else if (laufzeit < -200)
    {
      digitalWrite(Azmr, LOW);
      isStarted = true;
    }
  }
  if (isStarted)                                                 // zurückstellen ausgelöst
  {
    delay(5);                                                    // warten, bis der Sensor frei ist
    while (digitalRead(nullSensor) == HIGH) {}                   // warte, bis der Sensor wieder erreicht ist
    digitalWrite(Azml, HIGH);                                    // alles zurück stellen
    digitalWrite(Azmr, HIGH);
    isStarted = false;
    laufzeit = 0;
  }
}

Hallo,
wenn ich das Problem richtig verstanden habe, geht es im Wesentlichen um das sich Aufwickeln der Leitungen durch Neuausrichtung, oder?
Mit der Zeitmessmethode besteht doch immer die Gefahr, dass wenn der Wind den Motor bei der Ausrichtung unterstützt, die Zeiten zu sehr varieren, oder? Das könnte sich unglücklich aufsummieren.

Es wäre in jeden Fall sinnvoll, die Drehung selbst zu erfassen, denke ich. Das ginge recht einfach mit zwei Magneten, die an gegenüberliegenden Seiten der Welle angebracht sind und an einem HAL-Sensor vorbeilaufen Bei gegensätzlicher Polung würde, sich die Position und Rotationsrichtung der Welle auf eine halbe Umdrehung genau erkennen lassen.

mk

Das zweite Magnet "gegenüber" ist überflüssig.
Es nutzt ihm nichts, denn das WR nur um eine halbe Umdrehung zurückzustellen macht keinen Sinn.
Man könnte diesen dicht neben den ersten setzen, um die Richtung der laufenden Bewegung festzustellen.
Aber das macht auch das auslesen der Pins für den Antrieb.

Ich meinte eigentlich, mit zwei gegenüberliegenden Magneten die Anzahl der Halbdrehungen in die jeweilige Richtung registrieren zu können. Wenn nur ganze Drehungen gezählt werden müssen, hast du nat. Recht.

Der Mast ist 9m hoch, deshalb sind 5-10 Umdrehungen in eine Richtung schon verkraftbar, es muss also nicht jede halbe Umdrehung gemessen werden.

Das Problem ist, dass ich für einen weiteren Sensor keine Ader in meiner 16 adrigen Steuerleitung mehr frei habe. Auch deshalb kam die Idee der Zeitmessung.

Was machst Du mit den 16Adern?
Ich bräuchte 4.
Nicht eine mehr.
Als Verbindung: +5V, GND, und 2 Drähte für RS-485 zur Übertragung der gesamten Zustände.
Wenn es sein muss, auch gerne noch eine zweite RS-485, die direkt an RX/TX geht.
Macht also 6.

Die Steuerleitung ist ja nicht nur für den Azimut. Da brauche ich 6 für die Lichtschranke, und 2 für den 24V Antrieb. Dann noch 3 für die Drehzahlmessung , 3 für den Pitchmotor und 2 für die Rückmeldung der Blattstellung (Poti).

Ich kann hier vielleicht ein Paar 5V und 0V Adern zusammenfassen um noch 2 Adern frei zu bekommen. Habe für eine einfachere Fehlersuche erstmal alles einzeln nach oben gelegt.

...
Ich bin davon ausgegangen, das der Controller später oben mit eingebaut ist.
Also Fehler meinerseits.

Mit der Drehzahlmessung habe ich auch noch ein kleines Problem.


#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

float puls = 7;               // Pulseingang Drehzahlmessung
int red = 13;                 // Regelausgang Drehzahl -
int green =8;                 // Regelausgang Drehzahl +
const int analogInPin = A0;    // Eingang Rückmeldung Blattstellung
float N;                      
unsigned long T;
unsigned long time;
int messung = 2;             // Messdauer Sec.
int maxdrehzahl = 170;
int mindrehzahl = 165;
int sensorValue = 0;        // Rückmeldesignal Blattstellung         
int outputValue = 0;        // Ausgabe Rückmeldung Blattstellung
const int chipSelect = 10;


void setup() {

  
  // put your setup code here, to run once:
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(puls, INPUT);
pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
T = messung*1e6;
char outputValue;
}

void loop() {
  // put your main code here, to run repeatedly:
  //Rückmeldung Blattstellung

sensorValue = analogRead(analogInPin);
outputValue = map (sensorValue, 0, 1023, 0, 100);

//Drehzahlmessung und Pitchregelung
  
float drehzahl = ((N / messung/6)*10);
N=0; time = micros();

Serial.print(drehzahl,0);
Serial.print(" U/min \t");
Serial.print(outputValue);
Serial.println(" %");

do
{if (pulseIn(puls, HIGH)>0) N++;
}while ( micros() < (time+T) );

if(drehzahl> maxdrehzahl){
  digitalWrite(red, LOW);
}
  if (drehzahl < maxdrehzahl){
  digitalWrite(red, HIGH);
}
if(drehzahl < mindrehzahl) {
  digitalWrite (green, LOW);
}
if (drehzahl> mindrehzahl){
  digitalWrite (green, HIGH);



// LCD Ausgabe
  
}
lcd.setCursor(0,0);
if (drehzahl <100)lcd.print("0");
if (drehzahl <10) lcd.print("0");
lcd.print(drehzahl,0);
lcd.setCursor(3,0);
lcd.print(" U/min");
lcd.setCursor(0,1);
if (outputValue <100)lcd.print("0");
if (outputValue <10) lcd.print("0");
lcd.print(outputValue);
lcd.setCursor(3,1);
lcd.print("% Blattst.");
````Vorformatierter Text`

Zur Zeit zähle ich die Pulse, die der Sensor innerhalb von 2 Sekunden zum Controller schickt (6 Pulse pro Umdrehung). Bei einer Windböe habe ich den Eindruck, dass er zu langsam reagiert. Vielleicht wäre es besser die Zeit zwischen zwei Kontakten zu messen. Außerdem hatte ich im gleichen Sketch die Azimutsteuerung und einen Datenlogger einprogrammiert, was die Reaktionszeit dann noch weiter verschlechtert hat. Aus diesem Grund läuft die Azimutsteuerung jetzt auf einem zweiten Board. Den Datenlogger würde ich gerne wieder auf das Board mit der Drehzahlmessung setzen. 
Wie bekomme ich das hin, ohne die Reaktionszeit der Steuerung zu verlangsamen und gleichzeitig nicht eine riesige Datenmengen zu generieren, also max. alle 10sec einen Wert zu loggen.

Editiere mal den Post. Markiere den Code und klicke oben auf den </> Button.

#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);

float puls = 7;               // Pulseingang Drehzahlmessung
int red = 13;                 // Regelausgang Drehzahl -
int green =8;                 // Regelausgang Drehzahl +
const int analogInPin = A0;    // Eingang Rückmeldung Blattstellung
float N;                      
unsigned long T;
unsigned long time;
int messung = 2;             // Messdauer Sec.
int maxdrehzahl = 170;
int mindrehzahl = 165;
int sensorValue = 0;        // Rückmeldesignal Blattstellung         
int outputValue = 0;        // Ausgabe Rückmeldung Blattstellung
const int chipSelect = 10;


void setup() {

  
  // put your setup code here, to run once:
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(puls, INPUT);
pinMode (8, OUTPUT);
pinMode (9, OUTPUT);
T = messung*1e6;
char outputValue;
}

void loop() {
  // put your main code here, to run repeatedly:
  //Rückmeldung Blattstellung

sensorValue = analogRead(analogInPin);
outputValue = map (sensorValue, 0, 1023, 0, 100);

//Drehzahlmessung und Pitchregelung
  
float drehzahl = ((N / messung/6)*10);
N=0; time = micros();

Serial.print(drehzahl,0);
Serial.print(" U/min \t");
Serial.print(outputValue);
Serial.println(" %");

do
{if (pulseIn(puls, HIGH)>0) N++;
}while ( micros() < (time+T) );

if(drehzahl> maxdrehzahl){
  digitalWrite(red, LOW);
}
  if (drehzahl < maxdrehzahl){
  digitalWrite(red, HIGH);
}
if(drehzahl < mindrehzahl) {
  digitalWrite (green, LOW);
}
if (drehzahl> mindrehzahl){
  digitalWrite (green, HIGH);



// LCD Ausgabe
  
}
lcd.setCursor(0,0);
if (drehzahl <100)lcd.print("0");
if (drehzahl <10) lcd.print("0");
lcd.print(drehzahl,0);
lcd.setCursor(3,0);
lcd.print(" U/min");
lcd.setCursor(0,1);
if (outputValue <100)lcd.print("0");
if (outputValue <10) lcd.print("0");
lcd.print(outputValue);
lcd.setCursor(3,1);
lcd.print("% Blattst.");
tippe oder füge den Code hier ein

Ich denke, Du hast gleich mehrere Baustellen.
Einen Teil habe ich Dir mal abgenommen, nämlich das auftrennen des Codes in einzelne Funktionen, damit man ein wenig Übersicht bekommt.

Was mir als erstes aufgefallen ist:

Wie ist der Pin beschalten?
Und mit welcher Anzahl Impulse pro Sekunde rechnest Du denn als Obergrenze bei einer Windgeschwindigkeit von 140Kmh?
Die Messfunktion würde ich mit einem Interrupt lösen.
Noch zwei Fragen: Warum drehzahl als float, wenn die doch als ganze Zahl ausgegegebn wird... Und was passiert bei den led's, wenn drehzahl==maxdrehzahl, bzw. mindrehzahl;

#include <SD.h>
#include <SPI.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte puls = 7;               // Pulseingang Drehzahlmessung
const byte green = 8;                // Regelausgang Drehzahl +
const byte chipSelect = 10;
const byte red = 13;                 // Regelausgang Drehzahl -
const byte analogInPin = A0;    // Eingang Rückmeldung Blattstellung

float N;
float drehzahl;
unsigned long T;
unsigned long time;
unsigned int messung = 2;             // Messdauer Sec.
unsigned int maxdrehzahl = 170;
unsigned int mindrehzahl = 165;
unsigned int outputValue = 0;        // Ausgabe Rückmeldung Blattstellung

void setup()
{
  Serial.begin(9600);
  //lcd.init();
  lcd.backlight();
  pinMode(puls, INPUT);
  pinMode (8, OUTPUT);
  pinMode (9, OUTPUT);
  T = messung * 1e6;
  char outputValue;
}


void loop()
{
  bladePosition();
  rotorSpeed();
  lcdPrint();
  ledPrint();
  serialDebug();
}


void bladePosition()
{
  //Rückmeldung Blattstellung
  unsigned int sensorValue = 0;        // Rückmeldesignal Blattstellung
  sensorValue = analogRead(analogInPin);
  outputValue = map (sensorValue, 0, 1023, 0, 100);
}

void rotorSpeed()
{
  //Drehzahlmessung und Pitchregelung
  drehzahl = ((N / messung / 6) * 10);
  N = 0; time = micros();
  do
  {
    if (pulseIn(puls, HIGH) > 0)
    {
      N++;
    }
  }
  while ( micros() < (time + T) );
}
//
void lcdPrint()
{
  static uint16_t lastDrehzahl = 0;
  static uint16_t lastBladePosition = 0;
  if (lastDrehzahl != drehzahl)
  {
    lcd.setCursor(0, 0);
    if (drehzahl < 100)
    {
      lcd.print(0);
    }
    if (drehzahl < 10)
    {
      lcd.print(0);
    }
    lcd.print(drehzahl, 0);
    lcd.setCursor(3, 0);
    lcd.print(" U/min");
    lastDrehzahl = drehzahl;
  }
  if (lastBladePosition != outputValue)
  {
    lcd.setCursor(0, 1);
    if (outputValue < 100)
    {
      lcd.print(0);
    }
    if (outputValue < 10)
    {
      lcd.print(0);
    }
    lcd.print(outputValue);
    lcd.setCursor(3, 1);
    lcd.print("% Blattst.");
    lastBladePosition = outputValue;
  }
}
//
void ledPrint()
{
  if (drehzahl > maxdrehzahl)
  {
    digitalWrite(red, LOW);
  }
  if (drehzahl < maxdrehzahl)
  {
    digitalWrite(red, HIGH);
  }
  if (drehzahl < mindrehzahl)
  {
    digitalWrite (green, LOW);
  }
  if (drehzahl > mindrehzahl)
  {
    digitalWrite (green, HIGH);
  }
}
//
void serialDebug()
{
  const uint32_t intervall = 1000; // zeit in ms
  static uint32_t lastAusgabe = 0;
  if (millis() - lastAusgabe >= intervall)
  {
    Serial.print(drehzahl, 0);
    Serial.print(" U/min \t");
    Serial.print(outputValue);
    Serial.println(" %");
    lastAusgabe = millis();
  }
}

Bitte drauf achten, wem Du antwortest. Ich bin der Falsche.

Code formatieren und entsprechend einstelle wurde dir ja bereits gesagt. ich würde zudem noch dazu raten, dich mit eigenen Funktionen zu beschäftigen und nicht alles nahtlos in der loop() abzuwerfen. Das fördert die Übersichtlichkeit.
Richtig erkannt hast du, dass du vor dem Problem stehst, Loggingintervalle und zeitkritische Ansteuerungen unter einen Hut zu bekommen. Auch dafür taugt in der IDE das Beispiel blinkwithoutdelay.
Nicht gut gelöst ist deine do-while-Konstruktion in der loop(). Zum einen ist die loop() doch bereits der Dauerläufer, zum anderen blockierst du den Programmablauf mit der pulseIn()-Abfrage unnötig.

@ my_xy_projekt

Danke für das auftrennen des Codes.

Der Pin für die Drehzahlmessung schaltet +5V.
Die Regelung soll dafür Sorgen, dass die Drehzahl des Rotors auch bei hoher Windgeschwindigkeit 300U/min, also 30Pulse pro sec. nicht übersteigt.

Ein kleiner Hinweis noch, ich hatte vor diesem Projekt keine Ahnung von Programmierung, und habe mir einzelne Sketchfetzen aus dem Internet zusammengesucht und daraus mein Sketch programmiert. Ist es ein Nachteil wenn die Drehzahl ein float wert ist? Die Bezeichnung LED red und green stammen noch aus den Tests am Steckbrett. Tatsächlich wird mit diesen Ausgängen ein Stellmotor angesteuert, der den Anstellwinkel der Rotorblätter verändert ( Pitchsteuerung). Dadurch wird der Rotor gebremst.
Was ist der Vorteil einer Drehzahlsteuerung mit Interrupt? Wie ich das verstanden habe, wird das Programm dann unterbrochen, aber warum ist das besser? Werden die anderen Abschnitte dann überhaupt noch durchgeführt, z.B. die LCD-ausgabe?

Bezüglich der Logintervalle hatte ich mir überlegt, den Datenlogger auf das Board für die Azimutsteuerung zu bauen, die Drehzahl dahin zu übertragen und dann nur alle 30 sec. loggen zu lassen. Wäre das eine machbare Lösung?

Um mal die sprachlichen Differenzen auszumerzen:
Der PIN der Drehzahlmessung (Hier PIN 7) ist ein Eingang. Der schaltet nicht.
Wenn Du den PIN nicht extern mit einem Widerstand beschaltest, dann misst Du da Mist.Was ist da als Geber verbaut? Nen Reedkontakt?
Wenn wir die Geschwindigkeit sicher haben, gehts weiter.

Es ist ein Näherungsschalter mit 24V, der ein Koppelrelais schaltet, das dann die 5V schaltet. Ich habe es mal mit einem Optokoppler versucht, aber das hat nicht geklappt. Ich würde gerne eine normale 5V Lichtschranke einsetzen, habe aber noch nichts passendes gefunden.