Jump to content

rtrbt

Administrators
  • Gesamte Inhalte

    1.604
  • Benutzer seit

  • Letzter Besuch

  • Tagessiege

    164

Alle erstellten Inhalte von rtrbt

  1. Teste das nochmal mit Beta 3, die ich gerade in den Post oben eingefügt habe: Du kannst jetzt den Tick-Funktionen 0 als Timeout mitgeben, dann versuchen sie nur ein Callback zu empfangen, dass sofort gelesen werden kann, aber blockieren nicht weiter. Außerdem kannst du jetzt Callbacks z.b. so für 5 Sekunden ticken: uint32_t bench_start = tf_hal_current_time_us(&hal); while (tf_hal_current_time_us(&hal) - bench_start < 5000000) { tf_hal_callback_tick(&hal, 0); } Bei meinen Messungen war das praktisch genauso schnell, wie das Ticken von Hand auf die vier Bricklets zu verteilen. (Ich habe aber nur mit einem Pi 3 getestet, nicht einem Zero)
  2. Ja, aber nicht mit dem enumerate_handler. Der ist nur für die interne erste Suche, was angeschlossen ist. Offiziell gibt es die Funktion bool tf_hal_get_device_info(TF_HalContext *hal, size_t index, char ret_uid[7], char *ret_port_name, uint16_t *ret_device_id); Die Funktion gibt dir zurück, ob der HAL das n-te Bricklet (index) kennt und falls ja schreibt sie in ret_uid, ret_port_name und ret_device_id die entsprechenden Informationen. Wenn die Funktion false zurückgibt ist der Index zu groß. Benutzen kannst du die Funktion dann z.b. so um das erste Device mit einer Device-ID zu finden. (Wie bei den normalen C-Bindings gibt es im entsprechenden Header ein define für die Device-ID, z.b. TF_ACCELEROMETER_V2_DEVICE_IDENTIFIER bool find_first_uid_by_did(uint16_t device_id, char uid[7]) { char pos; uint16_t did; for (size_t i = 0; tf_hal_get_device_info(&hal, i, uid, &pos, &did); ++i) { if (did == device_id) { return true; } } return false; } Wenn du alle Bricklets sehen willst, die angeschlossen sind, kannst du folgendes machen: int i = 0; char uid[7] = {0}; char port_name; uint16_t device_id; while(tf_hal_get_device_info(&hal, i, uid, &port_name, &device_id)) { printf("Device %d: %s of type %d at port %c\n", i, uid, device_id, port_name); ++i; }
  3. Was es nicht alles gibt. Auf dem LCD ist dann auch nichts zu sehen? Soweit ich das sehe, (sind das diese Nodes?) sind die für Items, nicht für Actions. D.h. du müsstest irgendwie ein Item für den Text-Channel des LCDs anlegen und da dann einen String im Format "0,1,Hello World!" reinschreiben. Wenn du Node-RED benutzen willst kannst du aber alternativ zu den openHAB-Bindings auch die MQTT-Bindings verwenden, Node-RED kommt mit MQTT ziemlich gut klar.
  4. Das ist eine gute Frage, ich habe das immer nur über die PaperUI gemacht. Da kannst du sowohl das Item anlegen (blau) als auch den Channel konfigurieren (rot). Wenn du das zwingend über die Textdateien machen willst: Ich habe beim danach suchen diesen Thread gefunden, das sieht so aus als könnte es funktionieren. Edit: Man sollte das Bild auch anhängen
  5. Das macht der Brick Viewer für dich.
  6. Moin, Hast du die tinkerforge-2.1.26.jar aus der Java-Bindings-Zip oder aus der openHAB-Bindings-Zip? Mir fällt gerade auf, dass die nicht die selben sind, zweitere sind ein Maven-Bundle. Ich editiere mal meinen Post oben, da linke ich auf die falsche Datei, sorry dafür. Führe in der Konsole mal sha256sum /usr/share/openhab2/addons/tinkerforge-2.1.26.jar aus. Korrekt ist die 22c9d235f1c62c29a4ec4c9d1feccccf0e6f8b33. Wenn du da etwas anderes rausbekommst, musst du die Datei durch die aus den openHAB-Bindings ersetzen.
  7. Hi, By rebooting the Pi you mean power cycling it or just a software reboot? A software reboot does not restart the connected Master Brick, so this would indicate, that your problem is not the Brick or the Motion Bricklet. If this happens again, it would be interesting to see, if you can still connect to the Pi with Brick Viewer and if so, whether the Motion Bricklet is still working. Also the Brick Daemon log (/var/log/brickd.log) could be useful.
  8. Moin, Das das Bricklet nach dem Reset nicht wieder auftaucht liegt vermutlich daran, dass dessen Enumerate-Paket verloren gegangen ist. Wenn du Reconnectest, löst das auch eine Enumerierung aus, dann taucht das Bricklet wieder auf. Bezüglich der hängenden Temperatur selbst: Teste mal bitte die angehangene Firmware, die I2C-Kommunikationsfehler subtil anders behandelt, eventuell löst das dein Problem. Ich habe meinen Aufbau hier auch darauf umgestellt. temperature-v2-bricklet-firmware.zbin
  9. Moin, Das sieht aus als ob du das Programm nicht als Root startest. Die Root-Rechte brauchst du, damit du auf die SPI-Schnittstelle zugreifen darfst. Eventuell musst du erst set_configuration und dann die set_(continuous_)acceleration_callback_configuration aufrufen. Habe ich aber nicht getestet. Ich habe das hier mal getestet und komme auf 1850 Pakete pro Sekunde, also ~13900 Werte pro Sekunde und Bricklet (d.h. es würde für 16-Bit-Werte einer Achse mit 12800Hz reichen). Ich habe dabei die BRICKLET_STACK_SPI_CONFIG_MAX_SPEED_HZ in hal_linux.c auf 2000000 gesetzt, dann läuft die SPI-Kommunikation mit 2MHz, was das Maximum ist, das die Bricklets können und die Callback-Tick-Optimierung eingebaut, die ich erwähnt hatte. Ich habe dann mal mit dem Logic-Analyzer nachgesehen und festgestellt, dass selbst wenn ich das Programm "ideal" optimieren würde, man nicht die 25600 Hz bei 4 Bricklets schaffen wird: Der Linux-Kernel macht zwischen jedem Byte eine etwas längere Pause, die effektive Durchschnittsfrequenz liegt bei ~1.76 MHz. Mit der Frequenz kommt man dann auf 220 kByte/s unter der Annahme, ich könnte durchgängig Daten per SPI senden/empfangen. Ein Paket hat 60 Byte Payload, dazu 11 Byte Protokollheader usw. macht 71 Byte, ergibt ~3100 Pakete pro Sekunde, also 23250 Werte pro Sekunde und Bricklet. Durch den Overhead des Programms und weil ich auch auf das Bricklet warten muss, bis ein Acknowledgement kommt usw. verliert man dann nochmal einiges, auch deshalb, weil es vorkommt, dass aufgrund von Timing-Pech das Pi oder das Bricklet ein Paket neu senden muss. Falls du wirklich den vollen Durchsatz brauchst, sehe ich als Option nur noch, dass du einen ESP32 nimmst. Der ESP hat zwei benutzbare SPI-Einheiten, theoretisch könntest du einen HAL für jede SPI-Einheit anlegen und dann die HALs und deren zugeordnete Bricklets mit jeweils einem eigenen Thread auf einem der zwei Kerne des ESPs laufen lassen.
  10. Der Tick macht genau was du schreibst: Er blockiert für die übergebene Zeit und liefert Callbacks des Bricklets aus. Da auf einem Mikrocontroller kein Multitasking verfügbar sein muss, muss man das als Nutzer händisch machen. Hm, da hast du recht, für deinen Fall sind die 250µs wirklich sinnvoller. Noch ein Gedanke: Du willst ja eigentlich nicht die 250µs stehen, sondern falls innerhalb dieser Zeit ein Callback ankam weißt du ja, dass das nächste erst eine Millisekunde später kommen kann. Die Restzeit kannst du sinnvoller verwenden. D.h. ich baue in den Callback-Tick ein, dass du einen Timeout von 0 mitgeben kannst, das heißt dann "versuche ein Callback zu empfangen, falls gerade eins da ist, wenn nicht, brich sofort ab". Dann kannst du in deiner Loop alle Callbacks mit 0 als Timeout ticken und solltest damit nochmal deutlich effizienter sein. Du kannst ein ähnliches Verhalten testen, indem du TF_TFP_SLEEP_TIME_US in bindings/tfp.c auf z.b. 50 setzt und dann die Callback-Ticks mit z.B. 100µs aufrufst.
  11. Hi Claudio, Die Demo sieht soweit gut aus, es kann aber sein, dass du den Callback-Tick pro Device etwas länger ziehen musst, auf dem Raspberry Pi kann es dir bei ungünstigem Scheduling sonst passieren, dass du auf einem Device garnicht tickst und auf einem anderen dafür mehr, ist ja kein Echtzeitsystem. Bei meinen Tests meine ich mich daran erinnern zu können, dass etwas im Bereich 500 oder 1000µs besser lief. Ob das Continuous Callback schneller läuft als mit dem Brick Daemon würde mich auf jeden Fall auch interessieren, poste da mal deine Ergebnisse, wenn du getestet hast. Ich benutze im Linux-HAL zwar den selben Code wie der Brick Daemon, aber es gibt ein paar Stellen an denen ich aggressiver mit den Timings sein kann (Zielplattform sind ja Mikrocontroller), da kann es gut sein, dass du etwas mehr Performance rausziehen kannst. Die drei Callbacks gibt es garnicht, Connect und Disconnect fallen weg weil kein Brick Daemon läuft, zu dem man sich verbinden kann, Enumerate fällt weg, weil die Bindings beim hal_init nachsehen, welche Devices angeschlossen sind, danach aber nur mit diesen Devices arbeiten. High-Level-Callbacks sind Callbacks, die High-Level-Funktionen sind. (So weit, so nichtssagend). High-Level-Funktionen sind alle die intern streamen, also einen Funktionsaufruf der Bindings, bestes Beispiel dafür ist write_pixels vom LCD 128x64, in mehrere Pakete aufteilen, weil der Payload (in diesem Fall bis zu 128*64 boolsche Werte) nicht in ein Paket passt. High-Level-Callbacks sind dann zum Beispiel die für die Thermal-Bilder vom Thermal Imaging Bricklet oder das Spektrum des Sound Pressure Level Bricklets. Edit: Alle High-Level-Funktionen (also auch die Callbacks) haben eine entsprechende Low-Level-Variante. Man kann die Funktionalität also trotzdem verwenden, muss sich aber das Streaming selbst implementieren. Ich habe die High-Level-Callbacks mit vorgegebener Streaming-Implementierung rausgenommen, da die Daten temporär gehalten werden müssen, sie aber definitiv zu groß für den RAM eines Mikrocontrollers sind. (z.B: 80*60*2 =9600 Byte für das Thermal-Bild) Wenn man als User jetzt seine eigene Streaming-Logik implementiert, kann man z.b. ohne dass man das ganze Thermal-Bild im RAM hält, die wärmste Stelle im Bild finden.
  12. Moin, Nimm wie gesagt nur das NodeMCU mit dem HAT, der MEGA hat 5V Logikpegel, damit kannst du dir im schlimmsten Fall das HAT beschädigen. (Das HAT hat 3,3V Logikpegel, ich habe bei mir auf dem Tisch eins liegen, dass ich vermutlich genau mit diesem Fehler kaputt gemacht habe.) Es gibt 5 CS-Pins, weil das HAT Zero selbst einen Koprozessor hat. Aus Sicht der Bindings ist das HAT auch ein Brick, mit dem du Daten austauschen kannst. Im Sketch musst du die Pins auflisten, die du auf deiner Seite benutzt, also wenn du den MEGA weiter benutzt (mach das wie gesagt nicht!) wäre folgendes korrekt: TF_Port ports[5] = {{ .chip_select_pin=53, .port_name='A' }, { .chip_select_pin=49, .port_name='B' }, { .chip_select_pin=47, .port_name='C' }, { .chip_select_pin=45, .port_name='D' }, { .chip_select_pin=43, .port_name='I' }}; Ich vermute, dass deine Probleme mit dem Fehler -10 (errors.h sagt, das ist TF_E_DEVICE_NOT_FOUND) daher kommen, dass der MEGA die Antworten der Bricklets nicht versteht, weil ein 3,3V High nicht stark genug ist.
  13. Hi, If you use ti.set_spotmeter_config([20,20,40,40]) it should work: set_spotmeter_config requires an array of 4 elements instead of passing the four parameters directly.
  14. Moin, Hast du auf deinem Rechner auch eine statische IP konfiguriert? Auf der Extension läuft kein DHCP-Server. Folgende Einstellungen sollten beispielsweise funktionieren: Auf dem Rechner mit dem du dich auf die Extension verbinden willst: Adresse 10.0.0.2 Netzmaske 255.255.255.0 Gateway 10.0.0.1 Im Brick Viewer des Rechners musst du dann 10.0.0.1 als Host eintragen. Gruß, Erik
  15. Das hängt davon ab was für ein Brick/Bricklet das ist, bei dem du den Button drückst. Wenn du einen Brick oder ein altes 10-Pol-Bricklet resettest, startet der ganze Stapel neu. Wenn es ein 7-Pol-Bricklet ist, dann nur das Bricklet selbst. Danke, ich baue das hier mal nach. Falls sich da was tut, melde ich mich nochmal.
  16. 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?
  17. 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.
  18. 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.
  19. 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.
  20. 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
  21. 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
  22. 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.
  23. 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
  24. Hm ich teste das hier gerade auch, habe aber noch nicht gefunden, was genau kaputt ist. Ich melde mich morgen nochmal mit mehr Informationen.
  25. 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.
×
×
  • Neu erstellen...