Flowmeter um einen Alarmausgang erweitern

Hallo, ich verwende folgenden Sketch auf einem Arduino nano. Das flowmeter dient zur überwachung meiner Spindelkühlung. Ich würde gern einen Ausgang schalten wenn der Flow unter einem bestimmten Wert fällt um zb eine Warn led angehen zu lassen. Ich bin absoluter newbie mit arduino und bin froh dass der Sketch so schon läuft. Könnte mir bitte jemand helfen? Danke

//YF-S201-Water-Flow-Sensor

#include <AceWire.h>
#include<LiquidCrystal_I2C.h>
double flow; //Water flow L/Min
int flowsensor = 2;
unsigned long currentTime;
unsigned long lastTime;
unsigned long pulse_freq;
LiquidCrystal_I2C lcd (0x27, 16, 2);
void pulse () // Interrupt function
{
pulse_freq++;
}
void setup()
{
pinMode(flowsensor, INPUT);
Serial.begin(9600);
lcd.begin();
lcd.setCursor(1,0);
lcd.print("Johnny Baier");
lcd.setCursor(1,1);
lcd.print("Presents");
attachInterrupt(0, pulse, RISING); // Setup Interrupt
currentTime = millis();
lastTime = currentTime;
}
void loop ()
{
currentTime = millis();
// Every second, calculate and print L/Min
if(currentTime >= (lastTime + 1000))
{
lastTime = currentTime;
// Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
flow = (pulse_freq / 7.5);
pulse_freq = 0; // Reset Counter
Serial.print(flow, DEC);
Serial.println(" L/Min");
lcd.clear();
lcd.setCursor(1,0);
lcd.print("Water Flow ");
lcd.setCursor(0,1);
lcd.print(flow);
lcd.setCursor(5,1);
lcd.print("L/Min");
}
}

Tipp:
Um das Auslesen des Puls Zählers solltest du einen Atomic Block legen.
volatile ist hier nicht nötig, denn der Atomic Block bringt die Memory Barrier gleich mit.

//YF-S201-Water-Flow-Sensor

#include <AceWire.h>
#include<LiquidCrystal_I2C.h>
double flow; //Water flow L/Min
int flowsensor = 2;
unsigned long currentTime;
unsigned long lastTime;
unsigned long pulse_freq;

LiquidCrystal_I2C lcd (0x27, 16, 2);

constexpr uint16_t lowWarning {100}; //
constexpr uint16_t hysterese {10};

void pulse () // Interrupt function
{
  pulse_freq++;
}

void setup()
{
  pinMode(flowsensor, INPUT);
  Serial.begin(9600);
  lcd.begin();
  lcd.setCursor(1, 0);
  lcd.print("Johnny Baier");
  lcd.setCursor(1, 1);
  lcd.print("Presents");
  attachInterrupt(0, pulse, RISING); // Setup Interrupt
  currentTime = millis();
  lastTime = currentTime;
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWite8LED - BUILTIN, LOW);
}
void loop ()
{
  currentTime = millis();
  // Every second, calculate and print L/Min
  if (currentTime >= (lastTime + 1000))
  {
    lastTime = currentTime;
    // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
    flow = (pulse_freq / 7.5);
    pulse_freq = 0; // Reset Counter
    Serial.print(flow, DEC);
    Serial.println(" L/Min");
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Water Flow ");
    lcd.setCursor(0, 1);
    lcd.print(flow);
    lcd.setCursor(5, 1);
    lcd.print("L/Min");
  }
  lowWarning();
}

void lowWarning()
{
  if (!digitalRead(LED_BUILTIN, LOW))
  {
    if (flow < lowWarning)
    {
      digitalWrite(LED_BUILTIN, HIGH);
    }
  }
  else if (flow > lowWarning + hysterese)
  {
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Sorry wenn ich frage, was meinst du genau damit?? ich hab den sketch nur kopiert. mit den Fachbegriffen kenn ich mich gar nicht aus. die Überwachung läuft ja nur wenn ich fräse.

Du musst dafür sorgen, dass du ohne Störung durch die ISR den Zähler lesen/schreiben kannst.
https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html

ok, wie würde der Befehl oder die Befehle aussehen im sketch?
my_xy_projekt hat mir hier ja schon einen überarbeiteten sketch gepostet. muss da noch was geändert werden?

Danke dir. an welchen pin wird denn die led angeschlossen?

bei 100 den wert eingeben der untergrenze ist??? Zum beispiel 10l/min??

sorry wenn ich mich so doof anstelle :smiling_face:

Ja.
Und bei hysterese den Wert, der dann auf den Einschaltwert dazu gerechnet werden muss, damit die LED wieder aus geht.

Also lowWarning bei 10 -> Hysterese 2 -> LED geht aus bei 12.

Und nein. Wir haben alle mal angefangen.

1 Like

Würde ich sonst einen solchen Vorschlag machen, so ganz ohne Sinn und Verstand, oder ohne Notwendigkeit?

Hier ein Beispiel:

Dort wird die Timerinitialisierung vor Interrupts geschützt.

wie viel Liter pro Minute tritt da als absoluter Maximalwert auf?

Sind das mehr als 30 Liter pro Minute oder weniger als 30 Liter / Minute

Sind die 10 Liter pro Minute nur ein phantasievolle Beispielzahl oder ist das die reale Untergrenze bei deren Unterschreiten du im realen Einsatz die Warn-LED einschalten möchtest?

Wenn es die reale Grenze ist. 10 L / min bedeutet 75 Impulse.
Das bedeutet man könnte mit der Impulsezählzeit
von 1 Sekunde = 1000 Millisekunden auf 250 Millisekunden heruntergehen.
Das bedeutet es würden immer noch 75 / 4 = 18 Impulse gezählt.
Die Umrechnung wäre dann auf Liter pro Minute wäre dann
7.5 / 4 = 1.875
18 / 1.875 = 9.6 Liter
Die kürzere Impulszählzeit hat den Vorteil dass man bis zu einer höheren Impulszahl mit einem byte auskommt.

Bei einer Impulszählzeit von 0,25 Sekunden kann der Maximalwert 120 Liter / Minute sein.

Ein Arduino-Nano ist ein 8 bit-microcontroller
ein einzelnes byte kann in der interruptroutine
das ist dieser Teil vom Code

void pulse () {// Interrupt function
  pulse_freq++;
}

hochgezählt werden.

Ich nehme an wenn die Warmmeldung 0,5 bis 1 Sekunde später kommt das das keine Rolle spielt. Ist das so?

@my_xy_projekt

Für eine Warnung wäre doch gut wenn die LED nicht nur eingeschaltet wird sondern blinkt. Oder wenn ein akustisches Signal ertönt. Muss schon was lautes sein während dem Fräsen aber wenn es lauter als die Fräse ist und ein wirklicher heller Blitzer blitzt dann wäre das eine gut wahrnehmbare Warnung.

vgs

Was er mit dem PIN13 macht kann er selbst entscheiden.

Wie soll man denn das jetzt verstehen?

Es muss an deinem Vorschlag nichts geändert werden weil du einen Vorschlag mit Sinn und Verstand gemacht hast?

Na klar muss an deinem Vorschlag was geändert werden weil du Vorschläge ohne Sinn und Verstand machst?

Der Sinn und Verstand von dir besteht genau darin dass du Vorschläge machst die geändert werden müssen.

Und als Beispiel führst du dann diesen Code hier an

void setT1Freq(uint32_t freq)
{
  CriticalSection
  {
    TCCR1A = 0;
    TCCR1B = 0;
    TCCR1C = 0;
    TCNT1  = 0;


    TCCR1A = _BV(COM1A0); 
    TCCR1B = _BV(CS10) | _BV(WGM12);
    OCR1A =  F_CPU/freq/2-1;
  }
}

Der ist für einen Anfänger natürlich äußerst sinnvoll und vor allem besonders leicht verständlich.

Oh man !

Dass du damit überfordert bist, verwundert mich gar nicht!

Und bist du jetzt zu hochnäsig und zu arrogant es im Detail für Anfänger verständlich zu erklären?
Kommt jetzt wieder dein Hinweis lies mal folgendes Tausendseitenwerk?
= Deine Umschreibung für RT**?

1 Like

Warum schreibst du das dann so, wenn du schon weißt dass er überfordert ist?? Weil du genau das hören willst??

Gehts dir dann irgendwie besser, wenn du wieder mal zeigen konntest um wieviel besser du bist? Brauchst du das? Ich würde mir sorgen um mich machen, wenn ich mich an sowas hochziehen müßte.

Franz

1 Like

Merke: Es dreht sich hier um 2 Personen.

Einmal der TO welcher so seine eigenen Probleme hat.

Und einem Stefan Dingen, welches in regelmäßigen Abständen aus den Büschen gehüpft kommt und meint mich blöde von der Seite anzumachen.

Da schmeißt du sie in einen Topf!
Meine Texte waren für den TO, nicht für das Stefan Dingen.
Und der Überforderte ist das Stefan Dingen!
Der TO ist hoffentlich bereit auch mal Literatur in die Hand zu nehmen.

Also die pumpe bringt 3500lpro stunde, der Flowmeter geht bis 30l die Minute. Es ist nicht so tragisch wegen der Zeit. evtl. nehme ich den Ausgang auch um das Fräsprogramm zu stoppen. Das muss ich aber erst noch ausbaldowern.

Da möchte ich noch etwas genauer nachfragen ob ich das richtig verstehe.
Die Pumpe die den Kühlschmierstoff pumpt kann bis zu 3500 L / Stunde
Das sind 3500 / 60 = 58,33 Liter pro Minute.
Sind die 3500 L / Stunde der Maximalwert den die Pumpe kann wenn die Druckverluste minimal sind?

Hast du zu der Pumpe ein Diagramm Volumenstrom / Druckerhöhung das du posten könntest?

Das Flowmeter geht bis 30 Liter pro Minute. Das heißt wenn die Druckverluste zwischen Pumpe und Flowmeter minimal sind dann könnte die Pumpe nicht nur 30 Liter pro Minute durch das Flowmeter jagen sondern über 50 Liter pro Minute?

Was treten denn im realen Aufbau für maximale Volumenströme auf?

vgs

Hi, also die Pumpe und die Spindel sind noch auf dem Weg von China nach Deutschland :face_with_peeking_eye: ich weiss nur, dass alles mit 6mm Schläuche verbunden wird und laut der Beschreibung die Pumpe eben 3500lpro Minute bringen soll. Der Sensor kommt auch noch aus China. Laut Beschreibung macht der bia zu 60l. Hab mich nochmal vergewissert. Es ist der fs300a. Im Endeffekt geht's mir darum pumpt die Pumpe oder pumpt sie nicht. Normalerweise ist da keine Überwachung verbaut. Deshalb ist der Spielraum der Daten eher sehr weit gesteckt.

Also wenn es wirklich nur um ein "Schätzeisen" geht fließt Kühlmittel ja/nein dann reicht ja in der Tat kommen da Impulse ja/nein.

Aber ne Anzeige die anzeigt wie viel Liter pro Minute fliesen denn da ist ja auch ganz nett.

Dann lässt sich das mit der Code-Ergänzung wie von @my_xy_projekt vorgeschlagen gut machen. Im Originalcode wird da ein 16bit wert zum Impulsezählen benutzt. Auf einem 8 bit microcontroller kann nicht für jede Sekunde garantiert werden, dass das Auslesen eines 16bit-Wertes immer korrekt ist, weil der Interrupt den Zahlenwert zu jedem x-beliebigem Zeitpunkt verändern kann auch genau dann wenn der Zahlenwert vom Programm ausgelesen wird.
Wenn die maximale Anzahl Zählimpulse unter 255 bleibt dann reicht da auch eine 8bit-variable und dann kann das Phänomen nicht auftreten.

Es gibt aber noch eine zweite Stelle wo Überschneidung auftreten kann
im Hauptprogramm wird die Variable auf 0 zurückgesetzt.
Da kann die ISR auch genau dazwischen funken.
Dadurch wird dann der Wert etwas verfälscht.
In deiner Anwendung ist das aber nicht so wichtig. Wenn ein Messwert alle paar Minuten mal eine gewisse Abweichung hat.
vgs