TL-136 am Arduino Mega

Hallo,
ich bin auf der Suche nach einen Drucksensor für meinen Regenwassertank.
An Ardunio habe ich nur 5V anliegen. Die Sensoren die ich gefunden habe, haben alle 12-32V. Gibt es den auch mit 5V?
Level soll 0-2m sein.
Gefunden habe ich diesen:

Wenn es nur mit 12V geht, könnte man es ja mit einem Step-Up Modul erledigen:

Wenn es alles soweit passt, wie muss der Sensor am Arduino Mega angeschlossen werden, weil der Ausgang ja 12V hat?

4-20mA signal output

Das ist eine Stromschleife, die der Mega nicht direkt verarbeiten kann. Du benötigst daher noch eine Elektronik, um aus dem Strom eine Spannung zu machen. Beispielsweise das Current to Voltage Module.

Siehe auch Arduino und Sensoren mit 4mA - 20mA Stromschleifenschnittstelle.

2 Likes

Ein Widerstand von 250 Ohm macht aus 20 mA 5V.
150 Ohm ergeben max. 3V

Nur mal so als Hinweis :wink:

1 Like

Die Signale beginnen aber bei 4mA. Da muss (sollte) noch ein Offset rein. OK, geht auch mit map().

1 Like

Ja, z.B.

Oft will man weder Spannung noch (0 .. 3m), sondern einen Füllstand den man erst zwischen "voll" und "leer" kalibrieren muss, und wo man optimalerweise "Sensor Fehler" erkennen kann.

1 Like

Also brauche ich erstmal als Hardware:

  • Messsensor
  • BIlinli Current to Voltage Module 0/4-20mA
  • Step-Up Modul

Es soll dann über den Skript die Millimeter der Wasserhöhe ausgegeben werden und anschließen über man altes Script der Füllstand ausgerechnet werden.
Das war das Projekt:
Alternative für HC-SR04 - #138 by newpv.._gaNDU2MzYxMDY2LjE3NDc3NzAxMTE._ga_NEXN8H46L5czE3NDc3NzAxMDgkbzEkZzEkdDE3NDc3NzAzNDAkajAkbDAkaDg1MDc5MDQz

Meine Hardware ist angekommen. Angeschlossen habe ich diese nach diesen Schema, nur statt den D1 Mini, den Mega 2560 zum testen.

Der Sketch sieht so aus:

const int sensorPin = A0; // TL-136 angeschlossen an Pin A0


void setup()
{
Serial.begin(9600); // Start serial
}

void loop()
{
int Fuellstandssensor = analogRead(sensorPin);

Serial.print("Wasser Höhe: ");
Serial.print(Fuellstandssensor);
Serial.println(" cm");

delay(1000);
}

Die Serielle Ausgabe so:

Wasser Höhe: 83 cm
Wasser Höhe: 103 cm
Wasser Höhe: 103 cm
Wasser Höhe: 106 cm
Wasser Höhe: 120 cm
Wasser Höhe: 88 cm
Wasser Höhe: 100 cm
Wasser Höhe: 119 cm
Wasser Höhe: 76 cm
Wasser Höhe: 97 cm
Wasser Höhe: 96 cm
Wasser Höhe: 92 cm
Wasser Höhe: 113 cm
Wasser Höhe: 99 cm
Wasser Höhe: 86 cm

Ist der Sketch so ok?
Ist es möglich Millimeter zu messen?
Sollte man den Sensor "kalibieren"?
Es ist die 0-2m Version. Wird mit 12V betrieben. In der Praxis habe ich dann einen max. Füllhöhe von 1,8m. Sollte ich z.B. ein 2m Kunststoffrohr nehmen, den Sensor ganz nach ganz unten herab lassen und es bis oben hin Füllen, und dann auf 2m Ausgabe einstellen? Ein andere Frage ist ja, sobald die Sonde mit Wasser in Berührung kommt sollte dort ja direkt ca.18mm stehen, da die Kappe unten ja 18mm Lang ist und dann kommt erst der Sensor

Ist der Anschluss so ok?

PS.: Werde mal gucken, ob ich den Sketch mit der Libuary aus dem Link ans laufen bekomme!

Der Sketch zeigt mir immer 0cm an.

[Sensor] I:parameters ok, you can remove .check() from setup
Wasser Höhe: 0 cm

Aktuell sieht er so aus:

#include <NoiascaCurrentLoop.h>  // download library from https://werner.rothschopf.net/

const byte sensorPin = A0;      // ADC pin for the sensor
const uint16_t resistor = 150;  // used pull down resistor in Ohm
const byte vref = 50;           // VREF in Volt*10 (Uno 16MHz: 50, ProMini 8MHz: 3V3).
const byte maxValue = 20;

CurrentLoopSensor currentLoopSensor(sensorPin, resistor, vref, maxValue);  // create the sensor object


void setup()
{
  Serial.begin(9600);  // Start serial

  currentLoopSensor.begin();  // start the sensor
}

void loop()
{
  static unsigned long lastprint;
  if (millis() - lastprint > 3000)  // Testausgabe alle 3s
  {
    lastprint = millis();
  currentLoopSensor.check();  // remove this line if check shows no error, will save about 320 bytes program memory (flash)
  currentLoopSensor.getAdc(); // get the raw ADC value from the measurement. 
    int Fuellstandssensor = currentLoopSensor.getValue();  // read sensor value into variable

    Serial.print("Wasser Höhe: ");
    Serial.print(Fuellstandssensor);
    Serial.println(" cm");
  }
}

Muss der Sensor anders angeschlossen werden, wie im meinem Bsp. Bild?
Der Passt der Sketch so nicht?

Nö, Dir fehlt der berüchtigte Dreisatz, um aus 3,3 V, dem analogen Meßwert und der maximal gemessenen Höhe die Füllhöhe zu berechnen.

Der AD-Wandler vom Mega liefert 1023 bei 3,3 5 V, was theoretisch 2 m entspricht.

Beim D1 sind es dann 4095 bei 3,3 V.

1 Like

Vermutlich meinst du hier 5Volt.

2 Likes

Danke, habe es korrigiert.

1 Like

Du meinst also so:

const int sensorPin = A0;  // TL-136 angeschlossen an Pin A0
const uint16_t startWert = 0; // 0cm

void setup() {
  Serial.begin(9600);  // Start serial
}

void loop() {
  uint16_t messWert = analogRead(sensorPin);
  int Fuellstand = map(messWert, startWert, 1023, 0, 200);

  Serial.print("Wasserhöhe: ");
  Serial.print(Fuellstand);
  Serial.println(" cm");

  delay(1000);
}

Nicht wundern der Starwert passt mit 0, da ich es and er Platine Eingestellt habe.

Die Ausgabe sieht dann so aus:

Wasser Höhe: 20 cm
Wasser Höhe: 19 cm
Wasser Höhe: 18 cm
Wasser Höhe: 20 cm
Wasser Höhe: 17 cm

Geht es auch in Millimeter? Und bekommt man die Schwankungen auch stabiler? (Strom geht über den USB des PC, aktuell)

Dein Schaltplan sieht aber merkwürdig aus.

Normalerweise gehört der Sensor an die 2polige Klemme.
Und dann gibt es nur 2 Varianten.
Entweder: 0-20mA - Als Ausgangsspannung ist dann maximal 3,3V
Oder: 4-20mA - Als Ausgangsspannung ist dann maximal 2,5V

Da der Sensor als 4-20mA ausgelegt ist, würde ich die Variante mit Umax 2,5V nehmen.

Dann hast Du ca. 512 Stufen, mit denen Du die 180cm teilen kannst.
2Digit pendelt es eh.

Klar.
An Stelle der 200 im map() mach eine 2000.

2 Likes

Grundsätzlich ja :smiley:

Nur steckt die Sonde wohl nicht in 20 cm Wasser, weshalb eine Kalibrierung des Nullpunktes fehlt.

Wenn Du 200 durch 2000 ersetzt.

RC-Glied zum Glätten, eventuell genügt auch ein Kondensator. Oder Mittelwertbildung über mehrere Messungen.

Der AD-Wandler ist kein Präzisionsinstrument, das geht mit externen Wandlern genauer. Beim D1 ist das dann nochmal anders. Zum ESP8266 fehlen mir aber Erfahrungen, da ich nur mit ESP32 experimentiere.

@my_xy_projekt hat noch genauer hingesehen!

1 Like

Du kannst auch einen Tiefpass in Software bilden.
Hier eine Variante, die schnell einschwingt und sich damit schnell an die aktuellen Messwerte annähert.

const unsigned int FF = 10;

/* 
  newVal: neuer Messwert
  filterFaktor: glaetten über x Werte
  Return: geglaetteter Wert
*/
float filtern(float newVal, unsigned int filterFaktor){
static float filtVal = 0.0;
static unsigned int count = 0;
  // Damit sich am Anfang der Wert schneller dem realen Wert annaehert 
  if (count < filterFaktor) {
    filterFaktor = count++;
  }
  filtVal= ((filtVal * filterFaktor) + newVal) / (filterFaktor +1); 
  
  Serial.print("Count: "); Serial.print(count);
  Serial.print(" NewVal: ");Serial.print(newVal);
  Serial.print(" FiltVal: ");Serial.println(filtVal);
  return filtVal;
}

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  for(int i= 0; i < 20;i++) {
    filtern(i,FF);
  }

}

void loop() {}

Oder wenn Du es lieber objektorientiert hast:
(FilterClass.h)

#pragma once
// Tiefpass zur Glättung mit Anfangsbeschleunigung
class FilterClass {
  public:
    // FFconst: Filterfaktor kurzStart: Vor Erreichen von FFconst schneller aproximieren
    FilterClass(const uint16_t FFconst, const bool kurzStart = true): FFconst(FFconst), kurzStart(kurzStart) {}
    // neuen Wert hinzufügen und geglätteten Wert zurück geben
    float newValue(float newVal) {
      uint16_t FF = FFconst;
      // damit am Anfang der Wert nahe am Messwert ist
      if (kurzStart && count < FF) {
        FF = count++;
      }
      filtVal= ((filtVal * FF) + newVal) / (FF +1);
      return filtVal; 
    }
    // neu starten
    void reset() {
      count = 0;
      filtVal = 0.0;
    }
    
  private:
    const uint16_t FFconst;
    uint16_t count = 0;
    float filtVal = 0.0;
    const bool kurzStart = true;
};

Testprogramm (FilterTestC.ino)


#include "FilterClass.h"

float werte1[] {10.5, 10.3,10.4,10.6,10.2};
float werte2[] {20.5, 20.3,20.4,20.6,20.2};
const byte len = 5;

FilterClass fc1(3);
FilterClass fc2(2);

void setup() {
float m1,m2;
  Serial.begin(115200);
  Serial.println("Start");
  for(byte i=0;i<len;i++) {
    m1 = fc1.newValue(werte1[i]);
    Serial.print("Wert1: ");
    Serial.print(werte1[i]);
    Serial.print("\tErebnis1: ");
    Serial.println(m1);
    m2 = fc2.newValue(werte2[i]);
    Serial.print("Wert2: ");
    Serial.print(werte2[i]);
    Serial.print("\tErebnis2: ");
    Serial.println(m2);
  }
}
void loop() {}

Gruß Tommy

1 Like

ich habe es mal anders angeschlossen, die "Brücken" raus und den Sensor direkt an Plus und Minus, dann geht es nicht. Es bleibt immer auch 0cm!

@agmue
Doch die ca. 20cm waren vorhanden, steckte zum test in einer Gießkanne :wink:

Ne..
Die müssen drin bleiben!
Current to Voltage Module Presense.pdf (394,4 KB)

Schlingel!

Da muß der Sensor dran:

1 Like

genau da war er dran an Plus und Minus. Und an der anderen Seite an GND VCC die 12V von Power Up Modul und an VOUT dann die Verbindung zum Arduino A0

Stimmt, da hat mich wohl die Gießkanne verwirrt :zany_face:

1 Like

Also ist der Anschluss wie in meinem Bild doch korrekt!?

Was empfehlt ihr mehr meinen Sketch mit dem Filter oder den Sketch aus dem 2.Post mit Libruary?