Drehzahlsignal auswerten - Zu hoher Lag

Hallo,

ich habe mit mittels Arduino, einer kleinen Vorschaltelektronik und einem 2004 Display mit HD4470 einen Lüftercontroller gebaut.
Ich steuer Mittels Poti die Drezahl des jeweiligen Lüfters an und lese das Drehzahlsignal aus was am Display dann ausgegeben wird.
Mein Problem ist das ich einen sehr hohen Lag habe. Drehe ich am Poti dauert es ca. 2sek bis der Lüfter hochdreht und mir das Drehzahlsignal am Display ausgegeben wird.

Soweit ich jetzt rausgefunden habe verursacht den Lag der Teil des Codes der das Drehzahlsignal auswertet und umrechnet um es zum Schluss am Display auszuegeben.
Wenn ich den Teil des Codes rausnehmen der das Signal umrechnet und ich das Drehzahlsignal roh an den Display ausgebe ist der Lag sogut wie weg.

Meine Frage an euch: Kann man den Codeteil optimieren der das Drehzahlsignal umrechnet?

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

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int fan1pwm = 10;            //FAN1 PWM-Steuersignal
int fan2pwm = 9;             //FAN2 PWM-Steuersignal
int fan3pwm = 3;             //FAN3 PWM-Steuersignal
int fan4pwm = 5;             //FAN4 PWM-Steuersignal  
int fan1sensor = 11;         //FAN1 RPM-Sensor
int fan2sensor = 12;         //FAN2 RPM-Sensor
int fan3sensor = 7;          //FAN3 RPM-Sensor
int fan4sensor = 6;          //FAN4 RPM-Sensor
unsigned long teiler1;
unsigned long teiler2;
unsigned long teiler3;
unsigned long teiler4;


void setup()
{
  pinMode(fan1pwm, OUTPUT);
  pinMode(fan2pwm, OUTPUT);
  pinMode(fan3pwm, OUTPUT);
  pinMode(fan4pwm, OUTPUT);
  pinMode(fan1sensor, INPUT_PULLUP);
  pinMode(fan2sensor, INPUT_PULLUP);
  pinMode(fan3sensor, INPUT_PULLUP);
  pinMode(fan4sensor, INPUT_PULLUP);
  
  lcd.begin(20,4);
  
  lcd.setCursor(0,0);
  lcd.print("FAN1:");
  lcd.setCursor(11,0);
  lcd.print("   ");
  lcd.setCursor(14,0);
  lcd.print("U/min");

  lcd.setCursor(0,1);
  lcd.print("FAN2:");
  lcd.setCursor(11,1);
  lcd.print("   ");
  lcd.setCursor(14,1);
  lcd.print("U/min");

  lcd.setCursor(0,2);
  lcd.print("FAN3:");
  lcd.setCursor(11,2);
  lcd.print("   ");
  lcd.setCursor(14,2);
  lcd.print("U/min");

  lcd.setCursor(0,3);
  lcd.print("FAN4:");
  lcd.setCursor(11,3);
  lcd.print("   ");
  lcd.setCursor(14,3);
  lcd.print("U/min");

}


void loop()
{

  //FAN1 Programm
  int pot1 = analogRead(A0);
  int fan_speed1 = 255 - (pot1 * (255 / 1023.0));
  analogWrite(fan1pwm,fan_speed1);
 teiler1 = pulseIn(fan1sensor, LOW);
  double drehzahl1 = 1000000/teiler1;

  lcd.setCursor(6,0);
  lcd.print(drehzahl1/4*60);
 

  //FAN2 Programm
  int pot2 = analogRead(A1);
  int fan_speed2 = 255 - (pot2 * (255 / 1023.0));
  analogWrite(fan2pwm,fan_speed2);
  teiler2 = pulseIn(fan2sensor, LOW);
  double drehzahl2 = 1000000/teiler2;

  lcd.setCursor(6,1);
  lcd.print(drehzahl2/4*60);


  //FAN3 Programm
  int pot3 = analogRead(A2);
  int fan_speed3 = 255 - (pot3 * (255 / 1023.0));
  analogWrite(fan3pwm,fan_speed3);
  teiler3 = pulseIn(fan3sensor, LOW);
  double drehzahl3 = 1000000/teiler3;

    lcd.setCursor(6,2);
    lcd.print(drehzahl3/4*60);
  

  //FAN4 Programm
  int pot4 = analogRead(A3);
  int fan_speed4 = 255 - (pot4 * (255 / 1023.0));
  analogWrite(fan4pwm,fan_speed4);
  teiler4 = pulseIn(fan4sensor, LOW);
  double drehzahl4 = 1000000/teiler4;

  lcd.setCursor(6,3);
  lcd.print(drehzahl4/4*60);
  

  delay(1);

}

pulseIn() ist blockierend, wenn kein timeout angegben ist, kann hier bis 1 Sekunde gewartet werden. Du könntest erstmal versuchen einen timeout anzugeben um die Wartezeit zu verkürzen. Sonst den Flankenwechsel selbst erfassen und mit millis oder micros die Zeit erfassen.

pulseIn() blockiert für eine Sekunde, wenn es kein Signal erkennt.

Ich denke du hast 2 Möglichkeiten:

  • Die Zeit zwischen 2 Takten zu messen.
    -> Vielleicht per Interrupts

  • Die Anzahl der Takte innerhalb einer bestimten Zeit zu zählen (z.B. 1 Sekunde)
    -> Vielleicht per Interrupts
    -> Als externen Takt an Timer

Und nicht alles in der Loop laufen lassen.
Einzelne Funktionen aufbauen, die nur bei Potiänderung durchlaufen werden.
Auch da kannst du Zeit sparen.

verursacht den Lag der Teil des Codes der das Drehzahlsignal auswertet und umrechnet um es zum Schluss am Display auszuegeben.
Wenn ich den Teil des Codes rausnehmen der das Signal umrechnet und ich das Drehzahlsignal roh an den Display ausgebe ist der Lag sogut wie weg.

In diesem Fall würden die bisherigen Tips nicht wirklich helfen.

Die Berechnung

 int fan_speedx = 255 - (potx * (255 / 1023.0));

ist zwar Mist und optimierungsfähig,
auch lcd.print(double) ist unnötig aufwendig,
aber mir scheint doch das vierfache pulseIn, entgegen deiner Beobachtung, die Hauptursache zu sein.