pa-pa / AskSinPP

104 stars 71 forks source link

Füllstandssensor mit lokaler Displayanzeige #191

Closed HMelzer closed 4 years ago

HMelzer commented 4 years ago

Hallo, ich wende mich heute an euch, weil ich mit o.g. Projekt einfach nicht weiter komme: Ich beabsichtige, eine Füllstandsmessung mittels Ultraschallsensor HC-SR04 zu realisieren, bei gleichzeitiger Temperaturmessung, um die Temperaturabhängigkeit der Schallgeschwindigkeit zu kompensieren, und den Füllstand und die Temperatur lokal auf einem OLED-Display 128x64 anzuzeigen. Dazu verwende ich einen Arduino Pro mini. Das funktioniert auch hervorragend, wenn ich den folgenden Beispiel-Skech verwende:

`[code] / Fuellstandssensor V.1.0 Autor: H. Melzer Grundlage: Ardudronix https://www.ardutronix.de /

// Variable deklarieren int verzoegerung = 5000; double entfernung = 0.0; double heightTank=110.0, fuellhoehe;

//Definitionen fuer HC-SR04

define TRIG_PIN 7

define ECHO_PIN 6

//Display-Bibliotheken einbinden

include

include

//Bibliothek für den Temperaturfüler

include

//DS18B20 Sensors verbunden mit Pin 3 OneWire oneWire(3);

//Ultrasonic-Sensor einbinden

include "src\HCSR04.h"

// Auflösung des Displays setzen

define SCREEN_WIDTH 128 // OLED display width, in pixels

define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

define Dallas

//Initialisierung des Sensor zur Benutzung der Digital-Pins 7 und 6 //UltraSonicDistanceSensor distanceSensor(trigger, echo); UltraSonicDistanceSensor distanceSensor(TRIG_PIN, ECHO_PIN); DallasTemperature sens_temp(&oneWire);

void setup() { //Einrichten der Kommunikation mit der Arduino IDE Serial.begin (115200); Serial.println("Temperatursensor - DS18B20");

//Starten der Kommunikation mit dem Sensor sens_temp.begin();

//Display mit I2C-Adresse 0x3c initialisieren if(!display.begin(/SSD1306_EXTERNALVCC/SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); }

display.clearDisplay(); //Verhindert die Anzeige des Adafruit-Logos display.display();//Bereitet nächste Anzeige vor display.setTextColor(WHITE); //Textfarbe setzen (hier tatsächlich aber nicht weiß display.setFont(); //Standard-Text-Font verwenden }

void loop() { sens_temp.requestTemperatures(); //Temperatur abfragen float temperature = sens_temp.getTempCByIndex(0); //Temperatur des Gerätes mit Index 0 in Variable schreiben //Ausgabe an Serial Monitor in °C und °F Serial.println("Temperature: "); Serial.print(sens_temp.getTempCByIndex(0));Serial.println("°C"); Serial.print(sens_temp.getTempFByIndex(0));Serial.println("°F"); Serial.println();

double entfernung = distanceSensor.measureDistanceCm(temperature);

// Füllhöhe berechnen fuellhoehe = heightTank - entfernung;

//Ausgabe an Serial Monitor Serial.println(entfernung); Serial.println(fuellhoehe); Serial.println("");

if (fuellhoehe >= heightTank-10 || fuellhoehe < 0) { display.clearDisplay(); display.setTextSize(2); display.setCursor(18, 0); display.println("Achtung!"); display.setCursor(16, 20); display.println("Messwert"); display.setCursor(4, 40); display.println("fehlerhaft"); display.display(); } else { display.clearDisplay(); display.invertDisplay(false); display.setCursor(18, 0); display.setTextSize(2); display.println("F\x81\llh\x94\he"); display.setCursor(20, 20); display.setTextSize(2); display.print(fuellhoehe); display.println(" cm"); display.drawLine (10, 38, display.width ()-10, 38 , WHITE); display.setCursor(20, 46); display.print(temperature); display.print(" \xf7\C"); display.display(); } delay(verzoegerung); } [/code] ` Hier der Versuchsaufbau mit der Anzeige: Versuchsaufbau

In der Folge habe ich nun das Ergebnis auf eine Implementierung für Homematic mit AskSinPP anzuwenden versucht. Schwierig hierbei war erst einmal, den Programmumfang so zu gestalten, dass der Speicher ausreichte, was nur mit einigen Tricks und unter Verwendung der Master-Version oder Version 3 der AskSinPP gelang. Ein Problem konnte ich jedoch nicht beseitigen: Eine Initialisierung des Displays mit der erforderlichen I2C-Adresse 0x3C gelang nur, wenn ich die Anzeigegröße verringert habe. Interessanterweise funktioniert es wieder bei 128 x 56, Allerdings wird in jedem Fall nicht jedes Pixel angesprochen, das Display lässt praktisch jede zweite Zeile aus. Hier die Anzeige im Vergleich, wobei auch das Setzen der Textgröße nichts bringt: AnzeigeAnzeige

Auch die DEPRECATED-Version für das Adafruit-Display (Zeile 46+47 des Sketches) liefert die gleichen Ergebnisse). Hat AsksinPP ein Problem mit I2C oder der Adresse 0x3C oder liegt es an der geänderte Bibliothek für den Temperatursensor? Nachfolgend mein Code, wie erzwar funktioniert, aber eben nicht zufriedenstellend:

` [code] //--------------------------------------------------------- // Fuellstandssensor V.1.0 // HB-Sonic-Lev1 // (C) 2020 H. Melzer (Creative Commons) // https://creativecommons.org/licenses/by-nc-sa/4.0/ // You are free to Share & Adapt under the following terms: // Give Credit, NonCommercial, ShareAlike// +++ // AskSin++ 2016-10-31 papa Creative Commons // Basics: Ardudronix // https://www.ardutronix.de, // arduino-lib-hc-sr04 from Martin Sosic // https://github.com/Martinsos/arduino-lib-hc-sr04 // Sens_DS18X20 // 2018-08-12 Tom Major (Creative Commons) //---------------------------------------------------------

//--------------------------------------------------------- // !! NDEBUG sollte aktiviert werden, wenn die Sensorentwicklung und die Tests abgeschlossen sind und das Gerät in den 'Produktionsmodus' geht. // Damit wird Flash- und RAM-Speicher eingespart. // Insbesondere die RAM-Einsparungen sind wichtig für die Stabilität / dynamische Speicherzuweisungen etc. // Dies beseitigt dann auch die mögliche Arduino-Warnung 'Low memory available, stability problems may occur'. //

define NDEBUG

//---------------------------------------------------------

define EI_NOTEXTERNAL

include

include

include

include

include

include

include "Sens_DS18X20.h" // HB-UNI-Sensor1 custom sensor class

// Bibliotheken zur Kommunikation

include

include

include

ifdef NDEBUG

//Display-Bibliotheken einbinden

include

include

// Adafruit_SSD1306.h Zeile 29: #define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen //Adafruit_SSD1306 display(4);

// Definitionen für das Display

define SCREEN_WIDTH 128 // OLED display width, in pixels

define SCREEN_HEIGHT 32 // OLED display height, in pixels

//Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

endif;

// Pin Definitionen Allgemein

define CONFIG_BUTTON_PIN 8

define LED_PIN 4

// Pin und Address Definitionen Temperatur-Sensor

define ONEWIRE_PIN 3

//Definitionen fuer HC-SR04

define TRIG_PIN 7

define ECHO_PIN 6

// Sonstige Definitionen

define CLOCK_SYSCLOCK

define CLOCK sysclock

define SAVEPWR_MODE Sleep<>

UltraSonicDistanceSensor distanceSensor(TRIG_PIN, ECHO_PIN); // Initialize sensor.

// number of available peers per channel

define PEERS_PER_CHANNEL 6

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

// Hier Definition aller Geräteeigenschaften // Bei mehreren Geräten des gleichen Typs (Fuellstandssensor) muss Device ID und Device Serial unterschiedlich sein! // Device ID und Device Serial müssen an dieser Stelle geändert werden, damit die Geräte ordentlich angemeldet werden können.

define cDEVICE_ID { 0xF7, 0xA5, 0x03 }

define cDEVICE_SERIAL "HMSonicLe1"

const struct DeviceInfo PROGMEM devinfo = { cDEVICE_ID, // Device ID cDEVICE_SERIAL, // Device Serial { 0xF7, 0x01 }, // Device Model 0x10, // Firmware-Version 0x53, // Device Type { 0x01, 0x01 } // Info Bytes };

// Konfigure der verwendeten Hardware typedef AvrSPI<10, 11, 12, 13> SPIType; typedef Radio<SPIType, 2> RadioType; typedef StatusLed LedType; typedef AskSin<LedType, NoBattery, RadioType> BaseHal;

class Hal : public BaseHal { public: void init(const HMID& id) { BaseHal::init(id); }

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

} hal;

class MeasureEventMsg : public Message { public: void init(uint8_t msgcnt, int16_t temp, uint16_t Level_mm, uint8_t percent) { uint8_t t1 = (temp >> 8) & 0x7f; uint8_t t2 = temp & 0xff;

  // als Standard wird BCAST gesendet um Energie zu sparen, siehe Beschreibung unten.
  // Bei jeder 5. Nachricht senden wir stattdessen BIDI|WKMEUP, um eventuell anstehende Konfigurationsänderungen auch
  // ohne Betätigung des Anlerntaster übernehmen zu können (mit Verzögerung, worst-case 5x Sendeintervall).
  uint8_t flags = BCAST;
  if ((msgcnt % 5) == 1) {
    flags = BIDI | WKMEUP;
  }
  Message::init(14, msgcnt, 0x53, flags, t1, t2);
  // Message Length (first byte + param.): 11 + payload
  //  1 Byte payload -> length 12
  //  3 Byte payload -> length 14
  // max. payload: 17 Bytes (https://www.youtube.com/watch?v=uAyzimU60jw)

  // BIDI|WKMEUP: erwartet ACK vom Empfänger, ohne ACK wird das Senden wiederholt
  // LazyConfig funktioniert, d.h. eine anstehende Conf.Änderung von der CCU wird nach dem nächsten Senden übernommen. Aber erhöhter
  // Funkverkehr wegen ACK
  //
  // BCAST: ohne ACK zu Erwarten, Standard für HM Sensoren.
  // LazyConfig funktioniert nicht, d.h. eine anstehende Conf.Änderung von der CCU muss durch den Config Button am Sensor übernommen
  // werden!!

  // papa:
  // BIDI - fordert den Empfänger auf ein Ack zu schicken. Das wird auch zwingend für AES-Handling gebraucht. BCAST - signalisiert
  // eine Broadcast-Message. Das wird z.B. verwendet, wenn mehrere Peers vor einen Sensor existieren. Es wird dann an einen Peer
  // gesndet und zusätzlich das BCAST-Flag gesetzt. So dass sich alle die Nachrricht ansehen. Ein Ack macht dann natürlich keinen Sinn
  // - es ist ja nicht klar, wer das senden soll.
  //
  // WKMEUP - wird für LazyConfig verwendet. Ist es in einer Message gesetzt, so weiss
  // die Zentrale, dass das Geräte noch kurz auf weitere Nachrichten wartet. Die Lib setzt diese Flag für die StatusInfo-Message
  // automatisch. Außerdem bleibt nach einer Kommunikation der Empfang grundsätzlich für 500ms angeschalten.

  // Level
  pload[0] = (Level_mm >> 8) & 0xff;
  pload[1] = Level_mm & 0xff;

  // percent
  pload[2] = percent;
}

};

// die "freien" Register 0x20/21 werden hier als 16bit memory für das Update-Intervall in Sek., // die Register 0x22/0x23 für den konf. Parameter Bef_Hoehe_Sens und // die Register 0x34/0x35 für den konf. Parameter Max_Fuell_Hoehe benutzt

DEFREGISTER(Reg0, MASTERID_REGS, DREG_TRANSMITTRYMAX, 0x20, 0x21, 0x22, 0x23, 0x34, 0x35) class SensorList0 : public RegList0 { public: SensorList0(uint16_t addr) : RegList0(addr) { } bool updIntervall(uint16_t value) const { return this->writeRegister(0x20, (value >> 8) & 0xff) && this->writeRegister(0x21, value & 0xff); } uint16_t updIntervall() const { return (this->readRegister(0x20, 0) << 8) + this->readRegister(0x21, 0); } bool Bef_Hoehe_Sens(uint16_t value) const { return this->writeRegister(0x22, (value >> 8) & 0xff) && this->writeRegister(0x23, value & 0xff); } uint16_t Bef_Hoehe_Sens() const { return (this->readRegister(0x22, 0) << 8) + this->readRegister(0x23, 0); } bool Max_Fuell_Hoehe(uint16_t value) const { return this->writeRegister(0x34, (value >> 8) & 0xff) && this->writeRegister(0x35, value & 0xff); } uint16_t Max_Fuell_Hoehe() const { return (this->readRegister(0x34, 0) << 8) + this->readRegister(0x35, 0); } void defaults() { clear(); transmitDevTryMax(6); updIntervall(30); Bef_Hoehe_Sens(2000); Max_Fuell_Hoehe(1800); } };

class MeasureChannel : public Channel<Hal, List1, EmptyList, List4, PEERS_PER_CHANNEL, SensorList0>, public Alarm {

MeasureEventMsg msg;

int16_t  temperature10;
uint8_t  percent;
uint16_t Level_mm;

Sens_DS18X20 ds18x20;

public: MeasureChannel() : Channel() , Alarm(seconds2ticks(60)) , temperature10(0) , Level_mm(0) , percent(0) { } virtual ~MeasureChannel() {}

virtual void trigger(AlarmClock& clock)
{
  measure();

  uint8_t msgcnt = device().nextcount();
  msg.init(msgcnt, temperature10, Level_mm, percent);
  device().sendPeerEvent(msg, *this);

  // reactivate for next measure
  uint16_t updCycle = this->device().getList0().updIntervall();
  set(seconds2ticks(updCycle));
  clock.add(*this);
}

void measure()
{
  ds18x20.measure();
  uint16_t Bef_Hoehe_Sens = this->device().getList0().Bef_Hoehe_Sens();
  uint16_t Max_Fuell_Hoehe = this->device().getList0().Max_Fuell_Hoehe();
  temperature10 = ds18x20.temperature();
  uint16_t entfernung_mm = 10 * distanceSensor.measureDistanceCm(temperature10 / 10);
  DPRINT(F("Entfernung: ")); DPRINT(entfernung_mm); DPRINTLN(F(" mm"));
  Level_mm = Bef_Hoehe_Sens - entfernung_mm;
  percent = 100.0 * Level_mm / Max_Fuell_Hoehe;
  DPRINT(F("Füllgrad: "));   DDEC(percent);         DPRINTLN(F(" %"));
  DPRINT(F("Level: "));      DPRINT(Level_mm);      DPRINTLN(F(" mm"));

ifdef NDEBUG

  display.clearDisplay();
  display.invertDisplay(false);
  display.setTextSize(1);
  display.setCursor(18, 0);
  display.println("F\x81\llh\x94\he");
  display.setCursor(20, 10);
  display.print(Level_mm / 10);
  display.println(" cm");
  display.drawLine (10, 19, display.width () - 10, 19 , WHITE);
  display.setCursor(20, 23);
  display.print(temperature10/10);
  display.print(" \xf7\C");
  display.display();

endif

}

void initSensors()
{
  ds18x20.init(ONEWIRE_PIN);
  DPRINTLN(F("Sensor setup done"));
  DPRINT(F("Serial: "));
  DPRINTLN(cDEVICE_SERIAL);
  DPRINTLN(F("Clock SYSCLOCK"));
}

void setup(Device<Hal, SensorList0>* dev, uint8_t number, uint16_t addr)
{
  Channel::setup(dev, number, addr);
  initSensors();
  set(seconds2ticks(5));    // first message in 5 sec.
  CLOCK.add(*this);
}

void configChanged()
{
  // DPRINTLN(F("Config changed: List1"));
}

uint8_t status() const {
  return 0;
}

uint8_t flags() const {
  return 0;
}

};

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

virtual void configChanged()
{
  TSDevice::configChanged();
  DPRINTLN(F("Config Changed: List0"));

  uint8_t ledMode = this->getList0().ledMode();
  DPRINT(F("ledMode: "));
  DDECLN(ledMode);

  uint8_t txDevTryMax = this->getList0().transmitDevTryMax();
  DPRINT(F("transmitDevTryMax: "));
  DDECLN(txDevTryMax);

  uint16_t updCycle = this->getList0().updIntervall();
  DPRINT(F("updCycle: "));
  DDECLN(updCycle);

  uint16_t hTank = this->getList0().Bef_Hoehe_Sens();
  DPRINT(F("Bef_Hoehe_Sens: "));
  DDECLN(hTank);

  uint16_t Max_Fuell_Hoehe = this->getList0().Max_Fuell_Hoehe();
  DPRINT(F("Max_Fuell_Hoehe: "));
  DDECLN(Max_Fuell_Hoehe);
}

};

SensChannelDevice sdev(devinfo, 0x20); ConfigButton cfgBtn(sdev);

void setup() {

ifdef NDEBUG

Serial.begin(115200);

endif;

DINIT(115600, ASKSIN_PLUS_PLUS_IDENTIFIER); sdev.init(hal); buttonISR(cfgBtn, CONFIG_BUTTON_PIN); sdev.initDone();

ifdef NDEBUG

//Display mit I2C-Adresse 0x3c initialisieren //display.begin(SSD1306_SWITCHCAPVCC, 0x3c); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) { // Address 0x3C for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); } display.clearDisplay(); //Verhindert die Anzeige des Adafruit-Logos display.display();//Bereitet nächste Anzeige vor display.setTextSize(1); //Textgröße setzen display.setTextColor(WHITE); //Textfarbe setzen (hier tatsächlich aber nicht weiß display.setFont(); //Standard-Text-Font verwenden display.setCursor(5, 10); //Begin der Textausgabe setzen

endif;

}

void loop() { bool worked = hal.runready(); bool poll = sdev.pollRadio(); if (worked == false && poll == false) { // deep discharge protection // if we drop below critical battery level - switch off all and sleep forever // if nothing to do - go sleep hal.activity.savePower(hal); } } [/code] `

Ich hoffe auf Hilfe, vielen Dank.

pa-pa commented 4 years ago

Ich glaube mich zu erinnern, dass die GFX-Library zur Laufzeit ordentlich Speicher benötigt. Es wird das Bild er im Speicher aufgebaut und dann zum Display gesendet. Du könntest mal als Alternative die u8g2 Library für die Ausgabe probieren. Diese schreibt direkt in den Display-Speicher.

HMelzer commented 4 years ago

Nun, das würde den Speicherhunger erklären. Ich habe darüberhinaus schon mehrere unterschiedliche Libraries probiert, aber ohne eine wirkliche Verbesserung. Die u8g2 habe ich auch in meiner IDE, kann jetzt aber nicht sagen, ob ich die schon mal pobiert habe. Nichtsdestotrotz erklärt es aber nicht das Verhalten, dass die I2C-Adresse unter bestimmten Umständen nicht angesprochen wird und eben auch nicht, dass es keine volle Auflösung am Display gibt, und das eben dann, wenn die AskSinPP-Bibliothek im Spiel ist

HMelzer commented 4 years ago

Ich habe nun das mit der u8g2-Library versucht. Das hat gut funktioniert, wenn man den richtigen Fonts findet und verwendet. Es geht ohnehin nur mit der U8x8lib.h und eben nicht mit der U8g2lib.h. Interessant zu wissen wäre allerdings schon, warum es damit geht und nicht mit der Library von Adafruit. Die u8x8lib bzw. u8g2lib ist übrigens sehr schön vom Autor dokumentiert.

pa-pa commented 4 years ago

Weil die andere Lib zu viel Speicher braucht. Dann überlagern sich Stack und Heap irgendwann und schon passieren komische Dinge.

HMelzer commented 4 years ago

Hallo, ich muss noch einmal den Expertenrat in Anspruch nehmen. Ich habe das Programm und die zugehörige XML-Datei erstellt und in der Raspberrymatik installiert. Der Sensor wird wie erwartet angezeigt und zeigt auch die gemessenen bzw. errechneten Werte:

web-ui Die Einstellungsseite des Gerätes sieht so aus: Einstellungen

Und nun zum Problem: Nach dem Anlernen des Gerätes werden nicht die Default-Werte aus der XML-Datei auf der Einstellungsseite übernommen, sondern die Werte, die im Programm stehen und mit denen das Gerät derzeit läuft. Das wäre ja nicht schlimm, wenn man hier einfach ändern könnte. Eine Änderung der Werte für die Sendeversuche und das Sendeintervall wird problemlos an das Gerät weitergeleitet und übernommen, die Werte für die Befestigungs- und die Füllhöhe werden weder von der webui noch vom Gerät übernommen. Ich dachte, dass ich den Mechanismus verstanden hätte, aber irgendwo muss ja der Haken sein. Die XML-Datei füge ich hier mal an:

<?xml version="1.0" encoding="iso-8859-1"?>
<device version="2" rx_modes="CONFIG,WAKEUP,LAZY_CONFIG" cyclic_timeout="45000">
  <supported_types>
    <type name="HM-Sonic-Level" id="HM-Sonic-Level">
      <parameter index="10.0" size="2.0" const_value="0xF701" />
    </type>
  </supported_types>
  <paramset type="MASTER" id="hm_sonic_level_dev_master">
    <parameter id="TRANSMIT_DEV_TRY_MAX">
      <logical type="integer" min="1.0" max="10.0" default="6.0"/>
      <physical type="integer" interface="config" list="0" index="20" size="1"/>
    </parameter>
    <parameter id="Sendeintervall">
      <logical type="integer" min="10" max="600" default="60" unit="s" />
      <physical type="integer" interface="config" list="0" index="32" size="2" />
    </parameter>
    <parameter id="Befestigungshöhe des Sensors">
     <logical type="integer" min="0" max="4000" default="1800" unit="mm" />
      <physical type="integer" interface="config" list="0" index="34" size="2"/>
    </parameter>
    <parameter id="Max. Füllhöhe">
     <logical type="integer" min="0" max="4000" default="1500" unit="mm" />
      <physical type="integer" interface="config" list="0" index="52" size="2"/>
    </parameter>
  </paramset>
  <channels>
    <channel index="0" type="MAINTENANCE" ui_flags="internal" class="maintenance" count="1">
      <paramset type="MASTER" id="maint_ch_master" />
      <paramset type="VALUES" id="maint_ch_values">
        <parameter id="UNREACH" operations="read,event" ui_flags="service">
          <logical type="boolean" />
          <physical type="integer" interface="internal" value_id="UNREACH" />
        </parameter>
        <parameter id="STICKY_UNREACH" operations="read,write,event" ui_flags="service,sticky">
          <logical type="boolean" />
          <physical type="integer" interface="internal" value_id="STICKY_UNREACH" />
        </parameter>
        <parameter id="CONFIG_PENDING" operations="read,event" ui_flags="service">
          <logical type="boolean" />
          <physical type="integer" interface="internal" value_id="CONFIG_PENDING" />
        </parameter>
        <parameter id="LOWBAT" operations="read,event" ui_flags="service">
          <logical type="boolean"/>
          <physical type="integer" interface="internal" value_id="LOWBAT"/>
        </parameter>
        <parameter id="RSSI_DEVICE" operations="read,event">
          <logical type="integer" />
          <physical type="integer" interface="internal" value_id="RSSI_DEVICE" />
        </parameter>
        <parameter id="RSSI_PEER" operations="read,event">
          <logical type="integer" />
          <physical type="integer" interface="internal" value_id="RSSI_PEER" />
        </parameter>
        <parameter id="DEVICE_IN_BOOTLOADER" operations="read,event" ui_flags="service">
          <logical type="boolean" />
          <physical type="integer" interface="internal" value_id="DEVICE_IN_BOOTLOADER" />
        </parameter>
        <parameter id="UPDATE_PENDING" operations="read,event" ui_flags="service">
          <logical type="boolean" />
          <physical type="integer" interface="internal" value_id="UPDATE_PENDING" />
        </parameter>
      </paramset>
    </channel>
    <channel index="1" autoregister="true" type="SONIC_FILLING_LEVEL_SENSOR">
      <link_roles>
        <source name="Sonic_Level" />
      </link_roles>
     <paramset type="MASTER" id="HM-Sonic-Level_master" />
     <paramset type="VALUES" id="HM-Sonic-Level_values">
        <parameter id="Füllhöhe" operations="read,event">
          <logical type="float" min="0" max="4000" unit="cm"/>
          <physical type="integer" interface="command" value_id="Füllhöhe" no_init="true">
            <event frame="FILLING_EVENT"/>
          </physical>
          <conversion type="float_integer_scale" factor="10.0"/>
        </parameter>
        <parameter id="TEMPERATURE" operations="read,event">
          <logical type="float" min="-50.0" max="100.0" unit="°C"/>
          <physical type="integer" interface="command" value_id="TEMPERATURE" no_init="true">
            <event frame="FILLING_EVENT"/>
          </physical>
                    <conversion type="float_integer_scale" factor="10.0"/>
        </parameter>
        <parameter id="Füllgrad" operations="read,event">
          <logical type="integer" min="0" max="100" unit="%"/>
           <physical type="integer" interface="command" value_id="Füllgrad">
             <event frame="FILLING_EVENT"/>
           </physical>
        </parameter>
      </paramset>  
      <paramset type="LINK" id="HM-Sonic-Level_link" />
    </channel>
  </channels>
  <frames>
      <frame id="FILLING_EVENT" direction="from_device" event="true" fixed_channel="1" type="0x53">
         <parameter type="integer" index="9.0" size="2.0" param="TEMPERATURE"/>
         <parameter type="integer" index="11.0" size="2.0" param="Füllhöhe" />
         <parameter type="integer" index="13.0" size="1.0" param="Füllgrad"/>
    </frame>
  </frames>
  <paramset_defs></paramset_defs>
</device>

Das Programm hatte ich ja oben bereits gepostet. Wenn es jetzt auch auf die u8g2-Library umgeschrieben ist, ist der Programmteil, welcher die Werte der Liste 0 schreibt und liesst, ja unverändert geblieben.

Eine weitere Frage hätte ich noch: Bei der Anzeige der Gerätedaten wird die Füllhöhe und der Füllgrad in rechteckige Klammern dargestellt, die Temperatur jedoch nicht. Gibt es hier eine Möglichkeit, das zu ändern und wie wäre diese? Einen großen Dank im Voraus!

jp112sdl commented 4 years ago

Warum nimmst du nicht das fertige Ultraschall-Füllstandssensor-Projekt? https://github.com/jp112sdl/HB-UNI-Sen-LEV-US und hängst dort Temperatur + Display an?

Für die Umsetzung ist es nicht nur mit der XML getan, da muss noch wesentlich mehr angepasst werden. Siehe https://github.com/jp112sdl/JP-HB-Devices-addon/blob/master/src/addon/install_hb-uni-sen-lev-us und https://github.com/jp112sdl/JP-HB-Devices-addon/blob/master/src/addon/www/config/easymodes/HB-UNI-Sen-LEV-US_master.tcl ... kann sein, dass da noch mehr ist. Weiß ich nicht mehr aus dem Kopf.

Wenn du das Gerät vom Typ her bei CAPACITIVE_FILLING_LEVEL_SENSOR belässt, ersparst du dir auch ein wenig Arbeit, was die Darstellung in der WebUI betrifft, weil die internen Programme zum Zusammenstellen der Funktionen korrekt abgearbeitet werden.

In meinem Addon ist auch alles "eQ3-konform" was die Bezeichner betrifft. Umlaute, bzw. generell direkte Bezeichner in der XML sind nicht so schön, man arbeitet eigentlich mit Übersetzungstabellen innerhalb der CCU. Die eckigen Klammern kommen nämlich daher, dass keine Übersetzungen für z.B. Füllgrad gefunden wird.

Sind alles nur Anregungen...

HMelzer commented 4 years ago

Weil es bspw. kein Batteriegerät sein soll, ich ohnehin schon Schwierigkeiten mit dem Speicher des Arduino hatte, nicht sehen kann, wie ich meine Parameter für die Höhen da unterbringe und vielleicht auch noch was anderes. Trotzdem Danke für die Anregung.

jp112sdl commented 4 years ago

Weil es bspw. kein Batteriegerät sein soll

Aber das ist dem Sketch ja egal, ob der Strom aus Batterien oder einem Netzteil kommt ;) Lass den LowBat Parameter ruhig drin... dann wird eben niemals LowBat gemeldet.

Parameter für die Höhen

Du meinst die "Befestigungshöhe" ? Ist bei mir auch drin und mit distanceOffset bezeichnet

Trotzdem Danke für die Anregung.

Viel Erfolg

HMelzer commented 4 years ago

Wie gesagt, ich bekomme das im Speicher nicht unter, da die Anzeige viel davon benötigt. Allerdings wäre ich schon interessiert daran, zu erfahren, woran meine Lösung krankt und wie das zu korrigieren wäre.

jp112sdl commented 4 years ago

die Werte für die Befestigungs- und die Füllhöhe werden weder von der webui noch vom Gerät übernommen.

Werden sie denn überhaupt gesendet? Vielleicht liegt es tatsächlich an den Bezeichnern. Umlaute, Punkt, Leerzeichen

Bei der Anzeige der Gerätedaten wird die Füllhöhe und der Füllgrad in rechteckige Klammern dargestellt, die Temperatur jedoch nicht. Gibt es hier eine Möglichkeit, das zu ändern und wie wäre diese?

Siehe meinen Erklärungen zu den Übersetzungen weiter oben: Die eckigen Klammern kommen nämlich daher, dass keine Übersetzungen für z.B. Füllgrad gefunden wird.

Es gibt 2-3 Stellen (Dateien), an denen Übersetzungen einzutragen sind. Findest du alles hier https://github.com/jp112sdl/JP-HB-Devices-addon/blob/master/src/addon/install_hb-uni-sen-lev-us

HMelzer commented 4 years ago

Oh, vielen Dank, die Umlaute waren tatsächlich das Problem. Das mit den eingeklammerten Bezeichner schaue ich mir aber erst morgen an. Nochmals vielen Dank, dass es daran gelegen haben könnte, darauf wäre ich wohl nie gekommen.

jp112sdl commented 4 years ago

Danke auch für die Anregung mit der Temperaturkompensation. Habe das nun mit in den HB-UNI-Sen-LEV-US aufgenommen und lasse die Temperatur auch gleich noch mit anzeigen (wenn sie ja schon gemessen wird).