H3LIS331DL

Liebe Arduino Freunde
Als Arduino Neuling schreibe ich zum ersten Mal in diesem Forum. Alles ist neu und spannend, dennoch sitze ich nun seit Tagen am selben Problem.
Ich habe einen H3LIS331DL Accelerometer und ein Arduino Uno Rev.3. Der Sensor liefert mir aber nicht alle 1ms Werte, wie es mit dem delay(1) angegeben habe. Im Schnitt kommen so alle 6ms Werte rein.
Nun, die Baudrate habe ich auf 115200 gesetzt.
Der Code ist folgender: (Demo-Code)

#include <H3LIS331DL.h>
#include <Wire.h>

#define VAL_X_AXIS  3
#define VAL_Y_AXIS  57
#define VAL_Z_AXIS  248

H3LIS331DL h3lis;

void setup() {
  Serial.begin(115200);
  h3lis.init();
  h3lis.importPara(VAL_X_AXIS, VAL_Y_AXIS, VAL_Z_AXIS);
}

void loop() {
  int16_t x, y, z;
  h3lis.readXYZ(&x, &y, &z);
  Serial.print(millis());
  Serial.print(";");
  Serial.print(x);
  Serial.print(";");
  Serial.print(y);
  Serial.print(";");
  Serial.println(z);

  double xyz[3];
  h3lis.getAcceleration(xyz);
  Serial.print(millis());
  Serial.print(";");
  Serial.print(xyz[0]);
  Serial.print(";");
  Serial.print(xyz[1]);
  Serial.print(";");
  Serial.println(xyz[2]);

  delay(1);
}

Die Werte sehen so aus:

8;45;39;536
12;-0.39;0.02;1.18
18;-3;183;280
22;-0.39;-0.08;2.42
28;141;135;424
33;-0.58;0.40;1.99
39;221;119;600
45;-0.25;-0.41;2.09
51;13;-89;440
55;-0.30;0.17;1.85
61;-259;151;504
66;-0.39;0.17;2.14
72;221;-73;536
76;0.04;-0.41;2.18
82;-179;-121;584
88;-0.06;0.40;1.66
94;-51;423;776
98;0.37;0.26;0.65
104;-19;-9;648
109;-0.15;0.17;1.99
115;61;-25;920
119;-0.06;-0.60;2.09
125;-179;-41;312
131;-0.78;-0.94;2.42
137;61;151;328
142;-0.01;0.79;1.75

In der H3LIS331DL.h suchte ich nach den Einstellungen zu der Output Data Rate und dessen Frequenzen. Ehrlich gesagt, habe ich das noch nicht ganz verstanden und es gelingt mir einfach nicht, eine Ausgabe pro Millisekunde zu erzeugen.

Hat jemand eine Idee, wie man diese Werte noch etwas schneller bringen könnte?

Vielen Dank für eure Antworten

(deleted)

arduino-girl:
und es gelingt mir einfach nicht, eine Ausgabe pro Millisekunde zu erzeugen.

Das wird so auch nicht funktionieren. Du hast ja nicht nur dein delay(1); im loop, sondern auch das Auslesen des Sensors und die ganzen Ausgaben. Auch das braucht Zeit. Gerade der Zeitbedarf für die Serial.print wird oft unterschätzt. Selbst bei 115200 Baud brauchen deine ganzen Serial.print im loop fast 3 ms. Und das Auslesen über I2C gehört auch nicht unbedingt zu den schnellsten Kommunikationsarten.

Hallo Peter
Danke für deine schnelle Antwort.
Da habe ich schon mal reingesehen. Auf S. 10 ist DR bit set to 11 für 1000Hz.
In der H3LIS331DL.h finde ich das auch:

#define H3LIS331DL_DR                   BIT(3) //output data rate: 00 - 50hz / 01 - 100hz / 10 - 400hz / 11 - 1000hz

Nun, da ich in C++ ganz neu bin, finde ich es einfach nicht raus, wie ich diesen "Befehl" zu 1000Hz "ODR" auslösen könnte.
Das ist auch in der selben Datei: Ich habe mit dem 0x03 versucht:

typedef enum {  
    H3LIS331DL_ODR_50Hz    = 0x00,
    H3LIS331DL_ODR_100Hz   = 0x01,  
    H3LIS331DL_ODR_400Hz   = 0x02,
    H3LIS331DL_ODR_1000Hz  = 0x03
} H3LIS331DL_ODR_t;

Also so in etwa:

#define H3LIS331DL_DR 0x03

Es ändert sich aber nichts.

Da gibt es noch eine 2. Datei (H3LIS331DL.cpp) wo ich dieses hier über die Data Rate gefunden habe:

/*******************************************************************************
* Function Name  : setODR
* Description    : Sets H3LIS331DL Accelerometer Output Data Rate 
* Input          : Output Data Rate
* Output         : None
* Return         : Status [MEMS_ERROR, MEMS_SUCCESS]
*******************************************************************************/
status_t H3LIS331DL::setODR(H3LIS331DL_ODR_t dr){
    byte value;
  
    if( !readReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, &value) )
        return MEMS_ERROR;
  
    value &= 0xE7;
    value |= dr<<H3LIS331DL_DR;
  
    if( !writeReg(H3LIS331DL_MEMS_I2C_ADDRESS, H3LIS331DL_CTRL_REG1, value) )
        return MEMS_ERROR;
  
    return MEMS_SUCCESS;
}

Mir fehlen einfach die Kenntnisse, wie ich das dem guten Arduino sagen könnte, dass er hier noch etwas schneller die Daten vom Sensor holt und anzeigt.

Sieht jemand eine Möglichkeit, wie man das im Sketch eingeben könnte, damit es auch Sinn ergibt und der Arduino es versteht :slight_smile:

Danke für eure Tipps

Gruss Arduino-Girl

Hallo Franz-Peter
Dann denkst du, dass die 6ms alles ist, was ich aus dem Sensor / Arduino rausholen kann?
Hat jemand eine Idee, wie ich die Standart-Frequenz die eingestellt ist herausfinden oder abfragen könnte?
Die Baudrate habe ich auch mal auf 2000000 gemacht, das gibt kein Unterschied. So, wie ich gelesen habe, sollten die 115200 völlig ausreichen.
Gruss

Du könntest mal deine ganzen Serial-Ausgaben rausschmeißen und nur noch millis und einen Wert vom Sensor ausgeben. Wenn es dann immer noch nur alle 6ms einen Wert gibt, liegt es an der I2C Abfrage. Dann begrenzt die die maximale Rate.
Vielleicht gibt es eine Lib, die die SPI-Schnittstelle des Sensors nutzt. SPI ist deutlich schneller als I2C.

Mir fehlen einfach die Kenntnisse,

Ja!

Sieht jemand eine Möglichkeit, wie man das im Sketch eingeben könnte, damit es auch Sinn ergibt und der Arduino es versteht

Ja!

Vermutlich möchtest du in irgendeinem C++ Buch mal nachschauen, was Methoden sind und wie man sie aufruft. Nebenbei könntest du auch dort untersuchen, was enum so tut, oder bedeutet.

Hallo
Danke für die raschen Tipps und Informationen. Es bring mich auf jeden Fall weiter, da ich nun auch weiss, dass ich mich tiefer damit beschäftigen muss ich freue mich auf's tüfteln.
Falls ich was interessantes finde, werde ich es hier teilen.
Seid nett gegrüsst