[I2C_MMA845X] Modul für Beschleunigungssensor mit DSP

Begonnen von jensb, 29 März 2016, 13:52:58

Vorheriges Thema - Nächstes Thema

jensb

Hallo allerseits,

anbei ein neues Modul, mit dem man die digitalen Beschleunigungssensoren MMA8251, MMA8252 und MMA8253 von Freescale/NXP nutzen kann, die z.B. am I2C-Bus eines Raspberry oder über Firmata angeschlossen werden können.

Das Besondere an diesen Beschleunigungssensoren ist, dass sie nicht nur die aktuelle Beschleunigung als Messwert liefern, sondern über 4 parametrierbare Bewegungsmustererkennungsfunktionen verfügen, mit denen man gleichzeitig

  • Ausrichtung
  • Bewegung
  • Stöße
  • und Antippen
erkennen kann, ohne dass man selbst den Signalverlauf auswerten muss. Das erledigt der im Beschleunigungssensor integrierte DSP.

Der Einstieg ist nicht ganz ohne Hürden. Gerade die richtige Parametrierung der Bewegungsmustererkennungsfunktionen klappt meist nur, wenn man sich die Freescale-Dokumenation durchliest. Außerdem verwendet der Chip einen ungewöhnlichen I2C-Lesemodus, was einen zusätzlichen Schritt bei der Installation erforderlich macht. Spaß am Experimentieren ist also Voraussetzung. Wer es ausprobieren möchte, sollte mit der Modul-Hilfe anfangen. Die FHEMWEB-Screenshots zeigen einen Teil der vielen Modul-Attribute.

Wofür man das gebrauchen kann? Nun, da die meisten von uns nicht mit ihrer Hardware joggen gehen, fällt die leicht zu realisierende Schrittzählerfunktion als Motivation wohl aus. Bei mir war es das PiTFT-Display, das ich im Konsolenmodus nutze. Der Touchscreen hat leider keine Unterstützung für GPM, also kann man die Hintergrundbeleuchtung so nicht wieder einschalten. Mit der Tipp-Erkennung des Beschleunigungssensors, einem GPIO-Eingang, einem Notify und einem Systemaufruf geht das jetzt ganz intuitiv. Anbei ein Foto von PiTFT mit Sensor.

Viel Spaß beim Ausprobieren,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

klausw

Schöne Sache,
muss ich mal schauen, wofür ich es verwenden kann  8)
Das Modul muss sicher in in die physikal. Module eingetragen werden?
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

jensb

Hallo Klaus,

meinst du mit
ZitatDas Modul muss sicher in in die physikal. Module eingetragen werden?
die Client-Liste von RPII2C bzw. FRM? Zum Ausprobieren ist das nicht nötig, da man IODev ja auch manuell setzten kann (und manchmal auch muss). Es würde eine automatische Zuordnung ermöglichen, wenn IODev nicht definiert ist. Allerdings gewinnt das Modul mit der kleineren NR, wenn mehrere Module passen.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

klausw

Zitat von: jensb am 31 März 2016, 12:38:37
meinst du mit  die Client-Liste von RPII2C bzw. FRM? Zum Ausprobieren ist das nicht nötig, da man IODev ja auch manuell setzten kann (und manchmal auch muss). Es würde eine automatische Zuordnung ermöglichen, wenn IODev nicht definiert ist. Allerdings gewinnt das Modul mit der kleineren NR, wenn mehrere Module passen.
es war als Frage zu verstehen, ob ich es in diese Module eintragen soll
der Mechanismus ist mir schon klar  8)
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

jensb

Hallo Klaus,

sorry, da bin ich mit meiner Erklärung wohl über das Ziel hinaus :-\

Bis jetzt ist das Modul nicht eingecheckt, das werde ich mir fürs Wochenende vornehmen. Hatte auf ein klein wenig mehr Feedback gehofft, aber es ist nun mal auch ein eher ungewöhnlicher Sensor im Vergleich zu den "normalen" Umweltsensoren für Temperatur, Luftfeuchtigkeit, etc.

Um FRM kann ich mich selbst kümmern, aber wenn du RPII2C übernehmen könntest, wäre das toll. Wo wir gerade dabei sind: Der MMA845X benötigt "combined write/read mode" alias "repeated start". Das kann man derzeit mit RPII2C nur im SMBus-Modus am RPi aktivieren. Habe das in der Modulhilfe beschrieben. Nach meinen Recherchen sollte es theoretisch auch mit ioctl funktionieren, aber dafür müsste der "read" angepasst werden. Das wäre dann aber Fleißarbeit, für ein Modul lohnt es nicht.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

klausw

Hi Jens,

Zitat von: jensb am 01 April 2016, 11:25:59
sorry, da bin ich mit meiner Erklärung wohl über das Ziel hinaus :-\
Erklärungen schaden nie  :)

Zitat von: jensb am 01 April 2016, 11:25:59
Bis jetzt ist das Modul nicht eingecheckt, das werde ich mir fürs Wochenende vornehmen. Hatte auf ein klein wenig mehr Feedback gehofft, aber es ist nun mal auch ein eher ungewöhnlicher Sensor im Vergleich zu den "normalen" Umweltsensoren für Temperatur, Luftfeuchtigkeit, etc.
Ich habe im Mom. keine Verwendung dafür.
Auf den Panstamps 1.1 ist glaube ich der gleiche Sensortyp verbaut. Damit hatte ich mal bisschen experimentiert.

Zitat von: jensb am 01 April 2016, 11:25:59
Um FRM kann ich mich selbst kümmern, aber wenn du RPII2C übernehmen könntest, wäre das toll. Wo wir gerade dabei sind: Der MMA845X benötigt "combined write/read mode" alias "repeated start". Das kann man derzeit mit RPII2C nur im SMBus-Modus am RPi aktivieren. Habe das in der Modulhilfe beschrieben. Nach meinen Recherchen sollte es theoretisch auch mit ioctl funktionieren, aber dafür müsste der "read" angepasst werden. Das wäre dann aber Fleißarbeit, für ein Modul lohnt es nicht.
Das sehe ich etwas anders. Ursprünglich hatte ich das RPII2C nur für den PCF geschrieben. Da sind inzwischen ein paar Module dazugekommen. Wenn dieser Mode nicht zu exotisch ist macht es durchaus Sinn das einzubauen. Dann würde es nicht nur auf das Raspberry beschränkt sein.
Allerdings verstehe ich nicht, wieso es über SMBus geht und mit ioctl nicht.
Lese und Schreibbefehle werden doch bei beiden sequentiell abgearbeitet.
Wenn du Änderungsvorschläge diesbezüglich hast können wir die gern einbauen.



Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

jensb

Hi Klaus,

über SMBus geht es wohl, weil dann "einfach nur" die jeweils eingestellten Parameter des Device-Treibers BCM2708 verwendet werden und man kann mit
echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined
den "combined" Modus aktivieren.

Für ioctl habe ich hier folgendes gefunden:

ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
  Do combined read/write transaction without stop in between.
  Only valid if the adapter has I2C_FUNC_I2C.  The argument is
  a pointer to a

  struct i2c_rdwr_ioctl_data {
      struct i2c_msg *msgs;  /* ptr to array of simple messages */
      int nmsgs;             /* number of messages to exchange */
  }

  The msgs[] themselves contain further pointers into data buffers.
  The function will write or read data to or from that buffers depending
  on whether the I2C_M_RD flag is set in a particular message or not.
  The slave address and whether to use ten bit address mode has to be
  set in each message, overriding the values set with the above ioctl's.

wobei man daraus noch ein Lösung für eine write/read-Abfolge machen müsste, denn es geht ja um das Lesen von einem oder mehreren Bytes und darum, dass nach dem Schreiben der Registernummer auf dem I2C-Bus keine Pause eingelegt wird, bevor die Daten eingelesen werden (Single Master Mode), was aber normalerweise gemacht wird (Multi Master Mode). Die ioctl-Funktion heißt "I2C_RDWR", was genau umgekehrt ist, aber von der Beschreibung her habe ich den Eindruck, dass man sich die Abfolge aussuchen kann. Ob es geht, müsste man testen.

Der Arduino kennt dafür den Befehl " Wire.endTransmission(false)". Firmata bietet die Möglichkeit, den Modus für jedes I2C-Device individuell einzustellen, allerdings kann das FRM momentan noch nicht. Im einfachsten Fall führt man in RPII2C ein neues Attribut ein, das wie der Device-Treiber-Parameter für alle Devices gilt. In den allermeisten Fällen schadet es nämlich nicht, wenn alle Devices im Single Master Mode angesprochen werden, da es ja meist nur den RPi als Master gibt.

Bin gern bereit zu testen oder eine Erweiterung für RPII2C vorzubereiten. Letzteres würde aber etwas dauern, da ich momentan auf der Firmata-Seite bei ein paar kleineren Verbesserungen helfe.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

jensb

Hallo,

das Modul I2C_MMA845X ist jetzt eingecheckt.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

klausw

Hallo Jens,

Zitat von: jensb am 01 April 2016, 16:52:57
über SMBus geht es wohl, weil dann "einfach nur" die jeweils eingestellten Parameter des Device-Treibers BCM2708 verwendet werden und man kann mit
echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined
den "combined" Modus aktivieren.
ok, aber ob das immer geht... schließlich werden die Schreib/Lese Befehle nacheinander an das physical geschickt


Zitat von: jensb am 01 April 2016, 16:52:57
Für ioctl habe ich hier folgendes gefunden:

ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
  Do combined read/write transaction without stop in between.
  Only valid if the adapter has I2C_FUNC_I2C.  The argument is
  a pointer to a
...

wobei man daraus noch ein Lösung für eine write/read-Abfolge machen müsste, denn es geht ja um das Lesen von einem oder mehreren Bytes und darum, dass nach dem Schreiben der Registernummer auf dem I2C-Bus keine Pause eingelegt wird, bevor die Daten eingelesen werden (Single Master Mode), was aber normalerweise gemacht wird (Multi Master Mode). Die ioctl-Funktion heißt "I2C_RDWR", was genau umgekehrt ist, aber von der Beschreibung her habe ich den Eindruck, dass man sich die Abfolge aussuchen kann. Ob es geht, müsste man testen.
Vermutlich ja, "I2C_RDWR" hält bestimmt einfach nur den Bus belegt bis alle Daten durch sind.
Jetzt müssen wir nur noch rausfinden, was "I2C_RDWR" ist. Das muss irgend ein Hex-Wert sein.
Für die herkömmlichen Lese und Schreibvorgänge nutze ich "I2C_SLAVE", was 0x0703 entspricht.
Ich bin etwas irritiert, da in der SMBus Bibliothek auch kein I2C_RDWR vorkommt.

An sich ist die Implementation nicht so komplex. Es macht sicher Sinn eine weitere clientmsg->{direction} zu definieren, damit die komplette Botschaft reingepackt werden kann. Oder wir erweitern i2cwrite...

Zitat von: jensb am 01 April 2016, 16:52:57

Der Arduino kennt dafür den Befehl " Wire.endTransmission(false)". Firmata bietet die Möglichkeit, den Modus für jedes I2C-Device individuell einzustellen, allerdings kann das FRM momentan noch nicht. Im einfachsten Fall führt man in RPII2C ein neues Attribut ein, das wie der Device-Treiber-Parameter für alle Devices gilt. In den allermeisten Fällen schadet es nämlich nicht, wenn alle Devices im Single Master Mode angesprochen werden, da es ja meist nur den RPi als Master gibt.

Bin gern bereit zu testen oder eine Erweiterung für RPII2C vorzubereiten. Letzteres würde aber etwas dauern, da ich momentan auf der Firmata-Seite bei ein paar kleineren Verbesserungen helfe.

Derzeit würde ich letzteres bevorzugen, ich bin beruflich die nächsten Wochen recht eingespannt  :-\
Wenn ein Attribut reicht ist das auch gut.
Aber wie gesagt, wie stellst du sicher, das die Nachrichten auch direkt aufeinander folgen wenn beispielsweise neben dem MMA noch ein I2C Portextender oder dranhängt der auch gerade bedient werden will.

Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

jensb

Hallo Klaus,

Zitat... aber ob das [über SMBus] immer geht...
kann ich mit ja beantworten, zumindest wenn nur ein Device am RPi hängt. Ich vermute aber, dass der Treiber berücksichtigt, ob man das gleiche Device anspricht oder nicht und u.U. gibt es da vielleicht auch noch ein Timeout.

Bei ioctl kann man vielleicht pro I2C Device ein eigenes Filehandle verwenden. Gibt mir etwas Zeit für einen Test, denn mir geht es da so wie dir.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

klausw

Hi Jens,
Zitat von: jensb am 02 April 2016, 17:56:15
kann ich mit ja beantworten, zumindest wenn nur ein Device am RPi hängt. Ich vermute aber, dass der Treiber berücksichtigt, ob man das gleiche Device anspricht oder nicht und u.U. gibt es da vielleicht auch noch ein Timeout.

Bei ioctl kann man vielleicht pro I2C Device ein eigenes Filehandle verwenden. Gibt mir etwas Zeit für einen Test, denn mir geht es da so wie dir.
Ist natürlich eine Möglichkeit, andererseits könnte man, da die Schreib/Lese Befehle ja sicher am Stück raus gehen auch das Filehandle einfach solange angelegt lassen, bis ein anderes I2C-Device angesprochen werden soll. Das macht das handling evtl. leichter.
Gib einfach Bescheid wenn du was hast, was ich einbauen kann  8)

Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

locutus

Hallo,
ich bin zwar nach commandref vorgegangen, aber sobald ich dem Sensor IODev zuweise, endet die Abfrage mit dem State: invalid device

define I2C RPII2C 1
attr I2C alias I2C-Bus

define Accelerometer I2C_MMA845X 0x1C
attr Accelerometer IODev I2C
attr Accelerometer pollInterval 5
attr Accelerometer verbose 5


2016.05.21 21:37:08 1: 3: No I/O device found for Accelerometer
2016.05.21 21:37:13 1: Accelerometer no IODev assigned
2016.05.21 21:37:18 5: Accelerometer RX register 13, 1 bytes: 255
2016.05.21 21:37:18 1: Accelerometer I2C device at address 28 is not MMA845X compatible


pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- 1c -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

jensb

Hallo locutus,

scheinbar fehlt noch die richtige Konfiguration von RPII2C (siehe dazu bitte auch den Abschnitt "define - Raspberry" in der Device-Hilfe von I2C_MMA845X). Bei mir sieht es so aus:


define RPI_I2C_1 RPII2C 1
attr RPI_I2C_1 useHWLib SMBus


Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb

locutus

libmoose-perl und Device::SMBus sind istalliert.
Auf Raspbian Jessie Kernel 4.4.11-v7+ erhalte ich immer noch die Statusmeldung: invalid device

sudo su - echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined exit
Zugriff wird verweigert ...
-bash: /sys/module/i2c_bcm2708/parameters/combined: Permission denied

jensb

Hallo locutus,

dass man mit sudo beim Zugriff "/sys/module/i2c_bcm2708" "Permission denied" bekommst, ist wahrscheinlich default, solange man "/etc/sudoers" nicht geeignet anpasst.

Verwende statt "sudo" eine root-bash mit "sudo bash" oder melde dich mit "su" vorübergehend direkt als root an. Anschließend wieder "echo -n 1 > /sys/module/i2c_bcm2708/parameters/combined". Als weitere Alternative, die für den Dauerbetrieb ohnehin die besser Wahl ist, gibt es noch die Variante mit einem Eintrag in "rc.local"(siehe Device-Hilfe unter "define - Notes - Raspberry - Permanent").

Solange "cat /sys/module/i2c_bcm2708/parameters/combined" nicht "Y" liefert, wird es in FHEM bei "invalid device" bleiben.

Grüße,
Jens
FHEM 6.1 - RPi 4 Raspbian 12 + PiTFT - OPi Zero Armbian 5.35
EnOcean - (W)LAN/Firmata: BMP180, TSL2561, SHT21, Heatronic 3, OBIS - WLAN/ESP8266: Gardena 1251, Zirkulationspumpe - RTL433: Oregon - Bluetooth - MQTT
Contributions: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/jensb