Skocz do zawartości

Brak odczytu bitów z rejestru[STM32L4][LSM6DS33]


Pomocna odpowiedź

Napisano (edytowany)

Witam,

Ostatnimi czasy robię kurs Kurs STM32L4. Po pozytywnym zakończeniu tematu czujnik ciśnienia, pomiar wysokości (I2C) postanowiłem podjąć próbę odtworzenia kursu, ale na innym czujniku. Na stanie miałem akcelerometr lsm6ds33. Próbowałem odczytać z niego temperaturę i wartości x/y/z z żyroskopu i akcelerometru oraz temperaturę. Udało mi się połączyć z czujnikiem po i2c, ale nie udaje mi się odczytać wartości z rejestrów.

image.png.cded11a11b98999ed7631885f6fb86d8.png

Moje pierwsze przypuszczenie jest takie, że błędnie wczytuje coś do rejestrów, albo po prostu w ogóle nie wybudzam czujnika.

Definicje rejestrów mam następujące:

#define LSM6DS33_ADDR        0xD6

#define LSM6DS33_OUT_TEMP_L			0x20
#define LSM6DS33_OUT_TEMP_H			0x21
#define LSM6DS33_OUTX_L_G				0x22
#define LSM6DS33_OUTX_H_G				0x23
#define LSM6DS33_OUTY_L_G				0x24
#define LSM6DS33_OUTY_H_G				0x25
#define LSM6DS33_OUTZ_L_G				0x26
#define LSM6DS33_OUTZ_H_G				0x27
#define LSM6DS33_WHO_AM_I				0x0F
#define LSM6DS33_CTRL1_XL				0x10
#define LSM6DS33_CTRL2_G				0x11
#define LSM6DS33_CTRL3_C				0x12
#define LSM6DS33_CTRL4_C				0x13
#define LSM6DS33_CTRL5_C				0x14
#define LSM6DS33_CTRL6_C				0x15
#define LSM6DS33_CTRL7_G				0x16
#define LSM6DS33_CTRL8_XL				0x17
#define LSM6DS33_CTRL9_XL				0x18
#define LSM6DS33_CTRL10_C				0x19
#define LSM6DS33_OUTX_L_XL				0x28
#define LSM6DS33_OUTX_H_XL				0x29
#define LSM6DS33_OUTY_L_XL				0x2a
#define LSM6DS33_OUTY_H_XL				0x2b
#define LSM6DS33_OUTZ_L_XL				0x2c
#define LSM6DS33_OUTZ_H_XL				0x2d

 

Funkcję inicjującą wraz z ustawieniem rejestrów wywołałem w następujący sposób:

uint8_t lsm_read_reg(uint8_t reg)
{
    uint8_t value = 0;
    HAL_I2C_Mem_Read(&hi2c1, LSM6DS33_ADDR, reg, 1, &value, sizeof(value), TIMEOUT);


    return value;
}

void lsm_write_reg(uint8_t reg, uint8_t value)
{
    HAL_I2C_Mem_Write(&hi2c1, LSM6DS33_ADDR, reg, 1, &value, sizeof(value), TIMEOUT);
}

HAL_StatusTypeDef LSM6DS33_init(void)
{
    if (lsm_read_reg(LSM6DS33_WHO_AM_I) != 0x69)
         return HAL_ERROR;

    return HAL_OK;
    lsm_write_reg(LSM6DS33_CTRL1_XL, 0b01000000);
    lsm_write_reg(LSM6DS33_CTRL2_G, 0b01000000);

}

 

Przykładowa funkcja do pomiaru np. temperatury wygląda u mnie w następujący sposób:

float LSM6DS33_read_temp(void)
{
     int16_t temp;

     if (HAL_I2C_Mem_Read(&hi2c1, LSM6DS33_ADDR, LSM6DS33_OUT_TEMP_L | 0x80, 1, (uint8_t*)&temp, sizeof(temp), TIMEOUT) != HAL_OK)
         Error_Handler();

     return temp;
}

 

Następnie wywołuję tą oraz wszystkie pozostałe funkcje w mainie w printf

printf("T = %.1f*C\r\n", LSM6DS33_read_temp());

 

A wartości odczytywane z rejestrów we wszystkich przypadkach wynoszą 0. Nie dostrzegam nigdzie błędów, ale być może ktoś kto ma większe doświadczenie z STMkami je wyłapie 🙂 

Dodatkowo załączę jeszcze datasheet omawianego czujnika.

lsm6ds33_datasheet.pdf

 

Z góry dziękuję za wszystkie uwagi i pomysły 🙂 

Edytowano przez fidelty
1 godzinę temu, fidelty napisał:

Nie dostrzegam nigdzie błędów

Tak na szybko:

1 godzinę temu, fidelty napisał:
    return HAL_OK;
    lsm_write_reg(LSM6DS33_CTRL1_XL, 0b01000000);
    lsm_write_reg(LSM6DS33_CTRL2_G, 0b01000000);

Instrukcje po return raczej się nie wykonają...

  • Lubię! 2

Racja, tutaj faktycznie się troszkę zagalopowałem. Wcześniej były zapisane w hex a tak sprawdzając rejestry w bin przerzuciłem niżej i nie zwróciłem uwagi na to, że jest już poniżej return. Plus za czujność. 🙂 

Wersja poprawiona:

HAL_StatusTypeDef LSM6DS33_init(void)
{
    if (lsm_read_reg(LSM6DS33_WHO_AM_I) != 0x69)
         return HAL_ERROR;

    lsm_write_reg(LSM6DS33_CTRL1_XL, 0b01000000);
    lsm_write_reg(LSM6DS33_CTRL2_G, 0b01000000);
    return HAL_OK;


}

 

Niemniej jednak program zachowuje się bez zmian, dalej nie odczytuje żadnych wartości. 😕

Chyba nie pozostaje nic innego niż przeczytać dokładnie dokumentację czujnika. Uruchamiałem kiedyś LSM6DS3 na płytce B-L475E-IOT i z tego co pamiętam nie było większych problemów.

Proponuję zacząć od tego fragmentu datasheeta:

2123613101_Screenshot2022-11-08at17_27_46.thumb.png.01eb6730a29fab07d0772a9e437b986e.png

Może samo zapisanie 0x38 do CTRL9_XL wystarczy na początek.

  • Lubię! 2

Hmm... Faktycznie wstępna konfiguracja rejestrów na pewno u mnie leżała. Niestety dodanie rejestrów 9 i 10 do zapisu nie poprawiło efektu końcowego, ale jest to już duży krok do przodu. Spróbuję obszerniej zapoznać się z dokumentacją, może coś z tego jeszcze wyjdzie, może jeszcze nie wszystko poprawnie skonfigurowałem 🙂 

Edit: poprzedni plik pdf był notą aplikacyjną, datasheet czyli nota produkcyjna oczywiście tutaj:

datasheet_LSM6DS33.pdf

Jeszcze jedna uwaga:

4 godziny temu, fidelty napisał:
     if (HAL_I2C_Mem_Read(&hi2c1, LSM6DS33_ADDR, LSM6DS33_OUT_TEMP_L | 0x80, 1, (uint8_t*)&temp, sizeof(temp), TIMEOUT) != HAL_OK)

Proponuję usunąć | 0x80 - to działało tylko z LPS25.

  • Lubię! 1
  • Pomogłeś! 1
(edytowany)
LSM6DS33_ADDR, LSM6DS33_OUT_TEMP_L | (LSM6DS33_OUT_TEMP_H<<8)

Wow dzięki wielkie, maszyna ruszyła 🙂

Nie jestem pewny czy o taki zapis chodziło, ale nagle pojawiły się wartości 🙂 

image.thumb.png.314843bee3fe0d816677efe96cf3a901.png

Zakładając, że o to chodziło będę teraz musiał poszukać w Internecie jak to wszystko przeliczać na jednostki bardziej "realistyczne" 🙂

Martwi mnie mimo wszystko aż taka zmiana osi z akcelerometru z kilkudziesięciu tysięcy na 13.

Ale jest duży progres, wielkie dzięki za pomoc

 

 

Edytowano przez fidelty

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...