Tach Leute,
ich bin (recht) neu hier, insofern erstmal hallo!
Ich habe ein Problem mit einem analogen Drucksensor. Es handelt sich um einen Sensor, der 0-3000 Pa bzw. 0-300 mm Wassersäule messen kann. Die Dinger sind normalerweise in Waschmaschinen und Spülmaschinen verbaut und überwachen dort den Wasserstand.
Ich möchte auch einen Wasserstand damit messen (bzw, den Pegel am Ausgang mit einem Arduino weiter verarbeiten). Der Sensor ist neu.
Der Sensor hat drei Anschlüsse:
GND
OUT
+5 V
Ich habe Ground auf Minus und entsprechend 5 V auf Anschluss 3) gegeben. Meine Erwartung ist, dass ich an Anschluss 2 jetzt eine Spannung zwischen 0 und 5 Volt messen kann, und zwar linear zum Druck, der am Druckstutzen anliegt. Das ist aber nicht der Fall.
Ich messe relativ konstant etwa 2,5 V, vollkommen unabhängig vom Druck der vorne anliegt.
Ich habe einen anderen neuen Sensor getestet, der zeigt das selbe Verhalten.
Ich vermute, dass ich den Ausgang irgendwie anders messen muss, mit Pullup Widerstand oder so etwas? Pulldown? Ich hab mal mit 1kOhm sowohl up als auch down verschaltet, das bringt keinen Erfolg. Nur die gemessene Spannung geht leicht nach oben bzw. nach unten, wie zu erwarten ist.
Wie wird so etwas normalerweise angeschlossen?
Ich versuche mal noch Bilder anzuhängen, mal sehen, ob das klappt. ;-)
Vielen Dank schonmal vorab für eure Hilfe!
Nachtrag:
Ich kam eben auf die Idee, da mal anderes am Ausgang zu messen. Mein Multimeter kann Hz. Ergebnis:
Der gibt an dem OUT 620 Hz aus. Und wenn ich 17 cm Wassersäule an Druck drauf gebe, dann gibt er noch 550 Hz aus, und zwar reproduzierbar.
Ich dem anderen Sensor (den ich zwischenzeitlich bei meinen Versuchen geschrottet habe) ist ein IC drin mit der Bezeichnung HCF4060. Beim googeln finde ich, dass das ein Oszillator ist.
Kann es sein, dass hier eine Frequenz als Ausgangssignal des Sensors verwendet wird? Ist so etwas üblich? Ich hatte schon den ein oder anderen Sensor in der Hand, aber so etwas hatte ich noch nicht gesehen....
Kann es sein, dass hier eine Frequenz als Ausgangssignal des Sensors
verwendet wird? Ist so etwas üblich?
Ja, absolut. Wenn es ein kapazitiver Sensor ist, macht das Sinn.
Aha! Interessant…
In dem geschrotteten Sensor, welchen ich öffnete, ist die kleine Schaltung und angeschlossen eine Spule. Bei Druck fährt ein Kern (vermutlich Ferrit) in die Spule rein. Je höher der Druck, desto tiefer taucht der Kern ein. Ich vermute, in meinem JETZT vorliegenden ist es genau so.
Aber wie verarbeite ich dieses Signal sinnvoll weiter? Soweit ich gegoogelt habe, kann der Arduino auch Frequenzen am Eingang verarbeiten.
Also einfach rein damit? Es sind ja nur 2,5 V….
Ja. Die zuehoerige SW ist dann ein anderes Thema. Es sind uebrigens keine 2.5, sondern 5V. Die 2.5V sind nur der Mittelwert des Ausgangssignals mit offensichtlichen Tastgrad von 50%.
Ja. Die zuehoerige SW ist dann ein anderes Thema. Es sind uebrigens
keine 2.5, sondern 5V. Die 2.5V sind nur der Mittelwert des
Ausgangssignals mit offensichtlichen Tastgrad von 50%.
Okay cool, dann weiß ich erstmal weiter, danke. Einen Code um das zu verarbeiten, werd ich wohl hin kriegen bzw. finden.
Nochmal zu den gemessenen 2,5 V:
Legt der Sensor dann mit 620 Hz abwechselnd einmal +5 V und einmal GND auf seinen Ausgang? Dann müsste ich ja zwischen 5 V und Out ebenfalls 2,5 V messen können, vermute ich.
Dann müsste ich ja zwischen 5 V und Out ebenfalls
2,5 V messen können, vermute ich.
Ja.
Yeah. Hab grad auch mal noch nachgemessen, passt alles. Vielen Dank!
Da das Signal ohnehin im Arduino verarbeitet werden soll, versuch ich es mal mit pulseln, vielen Dank!
Aber mal noch aus Interesse: Kann man das auch easy in eine Spannung umwandeln? Ich dachte an so etwas wie an OUT einen Kondensator und Widerstand in Reihe. Je höher die Frequenz, desto höher der Strom durch den Kondensator, ergo mehr Spannungsabfall am Widerstand dahinter. Oder gibt das nix?
Je höher die Frequenz, desto höher der Strom durch
den Kondensator, ergo mehr Spannungsabfall am Widerstand dahinter. Oder
gibt das nix?
Im Prinzip ja (mit einem R parallel zum C), aber wozu?
Dieses Gemurkse ist alles andere als linear.
Nur so. Ist immer gut, einen Plan B zu haben. Oder wie James Bond sagt „Immer einen Fluchtweg offen halten!“
Allerdings ist das dann tatsächlich kein guter Plan B, weil nicht linear.
Mit der Frequenzmessung (am Multimeter) gehts richtig schön linear. 4,5 cm Wassersäule entsprechen 20 Hz Änderung.
9 cm entsprechen 40 Hz
13,5 cm entsprechen 60 Hz.
Bis 30 cm sollte das so weiter gehen, aber so einen großen Behälter hab ich grad nicht da.
Das lässt sich also wohl sehr schön verarbeiten. Aber nicht mehr jetzt. 😉
Ich finde ja ihr wuerdigt das noch nicht richtig. :-)
Da muss jemanden zu einem alten erfahrenen Analogentwickler gesagt
haben:
Wir brauchen einen Drucksensor, so billig wie moeglich weil
wir da jedes Jahr eine Million von brauchen, langfristig
verfuegbar, second Source, einfache Schnittstelle in
verstoerter Umgebung, Genauigkeit und Linearitaet
nicht gaaaanz so wichtig.
Und er hat geliefert ohne Spezial-IC, Microcontroler, Arduinomumpitz.
Kann man das auch easy in eine Spannung umwandeln?
Nein.
Ich dachte an so
etwas wie an OUT einen Kondensator und Widerstand in Reihe.
Das ergibt den Mittelwert, 2.5V.
Du brauchtest eine Auswertung wie bei Tacho und Drehzahlmesser, ein Monoflop das aus dem Impuls eine konstante Impulsbreite bei dann variabler Impulspause macht, dann kommt eine analoge Spannung raus. Aber bei 550-620Hz auch bloss 2.21 bis 2.5V, wenig Messbereich, also müsste man noch verstärken (dehnen). Das war der Krampf mit Analogtechnik, und ungenau auch noch, die meisten Bauteile bringen +/-10%.
Ich finde ja ihr wuerdigt das noch nicht richtig. :-)
Wie man es nimmt: Ein Tiny 10 kostet bei Mouser weniger als die Haelfte
eines HCF4060. ;-)
Das ist nicht vergleichbar. Der 4060 ist in einem wesentlich gröberen Prozess gefertigt. Der ist also nicht nur robuster, sondern fällt aus alten, längst abgeschriebenen Fabs in Massen raus. Den Preis bei Mouser würde ich da nicht als Maßstab nehmen.
Dann läuft der 4060 von 3V .. 15V. Er braucht auch keine Programmierung (die aufgebracht werden muß und vergessen werden kann). Es gibt ihn in DIP, dadurch kann man ihn auf Hartpapierplatinen mit gestanzten Löchern und per Siebdruck strukturierten Leiterbahnen einsetzen, die durch ebenfalls längst abgeschriebene Schwalllötanlagen laufen. Und und und.
Bei der Massenproduktion für z.B. weiße Ware gelten andere Regeln. Da kommt es nicht nur auf die Preise für Teile an.
Sooooo, also ich hab meinen Sensor mal an den Arduino dran gehangen. Am Ende hats geklappt.
Was komisch ist: pulseIn() liefert mir bei 620 Hz am Eingang eine Pulsdauer von rund 800 ms. Das ist viel zu lang, bzw ist zurückgerechnet ja eine Frequenz von rund 1,25 Hz. Das geht also nicht.
Falls mal jemand über den Code drüber schauen mag, ich weiß nämlich nicht, wo dran das liegt:
int pin = 7;
unsigned long duration;
float Frequenz;
Ein bisschen rumgoogeln hat mich bei irgendeinem Programmierer folgenden Code finden lassen, den ich mal weitestgehend kopiert habe. Mit diesem klappt es, am seriellen Monitor wird mir praktisch der Selbe Wert augegeben wie das Multimeter, welches ich parallel an den Eingang gehängt habe:
So, ich hoffe, ich hab den Code hier einigermaßen anständig dargestellt und ihr könnt gut drinnen lesen. Bin gespannt, ob jemand etwas dazu sagen kann. Vielen Dank auf jeden Fall schon mal für die Hilfe.
Ich würde erstens mal den Parameter timeeout von pulseln setzen wenn man den schon angeboten bekommt. Da hier wohl 100Hz etwas das Minimum darstellt, würde ich timeout auch auf 0.1s setzen (100 000 us).
2 Fehler sehe ich bei Deiner SW:
a) Du rechnest in s. Reden tust Du von ms. pulseln liefert aber us zurück
b) Du rechnest nur mit einer Halbwelle, bekommst also die doppelte Frequenz zurück.
Der Unterschied zur folgenden SW ist auch: Du machst eine einzige Messung während die 2. SW einen Mittelwert über eine Sekunde Messdauer bildet.
Dieser mysteriöse Korrekturwert ist wohl auch irgendeiner schlampigen Hardware geschuldet.
Ich würde erstens mal den Parameter timeeout von pulseln setzen wenn man
den schon angeboten bekommt. Da hier wohl 100Hz etwas das Minimum
darstellt, würde ich timeout auch auf 0.1s setzen (100 000 us).
2 Fehler sehe ich bei Deiner SW:
a) Du rechnest in s. Reden tust Du von ms. pulseln liefert aber us
zurück
b) Du rechnest nur mit einer Halbwelle, bekommst also die doppelte
Frequenz zurück.
Der Unterschied zur folgenden SW ist auch: Du machst eine einzige
Messung während die 2. SW einen Mittelwert über eine Sekunde Messdauer
bildet.
Dieser mysteriöse Korrekturwert ist wohl auch irgendeiner schlampigen
Hardware geschuldet.
Jo, danke, jetzt klappts. War vermutlich gestern schon etwas spät, so dass ich Milli-, Mikro- und Sekunden nicht mehr so recht auseinanderhalten und umrechnen konnte. ;-)
Mit diesem Code hier klappt es letzten Endes:
Leichte Schwierigkeiten hatte ich mit den Variablen. Ich wollte die ~800 Mikrosekunden gleich zu Anfang in Sekunden umrechnen, also durch 1.000.000 teilen. Aber 0,0008 wollte irgendwie keine Variable korrekt abspeichern, weder mit float noch mit double. Hat da noch jemand einen Tip für mich? Googeln hat mich da absolut nicht weiter gebracht, es klang so, als ginge das (mit dem Arduino) schlicht nicht.
Der andere Code mit der seltsamen Schleife und dem interessanten Korrekturwert funktioniert nur bedingt - nach etwa einer bis zwei Stunden hängt der sich auf. Ich vermute mal, das k++ in der Schleife bringt das k zum Überlauf?
Er ist damit nicht nutzbar für mich, ich brauche etwas, was dauerhaft läuft.
Das Zauberwort heißt explizite/implizite Typumwandlung. Lies Dich da mal
ein.
Hmmm, interessant, ja. Aber ich erkenne (noch) nicht, warum das hier beim Umrechnen der Mikrosekunden in HZ Fehler erzeugt haben könnte. Ich bin extra konsequent nur bei einem Datentyp geblieben, also alles als float z. b..
Int und double hatte ich auch mal getestet, ohne Erfolg.
Meines Wissens hätten alle Werte und Zwischenergebnisse problemlos innerhalb des Wertebereiches sein müssen. Sooooo unglaublich groß bzw. lang sind die Zahlen ja gar nicht.
Oder wechselt das System da irgendwie selbständig den Typ?
Letzten Endes hat mich ja zum Erfolg geführt, dass ich die vielen Stellen hinter dem Komma beseitigt habe. Also keine Berechnung mehr mit 0,00008 oder ähnlich.
Hmmm, wann hat man sich schon vollständig eingelesen….
Meines Wissens liegt der Wert, den pulseIn() ausgibt als unsigned long vor. Liegt darin das Problem, wenn ich den dann weiter verarbeite und in einer Variable vom Typ double abspeichere?
Demnach müsste es funktionieren, wenn ich alles als unsigned long deklariere. Hmmm.
Du hast noch nicht einmal damit angefangen, Dich über explizite und implizite Typumwandlung einzulesen.
Alles kau ich Dir jetzt nicht vor. Ich bin jetzt weg.
Ich wollte die ~800 Mikrosekunden gleich zu Anfang in
Sekunden umrechnen, also durch 1.000.000 teilen.
Wenn Du duration (und die Ergebnisvariante) schon als double deklariert hast, dann sollte das eigentlich klappen; wenn duration dagegen als Interger-Typ deklariert wäre, würde auch Deine derzeitige Variante nicht klappen, weil der / Operator eine Ganzzahldivision macht, solange beide Argumente Ganzzahltypen sind.
Demnach müsste es funktionieren, wenn ich alles als unsigned long
deklariere.
Nö. Dann kriegste nämlich auch eine Ganzzahl-Divison geliefert und in Deiner aktuellen Formel ist die Multiplikation mit 1000000 die letzte Operation und kommt damit auch zu spät um das schlimmste zu verhindern.
Frequenz = (1000000/(duration*2));
Das würde auch mit duration als Integer-Typ zumindest so halbwegs klappen; Du verlierst zwar auch die Nachkommastellen der Division, aber nachdem zuerst mit der Million multipliziert wurde, bleibt der Fehler 'erträglich'.