Forum: Analoge Elektronik und Schaltungstechnik Drucksensor Verschaltung unklar


von Benni (bennisg)


Angehängte Dateien:

Lesenswert?

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:
1) GND
2) OUT
3) +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.

Das hier ist das Ding, wie man ihn auf Ebay kaufen kann. Ein 
Standard-Ersatzteil:
https://www.ebay.de/itm/144665754990

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!

: Bearbeitet durch User
von Benni (bennisg)


Lesenswert?

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....

von Andreas B. (bitverdreher)


Lesenswert?

Benni schrieb:
> 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.
Ein HCF4060 ist ein Teiler mit Oszillator.

: Bearbeitet durch User
von Benni (bennisg)


Lesenswert?

Andreas B. schrieb:
> Benni schrieb:
>> 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….

von Andreas B. (bitverdreher)


Lesenswert?

Benni schrieb:
> Je höher der Druck, desto tiefer
> taucht der Kern ein.

Und genaus diese Spule ist ein Teil des Oszillators. Passt also. Das ist 
hier in diesem Fall ein induktiver Sensor.

Benni schrieb:
> 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%.

: Bearbeitet durch User
von Benni (bennisg)


Lesenswert?

Andreas B. schrieb:
> Benni schrieb:
>> Je höher der Druck, desto tiefer
>> taucht der Kern ein.
>
> Und genaus diese Spule ist ein Teil des Oszillators. Passt also. Das ist
> hier in diesem Fall ein induktiver Sensor.
>
> Benni schrieb:
>> 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%.

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.

von Andreas B. (bitverdreher)


Lesenswert?

Benni schrieb:
> Einen Code um das zu
> verarbeiten, werd ich wohl hin kriegen bzw. finden.

Der Arduino Befehl dazu heisst pulseln().

Benni schrieb:
> Dann müsste ich ja zwischen 5 V und Out ebenfalls
> 2,5 V messen können, vermute ich.

Ja.

von Benni (bennisg)


Lesenswert?

Andreas B. schrieb:
> Benni schrieb:
>> Einen Code um das zu
>> verarbeiten, werd ich wohl hin kriegen bzw. finden.
>
> Der Arduino Befehl dazu heisst pulseln().
>
> Benni schrieb:
>> 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?

von Andreas B. (bitverdreher)


Lesenswert?

Benni schrieb:
> 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.

von Benni (bennisg)


Lesenswert?

Andreas B. schrieb:
> Benni schrieb:
>> 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. 
😉

von Vanye R. (vanye_rijan)


Lesenswert?

> Ein HCF4060 ist ein Teiler mit Oszillator.

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.

Das muss man mal positiv hervorheben! .-)

Vanye

von Michael B. (laberkopp)


Lesenswert?

Benni schrieb:
> 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%.

Frequenzzähler per uC hingegen ist simpel.

von Andreas B. (bitverdreher)


Lesenswert?

Vanye R. schrieb:
> 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. ;-)

von Ali K. (teddy50)


Lesenswert?

Benni schrieb:
> ur so. Ist immer gut, einen Plan B zu haben. Oder wie James Bond sagt
> „Immer einen Fluchtweg offen halten!“

Für diesen Satz habe ich dir ein "-" gegeben

von Axel S. (a-za-z0-9)


Lesenswert?

Andreas B. schrieb:
> Vanye R. schrieb:
>> 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.

von Benni (bennisg)


Lesenswert?

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;

void setup() {
  Serial.begin(9600);
  pinMode(pin, INPUT);
}

void loop() {
  duration = pulseIn(pin, HIGH);
  Serial.println(duration);


  Frequenz = (1/duration);
  Serial.println (Frequenz);
  Serial.println("");

  delay(1000);
}
-------------------------------------------
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:

---------------------------------------------
float time, T, k;
float pin = 7;
float f;
float fsum;
void setup(){
  Serial.begin(9600);
  pinMode(pin, INPUT);
}
void loop() {
  time=micros();
  do {
    T = pulseIn(pin, HIGH) + pulseIn(pin, LOW);
    if (T==0) {
      Serial.println("Timeout.");
    }
    else {
      f=1/(double)T;        // f=1/T
      k++;
    }
    fsum+=f*1e6;
  } while( micros() < (time+1e6)); // 1 Sekunde mitteln
  f = fsum/k*0.9925;         // Korrekturwert einrechnen
  Serial.println(f);
  fsum=0.0;
  k=0;
}
---------------------------------------------------
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.

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

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.

von Benni (bennisg)


Lesenswert?

Andreas B. schrieb:
> 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:


#include "Wire.h";
#include "LiquidCrystal_I2C.h";
LiquidCrystal_I2C lcd(0x27, 16, 2);

int pin = 7;
double duration, Periode, Frequenz, Wasserstand;

void setup() {
  Serial.begin(9600);
  pinMode(pin, INPUT);
  lcd.init();
  lcd.backlight();
}

void loop() {
  duration = pulseIn(pin, HIGH, 0.1);
  Serial.print(duration);
  Serial.println(" micros");

  Frequenz = (1/(duration*2))*1000000;

  Wasserstand = (623 - Frequenz) * 2.35;

  Serial.print (Frequenz);
  Serial.println(" Hz");

  Serial.print(Wasserstand);
  Serial.println(" mm");
  Serial.println(" ");

  lcd.setCursor(0,0);
  lcd.print(Wasserstand);
  lcd.print(" mm");
  lcd.setCursor(0,1);
  lcd.print("(");
  lcd.print(Frequenz);
  lcd.print(" Hz)");

  delay(1000);
}

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.

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

Das Zauberwort heißt explizite/implizite Typumwandlung. Lies Dich da mal 
ein.

von Benni (bennisg)


Lesenswert?

Andreas B. schrieb:
> 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.

Also, wer klärt mich auf? ;-)

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

Du hast Dich nicht eingelesen. Ich habe Dir die Stichworte genannt.

von Benni (bennisg)


Lesenswert?

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.

von Andreas B. (bitverdreher)


Lesenswert?

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.

von Michi S. (mista_s)


Lesenswert?

Benni schrieb:
> 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.


Benni schrieb:
> f=1/(double)T;        // f=1/T

Das wäre dann die Variante mit expliziter Typumwandlung aus deinem 
ersten Internetfund.

Alternativ sollte auch f=1.0/pulseIn(...); funktionieren; in dem Fall 
weil 1.0 eben kein Ganzzahl-Typ ist.


Benni schrieb:
> 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'.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.