Jump to content

rtrbt

Administrators
  • Gesamte Inhalte

    1.489
  • Benutzer seit

  • Letzter Besuch

  • Tagessiege

    138

Alle erstellten Inhalte von rtrbt

  1. Moin, Das stimmt, also wurde dein Callback nicht einfach durch einen Reset deaktiviert. Soweit ich das aus der Firmware des Bricklets sehe, gibt es zwei Möglichkeiten was da passiert: Der Sensor selbst bleibt auf einem Wert hängen und gibt diesen aus irgendeinem Grund immer zurück. (Halte ich für unwahrscheinlich) Die I2C-Kommunikation zwischen Sensor und Bricklet-Prozessor ist gestört und zwar so, dass die Fehlerbehandlung der Bricklet-Firmware das nicht wieder repariert bekommt. Eventuell ist ein Bug in der Firmware, der die Kommunikations-State-Machine so durcheinander bringt, dass das Bricklet in einer Reinitialisierungsschleife hängt o.Ä. Auf deiner Seite ist das vermutlich nur zu lösen, wenn du den Wert in deinem Programm überwachst und wenn er untypisch lange hängt das Bricklet resettest. Mir ist aber auch unklar, warum es bei dir zwei Resets braucht. Hast du eventuell nach dem ersten nicht lang genug gewartet? Ich stelle hier mal einen Aufbau mit einem Temperature Bricklet 2.0 hin, eventuell bekomme ich das Problem reproduziert. Welche Callback-Konfiguration benutzt du für das Bricklet?
  2. Moin, Da geht es tatsächlich nur um die Geschwindigkeit, wenn du die Liste leer anlegst und immer neue Daten appendest, muss Python ziemlich oft intern eine neue (größere) Liste anlegen und die Daten kopieren. Das ist aber bei der relativ kleinen Problemgröße (und der Tatsache, dass auf das E-Paper zeichnen im Vergleich dazu ewig dauert) vermutlich egal. Die Formel benutze ich zur Umrechnung von (x,y)-Koordinaten in den eindimensionalen Index. Das hilft immer sich es als Bild vorzustellen, so wie hier zum Beispiel (Stride und Width sind bei unserem Bildformat identisch). Im Endeffekt überspringe ich y vollständige Bildzeilen mit y * WIDTH, dann bin ich bei der aktuelle Bildzeile, das + x ist dann in der aktuellen Zeile die Spalte die ich schreiben will. Weil mir das gerade noch aufgefallen ist: Du kannst die etwas verwirrende data[y,x] Vertauschung loswerden, wenn du die for-Schleifen-Indices umbenennst, x ist ja eigentlich die Spaltenkoordinate, y die Zeilenkoordinate.
  3. Moin, Das stimmt, mein Satz klingt etwas verwirrend, ich meinte "neben" im Sinne von "Im Ordner daneben liegend" nicht "neben den openHAB-Bindings Version 2.1.26....". Beta 23 ist die aktuelle openHAB-Bindings-Version.
  4. Moin, Die aktuelle Beta braucht neben den openHAB-Bindings auch die Java-Bindings in Version 2.1.26 (findest du hier). Die Jar kannst du einfach neben die der openHAB-Bindings selbst legen, dann sollte es funktionieren. Gruß, Erik Edit: Die Java-Bindings aus der Zip und die aus den openHAB-Bindings unterscheiden sich subtil. In den openHAB-Bindings liegt die korrekte Version, die ein Maven-Bundle ist.
  5. Moin, Die API des E-Paper-Bricklets erwartet nicht, dass du die Pixel in ints packst. Du kannst direkt ein Array von boolschen Werten übergeben, den Rest machen die Bindings. So sollte es funktionieren: pixel_matrix = [False] * WIDTH * HEIGHT for x in range(WIDTH): for y in range(HEIGHT): pixel_matrix[y * WIDTH + x] = data[x, y] == 1 epaper.write_black_white(0, 0, WIDTH - 1, HEIGHT - 1, pixel_matrix) eppaper.draw() Gruß, Erik
  6. Da würde ich zusammengefasst sagen "Nimm nur das NodeMCU und kauf dir ein HAT Zero Brick ". Das hat die korrekten Trenner/Buffer-Chips und du kannst 4 Bricklets anschließen ohne dass du Breakout Bricklets brauchst. Das HAT hat auch 3,3V Logikpegel, also sollte es am NodeMCU funktionieren. Wenn du das am Arduino machen willst, musst du dann doch etwas basteln: Wir benutzen den 74AHC244 als Trenner-Chip, damit kann man zwei Ports auf einmal verschalten. Der 74AHC125 scheint das Äquivalent dafür zu sein, wenn du nur einen Port brauchst. Du kannst dir die Schaltung vom bald erscheinenden Breakout Bricklet 2.0 ansehen, den ich angehangen habe. Die Schaltung oben links mit dem LD1117 und den CONN_01X03 Jumper kannst du weglassen, wenn du direkt 3,3V und 5V vom Arduino bekommst, für das Breakout Bricklet haben wir das eingebaut, damit man nur 5V einspeisen muss. Die 82Ω Widerstände und die 220pF Kondensatoren brauchst du auch nicht unbedingt. Der Rest sollte auf einem Breadboard aufbaubar sein. Nein. (Bzw. nur ein Isolator Bricklet und dahinter ein anderes) Die Ports sind nicht an die Bricklets gekoppelt: Du musst nur deklarieren, welche Ports es gibt und welcher Pin der zugehörige Chip-Select-Pin ist. Die HAL-Initialisierung fragt dann einmal an allen Ports ab, welche Bricklets angeschlossen sind. Nein, weil du pro Port mehr als ein Bricklet angeschlossen haben kannst. (Im Moment z.B. wenn du ein Isolator Bricklet benutzt) breakout-V2.pdf
  7. Sehr gut, ich habe den Fix mal in Beta 2 gepackt. Der hal_arduino_avr heißt jetzt hal_arduino. Ich habe den HAL hier auch mit einem Teensy (der hat einen ARM-Prozessor) getestet, deshalb die Namensänderung. Das hatte ich übrigens nur so gebaut, damit ich die selbe Demo-Implementierung für die Linux-Demo benutzen kann, der Arduino-Compiler läuft in Linkerprobleme wenn man ein normales Include benutzt weil die demo eine .c, keine .cpp ist.
  8. Teste bitte mal die Version der Bindings im Anhang. Ich glaube ich habe das Problem gefunden. Außerdem habe ich die io4ledbtn.c leicht verändert angehangen, die Signatur deines Callbacks passte nicht ganz: Der erste Parameter ist entgegen der Dokumentation ein Zeiger auf das Device von dem das Callback kam. Das muss ich mal ins README schreiben. Außerdem benutze ich da jetzt den callback_tick und gebe eventuelle Fehler aus. (Nur den Return Code, für die Fehlerbeschreibungen ist der RAM des Unos zu klein) PS: Ich habe gerade keinen Button zur Hand und deshalb nur mit einem Kabel Pin 1 der IO-4 auf Masse gezogen, ist das beabsichtigt, dass man immer zweimal drücken muss, damit die LED an oder aus geht? io4ledbtn.c tinkerforge_uc_bindings_2_0_0_rwblinn.zip
  9. Hm ich teste das hier gerade auch, habe aber noch nicht gefunden, was genau kaputt ist. Ich melde mich morgen nochmal mit mehr Informationen.
  10. Das hängt vom Bricklet ab. Manche brauchen die 5V, aber bei vielen ist das einfach auf Brickletseite nicht verbunden, weil sie mit 3,3V auskommen. Die Kurzfassung ist du kannst in deinem Buttonbeispiel anstelle von dem tf_io4_v2_get_value(&io, io_ret_value); in der io4ledbtn_loop-Funktion folgendes machen: tf_io4_v2_callback_tick(&io, 250); Das blockiert für 250µs und holt Callbacks ab, ohne dass du unnütz den Getter ausführst. Im Callback selbst hast du // <TODO> This function is not triggered - need to explore why // tf_io4_v2_set_selected_value(&io, 0, led_state); Die Funktion würde nicht ausgeführt werden, weil prinzipiell keine Ausführung von Device-Funktionen in Callbacks erlaubt ist. D.h. das richtige Vorgehen ist, wie du es auch gemacht hast, im Callback nur Informationen zu ändern, die du dann in der Loop benutzt.
  11. ATTENTION: Arduinos with an AVR microcontroller (for example the Arduino Uno or Mega) use a logic level of 5V. Bricklets use a logic level of 3.3V. A level shifter is required between the Arduino and any bricklet. Edit: Here's the official documentation. Hi, After multiple customer requests to be able to control Bricklets directly with a microcontroller, I've spent the last months creating bindings to be able to do so. The first beta version of the C/C++ bindings for microcontrollers are attached to this post. With them you can control Co-processor bricklets using for example an Arduino over SPI. The bindings are separated in a common implementation and Hardware Abstraction Layers (HALs) for the specific platforms. At this time a HAL for Arduino AVR and ESP32 boards and a HAL for the Raspberry Pi (Zero) with a Hat (Zero) Brick are available. Further information about the interface of the bindings, and on how to implement custom HALs for other boards can be found in the documentation. In the future there will be additional hardware for the bindings: An ESP32 based board on that programs using the bindings can be executed, as well as a new Breakout board that allows connecting multiple Bricklets to a micro controller. Cheers, Erik Edit: Beta 8 with the following change: Fixed a bug where callbacks stopped working after 35 minutes This will probably be the last beta version. However the beta phase will continue until the hardware for the bindings is released. tinkerforge_uc_bindings_2_0_0_beta_8.zip
  12. Moin, Erstmal danke für die Tests! Es überrascht mich etwas, dass der Aufbau funktioniert: Der Arduino Uno hat ein Logik-Pegel von 5V, das Bricklet ist 5V kompatibel, schickt selbst aber nur 3,3V über die MOSI-Leitung. Du hast anscheinend das Glück, dass dein Arduino die 3,3V High-Signale versteht, bei meinem hat das nicht funktioniert. Falls du mit irgendeinem Bricklet keine Antworten bekommst, liegt es vermutlich daran. Zu dem TODO bei deinem Push-Button-Test: Die Callbacks kommennur, wenn du eine Funktion aufrufst, da sonst keine Kommunikation mit dem Bricklet stattfindet. Es gibt aber pro Device eine Callback-Tick-Funktion, z.B. int tf_io4_v2_callback_tick(TF_IO4V2 *io4_v2, uint32_t timeout_us); Die Funktion blockiert für die übergebene Zeit (in Mikrosekunden) und liefert Callbacks aus die reingekommen sind. D.h. wenn du in deiner Loop noch Zeit übrig hast ist es sinnvoll bei allen Bricklets bei denen du Callbacks benutzt die Funktion aufzurufen. Wenn du die ganze Zeit mit dem Bricklet kommunizierst, z.b. bei dir mit get_value, werden die Callbacks dann ausgeliefert, wenn sie während des getters reinkommen. Die Tick-Funktion werde ich mal im Readme dokumentieren. Eventuell kommt noch eine allgemeinere Tick-Funktion, die alle Bricklets mit registrierten Callbacks tickt. Gruß, Erik Edit: Was mir noch aufgefallen ist: In deinem Callback-Handler hast du einen auskommentierten Funktionsaufruf auf dem IO4 Bricklet. Die Bindings unterstützen es aber nicht, aus einem Callback heraus wieder Funktionen aufzurufen, da ein Callback auch mitten in einem anderen Funktionsaufruf ankommen kann.
  13. ACHTUNG: Arduinos mit AVR-Mikrocontroller (z.b. der Arduino Uno und Mega) haben einen Logikpegel von 5V und brauchen deshalb einen Pegelwandler zwischen dem Arduino und dem Bricklet. Bricklets haben einen Logikpegel von 3,3V. Edit: Hier die offizielle Dokumentation. Moin, Nachdem es in letzter Zeit häufiger Kundenanfragen danach gab, Bricklets direkt mit einem Mikrocontroller zu verwenden, habe ich die letzten Monate entsprechende Bindings entwicklet. Die erste Beta der C/C++ Bindings für Mikrocontroller, mit denen Koprozessor-Bricklets direkt von z.B. einem Arduino über SPI gesteuert werden können, finden sich im Anhang. Die Bindings sind in eine allgemeine Implementierung und einen Hardware Abstraction Layer (HAL) für konkrete Plattformen unterteilt. Es gibt zur Zeit einen HAL für Arduino-AVR-Boards, einen für ESP32-Boards wie das NodeMCU und einen für das Raspberry Pi (Zero) + HAT (Zero). Details zum Interface, zur Implementierung eigener HALs für andere Boards usw. finden sich in der Dokumentation. Künftig wird es von uns eigene Hardware für die Bindings geben, sowohl ein ESP32-basiertes Board auf dem Programme, die die Bindings verwenden geflasht werden können, als auch ein neues Breakout Board, mit dem Koprozessor-Bricklets direkt mit einem Mikrocontroller verbunden werden können. (hier ein Teaser) Gruß, Erik Edit: Beta 8 mit folgender Änderung: Bug gefixt wegen dem Callbacks nach ~ 35 Minuten nicht mehr funktionierten. tinkerforge_uc_bindings_2_0_0_beta_8.zip
  14. Moin, ipcon.connect blockiert bis entweder die Verbindung aufgebaut ist oder ein Fehler auftritt. Folgende Dinge fallen mir am Code auf: Das "if __name__ == "__main__":" kannst du dir an der Stelle sparen, du bist da ja schon mitten im Programm. Wenn du dir die IPConnection weiter außen hältst, musst du nicht jedes Mal eine neue Verbindung aufbauen, wenn du einen Temperaturwert abfragen willst get_temperature() kann (wie fast alle anderen Funktionen der Bricks/Bricklets auch) Timeouts erzeugen, wenn aus irgendeinem Grund die Abfrage länger als (falls nicht umkonfiguriert) 2,5 Sekunden dauert. Je nachdem was sonst noch auf dem System passiert, kann das durchaus passieren. Am besten ist es, wenn du den Fehler fängst und behandelst, im einfachsten Fall probierst du es einfach nochmal, bis z.b. 5 Versuche nicht geklappt haben. Das kann z.b. so aussehen: from tinkerforge.ip_connection import Error # 3 Versuche, danach geben wir auf for i in range(3): try: temp = thermocouple.get_temperature() # Wenn der Aufruf geklappt hat, verlasse die Schleife break except Error as e: if e.value != Error.TIMEOUT: # Wenn der Fehler kein Timeout war wird er zum Aufrufer weitergegeben. raise e else: # Das else einer for-Schleife wird ausgeführt, wenn kein break in der Schleife getroffen wurde # Das heißt in diesem Fall, dass alle 3 Versuche Timeouts erzeugt haben print("Konnte Temperatur nicht abfragen") Damit du das nicht bei jedem Aufruf machen musst, kannst du dir das wie folgt in eine Funktion packen: from tinkerforge.ip_connection import Error def attempt_n_times(fn, name, attempts): for i in range(attempts): try: return fn() except Error as e: if e.value != Error.TIMEOUT: raise e print("Konnte {} nicht ausführen: {} Timeouts".format(name, attempts)) return None temp = attempt_n_times(thermocouple.get_temperature, "Temperaturabfrage", 3) attempt_n_times(lambda: thermocouple.set_configuration(16, 3, 0), "Thermocouple-Konfiguration", 3) Achtung: Das sind Codebeispiele für das Thermocouple Bricklet, das musst du noch auf das Temperature 2.0 oder PTC 2.0 Bricklet anpassen. Du scheinst ja beide zu benutzen. Warum die Timeouts bei dir manchmal gehäuft auftreten ist mir spontan nicht klar. Eventuell stört dein TK-Schrank die Signale? Gruß, Erik
  15. Das ist eine gute Frage. Ich würde an deiner Stelle mal folgendes testen: Du stellst das Voltage-Callback bei beiden Bricklets auf 2ms Periode, value_has_to_change false. Dann solltest du von jedem Bricklet 500 Callbacks pro Sekunde bekommen (das solltest du nachmessen, nicht dass bei deinem Aufbau/Programm noch irgendetwas limitiert). Da du hinter einem Master Brick auf 1000 Nachrichten pro Sekunde limitiert bist, kannst du nicht bei beiden Bricklets auf 1ms Periode gehen. Danach kannst du auf die Bricklets ein Synchronisationssignal legen, z.b. eine Rechteckspannung. Du solltest dann auf den Daten von beiden Bricklets den ersten Sprung sehen und kannst damit die Messungen korrelieren, relativ zum ersten Sprung sollte die jeweils n-te Messung im schlimmsten Fall ~4ms auseinanderliegen. Das basiert aber auch auf der Annahme, dass die Clocks der Bricklets nicht driften, das würde ich also nicht über Stunden laufen lassen. Das nächste Problem ist dann, dass das Sampling selbst nicht synchron ist. Du siehst schon, dass das in Summe extrem schwierig ist, an sinnvoll synchrone Daten zu kommen. Bist du dir ganz sicher, dass du für Zellspannungen (Ich gehe mal davon aus von Batteriezellen?) so starke Zeitanforderungen hast? Ich würde eigentlich erwarten, dass die Messwerte relativ träge sind.
  16. Hm, da wirst du glaube ich nicht glücklich mit den Bricklets. Intern laufen die Bricks und Bricklets mit einer Tickrate von 1000 Hz, der Master Brick kann also höchstens eine Messung pro Millisekunde wegtransportieren. Theoretisch könnten die Bricklets alle gleichzeitig messen und du hast den Zeitversatz nur in der Kommunikation, aber auf so kleinen Zeitskalen ist das praktisch unmöglich zu synchronisieren, sorry.
  17. Das kannst du höchstens über Tricks hinbekommen, hängt aber von deinem Anwendungsfall ab. Was versuchst du synchron zu messen? Von welchen Zeitskalen reden wir da? Das hängt davon ab, ob du alte Bricklets mit 10-Pol-Stecker verwendest, oder die neuen Koprozessor-Bricklets mit 7-Pol-Stecker: Bei den alten wird die Firmware vom Master Brick ausgeführt, der dann auch die Callbacks generiert. Bei den neuen läuft die Firmware direkt auf dem Koprozessor, der dann auch von sich aus Callbacks erzeugen kann.
  18. Moin, Nein, es gibt keine Möglichkeit, die Abfragen zu synchronisieren. Ersteres, die Befehle werden vom RED-Brick nacheinander zu den anderen Bricks/Bricklets gesendet. Die Bricklets können Callbacks parallel auslösen. Der Brick fragt aber intern nacheinander ab. D.h. du kannst parallel erzeugte Callbacks nacheinander bekommen, hast aber keine Möglichkeit herauszufinden, ob sie wirklich gleichzeitig ausgelöst wurden. Sowohl, als auch: Du hast weniger Arbeit und es muss pro Messwert nur noch ein Paket vom Bricklet zum RED-Brick geschickt werden, das Paket mit der Anfrage vom RED-Brick zum Bricklet fällt weg.
  19. Nein, das wird nicht unterstützt. Das kommt hin, ein Unterschied ist aber, dass du das Enumerate auch für Teile der Hardware bekommen kannst, du kannst ja zwei Stacks per USB angeschlossen haben und dann einen abziehen.
  20. Moin, Du kannst die LEDs steuern, indem du die entsprechenden Dateien schreibst. Es gibt folgende Ordner: Rote LED: /sys/class/leds/red-brick:led:error/ Grüne LED: /sys/class/leds/red-brick:led:running/ Darin kannst du z.B. default-on in die trigger-Datei schreiben um eine LED anzuschalten. Du kannst dir, indem du die trigger-Datei liest (z.b. mit cat /sys/class/leds/red-brick:led:error/trigger) anzeigen, welche Trigger es gibt und welcher aktuell ausgewählt ist. Die Helligkeit scheint nur binär, also an/aus, steuerbar zu sein: Wenn du eine 0 in brightness schreibst geht die LED aus, bei 1 bis 255 geht sie an (wenn der Trigger passt), bleibt aber gleich hell. Mit Python funktioniert das ganze dann z.B. so: with open('/sys/class/leds/red-brick:led:error/trigger', 'w') as f: f.write('heartbeat') Achtung: Damit du die Dateien schreiben darfst, musst du root-Rechte haben. Wenn du nur eine bestimmte Konfiguration für die LEDs setzen willst, kannst du auch den Brick Viewer benutzen: Im RED Brick -> Settings -> Brick Daemon-Tab kannst du die LEDs persistent setzen.
  21. Moin, Den Websocket-Port solltest du eigentlich nicht brauchen. Du kannst testen, ob die Jars geladen werden, indem du in der openHAB-Karaf-Konsole folgendes eingibst: bundle:list | grep Tinkerforge Bei mir sieht die Ausgabe dann so aus: 203 │ Active │ 80 │ 2.5.3.202005191321 │ openHAB Add-ons :: Bundles :: Tinkerforge Binding 211 │ Active │ 80 │ 2.1.26 │ Tinkerforge API Bindings Wenn das fehlt, hat openHAB die Jars aus irgendeinem Grund nicht geladen. Dann wäre es hilfreich, wenn du das openHAB-Log (die Datei logs/openhab.log im openHAB-Ordner) hier anhängst. Du kannst auch in der PaperUI nachsehen, ob das Binding installiert ist: Dann sollte es unter Configuration->Bindings aufgeführt sein. Wenn das alles klappt, solltest du über das Plus in der Inbox das Tinkerforge Binding und dann den Brick Daemon auswählen können. Da musst du dann für die Authentication auf Show More gehen, die Authentication aktivieren und das Passwort eingeben.
  22. Wenn du das weglässt, konfigurierst du auch alles, wenn du eine Enumerierung mit ENUMERATION_TYPE_DISCONNECTED bekommst, da sollte aber der Code auf keinen Fall laufen. Ansonsten gebe ich dir recht, wenn du eine Enumeration bei einem Reconnect auslöst, brauchst du sonst keine Spezialbehandlung.
  23. Wenn das Bricklet die Enumeration (mit -Type Connected) schickt, sollte es im Initialzustand sein, alles andere wäre ein Firmware-Bug. D.h. wenn du danach deine Abweichungen zum Initialzustand konfiguriest sollte das reichen. Bei einem Reconnect der IP-Connection kann es im worst-case natürlich sein, dass während du nicht verbunden warst, eins der Bricklets neugestartet wurde, um maximal robust zu sein musst du da also auch alles was du brauchst neu konfigurieren. Wenn sich jemand anderes per Brick Viewer verbindet und Konfiguration verstellt hast du verloren, das bekommst du nur in den Griff, wenn du die Bricklets resettest und danach neu konfigurierst. Da würde ich lieber die Authentication anschalten
  24. Du solltest übrigens prinzipiell darüber nachdenken, wenn ein _CONNECTED kommt, die Konfiguration des Bricklets (Callback-Registrierungen, Sample-Rates usw.) wiederherzustellen. Das ist ziemlich robust, habe ich z.B. in den openHAB-Bindings so gebaut.
  25. Moin, Das kann eigentlich nur passieren, wenn du entweder einen Code-Pfad hast, der das Callback deaktiviert, oder wenn das Bricklet aus irgendwelchen Gründen beschlossen hat, sich zu resetten. Hast du eventuell ein sporadisches Enumerate vom Bricklet gesehen, bevor keine Daten mehr kamen? Wenn das Bricklet ein Enumerate mit dem Enumeration-Type ENUMERATION_TYPE_CONNECTED (=1) schickt, dann hat es sich neugestartet. Erik
×
×
  • Neu erstellen...