Projekt Durchflußmessung Arduino Mega 2560

Hallo Liebe Community,

Ich bin erst seit kurzen hier und bin Neuling auf dem Gebiet Arduino. Ich habe eine Frage zu meinem aktuellen Projekt und zwar mache ich eine Durchflussmessung mit 24 Kreisen (24 Sensoren). Ich verwende die PulseIn Funktion beim Sketch der die Impulse der Sensoren pro Sekunde misst. Problem hier ich muss 24 Sekunden bis alle Werte angezeigt werden - ich bin mir nicht sicher aber ich denke das geht beim Arduino nicht anders oder?
Es handelt sich dabei um digitale Vortex-Sensoren (0,9...15 l/min -> 30...388 Hz Output).

Am besten wäre es wenn ich z.B. jede Sekunde oder jede 5 Sekunden alle Werte bekomme, gibt es hier eine Möglichkeit dies zu realisieren?

Mein Größtes Problem ist jedoch die Anzeige - ich möchte gerne ein Touch-Bildschirm als Anzeige verwenden und benötige eine GUI die ich so Programmieren kann wie ich Sie möchte (bin mit der Software die ich bereits gefunden habe nicht zufrieden).
Ist es möglich mit dem Arduino dazu noch gleichzeitig bestimmte Werte über das Netzwerk zu übertragen z.B. auf eine Datenbank, sowie auch gewisse Daten auf einen USB-Stick zu speichern und später auch auslesen zu können?

Oder ist es sogar besser die Daten nur über das Netzwerk zu übertragen und dann auf dem PC zu speichern und auszuwerten?

Ist dieses Projekt überhaupt mit dem Arduino Mega 2560 realisierbar?
Mit dem Raspberry Pi habe ich mich auch schon auseinandergesetzt, jedoch muss dieser Booten, hat zu wenig Pins und der Programmieraufwand erscheint mir noch schwieriger als beim Arduino. Kurzgefasst - ich würde auf den Raspberry Pi wenn möglich verzichten.

Ich hoffe ihr könnt mir da ein bisschen weiterhelfen, bin schon verzweifelt da ich nicht weiterkomme.

Freue mich auf eure Antworten.

MfG JM

Bei deinen Wünschen nimm lieber einen RPi. Setz' / auf readonly und mounte die Partition, wo deine Daten landen sollen, als RW. "Schwieriger" ist relativ, RPi mit wiringpi ist "einfach", Shellcode am RPi ist auch "einfach". Wenn du nichts mit Linux am hut hast, ist's allerdings "schwierig"

Lies Dich mal in PinChangeInterrupts am MEGA ein, da hast Du mehr Interrupts.
Aber ein Mega reicht für 24 Pins nicht. Du solltest dann 2 Prozessoren z.B. über I2C koppeln.

Gruß Tommy

Edit: Wodurch werden Deine Impulse ausgelöst? Kontakt oder Elektronik? Bei Kontakten musst Du entprellen. Um welche Impulsabstände geht es?

So eine ähnliche Aufgabe habe ich mit einem ESP32 und einem Raspi gelöst.
ESP32 als Controller für die Sensoren, der dann alle Daten über WLAN an den Raspi sendet. 10Zoll Touch an den Raspi, Webserver und MariaDb drauf, und...
dann geht die Programmiererei auf dem Raspi erst richtig los.
Als Webserver habe ich eine Express Anwendung am laufen. Lässt sich alles mit Node.js in JavaScript programmieren.

Die Funktion Interrupts denke ich ist die bessere und schönere Lösung aber ich benötige 24 solche Pins die diese Funktion unterstützen. (Beim Mega sind es 6 Pins)

Das habe ich mit PCF8574 gelöst. Der Baustein erweitert den I²C Bus um 8 Ports und es lassen sich bis zu vier davon kaskadieren (Adresse entsprechend setzen).
IMHO gibt es auch einen PCF8575 mit 16 IO Pins.
Im wurst case (Schaltungsfehler, Überspannung) ist nur der ESP hin und nicht gleich der Raspi.
Wenn du kein WLAN verwenden willst, geht das auch über USB.

Hi

Meine Wahl wäre auch Port-Erweiterung (Port-Expander).
Die können aktiv nach GND schalten, oder (per internem PullUP) einen externen Schalter erkennen, Der nach GND schaltet.
Weiter haben die Dinger eine Interrupt-Leitung, womit Die anzeigen 'Hier hat sich was geändert' - Was ist nun Deine Aufgabe - könnte ja theoretisch sein, daß zwei der Sensoren gleichzeitig umschalten.

Bei einem der Port-Expander gab's ein Problem mit dem Rücksetzen des Interrupt - dazu hatte Tommy56 (da suchst Du ein Mal einen Post von Dem, wegen der Nummer im Nick, und findest Nichts Aktuelles ... - also 'unser' Tommy) was geschrieben, meine, sogar einen WorkArround.

MfG

Edit
'Nummer' gefunden :slight_smile:
Edit2 ... die Welt kann sooo einfach sein - einfach nach oben scrollen und die Sache wäre fertig gewesen ...

Edit3 noch hat sich kein Schuldiger freiwillig gemeldet ... also Der mit dem WorkArround :wink:

@postmater-ino: Das war nicht von mir. Ich glaube es war vom Doc.

Gruß Tommy

postmaster-ino:
Edit3 noch hat sich kein Schuldiger freiwillig gemeldet ... also Der mit dem WorkArround :wink:

Meinst Du "MCP23017 Lib Thread - zum Austoben" mit eigener Bibliothek?

Hallo,

Danke für die schnellen Antworten! Ich werde mich da mal einlesen. Ich schaue das ich zuerst mein Arduino Programm sauber hinbekomme und dann schau ich mir das mit dem WLAN - Modul an.

Ist es überhaupt möglich Sensordaten gleichzeitig abzufragen mit dem Arduino?

Mein Code bisher für 4 Sensoren (den mit 24 ist genau gleich aufgebaut nur mehr Pins) ist im Anhang:
Ich bin mir sicher das gibt es noch einiges zu optimieren :wink:

Gruß JM

DFM_Versuch_V4_2.0.ino (1.3 KB)

Setze deinen Sketch bitte hier im Forum in Code-Tags, Schaltfläche </> oben links im Editorfenster.
Dann können alle den Sketch auch lesen.
Und ja man kann quasi mehrere Sensor gleichzeitig, das heißt ganz schnell hinter einander auslesen.
Dazu muss deine Loop ohne Blockierung ganz schnell durchlaufen.

hast du die gegebenen Tipps gelesen und annähernd nachvollziehen können was die Leute dir sagen? Ich sehe davon in deinem Code nämlich nichts. Wenn du Tipps nicht verstehst, dann sollst du die Ratgeber konkret fragen.

Ob dein Code das tut was du dir vorstellst, kann ich mangels Hardware nicht prüfen, hast du es getestet?

Was mir so auffällt:

pulseIn(pin, value, timeout)

timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long.

soll heißen, dein Code blockiert in der Do while je bis zu eine Sekunde. In der Zeit verpasst du die anderen 3 Sensoren. Ich bezweifle dass du das willst.

die Pins
int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;

kannst du const machen.

Die
N1 = 0;
N2 = 0;
N3 = 0;
N4 = 0;

werden bei jedem Loop-Durchlauf neu initialisiert. Entweder lässt sie mit static überleben oder du machst sie global.

das
while( micros() < (time+T) );

kann (wird) ein Problem werden wenn micros überläuft. Schau dir das Beispiel "BlinkWithoutDelay" an und arbeite mit Zeitdifferenzen.

Generell: schau dir auch die Verwendung von Arrays an. Aktuell schreibst du alles vierfach hin, das geht schöner, oder willst du später mal deinen Code 24x mal schreiben?

ach ja, und für sowas:

//die Zahl 33,33

macht man üblicherweise auch eine Konstante und schreibt nicht 4 mal eine "Magic-Number" hin.

Drück mal STRG-T in deiner IDE ... dann rückt es die Serial.prints an die richtige Stelle.

@noiasca

Danke für die super und ausführliche Erklärung!

Ich habe mein Programm überarbeitet jedoch komme ich mit dem "Blink without delay" und "Array" nicht ganz mit und weiß nicht wie ich das umsetzen kann um Sensoren auszuwerten.

ja du hast es Richtig erkannt ich möchte nicht das ich immer eine Sekunde auf einen Wert warten muss. Meine Wunschvorstellung wäre das alle Pins gleichzeitig (minimal versetzt um Millisekunden) anfangen mit der Zeitmessung und das ich dann alle Werte nach einer Sekunde (können auch 2 Sekunden sein) angezeigt bekomme.

Momentan Arbeite ich über den Seriellen Monitor um Werte anzeigen zu lassen.

Gruß JM

int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
const float f = 33.3;

static int N1;
static int N2;
static int N3;
static int N4;

unsigned long T;          //Zeitintervall in us
unsigned long time;       //Startzeit
long unsigned int millis();

void setup() {

  Serial.begin(9600);
  pinMode(pin2, INPUT);
  pinMode(pin3, INPUT);
  pinMode(pin4, INPUT);
  pinMode(pin5, INPUT);

  T = 1000;      //Zu messende Zeit (1 Sekunde)
}

void loop() {

  time = millis();
  do {
    if (pulseIn(pin2, HIGH) > 0) N1++;
    if (pulseIn(pin3, HIGH) > 0) N2++;
    if (pulseIn(pin4, HIGH) > 0) N3++;
    if (pulseIn(pin5, HIGH) > 0) N4++;
  }
  while ( millis() < (time + T) );

  float Calc1 = N1;
  Calc1 = (Calc1 / f);

  float Calc2 = N2;
  Calc2 = (Calc2 / f);

  float Calc3 = N3;
  Calc3 = (Calc3 / f);

  float Calc4 = N4;
  Calc4 = (Calc4 / f);

  Serial.print("|");
  Serial.println(Calc1);    //Messdaten Kreislauf 1
  Serial.print("|");
  Serial.println(Calc2);    //Messdaten Kreislauf 2
  Serial.print("|");
  Serial.println(Calc3);    //Messdaten Kreislauf 3
  Serial.print("|");
  Serial.println(Calc4);    //Messdaten Kreislauf 4

}

Es ist wahrscheinlich besser, jede Messung an ihrer ersten Flanke beginnen zu lassen.
Außerdem wäre es sinnvoll, wenn Du die Dir gestellten Fragen beantworten würdest.

Gruß Tommy

@ Tommy56

Danke und wie geht das mit den Flanken messen?

Welche Fragen denn, ich denke ich habe alles beantwortet oder hattest du noch eine Spezielle Frage?

Hallo,

ich gehe mal davon aus das es sich um 24 Frequenzen handelt die gleichzeit ,verschieden und unsynchron zueinander sein können.

deine kleinste Frequenz ist 30Hz, wenn du messen willst wieviel Impulse in einer 1s agbegeben werden " Tormessung" ergibt das ein Ergebniss vo 30 oder z.B 31 . Damit hast Du eine Auflösung von etwa 3%. Reicht Dir das ? Natürlich kannst Du auch 2 oder 5s messen um da genauer zu werden. Besser währe eine Periodendauermessung über eine oder mehrere Perioden. Ob man das aber für 24 Kanäle hinbekommt mit einem Controller kann ich nicht beurteilen.

Also der Vorschlag mehrer Controller und die mittels I2C zu verbinden halte ich einen gangbaren Weg. Wenn Du 4-5 Kanäle mit einem Controller vernünftig messen kannst, hast Du 5-6 "Slaves" nötig, darüber setzt du eine zusätzlichen "Master" der die Daten sammelt und sich um die Oberfäche kümmert. Kosten sind da auch nicht viel höher, die Dinger kosten je 5-7€. Vorteil modular und mehrfach gleiche Software. Die Skalierung auf l/min würde ich auch im Master machen, letztlich wirst Du die Werte dazu ja auch über die Oberfläche eingeben wollen und dann mussen diese Werte nicht noch an die Slaves übertragen werden.

Wenn das Ganze auch noch dezentral sein soll könntest Du z.B auch Wemos D1 einsetzen und die Verbindung untereinander über WLan machen.

Heinz

HotSystems:
Und ja man kann quasi mehrere Sensor gleichzeitig, das heißt ganz schnell hinter einander auslesen.
Dazu muss deine Loop ohne Blockierung ganz schnell durchlaufen.

Tommy56:
Es ist wahrscheinlich besser, jede Messung an ihrer ersten Flanke beginnen zu lassen.

noiasca:
Generell: schau dir auch die Verwendung von Arrays an.

julmoe98:
Danke und wie geht das mit den Flanken messen?

Ausgehend von diesen Hinweisen mache ich Dir mal einen ausbaufähigen Vorschlag mit Flanken aber ohne Interrupts:

uint32_t jetzt, ausgabeMicros;
const uint32_t ausgabeIntervall = 500000;
const float f = 30000.0;

struct Impuls {
  const byte pin;
  uint32_t intervall;
  uint32_t vorher;
  bool alt, neu;
  Impuls(const byte pin) : pin(pin), intervall(0), vorher(0), alt(0), neu(0) {}

  void messen() {
    alt = neu;
    neu = digitalRead(pin);
    if (!alt && neu) {
      intervall = jetzt - vorher;
      vorher = jetzt;
    }
  }

  void ausgabe() {
    Serial.print(pin);
    Serial.print('\t');
    Serial.print(intervall);
    Serial.print('\t');
    Serial.println(f / intervall);
  }
};

Impuls impuls[] = {
  // Eingangs-Pin
  {22},
  {23},
  {24},
  {25}
};

void setup() {
  Serial.begin(9600);
  Serial.println("Anfang");
}

void loop() {
  jetzt = micros();
  for (Impuls &i : impuls) i.messen();
  if (jetzt - ausgabeMicros >= ausgabeIntervall) {
    ausgabeMicros = jetzt;
    for (Impuls &i : impuls) i.ausgabe();
  }
}

TODO: Zeitüberwachung bei fehlendem oder zu langen Impuls

back to the roots:

F1: um welche Sensoren handelt es sich genau? Bitte auch einen Link aufs Datenblatt setzen.
F2: Warum müssen es ausgerechnet diese Sensoren sein, bzw. warum kannst du nicht Sensoren nehmen die eine "freundlichere" Schnittstelle ala Modbus oder ähnliches haben?
F3: An welchem Ergebnis bist du interessiert: am (akkumuliertem) Durchfluss seit dem letzten Reset oder an der aktuellen Durchflussmenge (z.B. l/sec)?

julmoe98:
Welche Fragen denn, ich denke ich habe alles beantwortet oder hattest du noch eine Spezielle Frage?

Dann lies Dir noch mal #2 durch.

Gruß Tommy

@noiasca

Morgen Miteinander,

zu F1: Ich verwende den Sensor mit der Nennweite DN 8:

zu F2: Diese Sensoren sind für meine Umstände am besten geeignet da das Wasser mit ca. 5-6 bar und einer Temperatur von 90°C durchläuft. Es sind keine großen Komponenten direkt im Wasser und es können sich nicht viele Kalkablagerungen bilden (Strömungsoptimal).

zu F3: Genau ich bin an der aktuellen Durchflussmenge interessiert sprich - l/sec und diesen Wert möchte ich dann später Umrechnen auf l/min.

Welchen Ausgang hast Du denn wirklich? Zitat aus dem Datenblatt:

Durchflussmessung wahlweise mit Spannungs-, Strom-, Impuls- oder Frequenzausgang

Auch bei 5bar können 1000 l/s oder 0,1l/h durchlaufen.

Etwas mitteilsamer solltest Du schon sein, sonst wird das eng mit der Hilfestellung.

Gruß Tommy

@ Tommy56

Ich hab doch schon geschrieben das die Sensoren einen OUTPUT: 30....388 Hz haben und einen Durchfluss von 0,9....15 L/min! Somit resultiere ich das 30 Hz -> 0,9 l/min entsprechen!! Oder sehe ich das falsch?

Rein vom logischen her denke ich nicht das bei 5 bar 1000 l/sec durch einen so kleinen Durchmesser von 8mm passen :wink:

Mit der Druckangabe wollte ich nur erläutern wie mein Versuchsaufbau ist, sodass man sich besser ein Bild machen kann.

Mir ist klar das ich als erstes auch etwas über die Anzeige und WLAN Verbindung geschrieben habe. Aber mein Programm auf dem Arduino ist nicht optimal und daher konzentriere ich mich als erstes auf ein funktionierendes und sauberes Programm und dann werde ich Step by Step weiter machen.

Gruß JM