Hallo zusammen,
ich habe ein folgendes Problem:
Bei meiner Durchflussmessung will ich so genau wie möglich 1,0 Sekunden messen. Doch mit meinem Code ist dies nicht möglich, denn dieser misst ca. 1,4 Sekunden.
Liegt es an der Schleife, die so lange dauert? Oder an "pulseIn"?
Hab ihr andere Lösungsvorschläge?
Benutzt habe ich den Ansatz: Youtube-Video
Benutzen tue ich den Durchflusssensor von BIOtech Serie: FCH-m-PP-LC Art.Nr: 155374.
Durchflussbereich 0,015-0,8L/min.
Bei der Messung selber habe ich keine Probleme.
Code:
while (micros() - previousMicros <= 1e6) { // Zähle solange bis Differenz auf 1e6 µs = 1 Sekunde (bzw. die gewünschte Spülzeit)
Impuls = 0;
starttime = micros();
do {
if (pulseIn(SignalDurchfluss, HIGH) > 0) Impuls++;
// Serial.println(Impuls);
}
while (micros() <= (starttime + 0.25e6)); // alle positiven Impulse werden innerhalb 0,25 Sekunden gezählt
float z = Impuls * 4; // Multiplikation der Impulse mit 4, damit Impulse/1s
//Serial.println(z,DEC); // Zeigt wie viele Impulse in einer Sekunde
z = (57 * z) / 10000; // Umrechnung der Impulse/s in L/min
Q = z * 1000 * 0.85692588; // Umrechnung in mL/min mit Kalibrierungsfaktor 0,86
if (Q <= 0) {
Serial.print(Q, 2); Serial.println(" mL/min"); // Zeige 0, wenn nichts fließt
}
if (Q > 0) { // Wenn was fließt, beginne zu zählen
int k = j++; // Zähle Messwerte
Serial.print("Messwert "); Serial.println(k);
Serial.print(Q, 2); Serial.println(" mL/min");
summe = summe + Q; // Summe der Messwerte
durchschnitt = summe / k; // Durchschnitt der Messwerte
Serial.print("Durchschnitt "); Serial.print(durchschnitt, 2); Serial.print(" ml/min"); Serial.println("");
Serial.println("");
}
}
Warum nimmst Du micros, statt millis? Das wird dadurch nicht genauer. Außerdem blockiert pulseIn.
Gruß Tommy
Hi danke dir für die schnelle Antwort.
Wieso ich micros nehme hat keinen besonderen Grund...doch die Benutzung von millis hat genauso keine Wirkung auf die Zeit gezeigt.
Wie kann ich pulseIn umgehen? Bzw. wie sonst kann ich am besten die Pulse zählen?
Brauchst Du die Anzahl der Pulse oder deren Länge? PulseIn bestimmt die Länge.
Gruß Tommy
Ich muss eigentlich die Pulse zählen und ausrechnen wie viel Pulse ich in einer bestimmten Zeit hatte.
Wenn ich das richtig verstande habe, zähle ich mit pulseIn wie viele Pulse ich hatte und erhöhe somit meine Variable "Impuls" um 1.
Hab die Lösung gefunden:
Lösung: Replace pulseIn
Mit diesem Code ersetze ich pulseIn. Bekomme keine exakte Sekunde, aber bin an der Sekunde viel näher dran als davor.
/*
* Non-blocking pulseIn(): returns the pulse length in microseconds
* when the falling edge is detected. Otherwise returns 0.
*/
unsigned long read_pulse(int pin)
{
static unsigned long rising_time; // time of the rising edge
static int last_state; // previous pin state
int state = digitalRead(pin); // current pin state
unsigned long pulse_length = 0; // default return value
// On rising edge: record current time.
if (last_state == LOW && state == HIGH) {
rising_time = micros();
}
// On falling edge: report pulse length.
if (last_state == HIGH && state == LOW) {
unsigned long falling_time = micros();
pulse_length = falling_time - rising_time;
}
last_state = state;
return pulse_length;
}
Vielen Dank! Kann geclosed werden 
So misst du nur die Dauer der HIGH Phase (wie bei einem pulseIn Aufruf).
Kannst du aber leicht modifizieren, um die Zeit zwischen zwei gleichen Flanken zu bekommen.
hasiman:
Ich muss eigentlich die Pulse zählen und ausrechnen wie viel Pulse ich in einer bestimmten Zeit hatte.
Dann solltest du eher die Impulse per Interrupt zählen und halt sehen wie wie viele du davon innerhalb deiner Torzeit hast.
Und das ohne ohne while-Schleife. Du hast in loop() schon eine Schleife. Da kann man dann abfragen ob die Zeit schon vorbei ist
Hi
byte SignalPin=7 //Signal an Pin 7
uint32_t Wartezeit=1000; // eine Sekunde = 1000
setup(){
}
loop(){
static uint32_t lastmillis=millis();
if (millis()-lastmillis>=Wartezeit){
//Wartezeit ist um
Serial.print("Anzahl:");
Serial.println(anzahl);
lastmillis=millis();
anzahl=0;
}
static boolean laststate=LOW;
boolean aktstate=digitalRead(SignalPin);
if (laststate!=aktstate}
if(laststate=LOW){
//Flanke LOW->HIGH
anzahl++;
}
laststate=aktstate;
}
}
Könnte ein Ansatz sein - ungetestet
MfG