Schaltblitz, RPM und andere lustige vorkommnisse

Hallo zusammen,

Ich habe ein Problem mit meinem derzeitigen Projekt. Leider macht mein UNO nicht das, was er soll.

Nach der Suche nach einer Lösung bin ich über folgenden Thread gestoßen, allerdings konnte mir dort nicht geholfen werden.

https://forum.arduino.cc/index.php?topic=521671.0

Nun zu Beschreibung des Problems: Ich möchte eine Rechteckfrequenz (Zündsignal vom Hallgeber) auswerte, umrechnen und je nach RPM verschiedene LED’s Ansteuern. Bei den Schaltschwellen 1-3 soll je eine Duo-Color LED in grün angesteuert werden, bei Schaltschwelle 4 soll bei LED’s 1-3 die rote mit an gehen und bei LED 4 direkt beide. Bei Schaltschwelle 5 sollen bei den LED’s 1-4 die grünen aus gehen und bei LED 5 rot angesteuert werden. Der Code steht auch schon soweit, allerdings Schaltet der Arduino beim übergang in loop LED’s 1-4 grün sofort ein, selbst wenn keine Frequenz am Messeingang (Pin8) anliegt.

Leider habe ich heute noch nicht die möglichkeit, eine Frequenz am Eingang zu testen. Morgen kommt ein Paket vom großen C, dann werde ich das mal testet, allerdings rein nach Logik sollte bei Freq=0 RPM=0 sein, also alle LED’s LOW.

Hier der Sketch:

#include <FreqMeasure.h>

int Ausgang2 = 2; // Digitaler Ausgang LED 1 Rot
int Ausgang3 = 3; // Digitaler Ausgang LED 1 Grün

int Ausgang4 = 4; // Digitaler Ausgang LED 2 Rot
int Ausgang5 = 5; // Digitaler Ausgang LED 2 Grün

int Ausgang6 = 6; // Digitaler Ausgang LED 3 Rot
int Ausgang7 = 7; // Digitaler Ausgang LED 3 Grün

int Ausgang9 = 9; // Digitaler Ausgang LED 4 Rot
int Ausgang10 = 10; // Digitaler Ausgang LED 4 Grün

int Ausgang11 = 11; // Digitaler Ausgang LED 5 Rot
int Ausgang12 = 12; // Digitaler Ausgang LED 5 Grün

int Schaltschwelle1 = 1000; // Drehzahl Schaltschwelle 1 - LED Gruen
int Schaltschwelle2 = 2000; // Drehzahl Schaltschwelle 2 - LED Gruen
int Schaltschwelle3 = 3000; // Drehzahl Schaltschwelle 3 - LED Gruen
int Schaltschwelle4 = 4000; // Drehzahl Schaltschwelle 4 - LED Orange
int Schaltschwelle5 = 5000; // Drehzahl Schaltschwelle 5 - LED Rot
int Schaltschwelle6 = 5500; // Drehzahl Schaltschwelle 6 = blinkende LEDs

int Zylinder = 4; // 
int Faktor = 6;   // Hier fehlt noch was zum Umrechnungsfaktor für Wasted Spark, COP, Dizzy...
int RPM = 0;

int ledBlink = LOW;
long previousMillis = 0;
long interval = 120;  // Blinkintervall in Millisekunden


void setup() {
  Serial.begin(9600);
  pinMode(Ausgang2, OUTPUT); //1rd
  pinMode(Ausgang3, OUTPUT); //1gn
  pinMode(Ausgang4, OUTPUT); //2rd
  pinMode(Ausgang5, OUTPUT); //2gn
  pinMode(Ausgang6, OUTPUT); //3rd
  pinMode(Ausgang7, OUTPUT); //3gn
  pinMode(Ausgang9, OUTPUT); //4rd
  pinMode(Ausgang10, OUTPUT); //4gn
  pinMode(Ausgang11, OUTPUT); //5rd
  pinMode(Ausgang12, OUTPUT); //5gn
  FreqMeasure.begin();
  digitalWrite (Ausgang2, HIGH); //rd 0.5
  digitalWrite (Ausgang4, HIGH);
  digitalWrite (Ausgang6, HIGH);
  digitalWrite (Ausgang9, HIGH);
  digitalWrite (Ausgang11, HIGH);
  delay(500);
  digitalWrite (Ausgang2, LOW); 
  digitalWrite (Ausgang4, LOW);
  digitalWrite (Ausgang6, LOW);
  digitalWrite (Ausgang9, LOW);
  digitalWrite (Ausgang11, LOW);
  delay(500);
  digitalWrite (Ausgang3, HIGH); //ye 0.5
  digitalWrite (Ausgang5, HIGH);
  digitalWrite (Ausgang7, HIGH);
  digitalWrite (Ausgang10, HIGH);
  digitalWrite (Ausgang12, HIGH);
  digitalWrite (Ausgang2, HIGH); 
  digitalWrite (Ausgang4, HIGH);
  digitalWrite (Ausgang6, HIGH);
  digitalWrite (Ausgang9, HIGH);
  digitalWrite (Ausgang11, HIGH);
  delay(500);
  digitalWrite (Ausgang2, LOW); 
  digitalWrite (Ausgang4, LOW);
  digitalWrite (Ausgang6, LOW);
  digitalWrite (Ausgang9, LOW);
  digitalWrite (Ausgang11, LOW);
  digitalWrite (Ausgang3, LOW);
  digitalWrite (Ausgang5, LOW);
  digitalWrite (Ausgang7, LOW);
  digitalWrite (Ausgang10, LOW);
  digitalWrite (Ausgang12, LOW);
  delay(500);
  digitalWrite (Ausgang3, HIGH); //gn 0.5
  digitalWrite (Ausgang5, HIGH);
  digitalWrite (Ausgang7, HIGH);
  digitalWrite (Ausgang10, HIGH);
  digitalWrite (Ausgang12, HIGH);
  delay(500);
  digitalWrite (Ausgang3, LOW);
  digitalWrite (Ausgang5, LOW);
  digitalWrite (Ausgang7, LOW);
  digitalWrite (Ausgang10, LOW);
  digitalWrite (Ausgang12, LOW);
  delay(1000);
}
double sum=0;
int count=0;


void loop() {
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 
    if (FreqMeasure.available()) {
      // average several reading together
      sum = sum + FreqMeasure.read();
      count = count + 1;
      if (count > 0) {
        double frequency = F_CPU / ((sum / count) * Faktor);
        Serial.print("Frequenz: ");
        Serial.println(frequency);
        Serial.print("CPU: ");
        Serial.println(F_CPU);
        Serial.print("RPM: ");
        RPM = frequency * 60;
        Serial.print(RPM);
        sum = 0;
        count = 0; }
        if (RPM < 1000) digitalWrite(Ausgang3, LOW); digitalWrite (Ausgang5, LOW); digitalWrite (Ausgang7, LOW); digitalWrite (Ausgang10, LOW);
        if (RPM >= Schaltschwelle1) { digitalWrite(Ausgang3, HIGH);
        }    else digitalWrite(Ausgang3, LOW); 
        
        if (RPM >= Schaltschwelle2) { digitalWrite(Ausgang5, HIGH);
        }    else digitalWrite(Ausgang5, LOW); 
        
        if (RPM >= Schaltschwelle3) { digitalWrite(Ausgang7, HIGH);
        }    else digitalWrite(Ausgang7, LOW); 
        
        if (RPM >= Schaltschwelle4) { digitalWrite(Ausgang9, HIGH); digitalWrite (Ausgang10, HIGH); digitalWrite (Ausgang2, HIGH); digitalWrite (Ausgang4, HIGH); digitalWrite (Ausgang6, HIGH); digitalWrite (Ausgang3, HIGH); digitalWrite (Ausgang5, HIGH); digitalWrite (Ausgang7, HIGH);
        }    else digitalWrite(Ausgang9, LOW); digitalWrite (Ausgang10, LOW); digitalWrite (Ausgang2, LOW); digitalWrite (Ausgang4, LOW); digitalWrite (Ausgang6, LOW); 
                    
        if (RPM >= Schaltschwelle5){ digitalWrite (Ausgang3, LOW); digitalWrite (Ausgang5, LOW); digitalWrite (Ausgang7, LOW); digitalWrite (Ausgang10, LOW);
        }    else digitalWrite(Ausgang12, LOW); digitalWrite (Ausgang3, HIGH); digitalWrite (Ausgang5, HIGH); digitalWrite (Ausgang7, HIGH); digitalWrite (Ausgang10, HIGH); 
        
        if (RPM >= Schaltschwelle6) 
            if (ledBlink == LOW) ledBlink = HIGH;
            else ledBlink = LOW;
            digitalWrite(Ausgang2, ledBlink); digitalWrite(Ausgang4, ledBlink); digitalWrite(Ausgang6, ledBlink); digitalWrite(Ausgang9, ledBlink); digitalWrite(Ausgang11, ledBlink);
        }    
    }
}

Der Teil vor dem loop funktioniert und ist nur prinzipiell nur eine Spielerei, damit sich die 5 LED’s ins Tacho einpassen (Golf2 bzw. Jetta2).

gut, dann direkt so:

du verwendest in deinem Code "Variablenbezeichner"

digitalWrite (Ausgang3, LOW); digitalWrite (Ausgang5, LOW); digitalWrite (Ausgang7, LOW); digitalWrite (Ausgang10, LOW); digitalWrite (Ausgang12, LOW);

die nicht zu deiner Fehlerbeschreibung passen.

"Bei Schaltschwellen 1-3 sind die ersten 3 LED's noch grün"

Das führt dazu dass ein ausstehender zweimal umdenken muss.

Ich rate dir daher

a) benenne deine Ausgänge so, dass sie so heißen was sie tun, und setze sie konstant: const int LED1_ROT_PIN = 2; b) ergänze Serial.print Ausgaben, in deinem IF-Konstrukt, damit du leichter erkennst was dein Code zur Laufzeit macht c) verwende unsigned dort wo du keine negative Zahlen brauchst. Ganz bestimmt bei deinem previousMillis aber auch an vielen anderen stellen. Und dabei schaust dir auch an, ob du überral dort wo du heute einfach int verwendest wirklich ein ganzes int (2bytes!!!) benötigst oder vieleicht ein kleinerer Datentyp auch ausreicht.

Hallo,

danke für die Antwort.
Habe den Code bezüglich der Variablen schonmal angepasst und auch schonmal die erste Serial.println im if-contruct hinzugefügt, allerdings bekomme ich keine ausgabe im Monitor über den Zustand der LED1_GRUEN.

Hier der angepasste Code:

#include <FreqMeasure.h>

const int LED1_ROT = 2; // Digitaler Ausgang LED 1 Rot
const int LED1_GRUEN = 3; // Digitaler Ausgang LED 1 Grün

const int LED2_ROT = 4; // Digitaler Ausgang LED 2 Rot
const int LED2_GRUEN = 5; // Digitaler Ausgang LED 2 Grün

const int LED3_ROT = 6; // Digitaler Ausgang LED 3 Rot
const int LED3_GRUEN = 7; // Digitaler Ausgang LED 3 Grün

const int LED4_ROT = 9; // Digitaler Ausgang LED 4 Rot
const int LED4_GRUEN = 10; // Digitaler Ausgang LED 4 Grün

const int LED5_ROT = 11; // Digitaler Ausgang LED 5 Rot
const int LED5_GRUEN = 12; // Digitaler Ausgang LED 5 Grün

int Schaltschwelle1 = 1000; // Drehzahl Schaltschwelle 1 - LED Gruen
int Schaltschwelle2 = 2000; // Drehzahl Schaltschwelle 2 - LED Gruen
int Schaltschwelle3 = 3000; // Drehzahl Schaltschwelle 3 - LED Gruen
int Schaltschwelle4 = 4000; // Drehzahl Schaltschwelle 4 - LED Orange
int Schaltschwelle5 = 5000; // Drehzahl Schaltschwelle 5 - LED Rot
int Schaltschwelle6 = 5500; // Drehzahl Schaltschwelle 6 = blinkende LEDs

int Zylinder = 4; // 
int Faktor = 6;   // Hier fehlt noch was zum Umrechnungsfaktor für Wasted Spark, COP, Dizzy...
int RPM = 0;

int ledBlink = LOW;
long previousMillis = 0;
long interval = 120;  // Blinkintervall in Millisekunden


void setup() {
  Serial.begin(9600);
  pinMode(LED1_ROT, OUTPUT); //1rd
  pinMode(LED1_GRUEN, OUTPUT); //1gn
  pinMode(LED2_ROT, OUTPUT); //2rd
  pinMode(LED2_GRUEN, OUTPUT); //2gn
  pinMode(LED3_ROT, OUTPUT); //3rd
  pinMode(LED3_GRUEN, OUTPUT); //3gn
  pinMode(LED4_ROT, OUTPUT); //4rd
  pinMode(LED4_GRUEN, OUTPUT); //4gn
  pinMode(LED5_ROT, OUTPUT); //5rd
  pinMode(LED5_GRUEN, OUTPUT); //5gn
  FreqMeasure.begin();
  digitalWrite (LED1_ROT, HIGH); //rd 0.5
  digitalWrite (LED2_ROT, HIGH);
  digitalWrite (LED3_ROT, HIGH);
  digitalWrite (LED4_ROT, HIGH);
  digitalWrite (LED5_ROT, HIGH);
  delay(500);
  digitalWrite (LED1_ROT, LOW); 
  digitalWrite (LED2_ROT, LOW);
  digitalWrite (LED3_ROT, LOW);
  digitalWrite (LED4_ROT, LOW);
  digitalWrite (LED5_ROT, LOW);
  delay(500);
  digitalWrite (LED1_ROT, HIGH); //ye 0.5
  digitalWrite (LED1_GRUEN, HIGH);
  digitalWrite (LED2_ROT, HIGH);
  digitalWrite (LED2_GRUEN, HIGH);
  digitalWrite (LED3_ROT, HIGH);
  digitalWrite (LED3_GRUEN, HIGH); 
  digitalWrite (LED4_ROT, HIGH);
  digitalWrite (LED4_GRUEN, HIGH);
  digitalWrite (LED5_ROT, HIGH);
  digitalWrite (LED5_GRUEN, HIGH);
  delay(500);
  digitalWrite (LED1_ROT, LOW);
  digitalWrite (LED1_GRUEN, LOW);
  digitalWrite (LED2_ROT, LOW);
  digitalWrite (LED2_GRUEN, LOW);
  digitalWrite (LED3_ROT, LOW);
  digitalWrite (LED3_GRUEN, LOW); 
  digitalWrite (LED4_ROT, LOW);
  digitalWrite (LED4_GRUEN, LOW);
  digitalWrite (LED5_ROT, LOW);
  digitalWrite (LED5_GRUEN, LOW);
  delay(500);
  digitalWrite (LED1_GRUEN, HIGH); //gn 0.5
  digitalWrite (LED2_GRUEN, HIGH);
  digitalWrite (LED3_GRUEN, HIGH);
  digitalWrite (LED4_GRUEN, HIGH);
  digitalWrite (LED5_GRUEN, HIGH);
  delay(500);
  digitalWrite (LED1_GRUEN, LOW);
  digitalWrite (LED2_GRUEN, LOW);
  digitalWrite (LED3_GRUEN, LOW);
  digitalWrite (LED4_GRUEN, LOW);
  digitalWrite (LED5_GRUEN, LOW);
  delay(1000);
}
double sum=0;
int count=0;


void loop() {
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 
    if (FreqMeasure.available()) {
      // average several reading together
      sum = sum + FreqMeasure.read();
      count = count + 1;
      if (count > 0) {
        double frequency = F_CPU / ((sum / count) * Faktor);
        Serial.print("Frequenz: ");
        Serial.println(frequency);
        Serial.print("CPU: ");
        Serial.println(F_CPU);
        Serial.print("RPM: ");
        RPM = frequency * 60;
        Serial.print(RPM);
        sum = 0;
        count = 0; }
        if (RPM < 1000) digitalWrite(LED1_GRUEN, LOW); digitalWrite (LED2_GRUEN, LOW); digitalWrite (LED3_GRUEN, LOW); digitalWrite (LED4_GRUEN, LOW);
        if (RPM >= Schaltschwelle1) { digitalWrite(LED1_GRUEN, HIGH);
        }    else digitalWrite(LED1_GRUEN, LOW); 
        Serial.println(LED1_GRUEN);
        if (RPM >= Schaltschwelle2) { digitalWrite(LED2_GRUEN, HIGH);
        }    else digitalWrite(LED2_GRUEN, LOW); 
        
        if (RPM >= Schaltschwelle3) { digitalWrite(LED3_GRUEN, HIGH);
        }    else digitalWrite(LED3_GRUEN, LOW); 
        
        if (RPM >= Schaltschwelle4) { digitalWrite(LED1_ROT, HIGH); digitalWrite (LED2_ROT, HIGH); digitalWrite (LED3_ROT, HIGH); digitalWrite (LED4_ROT, HIGH); digitalWrite (LED4_GRUEN, HIGH);
        }    else digitalWrite(LED1_ROT, LOW); digitalWrite (LED2_ROT, LOW); digitalWrite (LED3_ROT, LOW); digitalWrite (LED4_GRUEN, LOW); digitalWrite (LED4_ROT, LOW); 
                    
        if (RPM >= Schaltschwelle5){ digitalWrite (LED1_GRUEN, LOW); digitalWrite (LED2_GRUEN, LOW); digitalWrite (LED3_GRUEN, LOW); digitalWrite (LED4_GRUEN, LOW);
        }    else digitalWrite(LED5_GRUEN, LOW); digitalWrite (LED4_GRUEN, HIGH); digitalWrite (LED3_GRUEN, HIGH); digitalWrite (LED2_GRUEN, HIGH); digitalWrite (LED1_GRUEN, HIGH); 
        
        if (RPM >= Schaltschwelle6) 
            if (ledBlink == LOW) ledBlink = HIGH;
            else ledBlink = LOW;
            digitalWrite(LED1_ROT, ledBlink); digitalWrite(LED2_ROT, ledBlink); digitalWrite(LED3_ROT, ledBlink); digitalWrite(LED4_ROT, ledBlink); digitalWrite(LED5_ROT, ledBlink);
        }    
    }
}

Ich muss dazu sagen, der “Grundcode” stammt nich von mir, sondern aus einem anderen Forum. Ich denke bzw. hoffe der Ersteller hat sich gedanken über die Datentypen und -größen gemacht.

Zum zwecke der Übersichtlichkeit nochmal der Fehler: Beim übergang von void setup zu void loop schalten die LED’s 1-4GRUEN ein und nicht aus, obwohl keine Frequenz anliegt.

Im Anhang ein Screenshot des Seriellen Monitors nach dem Einschalten.

LoneWulf:
allerdings bekomme ich keine ausgabe im Monitor über den Zustand der LED1_GRUEN.

dann kommt dein Code erst gar nicht dort hin.

diese Zeile kommt mir noch eigenartig vor

if (RPM < 1000) digitalWrite(LED1_GRUEN, LOW); digitalWrite (LED2_GRUEN, LOW); digitalWrite (LED3_GRUEN, LOW); digitalWrite (LED4_GRUEN, LOW);

da es keine geschleiften Klammern gibt, wird der Abschnitt ab digitalWrite (LED2_GRUEN, LOW); immer ausgeführt werden, sofern das Programm hier überhaupt vorbeikommt.

Ich kann dir das nicht debuggen, und kann dir nur raten, weitere Debug ausgaben zu ergänzen bis du den Programmablauf nachvollziehen kannst. Aktuell tut er offenbar nicht das was du willst.

Eventuell auch öfters mit STRG-T den Code formatieren, vieleicht erhöht das die Lesbarkeit.

Hi

Was denkst Du, macht folgende Code-Zeile?

        if (RPM < 1000) digitalWrite(LED1_GRUEN, LOW); digitalWrite (LED2_GRUEN, LOW); digitalWrite (LED3_GRUEN, LOW); digitalWrite (LED4_GRUEN, LOW);

Da Du an der IF keinen Code-Block { … } angehangen hast, wird nur der nächste Befehl abhängig von der IF ausgeführt.
Die darauf folgenden Befehle aber IMMER.

Ich habe Deinen Code jetzt nicht im Kopf durchgespielt, denke aber, durch die Gliederung (kannst Du noch verbessern, drück Mal STRG+T in der IDE) sieht Es so aus, daß bei dieser IF-Abfrage alle 4 Ausgänge auf LOW geschaltet werden sollen, wenn RPM<1000 ist.
Bie Deinen 93 RPM wird Das sogar auch so ausgeführt, aber nur die LED1_GRUEN wird abhängig von der Abfrage geschaltet, die anderen Drei immer, egal welcher Wert vorliegt.

Denke, bei den unteren Abfragen werden die LEDs geschaltet, als ob die höchste Drehzahl erkannt wurde.

MfG

Edit
zu langsam :wink:

postmaster-ino: Edit zu langsam ;)

OT: so geht's mir normalerweise mit Tommy ;-)

Du willst Arduino in einem PKW verwenden

Hast Du dich um einen Störungsferie und den Spezifizierung für PKW Einsatz geeignete Spannungsversorgung gekümmert?

Grüße Uwe

Danke für die Tipps, werde ich, sobald ich wieder zu Hause bin, probieren.

@Uwe, Nein, noch nicht. Bzw. Nur halbherzig. Mein erstes Interesse liegt darin, der Code zum laufen zu bringen. Spannungversorgung im Fahrzeug wird vermutlich über Stepdown realisiert, also 12V->5V. Dann hab ich keine Spitzen drin und eine stabile 5V Spannung, auch wenn ich im lastbetrieb 14V von der LiMa bekomme. Das Zündungssignal vom Hallgeber werde ich vermutlich über eine Optokoppler laufen lassen, sofern dieser die Frequenz aushält. Da müsste ich dann nochmal das Datenblatt wälzen.

Aber wie gesagt, eins nach dem anderen.

So, habe dir Gliederung verbessert, die geschwungenen Klammern hinter der IF hinzu gefügt, aber die LED's 1-4GRUEN sind immernoch HIGH sobald er in den loop springt. Wie gesagt, das setup läuft einwandfrei durch, der loop hängt. Wenn ich jetzt einen Pin in Eingang 8 stecke und diesen berühre, bekomme ich über den Monitor eine Frequenz von ca. 50 angezeigt. Aber auch dann verändern sich die LED's nicht, es bleiben immer 1-4 grün HIGH.

Hi

Die 50 werden die Netzfrequenz sein, Die Du irgendwie einfängst. Was sagen Deine ganzen Serial.print, in welcher Reihenfolge Was angegrast wird? 'Klappt immer noch nicht' ist keine ausreichend genaue Beschreibung Deines Problem.

MfG

postmaster-ino: Hi

Die 50 werden die Netzfrequenz sein, Die Du irgendwie einfängst. Was sagen Deine ganzen Serial.print, in welcher Reihenfolge Was angegrast wird? 'Klappt immer noch nicht' ist keine ausreichend genaue Beschreibung Deines Problem.

MfG

Moin,

Die ersten Prints funktionieren, zeigen mir die Eingangsfrequenz, CPU-Frequenz und errechnete RPM an. Danach soll er mit eigentlich den Status der LED1_GRUEN anzeigen, als ausgabe bekomme ich jedoch eine 3.

Mein Problem habe ich eingangs beschrieben. Ich wundere mich, dass obwohl am Mess-Eingang keine Frequenz anliegt die LED's 1-4 grün angesteuert sind (Pins 2,5,7 und 10) obwohl ja recht eindeutig beschrieben ist, dass diese aus sein sollen, wenn meine Drehzahl unter 1000 RPM ist. Und genau das ist mein Problem, dass die LED's angesteuert werden, obwohl es dafür keinen Grund gibt.

Hi

Werden ggf. Deine LEDs nur nicht wieder AUS geschaltet, weil Deine loop() hängt? Deshalb fragte ich ja auch nach den Ausgaben im Terminal (nebst aktuellem Code, sofern sich daran was verändert hat).

Da die loop() NIE stehen bleibt (... ok, bleiben soll ... delay() ist da ein Kandidat für), sollten Deine Terminal-Ausgaben in großer Anzahl und rascher Folge erfolgen. Wenn die Ausgaben ausbleiben, solltest Du ab dem Programmbereich suchen, wo die letzte Ausgabe gemacht wurde. Ggf. auch in die Ausgaben Variablen-Werte mit einbeziehen, daß Du nachvollziehen kannst, ob eine der folgenden IF-Abfragen greifen müssten - und dann schauen, warum Diese nicht greifen.

MfG

Moin,

ja, er “hängt” quasi nach dem ersten digitalWrite. Den Print des Ausgangs bekomme ich noch, aber dann hörts auf. Wenn ich den Eingangspin der FreqMeasure.h (Pin8) berühre, bekomme ich auch weitere Ausgaben über den Monitor, wenn nicht bleibt der stehen und ich bekomme keine weiteren sachen angezeigt. Auch beim starten gibt er mir nur eine Ausgabe, danach kommt nichts mehr. Allerdings sollten die LED’s doch auch nicht EIN geschaltet werden, wenn ich keine Frequenz am Eingang habe, oder liege ich da falsch?

Der loop

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    if (FreqMeasure.available()) {
      // average several reading together
      sum = sum + FreqMeasure.read();
      count = count + 1;
      if (count > 0) {
        double frequency = F_CPU / ((sum / count) * Faktor);
        Serial.print("Frequenz: ");
        Serial.println(frequency);
        Serial.print("CPU: ");
        Serial.println(F_CPU);
        Serial.print("RPM: ");
        RPM = frequency * 60;
        Serial.print(RPM);
        sum = 0;
        count = 0;
      }
      if (RPM < 1000) {
        digitalWrite(LED1_GRUEN, LOW); digitalWrite (LED2_GRUEN, LOW); digitalWrite (LED3_GRUEN, LOW); digitalWrite (LED4_GRUEN, LOW);
      }
      Serial.println (3);

läuft bis zum hier gezeigten IF, er läuft aber nicht darüber hinaus. Selbst wenn ich den Pin berühre und die Datenausgabe weiter läuft, schalten die LED’s nicht aus. Allerdings steht da nichts mehr hinter, was den loop in irgendeiner weise anhalte könnte bzw sollte.

Gruß

Hi

Das klingt so, als ob Deine Frequenz-Messung blockierend abläufäuft - wenn also Nichts Da ist, was man messen kann (keine Frequenz am Pin), wird halt drauf gewartet. Und ALLE LED, Die bereits AN sind (warum auch immer), bleiben halt an, da NIEMAND Da ist, Der Die ausschaltet - da der Code hängt/blockiert.

Vll. der Zeitpunkt, wo man sich selber um die Frequenzmessung kümmert und eben nicht darauf wartet, daß eine Lib Einem das Ergebnis dampfend und mit Streußeln garniert serviert.

MfG

Nein. Die Library blockiert nicht. Die ist intern sehr gut aufgebaut und arbeitet mit einem Timer im Input Capture Modus und einem Ringpuffer für die Werte. Besser geht es nicht wirklich

Allerdings wird nichts angezeigt wenn kein Signal anliegt, da nie ein Interrupt ausgelöst wird. Das kann man abfangen indem man einen Timeout einbaut, so dass man 0 ausgibt wenn available() eine bestimmte Zeit lang false ist

Man sollte sich auch darüber im Klaren sein, dass das mit den millis() nur das Auslesen des Ringpuffers verzögert und nicht die Messungen. Die Messungen finden direkt nacheinander im Hintergrund statt. Das wird bei so geringen Intervallzeiten aber kein Problem sein

Die Frequenz muss man übrigens nicht selbst ausrechnen. Dafür gibt es countToFrequency(uint32_t count)

Serenifly: Nein. Die Library blockiert nicht. Die ist intern sehr gut aufgebaut und arbeitet mit einem Timer im Input Capture Modus und einem Ringpuffer für die Werte. Besser geht es nicht wirklich

Allerdings wird nichts angezeigt wenn kein Signal anliegt, da nie ein Interrupt ausgelöst wird. Das kann man abfangen indem man einen Timeout einbaut, so dass man 0 ausgibt wenn available() eine bestimmte Zeit lang false ist

Man sollte sich auch darüber im Klaren sein, dass das mit den millis() nur das Auslesen des Ringpuffers verzögert und nicht die Messungen. Die Messungen finden direkt nacheinander im Hintergrund statt. Das wird bei so geringen Intervallzeiten aber kein Problem sein

Die Frequenz muss man übrigens nicht selbst ausrechnen. Dafür gibt es countToFrequency(uint32_t count)

Hi,

Danke für den Tipp mit dem Timeout, das werd ich heute Nachmittag mal testen. Das mit dem ausrechnen... naja, gut, prinzipiell galt es erstmal die Frequenz des Hallgebersignals für die Tests zu ermitteln. Das ist aber mittlerweile abgehakt, sodass ich mich jetzt voll aufs testen konzentrieren kann. Bin gespannt.

So, ich wieder.

Nachdem heute Messstrippen und andere Spielzeuge vom großen C angekommen sind, mal schnell eine Frequenz auf den Pin 8 gelegt und siehe da, der serial Monitor spuckt am laufenden Band Daten aus. Allerdings verändern sich die LED's immer noch nicht. Heißt ja praktisch, der loop (zur erinnerung:)

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    if (FreqMeasure.available()) {
      // average several reading together
      sum = sum + FreqMeasure.read();
      count = count + 1;
      if (count > 0) {
        double frequency = F_CPU / ((sum / count) * Faktor);
        Serial.print("Frequenz: ");
        Serial.println(frequency);
        Serial.print("CPU: ");
        Serial.println(F_CPU);
        Serial.print("RPM: ");
        RPM = frequency * 60;
        Serial.print(RPM);
        sum = 0;
        count = 0;
      }
      Serial.println (3);
      if (RPM >= Schaltschwelle1) {
        digitalWrite(LED1_GRUEN, HIGH);
      }    else digitalWrite(LED1_GRUEN, LOW);
      Serial.println(LED1_GRUEN);
      if (RPM >= Schaltschwelle2) {
        digitalWrite(LED2_GRUEN, HIGH);
      }    else digitalWrite(LED2_GRUEN, LOW);

      if (RPM >= Schaltschwelle3) {
        digitalWrite(LED3_GRUEN, HIGH);
      }    else digitalWrite(LED3_GRUEN, LOW);

      if (RPM >= Schaltschwelle4) {
        digitalWrite(LED1_ROT, HIGH); digitalWrite (LED2_ROT, HIGH); digitalWrite (LED3_ROT, HIGH); digitalWrite (LED4_ROT, HIGH); digitalWrite (LED4_GRUEN, HIGH);
      }    else digitalWrite(LED1_ROT, LOW); digitalWrite (LED2_ROT, LOW); digitalWrite (LED3_ROT, LOW); digitalWrite (LED4_GRUEN, LOW); digitalWrite (LED4_ROT, LOW);

      if (RPM >= Schaltschwelle5) {
        digitalWrite (LED1_GRUEN, LOW); digitalWrite (LED2_GRUEN, LOW); digitalWrite (LED3_GRUEN, LOW); digitalWrite (LED4_GRUEN, LOW);
      }    else digitalWrite(LED5_GRUEN, LOW); digitalWrite (LED4_GRUEN, HIGH); digitalWrite (LED3_GRUEN, HIGH); digitalWrite (LED2_GRUEN, HIGH); digitalWrite (LED1_GRUEN, HIGH);

      if (RPM >= Schaltschwelle6)
        if (ledBlink == LOW) ledBlink = HIGH;
        else ledBlink = LOW;
      digitalWrite(LED1_ROT, ledBlink); digitalWrite(LED2_ROT, ledBlink); digitalWrite(LED3_ROT, ledBlink); digitalWrite(LED4_ROT, ledBlink); digitalWrite(LED5_ROT, ledBlink);
    }
  }
}

bleibt bei if (RPM >= Schaltschwelle1)[...] "hängen", bzw er führt die Funktion nicht aus. Er schmeißt mir im Monitor allerdings noch das Serial.println(LED1_GRUEN) raus. Aber er führt halt die if-funktion nicht korrekt aus, also die LED's 1-4GRUEN leuchten dauerhaft, egal welche Frequenz am Eingang anliegt.

Wenn du in if-else mehrere Zeilen ausführen willst brauchst du Scope-Blöcke mit { }. Ansonsten wird nur das erste Statement konditional ausgeführt und die anderen immer

Serenifly: Wenn du in if-else mehrere Zeilen ausführen willst brauchst du Scope-Blöcke mit { }. Ansonsten wird nur das erste Statement konditional ausgeführt und die anderen immer

Gib mir bitte mal ein kurzes Beispiel dafür. Kann mir das gerade nich so wirklich vorstelle, vorallem, weil ich den Wald vor lauter Bäumen nicht mehr sehe... :(

if (...)
{
}
else
{
}