Żyroskop i akcelerometr InvenSense/TDK MPU6050 na ESP32-S3

Skoncentrowałem się na zdjęciu samego modułu MPU6050, ale na zdjęciach ogólnych widać jakieś rozwiązania dziwnego łączenia przewodów, może wystarczy je poprawić… (dałbym albo lutowane przewody, albo jakieś z sensowną złączką, a nie taką partyzantkę)

W wątku zapadła cisza, z czego wnoszę, że masz już rozwiązanie, tylko się nim nie chwalisz. edit - egzemlarz należący do OPa wątku był wadliwy, co skończyło się zastosowaniem innego modelu czujnika - BMI160

Sprawiłem sobie taki MPU6050 i… u mnie działa.

Testowo odpaliłem ten czujnik na RPi Pico W “jedynce” (RP2040 133MHz, 256KB RAM, 2MB Flash) i tam były jeszcze duże luzy zasobów (framework arduino dla maliny), bo na tym S3 (ESP32S3 240MHz, 320KB RAM, 16MB Flash, 8MB PSRAM) to strzelamy z armaty do muchy (wykorzystanie RAMu i flasha w konfiguracji poniżej to 10%-12%, a ogromny PSRAM 8MB jest wykorzystany w 0%… więc nie wiem co planujesz jeszcze wrzucić na ten MCU). Aha testowałem też S3 na frameworku Arduino, ale IDF jest optymalny ze wzgłędów przyszłościowych (kierunek rozwoju ESPHome).

Wersja taka trochę na kolanie dla frameworka IDF dokładnie dla takiej płytki, jaką masz, czyli S3(N16R8) są jakieś zbędne komponenty, ale ta płytka S3 to fajna zabawka.
I jeszcze ze 3 słowa komentarza, jest spory drift niektórych parametrów (nie jest to zaskakujące, jedno, że stara generacja MEMS, drugie, że to raczej budżetowy czujnik) nie wiem czy się da temu sensownie zaradzić, o ile żyroskop jest banalny w kalibracji - wystarczy zmierzyć wskazania dłuższy czas w bezruchu, to kalibrowanie akcelerometru będzie w podobny sposób mega upierdliwe, no i tu wchodzi drift - wskazania się rozjeżdzają z czasem.
Druga kwestia szumy własne - dorzuciłem jakies filterki, ale nie są to dobrze dobrane parametry. Poza konkurencją - ze względu na budowę wewnętrzną oś Z ma inne parametry od X i Y więc optymalna orientacja montażu to pozioma (tak by oś Z była pionowa).

substitutions:
  name: "esp32-s3-n16r8-idf"
  friendly_name: "ESP32-S3-N16R8 IDF"

esphome:
  name: ${name}
  friendly_name: ${friendly_name}

esp32:
  board: esp32-s3-devkitc-1
  flash_size: 16MB 
  framework:
    type: esp-idf 

psram:
  mode: octal 
  speed: 80MHz

debug:
  update_interval: 5s

logger:
  level: debug
# Enable logging
#  level: VERY_VERBOSE
#  level: VERBOSE


api:
  encryption:
    key: !secret api_key

ota:
  platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  ap:
    ssid: "${friendly_name} brak sieci!"
    password: !secret wifi_rcvr

improv_serial:

captive_portal:

web_server:
  port: 80
  auth:
    username: !secret web_username
    password: !secret web_password

one_wire:
  - platform: gpio
    pin: GPIO10   # tu zmieniłem GPIO, bo miałem na takim jak używasz coś innego swojego
    id: one_wire_bus  # swoją drogą nie mam wolnego DS18B20 więc go nie uwzględniłem

i2c:
    sda: GPIO8
    scl: GPIO9
    scan: true
    frequency: 400kHz

text_sensor:
  - platform: debug
    device:
      name: ${friendly_name} Device Info
    reset_reason:
      name: ${friendly_name} Reset Reason
  - platform: wifi_info
    ip_address:
      name: ${friendly_name} IP Address
    ssid:
      name: ${friendly_name} Connected SSID
    bssid:
      name: ${friendly_name} Connected BSSID
    mac_address:
      name: ${friendly_name} Mac Wifi Address
    scan_results:
      name: ${friendly_name} Latest Scan Results


binary_sensor:
  - platform: status
    name: ${friendly_name} Node Status
    id: system_status

sensor:
# testowy MPU6050 max ~4mA 
  - platform: mpu6050
    address: 0x68
    update_interval: 50ms # Częstsze odczyty pozwalają na lepsze filtrowanie
    accel_x:
      name: "MPU6050 Accel X"
      id: accel_x
      filters:
        - sliding_window_moving_average:
            window_size: 35
            send_every: 9
        - or:
            - throttle_average: 500ms
            - delta: 1.0
#      internal: true # Ukrywamy surowe dane, by nie zaśmiecać interfejsu
    accel_y:
      name: "MPU6050 Accel Y"
      id: accel_y
      filters:
        - sliding_window_moving_average:
            window_size: 35
            send_every: 9
        - or:
            - throttle_average: 500ms
            - delta: 1.0
#      internal: true # Ukrywamy surowe dane, by nie zaśmiecać interfejsu
    accel_z:
      name: "MPU6050 Accel Z"
      id: accel_z
      filters:
        - sliding_window_moving_average:
            window_size: 35
            send_every: 9
        - or:
            - throttle_average: 500ms
            - delta: 1.0
#      internal: true # Ukrywamy surowe dane, by nie zaśmiecać interfejsu
    gyro_x:
      name: "MPU6050 Gyro X"
      id: gyro_x
      filters:
        - offset: 0.91
        - sliding_window_moving_average:
            window_size: 35
            send_every: 9
        - or:
            - throttle_average: 500ms
            - delta: 1.0

    gyro_y:
      name: "MPU6050 Gyro Y"
      id: gyro_y
      filters:
        - offset: -1.415
        - sliding_window_moving_average:
            window_size: 35
            send_every: 9
        - or:
            - throttle_average: 500ms
            - delta: 1.0

    gyro_z:
      name: "MPU6050 Gyro Z"
      id: gyro_z
      filters:
        - offset: 1.85
        - sliding_window_moving_average:
            window_size: 35
            send_every: 9
        - or:
            - throttle_average: 500ms
            - delta: 1.0

    temperature:
      name: "MPU6050 Temperature"
      filters:
        - sliding_window_moving_average:
            window_size: 45
            send_every: 15
        - or:
            - throttle_average: 5s
            - delta: 0.5
  # Obliczanie kąta nachylenia (Pitch)
  - platform: template
    name: "MPU6050 Kąt Nachylenia X"
    icon: "mdi:axis-x-rotate-clockwise"
    unit_of_measurement: "°"
    accuracy_decimals: 1
    lambda: |-
      return (atan2(id(accel_x).state, sqrt(pow(id(accel_y).state, 2) + pow(id(accel_z).state, 2))) * 180 / M_PI);
    filters:
      - sliding_window_moving_average:
          window_size: 25 # Uśrednia ostatnie 25 odczytów
          send_every: 7   # Wysyła dane do Home Assistant co 7 odczytów
      - or:
          - throttle: 500ms # Wysyła dane nie częściej niż co pół sekundy...
          - delta: 1.0      # ...chyba że kąt zmieni się o więcej niż 1 stopień
  # Obliczanie kąta nachylenia (Roll)
  - platform: template
    name: "MPU6050 Kąt Nachylenia Y"
    icon: "mdi:axis-y-rotate-clockwise"
    unit_of_measurement: "°"
    accuracy_decimals: 1
    lambda: |-
      return (atan2(id(accel_y).state, sqrt(pow(id(accel_x).state, 2) + pow(id(accel_z).state, 2))) * 180 / M_PI);
    filters:
      - sliding_window_moving_average:
          window_size: 15
          send_every: 5  
      - or:
          - throttle: 500ms 
          - delta: 1.0    
  - platform: debug
    free:
      name: "Heap Free"
    block:
      name: "Heap Max Block"
    loop_time:
      name: "Loop Time"
    psram:
      name: "Free PSRAM"
  - platform: internal_temperature
    name: ${friendly_name} Internal Temperature
    accuracy_decimals: 1


switch:
  - platform: restart
    name: ${friendly_name} Restart

button:
  - platform: safe_mode
    name: ${friendly_name} Safe Mode Boot
    entity_category: diagnostic
  - platform: template
    name: Light Red
    id: my_button_red
    icon: "mdi:alpha-r-box-outline"
    on_press:
      - light.turn_on:
          id: zarowa
          brightness: 50%
          red: 100%
          green: 0%
          blue: 0%
#          transition_length: 0.5s

  - platform: template
    name: Light Blue
    id: my_button_blue
    icon: "mdi:alpha-b-box-outline"
    on_press:
      - light.turn_on:
          id: zarowa
          brightness: 50%
          red: 0%
          green: 0%
          blue: 100%

  - platform: template
    name: Light Green
    id: my_button_green
    icon: "mdi:alpha-g-box-outline"
    on_press:
      - light.turn_on:
          id: zarowa
          brightness: 50%
          red: 0%
          green: 100%
          blue: 0%

  - platform: template
    name: Light Yellow
    id: my_button_yellow
    icon: "mdi:alpha-y-box-outline"
    on_press:
      - light.turn_on:
          id: zarowa
          brightness: 50%
          red: 70%
          green: 45%
          blue: 0%

  - platform: template
    name: "Buzzer LEDC"
    on_press:

# Example usage in an automation

        then:
    ######################################################
    # Must be turned on before setting frequency & level
    ######################################################
        - output.turn_on: buzzer
    ######################################################
    # Frequency sets the wave size
    ######################################################
        - output.ledc.set_frequency:
            id: buzzer
            frequency: "1000Hz"
    ######################################################
    # level sets the %age time the PWM is on
    ######################################################
        - output.set_level:
            id: buzzer
            level: "50%"
        - delay: 0.5s
        - output.turn_off: buzzer
        - delay: 0.5s
        - output.turn_on: buzzer
        - output.ledc.set_frequency:
            id: buzzer
            frequency: "2000Hz"
        - output.set_level:
            id: buzzer
            level: "50%"
        - delay: 0.5s
        - output.turn_off: buzzer
        - delay: 0.5s
        - output.turn_on: buzzer
        - output.ledc.set_frequency:
            id: buzzer
            frequency: "5000Hz"
        - output.set_level:
            id: buzzer
            level: "50%"
        - delay: 0.5s
        - output.turn_off: buzzer
        - delay: 0.5s
        - output.turn_on: buzzer
        - output.ledc.set_frequency:
            id: buzzer
            frequency: "10000Hz"
        - output.set_level:
            id: buzzer
            level: "50%"
        - delay: 0.5s
        - output.turn_off: buzzer
        - delay: 0.5s
        - output.turn_on: buzzer
        - output.ledc.set_frequency:
            id: buzzer
            frequency: "14000Hz"
        - output.set_level:
            id: buzzer
            level: "50%"
        - delay: 1.5s
        - output.turn_off: buzzer

light:
  - platform: esp32_rmt_led_strip
    rgb_order: GRB
    pin: GPIO48
    num_leds: 1
    chipset: ws2812
    name: "NeoPixel Light"
    default_transition_length: 0.5s

    id: zarowa
    effects:
      # Use default parameters:
      - random:
      - random:
          name: Random Effect With Custom Values
          transition_length: 5s
          update_interval: 7s
      # Customize parameters
      - random:
          name: "My Slow Random Effect"
          transition_length: 30s
          update_interval: 30s
      - random:
          name: "My Fast Random Effect"
          transition_length: 4s
          update_interval: 5s
      - pulse:
      - pulse:
          name: "Fast Pulse"
          transition_length: 0.5s
          update_interval: 0.5s
      - pulse:
          name: "Slow Pulse"
          # transition_length: 1s      # defaults to 1s
          update_interval: 2s
      - strobe:
      - strobe:
          name: Strobe Effect With Custom Values
          colors:
            - state: true
              brightness: 100%
              red: 100%
              green: 90%
              blue: 0%
              duration: 500ms
            - state: false
              duration: 250ms
            - state: true
              brightness: 100%
              red: 0%
              green: 100%
              blue: 0%
              duration: 500ms
      - flicker:
      - flicker:
          name: Flicker Effect With Custom Values
          alpha: 95%
          intensity: 1.5%
      - lambda:
          name: My Custom Effect
          update_interval: 1s
          lambda: |-
            static int state = 0;
            auto call = id(zarowa).turn_on();
            // Transition of 1000ms = 1s
            call.set_transition_length(1000);
            if (state == 0) {
              call.set_rgb(1.0, 1.0, 1.0);
            } else if (state == 1) {
              call.set_rgb(1.0, 0.0, 1.0);
            } else if (state == 2) {
              call.set_rgb(0.0, 0.0, 1.0);
            } else {
              call.set_rgb(1.0, 0.0, 0.0);
            }
            call.perform();
            state += 1;
            if (state == 4)
              state = 0;

# Configure the output
output:
  - platform: ledc
    ######################################################
    # One buzzer leg connected to GPIO12, the other to GND
    ######################################################
    pin: GPIO12
    id: buzzer