Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Hardware
    4. [Gelöst]TFMini Plus Arduino! Füllstandsmessung!

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    [Gelöst]TFMini Plus Arduino! Füllstandsmessung!

    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      Superdad last edited by Superdad

      Hallo,

      habe mir einen TFMini Plus besorgt, da ich mit dem JSN-SR04T und dem HC-SR04 unzufrieden bin.
      Bei dem einen ist die Streuung zu groß und der andere mißt nur richtig wenn es wärmer ist.

      Für den TFMini benutze ich eine NodeMCU8266 von Amica.
      Angeschlossen an 5V und Ground und D1 und D2.
      Diese ist mit Arduino geflasht.

      Dafür habe ich mir über link text einen Code mit angepasster TFMini.cpp herunter geladen.
      Das funktioniert auch sehr gut im Seriell Monitor.

      Um aber das Ganze dann an MQTT zu senden habe ich den Code von link text ausprobiert.
      Funktioniert auch, außer das ich keinen Wert in MQTT bekomme.

      Also habe ich jetzt versucht beide Arduino-Codes zu kombinieren.

      Jetzt nach ca. eineinhalb Wochen weiß ich aber nicht weiter.
      Muss auch zugeben, dass ich keine Ahnung von Arduino habe!

      Der Code funktioniert jetzt so, dass ich mal einen Wert in MQTT bekomme.
      Dann mal nach einer Stunde oder zwei. Und dann auch wiederum nur einen am Tag.

      Mein Arduino-Code:


      /* This example shows how to use the TFMini module.
      The nodeMCU have an build in Watchdog and therefore it is necessary,
      that you delete/disable all <<Serial.print>> commands from the TFMini.cpp.
      Otherwise you will run into an restart loop, because the Watchdog become
      activated...

      Wiring:
      TFMini -> nodeMCU
      SDA -> D2 -> 4 -> Tx
      SCL -> D1 -> 5 -> Rx
      VCC -> 5V
      GND -> GND
      */
      #include <Arduino.h>
      #include <SoftwareSerial.h>
      #include "TFMini.h"
      #include <ESP8266WiFi.h>
      #include "config.h"
      #include <ArduinoOTA.h>
      #include <PubSubClient.h>
      //#include "helper.h"

      // Setup software serial port
      SoftwareSerial mySerial(4, 5); // connection to TFMini
      TFMini tfmini; // tfmini access
      unsigned long previousMillis = 0; // access time
      const long interval = 20000; // interval at which to measure (milliseconds)

      WiFiClient wiFiClient;
      PubSubClient client(wiFiClient);

      byte clientStatus, prevClientStatus = 99;

      /*
      -----------------S E T U P-----------------
      */
      void setup() {

      // Step 1: Initialize hardware serial port (serial debug port)
      Serial.begin(115200);
      // wait for serial port to connect. Needed for native USB port only
      while (!Serial);

      // Step 2: Initialize the data rate for the SoftwareSerial port
      mySerial.begin(TFMINI_BAUDRATE); // default boudrate is 115200
      delay(10);

      // Step 3: Initialize the TF Mini sensor
      tfmini.begin(&mySerial);
      Serial.println ("Initializing Serial and mySerial finished");

      /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
      would try to act as both a client and an access-point and could cause
      network-issues with your other WiFi-devices on your WiFi-network. */

      // Set WIFI module to STA mode
      WiFi.mode(WIFI_STA);
      WiFi.begin(WIFI_SSID, WIFI_PASS);

      // Wait
      while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
      }

      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

      setupOTA();

      // MQTT
      client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT);
      digitalWrite(TRIGGER_PIN, LOW);
      delay(2);
      }

      void ensureMQTTConnection (){
      if (!client.connected()) {
      Serial.println("Attempting MQTT connection...");
      // Attempt to connect

      if (MQTT_SERVER_USER_ID != "" && MQTT_SERVER_PASS != ""){
        client.connect(MQTT_CLIENT_NAME, MQTT_SERVER_USER_ID, MQTT_SERVER_PASS);
        }
      else (client.connect(MQTT_CLIENT_NAME));
      
      if(client.connected()){
        Serial.println("connected");
      } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
      }
      

      }
      }

      void setupOTA(){
      ArduinoOTA.onStart( {
      String type;
      if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
      } else { // U_SPIFFS
      type = "filesystem";
      }

      // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
      Serial.println("Start updating " + type);
      });
      ArduinoOTA.onEnd([]() {
      Serial.println("\nEnd");
      });
      ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
      Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
      });
      ArduinoOTA.onError([](ota_error_t error) {
      Serial.printf("Error[%u]: ", error);
      if (error == OTA_AUTH_ERROR) {
        Serial.println("Auth Failed");
      } else if (error == OTA_BEGIN_ERROR) {
        Serial.println("Begin Failed");
      } else if (error == OTA_CONNECT_ERROR) {
        Serial.println("Connect Failed");
      } else if (error == OTA_RECEIVE_ERROR) {
        Serial.println("Receive Failed");
      } else if (error == OTA_END_ERROR) {
        Serial.println("End Failed");
      }
      

      });
      ArduinoOTA.begin();
      }

      /*
      -----------------L O O P-----------------
      */
      void loop() {
      // we will not use an delay...
      // but we wait some short time before taking the next measurement
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis >= interval) {

      // save the last measure time
      previousMillis = currentMillis;

      // Take one TF Mini distance measurement
      uint16_t dist = tfmini.getDistance();
      uint16_t strength = tfmini.getRecentSignalStrength();

      // Display the measurement
      Serial.print(dist);
      Serial.print(" cm Signal: ");
      Serial.println(strength);

      //MQWW Connectionint
      ensureMQTTConnection();
      static unsigned long last = millis();
      if (millis() - last >= IDLE_TIME *1000) {
      last = millis();
      int waterlevel = tfmini.getDistance();
      char cdist[16];
      itoa(waterlevel ,cdist, 10);
      client.publish(MQTT_TOPIC_NAME_LEVEL_CM, cdist);
      }
      client.loop();
      ArduinoOTA.handle();
      delay(1000);
      }
      }

      Die TFMini.cpp


      /*
      Arduino driver for Benewake TFMini time-of-flight distance sensor.
      by Peter Jansen (December 11/2017)
      This code is open source software in the public domain.

      THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY
      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY
      DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
      ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

      The names of the contributors may not be used to endorse or promote products
      derived from this software without specific prior written permission.
      */

      #include "TFMini.h"

      // Constructor
      TFMini::TFMini() {
      // Empty constructor
      }

      boolean TFMini::begin(Stream* _streamPtr) {
      // Store reference to stream/serial object
      streamPtr = _streamPtr;

      // Clear state
      distance = -1;
      strength = -1;
      state = READY;

      // Set standard output mode
      setStandardOutputMode();

      return true;
      }

      // Public: The main function to measure distance.
      uint16_t TFMini::getDistance() {
      int numMeasurementAttempts = 0;
      while (takeMeasurement() != 0) {
      numMeasurementAttempts += 1;
      if (numMeasurementAttempts > TFMINI_MAX_MEASUREMENT_ATTEMPTS) {
      // Serial.println ("TF Mini error: too many measurement attempts");
      // Serial.println ("Last error:");
      if (state == ERROR_SERIAL_NOHEADER) //Serial.println("ERROR_SERIAL_NOHEADER");
      if (state == ERROR_SERIAL_BADCHECKSUM) //Serial.println("ERROR_SERIAL_BADCHECKSUM");
      if (state == ERROR_SERIAL_TOOMANYTRIES) //Serial.println("ERROR_SERIAL_TOOMANYTRIES");

        state = ERROR_SERIAL_TOOMANYTRIES;
        distance = -1;
        strength = -1;
        return -1;
      }
      

      }

      if (state == MEASUREMENT_OK) {
      return distance;
      } else {
      return -1;
      }
      }

      // Public: Return the most recent signal strength measuremenet from the TF Mini
      uint16_t TFMini::getRecentSignalStrength() {
      return strength;
      }

      // Private: Set the TF Mini into the correct measurement mode
      void TFMini::setStandardOutputMode() {
      // Set to "standard" output mode (this is found in the debug documents)
      streamPtr->write((uint8_t)0x42);
      streamPtr->write((uint8_t)0x57);
      streamPtr->write((uint8_t)0x02);
      streamPtr->write((uint8_t)0x00);
      streamPtr->write((uint8_t)0x00);
      streamPtr->write((uint8_t)0x00);
      streamPtr->write((uint8_t)0x01);
      streamPtr->write((uint8_t)0x06);

      delay(100);
      }

      // Private: Handles the low-level bits of communicating with the TFMini, and detecting some communication errors.
      int TFMini::takeMeasurement() {
      int numCharsRead = 0;
      uint8_t lastChar = 0x00;

      // Step 1: Read the serial stream until we see the beginning of the TF Mini header, or we timeout reading too many characters.
      while (1) {

      if (streamPtr->available()) {
        uint8_t curChar = streamPtr->read();
      
        if ((lastChar == 0x59) && (curChar == 0x59)) {
          // Break to begin frame
          break;
      
        } else {
          // We have not seen two 0x59's in a row -- store the current character and continue reading.
          lastChar = curChar;
          numCharsRead += 1;
        }
      }
      
      // Error detection:  If we read more than X characters without finding a frame header, then it's likely there is an issue with
      // the Serial connection, and we should timeout and throw an error.
      if (numCharsRead > TFMINI_MAXBYTESBEFOREHEADER) {
        state = ERROR_SERIAL_NOHEADER;
        distance = -1;
        strength = -1;
        if (TFMINI_DEBUGMODE == 1)// Serial.println("ERROR: no header");
        return -1;
      }
      

      }

      // Step 2: Read one frame from the TFMini
      uint8_t frame[TFMINI_FRAME_SIZE];

      uint8_t checksum = 0x59 + 0x59;
      for (int i=0; i<TFMINI_FRAME_SIZE; i++) {
      // Read one character
      while (!streamPtr->available()) {
      // wait for a character to become available
      }
      frame[i] = streamPtr->read();

      // Store running checksum
      if (i < TFMINI_FRAME_SIZE-2) {
        checksum += frame[i];
      }
      

      }

      // Step 2A: Compare checksum
      // Last byte in the frame is an 8-bit checksum
      uint8_t checksumByte = frame[TFMINI_FRAME_SIZE-1];
      if (checksum != checksumByte) {
      state = ERROR_SERIAL_BADCHECKSUM;
      distance = -1;
      strength = -1;
      if (TFMINI_DEBUGMODE == 1)// Serial.println("ERROR: bad checksum");
      return -1;
      }

      // Step 3: Interpret frame
      uint16_t dist = (frame[1] << 😎 + frame[0];
      uint16_t st = (frame[3] << 😎 + frame[2];
      uint8_t reserved = frame[4];
      uint8_t originalSignalQuality = frame[5];

      // Step 4: Store values
      distance = dist;
      strength = st;
      state = MEASUREMENT_OK;

      // Return success
      return 0;
      }

      Die config.h


      #define WIFI_SSID "xxxxxxxxx" //enter SSID and pass without <>
      #define WIFI_PASS "xxxxxxxxxxxxxxxxxxx"

      #define MQTT_SERVER_IP "192.168.1.141"
      #define MQTT_SERVER_PORT 1886

      #define MQTT_CLIENT_NAME "cistern-sensor"
      #define MQTT_SERVER_USER_ID "xxxxxxxxxx" // leave quotes empty, if no authentication is required
      #define MQTT_SERVER_PASS "xxxxxxxxxxxxx"

      //#define MQTT_TOPIC_NAME_LEVEL_PERCENT "cistern/level/percent"
      //#define MQTT_TOPIC_NAME_LEVEL_LITERS "cistern/level/liters"
      #define MQTT_TOPIC_NAME_LEVEL_CM "cistern/level/cm"

      #define TRIGGER_PIN 5 //~D1
      #define ECHO_PIN 4 //~D2

      #define SENSOR_DISTANCE_TO_MAX_VOLUME 0 // in cm - minimum is 21
      #define SENSOR_OFFSET 2 // use ruler and the mqtt topic cistern/level/cm to calibrate this value

      #define IDLE_TIME 180 // in seconds

      #define TIME_PERIOD_BETWEEN_READINGS 30 // in seconds
      #define SAMPLE_SIZE 10

      //#define CISTERN_HEIGHT 290 // in cm
      //#define CISTERN_LENGTH 200 // in cm

      /** ===============ADVANCED SETTINGS==================== **/

      #define TRIGGER_PULSE_WIDTH 15 // in microseconds - adjust this setting if your sensor doesn't send the pulse

      #define READING_TIMEOUT 60 // in milliseconds - max is 60ms - post-pulse time period after which the MCU gives up waiting for a return signal

      Ich hoffe, dass mir jemand helfen kann.
      Ich weiß nicht weiter!

      Vergessen! Die Ausgabe vom Seriell Monitor:


      14:15:55.683 ->
      14:15:55.683 -> ets Jan 8 2013,rst cause:4, boot mode:(3,7)
      14:15:55.683 ->
      14:15:55.683 -> wdt reset
      14:15:55.683 -> load 0x4010f000, len 1392, room 16
      14:15:55.718 -> tail 0
      14:15:55.718 -> chksum 0xd0
      14:15:55.718 -> csum 0xd0
      14:15:55.718 -> v3d128e5c
      14:15:55.718 -> ~ld
      14:15:55.891 -> Initializing Serial and mySerial finished
      14:15:56.378 -> ..
      14:15:56.899 -> WiFi connected
      14:15:56.899 -> IP address:
      14:15:56.899 -> 192.168.1.162
      14:16:15.680 -> 5 cm Signal: 10624
      14:16:15.680 -> Attempting MQTT connection...
      14:16:15.715 -> connected
      14:16:23.365 ->
      14:16:23.365 -> ets Jan 8 2013,rst cause:4, boot mode:(3,7)
      14:16:23.365 ->
      14:16:23.365 -> wdt reset
      14:16:23.365 -> load 0x4010f000, len 1392, room 16
      14:16:23.400 -> tail 0
      14:16:23.400 -> chksum 0xd0
      14:16:23.400 -> csum 0xd0
      14:16:23.400 -> v3d128e5c
      14:16:23.400 -> ~ld
      14:16:23.572 -> Initializing Serial and mySerial finished
      14:16:24.058 -> ..
      14:16:24.582 -> WiFi connected
      14:16:24.582 -> IP address:
      14:16:24.582 -> 192.168.1.162
      14:16:31.849 ->
      14:16:31.849 -> ets Jan 8 2013,rst cause:4, boot mode:(3,7)
      14:16:31.849 ->
      14:16:31.849 -> wdt reset
      14:16:31.849 -> load 0x4010f000, len 1392, room 16
      14:16:31.849 -> tail 0
      14:16:31.884 -> chksum 0xd0
      14:16:31.884 -> csum 0xd0
      14:16:31.884 -> v3d128e5c
      14:16:31.884 -> ~ld
      14:16:32.056 -> Initializing Serial and mySerial finished
      14:16:32.541 -> ..
      14:16:33.061 -> WiFi connected
      14:16:33.061 -> IP address:
      14:16:33.061 -> 192.168.1.162
      14:16:43.517 ->
      14:16:43.517 -> ets Jan 8 2013,rst cause:4, boot mode:(3,7)
      14:16:43.517 ->
      14:16:43.517 -> wdt reset
      14:16:43.552 -> load 0x4010f000, len 1392, room 16
      14:16:43.552 -> tail 0
      14:16:43.552 -> chksum 0xd0
      14:16:43.552 -> csum 0xd0
      14:16:43.552 -> v3d128e5c
      14:16:43.552 -> ~ld
      14:16:43.723 -> Initializing Serial and mySerial finished
      14:16:44.243 -> ..
      14:16:44.728 -> WiFi connected
      14:16:44.728 -> IP address:
      14:16:44.728 -> 192.168.1.162
      14:17:03.539 -> 5 cm Signal: 10910
      14:17:03.539 -> Attempting MQTT connection...
      14:17:03.539 -> connected

      joergeli 1 Reply Last reply Reply Quote 0
      • joergeli
        joergeli @Superdad last edited by joergeli

        @Superdad
        Hi,
        so wie es in der Ausgabe vom seriellen Monitor aussieht, macht die NodeMCU in unregelmäßigen, rel. kurzen Abständen ( ca. 10 bis 30 Sekunden) einen Reboot ( wdt reset ).
        Mal läuft es so weit, bis die Wifi-Connection steht, manchmal aber auch bis MQTT verbunden ist.

        Ich tippe auf ein Timing-Problem, aber wo das auftritt, bzw. wie man es beheben kann, kann ich auch nicht sagen.
        (Ich hatte auch mal mit einem RGB-Stripe ständige Reboots, bis ich an entspr. Stelle ein delay(1) = 1 Millisekunde eingefügt habe.)

        Ein Schuss in's Blaue:
        Ich würde zum Testen erst mal alles, was mit OTA ( Flashen via WLAN) zu tun hat, auskommentieren / löschen und dann nochmals im seriellen Monitor beobachten, ob immer noch Reboots autreten.

        Evtl. solltest Du Dein Problem auch mal in einem Arduino-Forum posten.

        S 1 Reply Last reply Reply Quote 0
        • S
          Superdad @joergeli last edited by

          @joergeli Erstmal vielen Dank für deine Antwort.
          Ich werde es mal ausprobieren.

          1 Reply Last reply Reply Quote 0
          • S
            Superdad last edited by

            Habe jetzt weiter probiert.
            OTA raus zu nehmen hat nichts gebracht.
            Im Arduino-Forum habe ich auch keine Antwort erhalten.

            Habe dann noch einmal Google belästigt und bin auf eine Seite gestossen, wo angeraten wurde RX und TX auf D5 und D6 zu setzen.
            Ausprobiert und läuft.

            Jetzt muss ich dann nur noch testen, wie der Sensor so läuft im Dauerbetrieb.

            1 Reply Last reply Reply Quote 0
            • S
              Superdad last edited by

              Der TFMini hängt jetzt seit 5 Tagen neben dem HC-SR04 in der Zisterne.

              Die Messgenauigkeit beim TFMini Plus ist bis auf 1cm genau.
              Der HC-SR04 hat bis zu 12cm Abweichungen.
              Außerdem hat der HC-SR04 während der kalten Jahreszeit seinen Meßbetrieb komplett eingestellt.

              Bin bis jetzt hoch zufrieden mit dem TFMini Plus und kann ihn weiter empfehlen.
              Klar ist er einiges teurer als der HC-SR04, aber das ist es mir wert.

              1 Reply Last reply Reply Quote 0
              • wendy2702
                wendy2702 last edited by

                Hi,

                bist du noch immer mit dem TF Mini zufrieden?

                Wenn ja, kannst du eine Zeichnung bereitstellen wie genau du den angeschlossen hast und die ganzen Code sachen!?

                Danke und Gruß

                1 Reply Last reply Reply Quote 0
                • S
                  Superdad last edited by

                  Bis auf ein paar Aussetzer, wo er mal Mist mißt, bin ich sehr zufrieden.
                  Die sind aber eher selten.
                  Für mich bisher die beste Füllstandsmessung.

                  Bin erst morgen Abend wieder zu Hause.
                  Und da ich den sowieso noch einmal ausbauen wollte um OTA zu aktivieren, kann ich dann Fotos machen.
                  Den Code den ich am Ende dann verwendet habe, sollte der gleiche sein wie oben.
                  Lese den aber noch einmal aus und poste ihn dann.

                  Wie gesagt, ich bin zufrieden damit.
                  Vielleicht kannst du ja dann noch einmal über den Code schauen und findest ein paar Verbesserungen.

                  1 Reply Last reply Reply Quote 0
                  • S
                    Superdad last edited by

                    Wie versprochen ein paar Fotos.
                    Musste heute sowieso alles neu machen, da durch das Gewitter meine Box geflutet war.
                    Habe jetzt erstmal alles mit Silikon abgedichtet.

                    Die NodeMCU ist eine Amica.
                    Habe es mit einer anderen NodeMCU probiert, hat aber nicht funktioniert.
                    Warum auch immer.

                    Das sind die Kabel, die vom TFMini Plus kommen.
                    Die habe ich dann mit lila, grau, weiß und schwarz verlängert.

                    ![alt text](IMG_0576[1].JPG image url)

                    Dann die NodeMCU.
                    Da geht lila auf Vin, Schwarz auf Grd, Weiß auf D5 und Grau auf D6.

                    ![alt text](IMG_0581[1].JPG image url)

                    Und zum Schluss das Arduino-Programm.
                    mqtt_iobroker_richtig .zip

                    In der config.h musst du dein Wlanname und Passwort einsetzen.
                    Ebenso der IP-Adresse für Mqtt und Benutzer und Passwort.
                    Mqtt-Client-Name kannst du nach deinem Bedürfniss anpassen.

                    Wie gesagt, ich bin nicht der Arduinoguru und es sind bestimmt auch noch Fehler im Programm.
                    Ich habe mir das selber zusammen "gestrickt".
                    Sicherlich ist auch einiges zuviel drin, was man rausnehmen könnte.

                    Wenn du eine bessere Lösung finden solltest, kannst du ja mal was dazu schreiben.

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post

                    Support us

                    ioBroker
                    Community Adapters
                    Donate

                    912
                    Online

                    31.7k
                    Users

                    79.9k
                    Topics

                    1.3m
                    Posts

                    arduino nodemcu tfmini
                    3
                    8
                    983
                    Loading More Posts
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes
                    Reply
                    • Reply as topic
                    Log in to reply
                    Community
                    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                    The ioBroker Community 2014-2023
                    logo