TL-136 an Arduino uno anschliessen

Hallo zusammen

Ich möchte einen Drucksensor (TL-136) mit einem Arduino abfragen und die empfangen
Werte in cm auf einem LCD Display wiedergeben.
Ich bekomme vom Arduino auf dem Display schon Werte angezeigt, aber irgendwie komme ich jetzt nicht weiter, und mit den Werten kann ich nichts anfangen.

Infos zum Sensor:
Versorgungsspannung: 12-32 VDC
Ausgangssignal: 4-20 mA
Messbereich: 0-1 m/0-2 m/0-3 m/0-4 m/0-1 m/0-5 m

Wenn der Drucksensor nicht im Wasser ist, bekomme ich auf dem Arduino einen Wert von 446 - 461 (über den Widerstand gemessen, mit einem Messgerät einen Wert von 2.334), wenn ich den Drucksensor in einen Eimer lege, 30cm Wasser, bekomme ich einen Wert von 627 - 647 (über den Widerstand gemessen, mit einem Messgerät einen Wert von 3.279)

Ist der Wert mit 3.279 bei 30cm Wasser nicht schon etwas hoch? der soll mal bis zu einem Meter messen können.
Wie bekomme ich das jetzt in cm umgewandelt?

Hier noch der Aufbau, die Batterie und der Sensor sind auf dem Bild nur zu darstellungszwecken. Es sind aber die richtigen Werte auf die Bauteile geschrieben.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define CurrentSensorPin  A1
unsigned int voltage; //unit:mV

void setup() 
{
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("Wasserstand");
  Serial.begin(9600);
}

void loop() 
{
  voltage = analogRead(CurrentSensorPin);
  lcd.setCursor(1, 1);
  lcd.print(voltage);
  
  delay(1000);
}

womit an welchen Punkten gemessen?
Einheit?

Deine Zeichnung ist auch irgendwie verwirrend. Mach mal ne einfache Handskizze und zeige deinen Aufbau.

Zu zweidrahtigen Stromschleifensensoren habe ich da mal was geschrieben:

https://werner.rothschopf.net/202009_arduino_stromschleifenschnittstelle_4mA_20mA.htm

Hallo

Die Anleitung ist gut, fände es noch besser ohne Library und den abfragen, gibt es da eine vereinfachte Version?

Na ist ja schon fast schick.
Der ganzzahlige Wert ist das, was Dir der ADC liefert.
Wenn der im "Null"Zustand 455 bringt und bei 30cm 637 dann sind das 182. Die Frage wäre jetzt, was bei 60cm raus kommt. Wenn es linear wäre, wäre es 455+2*182=819.
Das wäre etwas zu viel, denn bei 100cm würden über dem R 10* ((3.279V-2.334V)/3) = 3,15V abfallen. Wenn die 2.334V Grund dazu kommen, hast Du 5,484V auf dem Pin. Pin kaputt.

Und fürs Umrechnen ist es eigentlich ganz einfach...

const byte sensorPin = A1;
const uint16_t startWert = 455; // 0cm

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
}

void loop()
{
  uint16_t messWert = analogRead(sensorPin);
  tiefe = map(messWert, startWert, 1023, 0, 100);
  Serial.print(F("Tiefe: "))
  Serial.print(tiefe);
  Serial.println(F(" cm"));
}

Hallo

Habe es jetzt so aufgebaut wie noiasca das beschrieben hat, tolle Arbeit, nur gefällt mir das mit der Library nicht. Deswegen habe ich jetzt dein Skript genommen.

Bei 0cm zeigt mir der Arduino 168 an und bei 20cm 237 , wenn ich in dem Sketch jetzt als Startwert 168 angebe, dann bekomme ich 8 als tiefen Ausgabe. Irgendwo ist da noch was faul.

Nein.da ist nichts faul. Die Rechnung musst Du nur anpassen.
Wenn Dein Startwert 168 ist und Du bei 20cm 237 hast, sind das je 20 cm 237-168=69.
Dein Teiler zum Endwert ist 100cm / 20cm = 5
69*5=345. Dem der Grundwert dazu gerechnet: 345+168 = 513.
Das ist Dein (voraussichtlicher) Endwert.
In meiner Formel bin ich davon ausgegangen, das der Endwert 1023 (was 5V entspricht) ist.
Wenn Du den austauscht gegen die 513 und der Startwert richtig gesetzt ist, sollte es passen.

Sorry kommt:
5V / 0,020A = 250 Ohm = 220 Ohm genommen

bei 0,004A * 220Ohm = 0,88V
bei 0,020A * 220Ohm = 4,4V

12V - (5V + 0,6V) = 6,4V
6.4V / 0,0009A = 7111 Ohm.
Wir nehmen also für R2 einen 8,2K Widerstand.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte sensorPin = A1;
const uint16_t startWert = 161; // 0cm

void setup() 
{
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("Wasserstand");
  Serial.begin(115200);

}

void loop() 
{
  uint16_t messWert = analogRead(sensorPin);
  int tiefe = map(messWert, startWert, 1023, 0, 100);
  
  lcd.setCursor(3, 2);
  lcd.print(tiefe);


  lcd.setCursor(10, 2);
  lcd.print(messWert);

  
  delay(500);
}

wie sauber sind deine 12V (kannst du das messen?) und wie hoch ist deine tatsächliche 5V? (gemessen am 5V Pin am Arduino)?

(denn wenn du 5V an VIN gibst, hast du niemals 5V für den Arduino nach dem internen Regler).

welchen Sensor hast du genau? sicher einen 0-1m?

Hallo,
Oh mit dem Sensor habe ich jetzt erst gesehen das es verschiedene höhen gibt.
Auf der Verpackung steht 0-2m
Wenn alles läuft liefert mit die 12V Stromquelle 12.16V.
Der Arduino ist per USB angeschlossen, weiss nicht wie ich da den Spannungsabfall messen kann.

Mir ist folgendes aufgefallen.
Wenn ich die Variable "tiefe" als double deklariere, dann funktioniert alles hervorragend, die verschiedenen höhen von 0-20cm werden exakt angezeigt. Wenn ich die Variable aber als int deklariere macht die anzeige bei ca. 10 cm ein Sprung auf 70-90.

Ich hoffe das war verständlich

Ich glaube das liegt am LCD Display

es wird so angezeigt
20
19
18
...
11
10
90
80
70

Da muss ich irgendwas am LCD ändern

Dann muss die Auflösung angepasst werden.

Neue Rechnung:
Teiler: 200 cm / 20cm = 10
69*10 = 690. dem der Grundwert dazu gerechnet: 690 + 168 = 858.

Damit ist 858 bei 200 cm als Endwert gedacht.
Wäre dann wie folgt:

const byte sensorPin = A1;
const uint16_t startWert = 168; // 0cm

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
}

void loop()
{
  uint16_t messWert = analogRead(sensorPin);
  uint16_t tiefe = map(messWert, startWert, 858, 0, 200);
  Serial.print(F("Tiefe: "));
  Serial.print(tiefe);
  Serial.println(F(" cm"));
}

Las den mal laufen und schau mal auf dem Seriellen Monitor, ob das passt.

Ja das funktioniert, doch ich habe immer noch das gleiche Problem auf dem LCD.
Bei serieller Ausgabe ist alles gut.

Ich habe es mal aufgenommen was ich meine, man sieht es beim umschalten von 10 auf 9

video_2022-09-08_13-38-02.zip (3.8 MB)

ungesehen, du musst halt schon vorher das LCD löschen bevor du was drüber schreibst

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const byte lcdZeilen = 2;
const byte lcdSpalten = 16;
const byte sensorPin = A1;
const uint16_t startWert = 161; // 0cm

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  lcd.begin(lcdSpalten, lcdZeilen);
  lcd.setCursor(2, 0);
  lcd.print(F("Wasserstand"));
}

void loop()
{
  uint16_t messWert = analogRead(sensorPin);
  uint16_t tiefe = map(messWert, startWert, 858, 0, 200);
  serialDebug(tiefe);
  lcdAusgabe(tiefe, messWert);
}

void serialDebug(const uint16_t t)
{
  Serial.print(F("Tiefe: "));
  Serial.print(t);
  Serial.println(F(" cm"));
}

void lcdAusgabe(const uint16_t tvar, const uint16_t mvar)
{
  char ausgabe[lcdSpalten]={'\0'};
  lcd.setCursor(0, 2);
  sprintf(ausgabe, "%i %i", tvar, mvar);
  lcd.print(ausgabe);
}

Vielen dank an euch beide, es funktioniert super.
Habe das mit dem Display allerdings anders abgefangen.
Ich habe einfach eine If abfrage eingebaut :slight_smile:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const byte sensorPin = A1;
const uint16_t startWert = 168; // 0cm

void setup() 
{
  Serial.begin(115200);
  
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("Wasserstand");
}

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

  lcd.setCursor(3, 1);
  lcd.print("             ");

  if (tiefe >= 10) { 
    lcd.setCursor(3, 1);
    lcd.print(tiefe);
  } 
  else {
    lcd.setCursor(4, 1);
    lcd.print(tiefe);
  }

  lcd.setCursor(10, 1);
  lcd.print(messWert);

  delay(500);
}

Wenn Du das änderst in:

 int tiefe = map(messWert, startWert, 1023, 0, 267);

kommt das selbe raus. Aber Du vermeidest das, wenn der Endwert über 858 geht, es zu einem Überlauf kommt.

Ok, super

danke für den Tipp

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.