Ankündigung

Einklappen
Keine Ankündigung bisher.

ESP8266 KNX mit ETS

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • MasterOfPuppets
    antwortet
    Zitat von manu241 Beitrag anzeigen
    Hallo,

    wäre eventuell jemand so nett und erstellt ein DemoIO-Projekt wie man die I/Os eines Arduino nutzen kann um KNX Befehle per Arduino sendet und auch empfängt?
    Ich verstehe aktuell nicht, wie es funktioniert und könnte so eventuell einen besseren Einstieg finden.

    Gruß und danke Manuel
    Geht mir genau so! Finde das Thema extrem spannend, Arduinos habe ich auch schon des öfteren programmiert, aber hier steige ich irgendwie nicht durch.
    Zuletzt geändert von MasterOfPuppets; 10.10.2019, 13:27.

    Einen Kommentar schreiben:


  • manu241
    antwortet
    Hallo,

    wäre eventuell jemand so nett und erstellt ein DemoIO-Projekt wie man die I/Os eines Arduino nutzen kann um KNX Befehle per Arduino sendet und auch empfängt?
    Ich verstehe aktuell nicht, wie es funktioniert und könnte so eventuell einen besseren Einstieg finden.

    Gruß und danke Manuel

    Einen Kommentar schreiben:


  • Bernator
    antwortet
    thesing da hat sich glaub was überschnitten, aber deine erklärte Vorgehensweise entspricht nahezu 1:1 wie ich es angegangen bin, zum Problem mit den wechselnden Table Größen hab ich eben ein kleines dynamisches memory management für den Flash implementiert. Das wiederfinden passiert über eine eindeutige "memoryID" welche in addSaveRestore() vergeben wird.

    Zu den 4,5k, gute Frage, eigentlich sollten es ca. 3k weniger sein (2k Emulation +1k ETS Daten), kann ich mir grad auch nicht erklären aber vielleicht ist da bei meiner Messung was schief gegangen (Ram usage zu untersuchen ist ja gar nicht sooo leicht )

    Die Werte der KOs bleiben natürlich im RAM die müssen ja nicht über einen Device neustart hinaus gerettet werden....

    Firmware-Update mache ich über den Debugger (Jlink) und der löscht nur den Flashbereich für den es auch neue Daten gibt (überschreibt quasi die alten), mehr zu löschen ist ganz einfach nicht notwendig. Ich vermute mal der Arduino Bootloader macht das auch so aber ich weiß es eben nicht. Der Grund warum bei der FlashStorage lib die ETS Daten nach jedem Update verlorgen gehen ist, das die Lib Flash Speicher über ein const Array reserviert und das landet natürlich irgendwo inmitten des text segements welches jedes mal vor dem schreiben der neuen daten gelöscht werden muss. Deshalb bin ich ja einen anderen Weg gegangen und mach es ähnlich wie Stack/Heap mit dem Ram, damit kommen sich die Bereiche so lange nicht in die Quere solange die Summe unter ~99% bleibt.

    Nachdem das alles rel. grobe Änderungen mit sich brachte sind ausführliche Tests hier sehr wilkommen

    thesing , was hälst du von einem stable/develop branch?

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi,

    das ist jetzt echt strange - ich mach mir ein paar Gedanken und Du hast gleich eine Lösung! Und auch noch eine wesentlich bessere als ich es mir hätte ausdenken können!

    Noch ein paar Fragen eines technisch interessierten (hab mir Dein Coding noch nicht angeschaut, kommt am Wochenende):
    • internalRam spart die Duplizierung bei den TableObject-Daten, hab ich verstanden -> Also hast Du hier die gleiche Idee wie ich gehabt, die Klassen arbeiten nur mit einem Pointer, deswegen auch 1,1k weniger RAM-Verbrauch, verstehe ich.
    • external ist das, was ich eigentlich für meinen i2c-EEPROM-Implementierung gebraucht hätte, wenn ich vorher richtig drüber nachgedacht hätte... auch verstanden.
    • internalFlash hört sich vom Speicherverbrauch am interessantesten an, aber hier verstehe ich nicht, wo Du die ca. 4,5k gespart hast? Und was passiert mit den Werten der KO (also die GroupObject-Klasse)? Werden deren Änderungen auch im Flash gespeichert? Das würde ja endlos viele Seiten-Updates erfordern, da man ja häufig KO wegschreibt (zumindest mach ich das, viele davon mit valueNoSend, damit sie für den nächsten ReadRequest verfügbar sind). Macht das den Flash nicht zu schnell kaputt?
    • Wie machst Du denn den Firmware-Update, wenn Du sagst, dass bei Dir nicht der ganze Flash gelöscht wird? Ich hab nämlich keine Ahnung, wer den Flash löscht, bisher dachte ich immer, das "gehört" so .
    Ansonsten teste ich gerne auch noch die Linux-Version, da kann ich auch beim debuggen mal sehen, wie Deine Sachen funktionieren. Und Deine SAMD-Implementierung werde ich natürlich auch ausprobieren, denn das verspricht mir mehr RAM... Ich berichte mal, auf wie viele Logikkanäle ich dann komme...

    Ich habe mit der bisherigen Plattform eine EEPROM_EMULATION_SIZE von 6144 hin bekommen, bei ca. 5500 bytes an ETS-Daten. Das sind entweder 50 meiner Logikkanäle oder der BME280 (mit seiner Lib) mit Temperatur, Luftfeuchte, Luftdruck, Taupunkt, Wohlfühlbereich und 40 Logikkanälen. Oder ein SCD30 mit Temperatur, Luftfeuchte, Co2, Taupunkt, Wohlfühlbereich und 40 Logikkanälen. Ich wollte mich demnächst mal am BME680 versuchen, aber da scheint dessen Lib recht viel Speicher zu verbrauchen. Insofern wäre mehr RAM sehr interessant, dann könnte ich einheitliche Firmware für verschiedene Sensoren haben.

    Auf jeden Fall super, dass Du das gemacht hast, ich versuche mich durch Tests zu bedanken...

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • thesing
    antwortet
    Hallo Waldemar,

    ich finde dein Vorhaben sehr löblich Ich würde bei der SaveRestore-Klasse und der Memory-Klasse anfangen, da Flash blockweise geschrieben werden muss, und möglichste jedes InterfaceObjekt getrennt voneinander geschrieben werden muss. Daher musst du ggf. Padding einführen. Da weiterhin partielle Programmierung möglich sein sollte, musst du dann damit klar kommen, dass sie die Größe von einzelnen InterfaceObjekten verändern könnte wenn z.B. neue GAs zu den KOs hinzugefügt werden.

    Zitat von mumpf Beitrag anzeigen
    • TableObject wird so umgebaut, dass es nur mit einer Speicherreferenz auf den Anfang eines Speicherblocks arbeiten kann und kein einziger Wert ins RAM kopiert wird.
    • Damit könnte man für die Parameter und die GA-Zuordnungen direkt auf den Flash referenzieren, da sich diese Tabellen ja zur Laufzeit nicht ändern (nur beim Programmieren -> kommt noch). Damit könnte man für diese Tabellen auf ein malloc verzichten.
    • Nach dem Programmieren werden die Daten ins Flash geschrieben und dann der SAMD neu gestartet, dann bekommt die Firmware ja ihr RAM wieder.
    Passt soweit.

    Zitat von mumpf Beitrag anzeigen
    • KO und deren Werte werden weiterhin im RAM belassen. Dazu muss hier ein malloc passieren, das müsste dann "außerhalb" der TableObject-Klasse passieren (oder über einen alternativen Konstruktor, das kann man ja noch sehen)
    Hier muss nichts geändert werden, da die GroupObjekt-Objekte eh in der GroupObjektTable erzeugt werden.

    Zitat von mumpf Beitrag anzeigen
    • Beim Programmieren gehe ich davon aus, dass die eigentliche Firmware (also das, was den Stack nutzt) gestoppt ist. Sollte diese RAM brauchen, dann wird dieser während der Programmierung nicht gebraucht und kann "missbraucht" werden - für die zu programmierenden TableObject (Parameter, KO und GA).
    Da solltest du ein zusätzliches Callback an der Facade oder der Bau-Klasse vorsehen. Durch dieses Callback kann die eigentliche Anwendung dann vor der Programmierung Speicher freigeben.
    Zitat von mumpf Beitrag anzeigen
    • Ich muss nochmal untersuchen, was beim partiellen Programmieren abgeht, das blicke ich noch nicht ganz, obiges würde nur (falls überhaupt) für das Programmieren der gesamten Applikation funktionieren.
    Das Hauptproblem bei der partiellen Programmierung besteht, ist dass du dann damit klar kommen musst, dass sich die Größe von einzelnen InterfaceObjekten verändern könnte wenn z.B. neue GAs zu den KOs hinzugefügt werden.

    Bsp.:
    Ist AdressTable 100 Byte startet an Offset 0, AssoziationTable 100 Byte startet and Offset 100, GoT 100 Byte startet an Offset 200, Paramter 100 Byte startet an Offset 300.
    Nun soll nur die AssoziationTable geändert werden. (da eine GA auch an ein anderes KO zugewiesen wurde). Diese wird jetzt größer. Also ändern sich die Offsets von Got und Parameter. Du kannst dann entweder für die einzelnen InterfaceObjekte feste Größen vorsehen, oder du schreibst die abwechselnd auf zwei Bereiche im Flash, oder du lädst alle in den Ram und schreibst sie neu in den Flash. (ggf. pro Block prüfen ob man neu schreiben muss). Oder dir fällt noch etwas neues ein.

    Die Hauptarbeit wird am Zusammenspiel der Klassen Memory, SaveRestore und TableObject sein. Die Platform muss wahrscheinlich auch mehr Operationen für das blockweise Speichern bekommen. Das ist insgesamt sicher keine ganze einfache Aufgabe.
    Ich würde wahrscheinlich damit anfangen, dass die Memory-Klasse die Platform fragt wie groß die Blockgröße zum Speichern sein soll. Dann fragt die MemoryKlasse der Reihe nach alle registrierten SaveRestore Objekte nach den Blöcken und speichert diese. Den letzen Block sollte man am besten auffüllen damit ein neues SaveRestore immer an einem Block beginnt. Zusätzlich muss du dir irgendwo merken wie viele Blöcke jedes SaveRestore hat (vielleicht in den ersten zwei Blöcken?)
    Dies nur als schnell heruntergeschriebene Idee.

    Ich wünsche jedenfalls viel Spaß

    VG
    Thomas

    Einen Kommentar schreiben:


  • Bernator
    antwortet
    lustig das du das genau jetzt schreibst, ich habe vor genau dazu einen pull request zu machen

    habe den Stack nämlich folgendermaßen erweitert damit es möglich ist 3 unterschiedliche NV Memory "Typen" zu handeln:
    • internalRam = externe Library welche die Daten eines externen Speichers selbst in den Ram kopiert (wie zb. die aktuell verwendeteFlashStorage lib). Hier wird den saveRestore Objekten dann aber nur der Pointer auf diese Daten übergeben und nicht nochmal dupliziert
    • internalFlash = hier wird direkt (kleinere Buffer im Ram sind nötig) alles in den Flash geschrieben und gelesen, dazu braucht es ein memory management welches malloc/free etc. auf den Flash ermöglicht (hab ich für den sam in samd_flash.h gemacht). Beim Programmieren fordert allocTable() dann Speicher der jeweiligen Größe von der Platform an. Die Daten selbst kommen dann später häppchenweise über memoryWriteIndication()
    • external = hier wird im memory Objekt ein Ram buffer für jedes saveRestore Objekt erzeugt mit welchem der Stack dann arbeitet, die Daten für den buffer können byteweise aus dem externen Speicher gelesen/geschrieben werden. Hier könnte man noch ansetzen und die selten/langsam benötigten Daten vom z.b. Application Table (Parameter) nicht im Ram zu buffern sondern byteweise direkt in den externen Speicher zu schreiben/lesen (hab ich aber noch nicht implementiert)
    zu finden ist das Ganze in meinem Fork: https://github.com/Bernator/knx/tree/memory_rework/src
    In samd_platform.cpp findet man Beispiele (meine Tests) für die Implementierung der 3 Varianten.....

    Für den Samd sollte das bereits alles funktionieren, bei den anderen Plattformen hab ich versucht die "internalRam" Variante zu implementieren (wie vorher nur ohne die zusätzliche Ram Kopie in den Stack Objekten) aber das ist alles ungetestet. Hier könntest du Waldemar evtl. aushelfen und zumindest die Linux Variante mal anschaun, ich hab dazu nämlich nicht wirklich was am Start

    Auch interessant wäre wie weit du beim SamD mit deiner Kanalduplizierung kommst, ich hab mit meinem Testprojekt mal grob die max Ram usage angeschaut, absolut natürlich wenig aussagekräftig aber relativ zueinander schon plausibel: (ETS Daten sind hier ca. 1,1k)
    original Stack 12,8k EEPROM_EMULATION_SIZE = 2048k
    internalRam 11,7k EEPROM_EMULATION_SIZE = 2048k
    external 12,8k EEPROM_EMULATION_SIZE = 2048k, hier werden die Daten dupliziert weil ich den externen EEPROM nur emuliere, sonst wären es 2k weniger also ca. 10,8k
    internalFlash 8,3k

    thesing vielleicht findest du auch die Zeit und schaust dir das mal an, evtl. hast du noch div. Anregungen

    PS: mein flash memory management arbeitet von oben herab bis zur nächsten Row der text+data Adresse, bleibt somit also auch beim neu Flashen des MC erhalten wenn man nicht vorher den ganzen Flash löscht (macht das der Arduino Bootloader?) und somit muss man auch nicht immer neu programmieren über die ETS

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Thomas ( thesing ) et all,

    ich wollte hier mal ein paar Fragen zur Speicherverwaltung los werden und hoffe auf Tipps...

    Ausgangssituation: Ich habe mal auf dem SAMD ein Speichern und Lesen der ETS-Daten auf einem I2C-EEPROM statt im Flash implementiert, in der Hoffnung, damit RAM zu sparen (das war zugegebenermaßen blauäugig und ohne es zu Ende zu überlegen). Die Daten werden ja immer erstmal ins RAM geladen, egal ob aus dem Flash oder aus dem EEPROM... Immerhin kann ich jetzt nach einem Flash der Firmware sofort testen, da die Parametrisierung der ETS nicht mehr verloren geht.

    Dann habe ich mir den Startup vom knx-Stack weiter angesehen und festgestellt, dass die jeweiligen TableObject die Daten nochmal ins eigene Objektmodell deserialisieren, also wird der Inhalt nochmal ins RAM gepackt. Und wenn man so programmiert wie ich, dann packt man die Parameter- und KO-Werte in Variablen und hat dann so die Daten ein drittes mal im Speicher . Das "3. mal im Speicher" habe ich inzwischen behoben, aber ich hätte gerne noch mehr RAM frei .

    Ich würde gerne folgendes probieren (aber vorher mit euch diskutieren, um nicht wieder komplett falsch zu liegen):
    • TableObject wird so umgebaut, dass es nur mit einer Speicherreferenz auf den Anfang eines Speicherblocks arbeiten kann und kein einziger Wert ins RAM kopiert wird.
    • Damit könnte man für die Parameter und die GA-Zuordnungen direkt auf den Flash referenzieren, da sich diese Tabellen ja zur Laufzeit nicht ändern (nur beim Programmieren -> kommt noch). Damit könnte man für diese Tabellen auf ein malloc verzichten.
    • KO und deren Werte werden weiterhin im RAM belassen. Dazu muss hier ein malloc passieren, das müsste dann "außerhalb" der TableObject-Klasse passieren (oder über einen alternativen Konstruktor, das kann man ja noch sehen)
    • Beim Programmieren gehe ich davon aus, dass die eigentliche Firmware (also das, was den Stack nutzt) gestoppt ist. Sollte diese RAM brauchen, dann wird dieser während der Programmierung nicht gebraucht und kann "missbraucht" werden - für die zu programmierenden TableObject (Parameter, KO und GA).
    • Nach dem Programmieren werden die Daten ins Flash geschrieben und dann der SAMD neu gestartet, dann bekommt die Firmware ja ihr RAM wieder.
    • Ich muss nochmal untersuchen, was beim partiellen Programmieren abgeht, das blicke ich noch nicht ganz, obiges würde nur (falls überhaupt) für das Programmieren der gesamten Applikation funktionieren.
    Wenn das so gehen würde, hätte ich
    • alle Parameter im Flash (bei mir ca. 5k, gerne mehr)
    • alle GA-Zurodnungen im Flash (das können auch viele werden, wenn man viele KO hat)
    • alle KO im RAM
    • Es gibt noch eine 4. Tabelle, von der weiß ich nicht, was drin steht, aber die ist nie groß, könnte also auch ins RAM...
    Liege ich da komplett falsch? Oder könnte das klappen?

    Ich sage jetzt nicht, dass ich wirklich in der Lage bin, das zu programmieren - ich bin noch recht neu dabei, aber ich würde es gerne versuchen. Die Frage ist, was ich nicht bedacht habe oder ob ich etwas falsch verstanden habe...

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • manu241
    antwortet
    Oh mann... Ich war einfach nur zu dumm... Ich habe irgendwie die Falsche Version der KNX-Demo geladen ...
    Nun geht schonmal etwas...

    Gruß Manuel
    Zuletzt geändert von manu241; 09.10.2019, 09:53.

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Manuel,

    leider kann ich dir hier nicht helfen, ich bin auf der SAMD Plattform unterwegs. Ich hab mir zum Spielen einen ESP 32 besorgt, aber noch nichts damit gemacht.

    Mir hat es aber sehr geholfen, die ersten Schritte unter Linux zu machen, und dann erst auf die Zielhardware zu wechseln.

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • manu241
    antwortet
    Hallo mumpf,

    Auf dem NodeMCU Wifi-Chip steht ESP8266MOD. Ich hoffe, dann sollte es passen, oder ? Geladen habe ich die KNX-Demo und Lade es via Arduino 1.8.10 in den NodeMCU. Jedoch wie geschrieben, bekomme ich diese Meldung:

    Code:
    ets Jan  8 2013,rst cause:2, boot mode:(3,7)
    
    load 0x4010f000, len 1384, room 16 
    tail 8
    chksum 0x2d
    csum 0x2d
    v8b899c12
    ~ld
    ISR not in IRAM!
    Gruß Manuel

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Thomas,

    ich habe nach längeren Tests jetzt den Pull-Request fürs "Restart Device" gestellt. Es funktioniert mit allen Geräten, dich ich im Haus habe (wobei ich nicht jedes Gerät, sondern nur Gerätekategorie/Hersteller-Kombis getestet habe). Wäre schön, wenn das in den Haupt-Stack mit rein könnte.

    manu241: Ich hab mit dem ESP noch nichts gemacht, aber so wie ich das verstanden habe, ist derzeit nur der ESP8266 und der ESP32 unterstützt. Und zum CreateKnxProd: Ich habe gerade mal Version 2.0 runtergeladen, das hat ohne Probleme geklappt und das config-File ist in dem Zip drin.

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • manu241
    antwortet
    Moin,

    Ich habe nun auch mal versucht das Demo-Projekt in ein Nodemcu 1.0 ESP-12E zu laden. Jedoch steht im Seriellen Monitor : ISR not in IRAM! Was hat das zu bedeuten und was müsste ich anders machen ?

    Gruß Manuel

    Einen Kommentar schreiben:


  • manu241
    antwortet
    Hallo,

    ich wollte mich morgen mal an diesem Projekt versuchen. Dazu habe ich mir das Demo-Projekt geladen, sowie das CreateKNXProd.
    Dort steht:
    Code:
    Configuration: Change the path in CreateKnxProd.exe.config to your ETS4 Path. If you have ETS5 use the path to the ETS4 dlls of ETS5. For example: C:\Program Files (x86)\ETS5\CV\4.0.1997.50261 You can also change UICulture and Culture from 'de' to 'en' there.
    Jedoch finde ich im Downloadverzeichnis dieses file :
    Code:
    CreateKnxProd.exe.config
    nicht. Verstehe ich da etwas falsch?

    Sorry für die Anfängerfragen.

    Gruß Manuel

    Einen Kommentar schreiben:


  • mumpf
    antwortet
    Hi Manuel,

    ja, mit der ESP-Plattform kannst Du über das eingebaute WLAN-Modul und über Deinen KNX-Router Daten auf den Bus senden/empfangen. Das Projekt selbst kann noch viel mehr

    Gruß, Waldemar

    Einen Kommentar schreiben:


  • manu241
    antwortet
    Hallo,

    verstehe ich dieses Projekt richtig, dass der Arduino ein "KNX-Gerät" ist, dass eigenständig ohne KNX-Kabel über ein KNX-Router Daten auf mein Bussystem schreiben kann, je nachdem welcher Sensor etc angeschlossen ist.

    Ich finde es sehr intressant, da ich damit gerne einen Regenmesser realisieren würde (wie in diesem Projekt https://knx-user-forum.de/forum/%C3%B6ffentlicher-bereich/knx-eib-forum/diy-do-it-yourself/36798-arudino-knx-regenmesser nur ohne TPUART)

    Gruß Manuel

    Einen Kommentar schreiben:

Lädt...
X