Anfängerproblem if Schlaufe

Hallo zusammen

Ich habe ein Problem mit den Basics bin aber auch noch blutiger Anfänger

Ich Messe über die FreqCount Libary eine Frequenz diese Möchte ich gerne 5 mal messen und darüber einen Schnitt ziehen. Da ich das über mehrere Sensoren machen will welche ich per Multiplexer ansteuere schreibe ich die Werte in ein Array.

Das Problem ist das jetzt nur die erste Messung ausgeführt wird und die zweite nicht was natürlich ein Anfängerproblem sein wird aber welches ich trotzdem lösen muss :smiley:

hier der verwendete Code

#include <FreqCount.h>

int Messung1[] = {0};
int Messung2[] = {0};
int Messung3[] = {0};
int Messung4[] = {0};
int Messung5[] = {0};
int Schnitt [] = {0};

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  if (FreqCount.available()) {
    unsigned long Messung1 = FreqCount.read();
    Serial.print ("Messung 1 ");
    Serial.println(Messung1);
   if (FreqCount.available()) {
    unsigned long Messung2 = FreqCount.read();
    Serial.print ("Messung 2 ");
    Serial.println(Messung2);
    
    } 
  }
  
}

Messung 3,4 und 5 hab ich natürliuch noch nicht geschrieben da ich wie ihr seht schon an zwei Messungen scheitere.. :smiley:

Den Sinn von Arrays hast du irgendwie auch nicht verstanden :slight_smile:

Ich möchte danach Das selbe für sensor 2,3 etc. machen deswegen hätte ich gedacht ich nehme die einzelnen Messungen Vertikal damit ich danach die einzelnen Sensoren Horizontal nehmen kann. Das ich ein Array machen kann im Code nur für die Messungen ist mir schon klar nur weiss ich noch nicht wirklich wo ich das hinpacken soll... ist das so falsch?

Anders herum. Alle Messungen eines Sensors horizontal. Also int messung[5]

Für mehrere Sensoren nimmst du am besten ein zwei-dimensionales Array. Dann kann man in beide Richtungen iterieren.

Das Problem mit deinem Code ist, dass fast immer nur die erste Abfrage zutrifft. Die zweite ist immer falsch. Es sei denn genau dazwischen ist gerade mal eine Messung fertig ist. Dazu solltest du dir mal anschauen was FreqCount überhaupt macht. Das arbeitet mit einer Torzeit und misst die Impulse dazwischen. Es dauert also einige Zeit bis wieder ein Ergebnis da ist:
https://www.pjrc.com/teensy/td_libs_FreqCount.html

Es gibt keine "if-Schleife" (nicht Schlaufe). Die Schleife ist die Loop und das reicht.
Du meinst die "if-Anweisung" und da reicht eine.

Wenn du mehrfach messen möchtest, dann kann es so funktionieren:

 if (FreqCount.available()) {
    unsigned long Messung1 = FreqCount.read();
    Serial.print ("Messung 1 ");
    Serial.println(Messung1);

// hier evtl. ein kleienes delay(10), einfach ausprobieren. 

    unsigned long Messung2 = FreqCount.read();
    Serial.print ("Messung 2 ");
    Serial.println(Messung2);
}

Alles weitere wie Serenifly schreibt auch das Problem mit der Library, die ich nicht kenne.

Edit:
Längere Pausen solltest du über millis lösen.

Ein "kleines" delay() reicht da nicht! Die Torzeit ist 1 Sekunde!

FreqCount.begin(1000);

d.h. eine Messung braucht eine ganze Sekunde und available() ist nur jede Sekunde wahr. Man muss alle zusammenhängende Messungen in ein Array schreiben und bei jedem available() den Index inkrementieren

Wenn man viele Sensoren hat sollte man da sowieso die Torzeit runter setzen sonst ist das ganze eh Schwachsinn. Kommt natürlich auf die Frequenz an die man messen will. FreqCount ist eher für höhere Frequenzen > 1kHz gedacht. Für niedrigere Frequenzen ist FreqMeasure besser. Das misst die Impulse-Länge

Sowas?

#include <FreqCount.h>

int Messungen[] = {0,0,0,0,0};
int x = 0;

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  for (x = 0; x < 6; x++) {
  if (FreqCount.available()) {
    unsigned long Messungen[x] = FreqCount.read();
    Serial.print ("Messung [x] ");
    Serial.println(Messungen[x]);
   
    } 
  } 
}

Habe aber noch einen Fehler drin (
Serial_Output:19: error: variable-sized object 'Messungen' may not be initialized

unsigned long Messungen[x] = FreqCount.read();

^

exit status 1
variable-sized object 'Messungen' may not be initialized)

Welchen ich nicht finde...

RomN:
Sowas?

Habe aber noch einen Fehler drin (
Serial_Output:19: error: variable-sized object 'Messungen' may not be initialized

unsigned long Messungen[x] = FreqCount.read();

exit status 1
variable-sized object 'Messungen' may not be initialized)

Welchen ich nicht finde...

Nimm für den Sketch bitte mal die Code-Tags und nicht Quote, dann ist der Sketch auch lesbar.

Das kannst du jetzt noch ändern. Schaltfläche </> verwenden.

Edit:
OK, erledigt.

Habe ich gerade gesehn schon geändert sorry...

Du definierst die variable "Messungen" doppelt, einmal als int Array und einmal als Long, warum ?

Hab das mal so geändert jetzt habe ich zwei Probleme...

#include <FreqCount.h>

unsigned long Messungen[] = {0,0,0,0,0};
int x = 0;

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  for (x = 0; x < 6; x++) {
  if (FreqCount.available()) {
    Messungen[x] = FreqCount.read();
    Serial.print ("Messung ");
    Serial.println(Messungen[x]);
   
    } 
  } 
}

Wie kriege ich es hin das die der Zählerwer bei SerialPrint ("Messung ") angezeigt wird?

Und noch viel schlimmer nach 16 Messungen kommen falsche Resultate

Mein Serial Monitor zeigt folgendes...

Messung 167458
Messung 166421
Messung 166265
Messung 166432
Messung 165954
Messung 160451
Messung 160797
Messung 160822
Messung 165240
Messung 166084
Messung 166047
Messung 166165
Messung 166278
Messung 166330
Messung 166110
Messung 165975
Messung 1331
Messung 1332
Messung 1331
Messung 1332
Messung 1332
Messung 1335
Messung 1332

Lerne erst mal wie man mit Arrays umgeht. Sonst wird das nie was. Dir fehlen zu viele Grundlagen. Du tippst einfach nur Code ein und hoffst dass es geht. Dann sind aber jedesmal neue Fehler drin.

Ich habe doch gesagt, dass es 1 Sekunde dauert bis available() true ist. Jede Messung dauert bei dir 1 Sekunde! Du kannst nicht ununterbrochen messen. Ich hatte auch erst daran gedacht eine for-Schleife zu nehmen, aber das geht hier einfach nicht.

Deine Array-Grenze ist auch falsch. Ein Array der Größe 5 geht von 0 bis 4

Hier ist ein allgemeines Programm dazu. Die available() Funktion gibt alle 200ms true zurück. Das ist einfach damit man ohne Sensoren, Library oder echte Messungen was sieht. Und das Ergebnis ist zufällig per random()

const int ANZAHL_MESSUNGEN = 5;
int messungen[ANZAHL_MESSUNGEN];

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  static byte index;

  if (available())
  {
    messungen[index++] = random(0, 1001);

    if (index == ANZAHL_MESSUNGEN)
    {
      index = 0;

      for (int i = 0; i < ANZAHL_MESSUNGEN; i++)
        Serial.println(messungen[i]);
      Serial.println("---");
    }
  }
}

bool available()
{
  static unsigned long previousMillis;

  if (millis() - previousMillis > 200)
  {
    previousMillis = millis();
    return true;
  }
  else
    return false;
}

Und wie gesagt: in welchem Bereich liegt deine zu messende Frequenz überhaupt? Dementsprechend musst du die Torzeit wählen oder evtl. eine andere Library verwenden.

eine for Schleife ist in diesem Zusammenhang nicht zielführend, bzw. blockierend.

Die Frequenzen liegen über 1kHz deswegen habe ich mich fürs "zählen" entschieden und nicht fürs messen. Die Torzeit ist bei 1 Sekunde da ich so nicht umrechnen muss. Was zwar kein Problem wäre... die Messwerte die ich mit dem Beispielsketch messe decken sich mit dem was ich auf dem KO sehe.

Array Grenze war ein Tippfehler

Ich gehe über die Bücher.. ich weiss dass mir Grundlagen fehlen, ich versuche anhand diesem Projekt diese zu erlernen... da es mir oft schwer fällt mit den kleinen Tutorials das Grosse ganze zu sehen... aber ihr habt mir wieder sehr geholfen. Vielen Dank

500ms Torzeit reichen eigentlich bei sowas. Da du sowieso einen Mittelwert bilden willst, kannst du z.B. 6 Messungen machen und durch 3 teilen. Oder 4 Messungen und durch 2 teilen

Es geht halt darum dass du bei X Sensoren und 5 Messungen pro Sensor eine sehr, sehr lange Reaktionszeit hast.

Das ist richtig. Ich habe für diese Messung ewigs Zeit weswegen ich die aktuell die Zeit noch nicht minimieren wollte... Ich habe nun die Fehler korrigiert und ein delay von 1000 eingefügt und es macht den Anschein zumindest auf dem Serialmonitor das ausgegeben wird was ich möchte :smiley:

#include <FreqCount.h>

unsigned long Messungen[] = {0,0,0,0,0};
int x = 0;
int Schnitt = 0;

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  for (x = 0; x < 5; x++) {
  if (FreqCount.available()) {
    Messungen[x] = FreqCount.read();
    Serial.print ("Messung ");
    Serial.print (x);
    Serial.print (" ");
    Serial.println(Messungen[x]);
    delay (1000);
   
    }    
  } 
}

Auschnitt Serialmonitor...

Messung 0 174588
Messung 1 174590
Messung 2 174587
Messung 3 174588
Messung 4 174585
Messung 0 174584
Messung 1 174583

Das ist nun ein kleiner Teilerfolg für mich :smiley:

Den Sketch von dir habe ich noch nicht ganz verstanden da kümmere ich mich nächstes mal drum :smiley:
Mir ist schon klar das ich das ganze vieleicht von einer unkoventionellen Seite angehe.. aber von der Seite hab ich bis jetzt immer am besten gelernt :smiley:

Vielen Dank!

Den Sketch von dir habe ich noch nicht ganz verstanden

Lass dich von der available() Funktion nicht verwirren. Das ist nur zum Test.

Das fragt letztlich nur ab ob eine Messung fertig ist. Wenn ja wird der Index inkrementiert. Und nach X Messungen wird alles ausgegeben. Ganz einfach.

ich kann mich nur wiederholen. Jetzt hast du es geschafft, mit der for Schleife den Arduino für alles andere zu blockieren.

So ich sitze wieder dran und habe mir den Code von Serenifly angeschaut und nun stellt sich mir eine Frage. Wenn ich mir das Beispiel von der FreqCount Libary anschaue definiere ich die Tor-Zeit mit FreqCount.begin(GateInterval);

und mit FreqCount.available();

Returns true when a new measurement is available. Only a single measurement is buffered, so it must be read before the next gating interval.

sollte diese nur True sein wenn die Torzeit abgelaufen ist.

Wiso brauche ich denn trotzdem das Delay damits funktioniert bei meinem oben geposteten Teilerfolgsskript?

Das ganze sollte ja nur laufen wenn FreqCount.available true ist...

Kann mir das jemand erklären?

Wegen der for-Schleife die endlich mal weg muss. Du hast in loop() schon eine Schleife die immer läuft!

Also kann das for weg und man fragt statt dessen per Hand ob man X Messungen gemacht hat:

if (index == ANZAHL_MESSUNGEN)
{
   index = 0;

    ...
}

Das haben wir nicht zum Spaß schon die ganze Zeit gesagt, oder weil wir for-Schleifen nicht mögen. Es gibt Anwendungen dafür, aber hier ist das völlig falsch. Ganz am Anfang hatte ich auch mal kurz gedacht "Ok, du nimmst eine for-Schleife und iterierst über das Array", aber mir ist dann sofort aufgefallen dass das nicht geht. Eben weil eine gewisse Zeit vergehen muss bis die nächste Messung vorliegt. Und statt diese Zeit mit delay() zu verplempern, lässt man einfach loop() Runden drehen. Dann kann man solange andere Dinge tun.