Silent Drummer's Dilemma: Measuring E-Drum Vibration Before Your Neighbor Complains

Hey guys,

I would like to share my new project. I’ve seen many videos regarding how to mount a platform and how to avoid annoying your neighbors while playing in an apartment. So, I followed those recommendations, and for almost a year I didn’t have any issues.

However, two weeks ago, a neighbor complained that someone was playing some kind of drums on Sunday (a no go in Switzerland). I thought it was me, so my engineer mind made me check whether I was annoying people. Meanwhile, I found out it was some kids playing for a carnival group, not me. Too late, I had already bought all the components.

The idea is to measure the vibration on the Thomann platform and how much of it transfers to the floor. Ideally, I would have needed a 3rd sensor close to the pedals, on top of the noise eater, to get a real reference, but for now it’s fine; I used a phone to measure this reference.

You can see the results so far. Using the reference I got from my phone, the absorption is around 99% of the real vibration created by the pedals.

Dashboard:

How does it work?

The idea is to measure the source of vibration and compare it with the floor, to understand the attenuation and whether the vibration is reaching your neighbor. In my case, I am using 2 sensors, but ideally I need a 3rd one.

I need to measure the vibration side by side with the pedal. The pedals are on top of a Roland Noise Eater, and the stand is using a Noise Eater too, and the drum rack is using this washing machine rubber for vibration.

All of those things are on top of the Thomann platform. Then I need another sensor to measure the vibration on the Thomann platform and understand whether the Noise Eaters are attenuating the vibration.

Finally, a third sensor goes on the floor, close to or under the platform; then you can see the source of vibration, the attenuation on the platform, and how much is reaching the floor.

So far, I’ve measured the source using my phone as a reference, and I can see the performance of the system is 99%.

=====

List of components:

  • ESP32 NodeMCU Development Board
  • Accelerometer ADXL345 GY-291
  • Single Dupont cableFemale

Inside the configuration.yaml (You need to use app like Studio Code server to get access to it)
Add it after the last line in your configuration.yaml

template:
  - sensor:
      - name: "Vibration Platform Percent"
        unique_id: vib_platform_pct
        unit_of_measurement: "%"
        state: >
          {% set max_g = 0.05 %}
          {% set v = states('sensor.office_adsxl_vib01_vibra_rms_g')|float(0) %}
          {{ [100, (v / max_g * 100)] | min | round(1) }}

      - name: "Vibration Floor Percent"
        unique_id: vib_floor_pct
        unit_of_measurement: "%"
        state: >
          {% set max_g = 0.05 %}
          {% set v = states('sensor.office_adsxl_vib02_vibra_rms_g')|float(0) %}
          {{ [100, (v / max_g * 100)] | min | round(1) }}

      - name: "Vibration Difference Percent"
        unique_id: vib_diff_pct
        unit_of_measurement: "%"
        state: >
          {% set p = states('sensor.vibration_platform_percent')|float(0) %}
          {% set f = states('sensor.vibration_floor_percent')|float(0) %}
          {{ (p - f) | round(1) }}

Electrical connection:

You need to use the same 3V3 for the VCC and CS.

Create a new device in the ESPHOME device Builder

Device configuration inside the ESPHome device Builder:
You need to flash each device with differente name, don’t forget it.

# Board: NodeMCU-32S (NodeMCU)
# Definition: definitions/boards/nodemcu-32s/manifest.yaml
esphome:
  name: Sensor Name
  friendly_name: Sensor Name

esp32:
  variant: esp32
  flash_size: 4MB
  framework:
    type: esp-idf

logger:
api:
  encryption:
    key: API ENCRYPTION KEY IN THE CONFIGURATION
ota:
  - platform: esphome
wifi:
  ssid: YOUR_WIFI_NETWORK
  password: YOUR_WIFI_PASSWORD
  ap:
    ssid: Sensor Name Fallback Hotspot
    password: AUTOMATIC GENERATED IN THE CONFIGURATION
captive_portal:

external_components:
  - source:
      type: git
      url: https://github.com/jdillenburg/esphome
      ref: main
    components: [ adxl345 ]

i2c:
  sda: GPIO21
  scl: GPIO22
  frequency: 400kHz

adxl345:
  - id: my_adxl345
    address: 0x53
    update_interval: 100ms
    range: 4G   # options: 2G, 4G, 8G, 16G
    accel_x:
      name: "Vibra X"
    accel_y:
      name: "Vibra Y"
    accel_z:
      name: "Vibra Z"

Dashboard:

You need to change the entity and heading here:

views:
  - type: sections
    sections:
      - type: grid
        cards:
          - type: heading
            heading: Neighbor Mood
          - type: custom:button-card
            entity: sensor.vibration_floor_percent
            show_name: false
            show_state: false
            show_icon: false
            show_label: true
            label: |
              [[[
                var pct = parseFloat(entity.state);
                if (pct < 10) return '😊';
                else if (pct < 40) return '😐';
                else return '😢';
              ]]]
            styles:
              card:
                - background-color: |
                    [[[
                      var pct = parseFloat(entity.state);
                      if (pct < 10) return '#2e7d32';
                      else if (pct < 40) return '#f9a825';
                      else return '#c62828';
                    ]]]
                - border-radius: 12px
                - padding: 30px 0
                - transition: background-color 0.3s ease
              label:
                - font-size: 110px
                - line-height: 1
                - justify-content: center
                - width: 100%
          - type: custom:button-card
            entity: sensor.vibration_floor_percent
            show_name: false
            show_state: false
            show_icon: false
            show_label: true
            label: |
              [[[
                var pct = parseFloat(entity.state);
                if (pct < 10) return 'Happy Neighbor';
                else if (pct < 40) return 'Neutral Neighbor';
                else return 'Annoyed Neighbor';
              ]]]
            styles:
              label:
                - font-size: 32px
                - font-weight: bold
                - justify-content: center
                - width: 100%
                - color: |
                    [[[
                      var pct = parseFloat(entity.state);
                      if (pct < 10) return '#4caf50';
                      else if (pct < 40) return '#f9a825';
                      else return '#e53935';
                    ]]]
          - type: heading
            heading: Isolation Analysis
          - type: markdown
            content: >
              {% set v01 =
              states('sensor.office_adsxl_vib01_vibra_rms_g')|float(0) %} {% set
              v02 = states('sensor.office_adsxl_vib02_vibra_rms_g')|float(0) %}
              {% set db01 =
              states('sensor.office_adsxl_vib01_vibra_db_re_1g')|float(0) %} {%
              set db02 =
              states('sensor.office_adsxl_vib02_vibra_db_re_1g')|float(0) %} {%
              set activity_threshold = 0.01 %}

              {% if v01 < activity_threshold %} ⚪ **At rest** — not enough
              excitation for a reliable transmission reading

              *(Platform: {{ v01 }} g | Floor: {{ v02 }} g — background noise)*
              {% else %} {% set diff_g = (v01 - v02) | round(5) %} {% set
              isolation_db = (db01 - db02) | round(1) %} {% set transmitted =
              ((v02 / v01) * 100) | round(1) %} {% set absorbed = (100 -
              transmitted) | round(1) %}

              **Difference (g):** {{ diff_g }} g

              **Isolation:** {{ isolation_db }} dB

              **Transmitted to floor:** {{ transmitted }}%

              **Absorbed by platform:** {{ absorbed }}%

              {% if v02 > 0.02 %} 🔴 **Vibration HIGH on floor** — risk of
              disturbing the neighbor {% elif v02 > 0.005 %} 🟡 **Vibration
              MEDIUM on floor** — pay attention {% else %} 🟢 **Vibration LOW on
              floor** — all quiet {% endif %} {% endif %}
      - type: grid
        cards:
          - type: heading
            heading: adsxl-vib01
          - type: tile
            entity: sensor.office_adsxl_vib01_vibra_db_re_1g
            icon: mdi:sine-wave
          - type: tile
            entity: sensor.office_adsxl_vib01_vibra_db_re_1um_s2
            icon: mdi:volume-vibrate
          - type: tile
            entity: sensor.office_adsxl_vib01_vibra_rms_g
            icon: mdi:vibrate
          - type: tile
            entity: sensor.office_adsxl_vib01_vibra_rms_m_s2
            icon: mdi:vibrate
          - type: heading
            heading: Comparison
          - type: history-graph
            title: Vibration Difference Over Time (%)
            entities:
              - entity: sensor.vibration_platform_percent
                name: Platform
              - entity: sensor.vibration_floor_percent
                name: Floor
              - entity: sensor.vibration_difference_percent
                name: Difference
            hours_to_show: 1
      - type: grid
        cards:
          - type: heading
            heading: adsxl-vib02
          - type: tile
            entity: sensor.office_adsxl_vib02_vibra_db_re_1g
            icon: mdi:sine-wave
          - type: tile
            entity: sensor.office_adsxl_vib02_vibra_db_re_1um_s2
            icon: mdi:volume-vibrate
          - type: tile
            entity: sensor.office_adsxl_vib02_vibra_rms_g
            icon: mdi:vibrate
          - type: tile
            entity: sensor.office_adsxl_vib02_vibra_rms_m_s2
            icon: mdi:vibrate
      - type: grid
        cards:
          - type: heading
            heading: Vibration Level
          - type: gauge
            entity: sensor.vibration_platform_percent
            name: Platform Vibration
            min: 0
            max: 100
            severity:
              green: 0
              yellow: 20
              red: 60
          - type: gauge
            entity: sensor.vibration_floor_percent
            name: Floor Vibration
            min: 0
            max: 100
            severity:
              green: 0
              yellow: 10
              red: 40

Sensor temporary installed:

I hope you like it.

Cheers
Fab from Brazil in Switzerland

1 Like