Ich mache gerade meine ersten Schritte mit dem Dongle und hänge bereits fest, weit entfernt vom Auslesen meines Bosch BME280 sensors. Bitte um Hilfe.
Treiber ist installiert, die Library ebenfalls, das Testprogramm iowkittest gibt die gleichen Antworten wie 'lsusb -v' (wenngleich am Dongle nur sehr wenige LEDs leuchten ;-) ). Ich hab mich an den Sourcen für iowkittest und für die Library orientiert, sowie an diesem Post viewtopic.php?f=2&t=1710&p=9565&hilit=p ... 9479#p9565 (der jedoch für Python unter Windows erstellt ist).
ciowHandle = ctypes.c_ulong(iowHandle)
iowKitID = iowl.IowKitGetProductId(ciowHandle) # always zero (=bool False)
iowRev = iowl.IowKitGetRevision(ciowHandle) # always zero (=bool False)
Die ersten Zeilen liefern anscheinend richtige Ergebnisse, aber die letzten beiden liefern nur 0, was nach iowkit.c das boolesche False ist, und auf einen falschen Handle weist. Obwohl der Handle in dem o.g. Post genauso gemacht wurde und funktionierte. Jedoch war der auf Windows.
Ist das auf Linux irgendwie anders zu machen? Was ist falsch an meinem ciowHandle?
Ehrlich ich weiß gerade nicht, warum die beiden Funktionen 0 zurück geben.
Aber hier ist einmal ein Python Beispiel unter linux (raspi), was bei mir funktioniert:
import ctypes
from ctypes import *
import time, os
import sys
if sys.platform == 'linux2':
iowkit = ctypes.CDLL("libiowkit.so")
else:
NotImplementedError("loading the iowkit library not implemented yet")
#######################################################################
# iowkit definitions and declarations
# TODO: manually declare all function arguments and return types because
# ctypes does not seem to recognize 64bit pointers on its own
iowkit.IowKitOpenDevice.restype = ctypes.c_voidp
iowkit.IowKitVersion.restype = ctypes.c_char_p
iowkit.IowKitGetProductId.argtypes = [ctypes.c_voidp]
iowkit.IowKitGetProductId.restype = ctypes.c_ulong
iowkit.IowKitRead.argtypes = [ctypes.c_voidp, ctypes.c_ulong, ctypes.c_voidp, ctypes.c_ulong]
iowkit.IowKitCloseDevice.argtypes = [ctypes.c_voidp]
iowkit.IowKitGetDeviceHandle.argtypes = [ctypes.c_ulong]
iowkit.IowKitGetDeviceHandle.restype = ctypes.c_voidp
iowkit.IowKitGetNumDevs.restype = ctypes.c_ulong
iowkit.IowKitSetTimeout.argtypes = [ctypes.c_voidp, ctypes.c_ulong]
iowkit.IowKitReadImmediate.argtypes = [ctypes.c_voidp, ctypes.POINTER(ctypes.c_ulong)]
iowkit.IowKitGetSerialNumber.argtypes = [ctypes.c_voidp, ctypes.c_wchar_p]
Treffer! Die "# iowkit definitions and declarations" machen den Unterschied; da hätte ich lange suchen können, danke!
Dazu demnächst mehr, im Augenblick stolpere ich über die Library. Kann es sein, dass für Linux noch immer eine veraltete Library gepackt ist?
Heute nochmals downgeladen, und obgleich es darin "libiowkit-1.5.0" heisst, ist libiowkit.so dann verlinkt zu /usr/lib/libiowkit.so.1.0.5. Dazu kommt dass alle Dateien ein Datum von 2007 bzw 2012 haben, und der Output meines Programms gemäß dem IowKit_V15_API.pdf dokument anders sein müssten. Z.B. erfordert iowkit.IowKitCloseDevice.argtypes = [ctypes.c_voidp] eine Sequenz, während Version 1.5 ganz ohne Eingabe auskommen sollte, so wie das Open Gegenstück.
Wenn der CloseDevice im Raspi Programm funktionieren sollte (bei mir nicht), dann nur weil dort die echte 1.5 Version benutzt wird, und es der egal ist, ob ein handle, eine sequenz oder gar nichts eingeben wird?
Was heißt noch immer eine veraltete Version? Die API wurde seit 2007 nicht mehr geändert und für IowKitCloseDevice() musste schon seit Version 1.4 ein Parameter mit übergeben werden.
Ich habe eine Raspi mit einem frischen Linux gerade noch einmal mit der bei uns im Download liegenden API bespielt und alles funktioniert so wie es soll. Ja die libiowkit.so hat komischerweise die
Versionsnummer 1.0.5, aber evtl. ist das ein Zahlendreher.
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Wow, das spricht für eine erfreulich stabile Software!
Ich denke, ich kann jetzt alle Befehle per Python3 geben. Nun möchte ich mit I2C Sensoren kommunizieren, und da hakt es erneut, wie geht denn die Kommunikation?
Konkret für einen ersten Schritt: für einen LM75 Sensor muss ich 'S 90 00 R 02 P' an den Sensor schicken, und kann dann 2 Bytes lesen, in denen der Temperaturwert steckt. Soweit so einfach. Aber wie stelle ich es an, dass "S", "R", "P" übersandt werden? Beim Bosch BME280 wird es dann komplizierter, wenn ein Dutzend Bytes gelesen werden müssen.
Ich suche vergeblich nach einem I2C-Ratgeber-für-Dummies für den IOW24 Dongle - gibt es da einen irgendwo auf Eurer Seite?
Das Problem was ich habe ist, was ist mit "S", "R" und "P" gemeint? Soll das ein String sein oder die Flags, Start, Reset, Pause/Stop?
Die Start und Stop-Bits werden beim IO-Warrior im Flag eingetragen. Mehr dazu ist im Datenblatt beschrieben, wie ein Report aufgebaut ist.
Man muss an den IO-Warrior also einfach die Bytes (inkl. I2C Adresse) senden und dann den Status zurücklesen und dann einen Lesebefehl senden um die Daten die im Sensor stehen
dann auszulesen.
Beim Lesen mehrerer Bytes ist es so, das man dem IO-Warrior einfach sagt, wie viele Bytes man lesen möchte und dann dem entsprechend die IowKitRead() befehle durchführt.
Ein Konkretes Beispiel in Python haben wir dazu nicht nur etwas, was ich vor langer Zeit einmal für den IOW56 getestet hatte für I2C (unter Windows):
# DON'T FORGETT TO CLOSE AT THE END OF THE SCRIPT!!!!!
iowkit.IowKitCloseDevice(ioHandle)
Dieses Skript müsste man ein wenig anpassen aber es ist alles drin was man zum schreiben und lesen benötigt (Halt nur für den IOW56 und nicht für den IOW24).
Abteilung: Softwareentwicklung
Folge uns auf Twitter
Follow us on twitter
Danke. Nachdem ich dann festgestellt hatte, dass sich in den Tiefen der Datenblätter noch eine I2C Beschreibung findet, ging es dann recht einfach. Eine Python3 Demoversion für den IOW24-Dongle und den LM75 Sensor habe ich auf Sourceforge hochgeladen, hier: https://sourceforge.net/projects/i2cpytools/
Die Voranstellung der Typendeklaration erwies sich als ungemein hilfreich, ich habe sie korrigiert und komplettiert. Es kam aber bei der IowKitGetSerialNumber zu einem Problem: Das IOWkit definiert die Seriennummer als 8-stelligen Unicode String mit 2 bytes pro Character. Python - zumindest meine Python 3.5.2 Version - erwartet aber Unicode mit 4 Bytes pro char. Die versuchte Wandlung mit .value führte dann stets zum Crash. Ein Workaround mit ctypes.create_string_buffer(18) löst das Problem.
Die Definition der Reports und Flags ist ein bisschen frickelig. Ein bisschen Wrapping in Python hilft, könnte aber noch verbessert werden. Etwas komplexer wird es noch, wenn die Datenmengen nicht mehr in einen einzelnen Report passen. Vorerst mal als Demo ok.
Das Auslesen der Temperatur aus dem LM75B Sensor läuft über viele Stunden ohne Fehler. Ein Datensegment ist in der Abb geplottet. Die starken Flattereien betragen bis zu 4 bit der 11bit Auflösung; damit ist der Gewinn durch 11 bit beim neuen LM75B versus 9 bit beim alten LM75 nicht richtig nachvollziehbar, ist aber noch im Rahmen der Specs. Mit der Messrate (linker Teil 1 sek, rechts 10sek) hat es nichts zu tun. Die rote Kurve des gleitenden Mittelwertes zeigt, dass der Sensor "im Mittel" richtig misst. Der Dongle arbeitet korrekt. Der Vorteil des LM75(B) ist, dass er so einfach zu programmieren ist und damit für einen I2C Einstieg gut geeignet ist.
Probleme mit Datentypen sind bei Python durch die Sprache verursacht. Der Versuch dem Programmierer da durch inherente Typen die Arbeit zu erleichtern führt zum Gegenteil.
Das Rauschen auf dem Sensor kann durch die Stromversorgung kommen. Da empfiehlt es sich mal ganz detailliert ins Datenblatt zu schauen, möglicherweise sind da Hinweise drin wie man die Stromversorgung auslegen sollte, oder für zusätzliche Filterelemente. Bei A/D Wandlung kann es manchmal schon einen Unterschied machen, ob man die Masseleitung um den Chip oder drunter durch führt, oder wo der Kondensator sitzt.
Wir hatten beim StarterKit für den IOW56 auch viel Spaß den 14 Bit A/D Wandler ruhig zu kriegen :)
Inzwischen läuft alles bestens, der IOW24-DG Dongle funktioniert gut mit den I2C Sensoren BME280 (Temperatur, Luftdruck, Feuchtigkeit), LM75 Temperatur) und TSL2591 (LIcht Vis+IR), siehe Abb.
Mit im Paket ist die Plotting Software pytoolsPlot, die aber auch Stand-Alone zum Plot von CSV (Comma Separated Values) verwendet werden kann; die Abb ist damit gemacht
I2Cpytools unterstützt übrigens auch den USB-I2C Dongle von ELV Elektronik AG mit den gleichen Sensoren.