HB-UNI-Sen-DIST / LEV-US

Entwicklung und Bau von Hardware aller Art, die im HM-Umfeld eingesetzt werden kann

Moderator: Co-Administratoren

tonischabloni
Beiträge: 76
Registriert: 16.05.2019, 10:10
Hat sich bedankt: 11 Mal
Danksagung erhalten: 11 Mal

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von tonischabloni » 12.10.2019, 23:20

Anbei meine Version für eine Gehäuse von dem Ultraschall Abstands Sensor HB-UNI-Sen-DIST-US von Jerome https://github.com/jp112sdl/HB-UNI-Sen-DIST-US mit der Platine von Pafra https://github.com/pafra-123/AskSin_Uni_PCB

Zu finden ist das Gehäuse auf Thingiverse https://www.thingiverse.com/thing:3899526
IMG_7314.jpeg
IMG_6737.jpeg
dd439342-aa7b-43f4-a763-b9a5063aa92c.jpeg

Bengel00
Beiträge: 34
Registriert: 04.03.2015, 12:56
Hat sich bedankt: 1 Mal

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von Bengel00 » 26.08.2020, 19:31

Hallo Gemeinde,
ich hab jetzt seid ca einem halben Jahr Jeromes HB-UNI-Sen-LEV-US in meiner Zisterne im einsatz. Da meine Zisterne eine sehr unnormale Form hat, will ich den scetch soweit anpassen mittels wertetabelle oder so um den ungefähren Inhalt auszugeben. Momantan gebe ich mir nur den abstand Sensor-Wasseroberfläche aus und will das demnächst weiter voran treiben. Dazu benutze ich folgenden sketch

Code: Alles auswählen

#define EI_NOTEXTERNAL
#include <EnableInterrupt.h>
#include <AskSinPP.h>
#include <LowPower.h>
#include <Register.h>
#include <MultiChannelDevice.h>
#define CONFIG_BUTTON_PIN  8
#define LED_PIN            4

#define SENSOR_EN_PIN      5 //VCC Pin des Sensors
#define SENSOR_ECHO_PIN    6
#define SENSOR_TRIG_PIN    14 //A0
#define BATT_EN_PIN        15
#define BATT_SENS_PIN      17

// number of available peers per channel
#define PEERS_PER_CHANNEL 2

// all library classes are placed in the namespace 'as'
using namespace as;

//Korrekturfaktor der Clock-Ungenauigkeit, wenn keine RTC verwendet wird
#define SYSCLOCK_FACTOR    0.88
#define MAX_MEASURE_COUNT  5

/* enum UltrasonicSensorTypes {
  JSN_SR04T_US100,
  MAXSONAR
}; */

// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
  {0xF9, 0xD2, 0x01},          // Device ID
  "JPLEV00001",                // Device Serial
  {0xF9, 0xD2},                // Device Model
  0x10,                        // Firmware Version
  0x53,                        // Device Type
  {0x01, 0x01}                 // Info Bytes
};

/**
   Configure the used hardware
*/
typedef AskSin<StatusLed<LED_PIN>, BatterySensorUni<BATT_SENS_PIN, BATT_EN_PIN, 0>, Radio<AvrSPI<10, 11, 12, 13>, 2>> BaseHal;
class Hal : public BaseHal {
  public:
    void init (const HMID& id) {
      BaseHal::init(id);
      battery.init(seconds2ticks(60UL * 60) * SYSCLOCK_FACTOR, sysclock); //battery measure once an 60 min
      battery.low(22);
      battery.critical(19);
    }

    bool runready () {
      return sysclock.runready() || BaseHal::runready();
    }
} hal;


DEFREGISTER(UReg0, MASTERID_REGS, DREG_LOWBATLIMIT, 0x20, 0x21)
class UList0 : public RegList0<UReg0> {
  public:
    UList0 (uint16_t addr) : RegList0<UReg0>(addr) {}

    bool Sendeintervall (uint16_t value) const {
      return this->writeRegister(0x20, (value >> 8) & 0xff) && this->writeRegister(0x21, value & 0xff);
    }
    uint16_t Sendeintervall () const {
      return (this->readRegister(0x20, 0) << 8) + this->readRegister(0x21, 0);
    }

    void defaults () {
      clear();
      lowBatLimit(22);
      Sendeintervall(600);
    }
};

DEFREGISTER(UReg1, CREG_CASE_HIGH, CREG_CASE_WIDTH, CREG_CASE_DESIGN, CREG_CASE_LENGTH, 0x01, 0x02, 0x03)
class UList1 : public RegList1<UReg1> {
  public:
    UList1 (uint16_t addr) : RegList1<UReg1>(addr) {}

    bool distanceOffset (uint16_t value) const {
      return this->writeRegister(0x01, (value >> 8) & 0xff) && this->writeRegister(0x02, value & 0xff);
    }
    uint16_t distanceOffset () const {
      return (this->readRegister(0x01, 0) << 8) + this->readRegister(0x02, 0);
    }

    bool sensorType (uint16_t value) const {
      return this->writeRegister(0x03, value & 0xff);
    }
    uint16_t sensorType () const {
      return this->readRegister(0x03, 0);
    }

    void defaults () {
      clear();
      caseHigh(100);
      caseWidth(100);
      caseLength(100);
      caseDesign(0);
      distanceOffset(0);
      sensorType(0);
    }
};

class MeasureEventMsg : public Message {
  public:
    void init(uint8_t msgcnt, uint8_t percent, uint32_t liter, uint8_t volt) {
      Message::init(0x0f, msgcnt, 0x53, BIDI | WKMEUP, percent & 0xff, volt & 0xff);
      pload[0] = (liter >>  24) & 0xff;
      pload[1] = (liter >>  16) & 0xff;
      pload[2] = (liter >>  8) & 0xff;
      pload[3] = liter & 0xff;
    }
};

class MeasureChannel : public Channel<Hal, UList1, EmptyList, List4, PEERS_PER_CHANNEL, UList0>, public Alarm {
    MeasureEventMsg msg;
    uint32_t fillingPercent;
    uint32_t fillingLiter;
    uint16_t distance;

    uint8_t last_flags = 0xff;

  public:
    MeasureChannel () : Channel(), Alarm(0), fillingLiter(0), fillingPercent(0)  {}
    virtual ~MeasureChannel () {}

	void measure() {
      uint32_t m_value = 0;
      // loeschen - uint16_t temp = 0;
	  uint16_t abstand = 0;
	  uint32_t fillingHeight;
      uint32_t ZisternenVolume = 6000;  //Maximales Volumen der Zisterne 
 
  	  // ** Ausgabe der Pins bei der Messung	
	  uint8_t en;
      uint8_t trig;
	  uint8_t echo;
   	  en = digitalRead(SENSOR_EN_PIN);
      trig = digitalRead(SENSOR_TRIG_PIN);
	  echo = digitalRead(SENSOR_EN_PIN);
/* 	  // DPRINT(F("#####                 en: ")); DDECLN(en);
	  // DPRINT(F("#####               trig: ")); DDECLN(trig);
	  // PRINT(F("#####               echo: ")); DDECLN(echo); */	
      
	  
	  
//######################################################################
      
	  int x = 0; // Initialisiere x mit Wert 0
      uint32_t m_value_all = 0;
	  
      do 
	    {
	    _delay_ms(300);
      
	    digitalWrite(SENSOR_EN_PIN, HIGH);
        _delay_ms(300);
        digitalWrite(SENSOR_TRIG_PIN, LOW);
        delayMicroseconds(2);
  	    digitalWrite(SENSOR_TRIG_PIN, HIGH);
		delayMicroseconds(10);
		digitalWrite(SENSOR_TRIG_PIN, LOW);

		m_value = pulseIn(SENSOR_ECHO_PIN, HIGH);   // Lies den Sensorwert
		DPRINT(F("#####            m_value: ")); DDECLN(m_value);
		DPRINT(F("#####            m_value: ")); DDECLN(m_value_all);
		m_value_all = m_value_all + m_value;
		x++;                //Inkrementiere die Zählervariable
        } 
	  while (x < 5);    // Wiederhole das ganze 5 Mal
      m_value = m_value_all / x;
	  DPRINT(F("#####            m_value: ")); DDECLN(m_value);
	  
//#####################################################################
 
 
      abstand = (m_value * 10000L / 57874L * 2);
	  
	  fillingLiter = abstand;
      fillingPercent = abstand;
	  
	  digitalWrite(SENSOR_EN_PIN, LOW);
	  
	  
/* 	 // DPRINT(F("#####            m_value: ")); DDECLN(m_value);
     // DPRINT(F("#####       abstand (mm): ")); DDECLN(abstand);

	 // fillingHeight = 3000 - abstand;  // groeste entfernung - abstand
	 // DPRINT(F("##### fillingHeight (mm): ")); DDECLN(fillingHeight);
	  
	 // fillingLiter = fillingHeight;
	
	 // fillingPercent = (fillingLiter * 100) / ZisternenVolume;
     // DPRINT(F("Behaeltervolumen (gesamt): ")); DDECLN(ZisternenVolume);
     // DPRINT(F("               Inhalt (l): ")); DDECLN(fillingLiter); 
	 // DPRINT(F("               Inhalt (%):")); DDECLN(fillingPercent);
     // DPRINTLN(""); */
	 
    }
	
	
    virtual void trigger (__attribute__ ((unused)) AlarmClock & clock) {
      uint8_t msgcnt = device().nextcount();
      if (last_flags != flags()) {
        this->changed(true);
        last_flags = flags();
      }
      measure();
      tick = delay();
      msg.init(msgcnt, fillingPercent, fillingLiter, device().battery().current());
      if (msgcnt % 20 == 1) device().sendPeerEvent(msg, *this); else device().broadcastEvent(msg, *this);
      sysclock.add(*this);
    }

    uint32_t delay () {
      uint16_t _txMindelay = 20;
      _txMindelay = device().getList0().Sendeintervall();
      if (_txMindelay == 0) _txMindelay = 20;
      return seconds2ticks(_txMindelay  * SYSCLOCK_FACTOR);
    }



    void setup(Device<Hal, UList0>* dev, uint8_t number, uint16_t addr) {
      Channel::setup(dev, number, addr);
      pinMode(SENSOR_ECHO_PIN, INPUT_PULLUP);
      pinMode(SENSOR_TRIG_PIN, OUTPUT);
      pinMode(SENSOR_EN_PIN, OUTPUT);
      sysclock.add(*this);
    }

    uint8_t status () const {
      return 0;
    }

    uint8_t flags () const {
      uint8_t flags = this->device().battery().low() ? 0x80 : 0x00;
      return flags;
    }
};

class UType : public MultiChannelDevice<Hal, MeasureChannel, 1, UList0> {
  public:
    typedef MultiChannelDevice<Hal, MeasureChannel, 1, UList0> TSDevice;
    UType(const DeviceInfo& info, uint16_t addr) : TSDevice(info, addr) {}
    virtual ~UType () {}

    virtual void configChanged () {
      TSDevice::configChanged();
      DPRINT(F("*LOW BAT Limit: "));
      DDECLN(this->getList0().lowBatLimit());
      this->battery().low(this->getList0().lowBatLimit());
      DPRINT(F("*Sendeintervall: ")); DDECLN(this->getList0().Sendeintervall());
    }
};

UType sdev(devinfo, 0x20);
ConfigButton<UType> cfgBtn(sdev);

void setup () {
  DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  sdev.init(hal);
  buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
  DDEVINFO(sdev);
  sdev.initDone();
}

void loop() {
  bool worked = hal.runready();
  bool poll = sdev.pollRadio();
  if ( worked == false && poll == false ) {
    if ( hal.battery.critical() ) {
      hal.activity.sleepForever(hal);
    }
    hal.activity.savePower<Sleep<>>(hal);
  }
}
Nun zu meinem Problem. Der abstand Sensor-Wasseroberfläche vareiert sehr stark um so max 10-12mm hoch und runter, wenn ich den sensor auf eine Zimmerwand richte bringt er auf den mm konstante werte. Ist das bei Wasser evtl so das der immer mal unterschiedliche werte bringt oder was ist hier faul? ich hab ihn momentan um Haus über einem Becken mit wasser gefüllt hängen, da brint er auch Werte 2mm hoch - 2mm runter. Also auch nix konstantes. ICh weiß Ist krümelkackerei, aber wenn der Sensor es genauer kann soll er es auch genau anzeigen ;-)

jp112sdl
Beiträge: 12108
Registriert: 20.11.2016, 20:01
Hat sich bedankt: 848 Mal
Danksagung erhalten: 2148 Mal
Kontaktdaten:

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von jp112sdl » 26.08.2020, 19:37

Hi,
Bengel00 hat geschrieben:
26.08.2020, 19:31
da brint er auch Werte 2mm hoch - 2mm runter
das könnte an der Lufttemperatur liegen.
Ich hab vor einiger Zeit mal die Temperaturkompensation mit eingebaut:
https://github.com/jp112sdl/HB-UNI-Sen- ... US.ino#L11

VG,
Jérôme ☕️

---
Support for my Homebrew-Devices: Download JP-HB-Devices Addon

Bengel00
Beiträge: 34
Registriert: 04.03.2015, 12:56
Hat sich bedankt: 1 Mal

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von Bengel00 » 26.08.2020, 21:40

Aber warum macht er das dann nur wenn er den Wasserstand mist? Wenn er gegen eine Wand Pingt bringt er ja immer konstante Werte.

cmjay
Beiträge: 2386
Registriert: 19.09.2012, 10:53
System: CCU
Wohnort: Jottweedee
Hat sich bedankt: 250 Mal
Danksagung erhalten: 351 Mal

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von cmjay » 26.08.2020, 22:42

Aber warum macht er das dann nur wenn er den Wasserstand mist? Wenn er gegen eine Wand Pingt bringt er ja immer konstante Werte.
Vielleicht hast du Mehrfachreflexionen von den Behälterwänden, die du beim Messen gegen die Zimmerwand nicht hast.
Es kann leider nicht ganz ausgeschlossen werden, dass ich mich irre.
HmIP muss leider draussen bleiben. in Ausnahmefällen erlaubt
ACHTUNG! Per Portweiterleitung aus dem Internet erreichbare CCU-WebUI ist unsicher! AUCH MIT PASSWORTSCHUTZ! Daher: Portweiterleitung deaktivieren!

ad.rian
Beiträge: 2
Registriert: 24.09.2020, 13:53
System: Alternative CCU (auf Basis OCCU)

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von ad.rian » 24.09.2020, 13:57

Hallo zusammen,

ich habe diesen Sensor (LEV-US) auch nachgebaut, funktionierte (fast) auf Anhieb und der Einbau steht kurz bevor, bin sehr gespannt... Eine Frage habe ich allerdings, auf die ich nirgendwo eine Antwort finden konnte - nachdem ich den Sensor in der Variante ohne Temperaturfühler gebaut habe, erscheint nun immer eine Servicemeldung "Fehler Temperatursensor" deswegen. Kann man diese selektiv deaktivieren?

Vielen Dank :-)

jp112sdl
Beiträge: 12108
Registriert: 20.11.2016, 20:01
Hat sich bedankt: 848 Mal
Danksagung erhalten: 2148 Mal
Kontaktdaten:

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von jp112sdl » 24.09.2020, 14:38

ad.rian hat geschrieben:
24.09.2020, 13:57
nachdem ich den Sensor in der Variante ohne Temperaturfühler gebaut habe
...dann musst du Zeile 11 auskommentieren.

Also erstmal Gerät ablernen, Code ändern + neu flashen, Gerät neu anlernen.

VG,
Jérôme ☕️

---
Support for my Homebrew-Devices: Download JP-HB-Devices Addon

ad.rian
Beiträge: 2
Registriert: 24.09.2020, 13:53
System: Alternative CCU (auf Basis OCCU)

Re: HB-UNI-Sen-DIST / LEV-US

Beitrag von ad.rian » 25.09.2020, 21:53

Danke für die schnelle und präzise Antwort, das ist ja eine einfache Übung!
Ansonsten liefert der Sensor bereits seit knapp 2 Tagen gute Daten aus der Zisterne (jedenfalls, solange diese nicht "plätschernd" aufgefüllt wird), ist somit wirklich eine schöne und nützliche Erweiterung :-)

Antworten

Zurück zu „Hardwareentwicklung und Selbstbau von Aktoren und Sensoren“