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
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..
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
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
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.
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
#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);
}
}
}
Den Sketch von dir habe ich noch nicht ganz verstanden da kümmere ich mich nächstes mal drum
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
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...
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.