Detection if device is moving (in motion) or not

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
netsrac
Posts: 17
Joined: Sun Jun 07, 2020 7:19 pm
Location: Berlin, Germany

Detection if device is moving (in motion) or not

Post by netsrac » Tue Dec 14, 2021 10:13 am

Hi,

I'm desperately searching for a simple solution to detect if my ESP32 is moving or not. The application is quite simple: I want to detect if my car is driving/moving or if it's parked somewhere and not moving - then do different actions depending on it's current state.

I tried various gyroscope and acceleration sensor but they all seems to have problems with sensor noise and not giving me a clear indicator. Is there a library available that would allow an easy detection of "object is moving" with any of the common sensors? Or anybody have a recommendation for a sensor which allows simple detection?

Thanks, Carsten

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Detection if device is moving (in motion) or not

Post by OlivierLenoir » Tue Dec 14, 2021 4:56 pm

Can you share with us, which 3-axis accelerometer and gyroscope sensor you are using?

netsrac
Posts: 17
Joined: Sun Jun 07, 2020 7:19 pm
Location: Berlin, Germany

Re: Detection if device is moving (in motion) or not

Post by netsrac » Tue Dec 14, 2021 7:04 pm

OlivierLenoir wrote:
Tue Dec 14, 2021 4:56 pm
Can you share with us, which 3-axis accelerometer and gyroscope sensor you are using?
I tried the MPU6050 which I had laying around…but I would be more than happy to try out a different sensor if this gives me the result I need…

netsrac
Posts: 17
Joined: Sun Jun 07, 2020 7:19 pm
Location: Berlin, Germany

Re: Detection if device is moving (in motion) or not

Post by netsrac » Tue Dec 14, 2021 7:14 pm

But maybe it’s not a problem of the sensor….maybe it’s more the understanding of the data and normalize them. Anybody aware of an algorithm that could help me?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Detection if device is moving (in motion) or not

Post by pythoncoder » Wed Dec 15, 2021 1:42 pm

Detection of constant velocity motion in a straight line is fundamentally impossible without an external reference. The best you can do with an IMU (which lacks an external reference) is to detect change: acceleration and deceleration using the g sensor or changes in direction using the gyro.

The alternative is to use a sensor which does have an external reference: GPS comes to mind.

Or detect rotation of the wheels.
Peter Hinch
Index to my micropython libraries.

netsrac
Posts: 17
Joined: Sun Jun 07, 2020 7:19 pm
Location: Berlin, Germany

Re: Detection if device is moving (in motion) or not

Post by netsrac » Wed Dec 15, 2021 4:50 pm

pythoncoder wrote:
Wed Dec 15, 2021 1:42 pm
The alternative is to use a sensor which does have an external reference: GPS comes to mind.
Well, GPS consumes to much power. I want to wake up, see if we are in motion and then decide if I should boot the GPS or not. Booting up the GPS, waiting for satellite fix and then see if we are in motion takes a long time and power.

Maybe a vibration sensor would help here, assuming that it's sensitive enough to detect that the car is driving. Are there sensor that can detect vibrations? Or is this all done via an IMU?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Detection if device is moving (in motion) or not

Post by pythoncoder » Wed Dec 15, 2021 5:20 pm

The acceleration sensor should be able to detect vibration.
Peter Hinch
Index to my micropython libraries.

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Detection if device is moving (in motion) or not

Post by OlivierLenoir » Wed Dec 15, 2021 7:52 pm

If you consider that your sensor is static when powered on and that you are doing one acceleration measure per second you get the velocity variation . Sum those variations and you get the velocity.

Code: Select all

from utime import sleep

# Init velocity at power on
velocity = 0  # m/s
period = 1  # second

def get_acceleration():
    # your code to read MPU6050
    return acceleration  # m/s**2

while True:
    vilocity += get_acceleration() * period
    print('{velocity} m/s'.format(velocity))
    sleep(period)
For the gyro, as it should return the angle, you can remove noise by sampling measures. Do n measure, sum them and divide my the number of measures.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Detection if device is moving (in motion) or not

Post by pythoncoder » Thu Dec 16, 2021 10:41 am

OlivierLenoir wrote:
Wed Dec 15, 2021 7:52 pm
...Sum those variations and you get the velocity...
This is fine in physics textbooks. Have you ever tried to do it with available IMU's? I recommend it as an educational experience. To determine a change in position you need to double integrate acceleration by which time the slightest offset has the output hitting the endstops.
Peter Hinch
Index to my micropython libraries.

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Detection if device is moving (in motion) or not

Post by OlivierLenoir » Thu Dec 16, 2021 10:04 pm

pythoncoder wrote:
Thu Dec 16, 2021 10:41 am
OlivierLenoir wrote:
Wed Dec 15, 2021 7:52 pm
...Sum those variations and you get the velocity...
This is fine in physics textbooks. ...
I agree with you Peter. I've been able to find, in my toolbox, a GY-521 MPU-6050 3-axis gyroscope and acceleration sensor.
Here is a small test based on this excellent video.

Code: Select all

# Created: 2021-12-16 19:54:43
# License: MIT, Copyright (c) 2021 Olivier Lenoir
# Language: MicroPython v1.17
# Project: Test GY-521 MPU-6050 3-axis gyroscope and acceleration sensor
# Description:


from machine import Pin, I2C
from ustruct import unpack
from utime import sleep_ms


SDA = const(21)
SCL = const(22)
MPU6050_ADDR = const(0x68)  # 104
MPU6050_TEMP_OUT = const(0x41)  # 2 bytes
MPU6050_ACCEL_OUT = const(0x3b)  # 6 bytes
MPU6050_GYRO_OUT = const(0x43)  # 6 bytes


i2c = I2C(0, scl=Pin(SCL), sda=Pin(SDA), freq=400000)

i2c.scan()  # [104]


# Wake device
i2c.writeto_mem(MPU6050_ADDR, 0x6b, bytes([0]))

for _ in range(20):
    # Read temperature
    temp_raw = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_TEMP_OUT, 2)
    temp_data = unpack('>h', temp_raw)[0]
    temp_c = temp_data / 340 + 36.53
    print(temp_c, '°C')

    # Read accelerometer
    accel_raw = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_ACCEL_OUT, 6)
    accel_data = unpack('>hhh', accel_raw)
    accel_g = [d / 16384 for d in accel_data]
    print(accel_g, 'g')

    # Read gyro
    gyro_raw = i2c.readfrom_mem(MPU6050_ADDR, MPU6050_GYRO_OUT, 6)
    gyro_data = unpack('>hhh', gyro_raw)
    gyro_deg = [d / 131 for d in gyro_data]
    print(gyro_deg, '°/s')

    # Sleep
    sleep_ms(200)
The output will be something like that.

Code: Select all

24.43588 °C
[0.006835938, -0.5654297, 0.7666016] g
[73.85497, 55.77099, -20.08397] °/s
24.43588 °C
[-0.02172852, -0.2919922, 0.9108887] g
[35.48092, 25.16794, -23.55725] °/s
24.43588 °C
[-0.06835938, -0.1403809, 0.9416504] g
[72.40458, 19.96183, -28.85496] °/s
24.34176 °C
[-0.06225586, 0.04321289, 0.9279785] g
[28.32061, -2.656489, -8.847328] °/s
24.34176 °C
[0.02587891, 0.2089844, 0.9841309] g
[61.37405, -41.58016, -34.52672] °/s
24.34176 °C
[0.07202148, 0.3215332, 0.8552246] g
[5.320611, -5.427481, 11.32061] °/s
24.34176 °C
[0.07202148, 0.3820801, 0.7819824] g
[-28.99237, -2.450382, 27.58779] °/s
24.38882 °C
[0.2009277, 0.173584, 0.9230957] g
[-98.03817, 0.3435115, 46.99237] °/s
24.34176 °C
[0.2268066, -0.01953125, 0.9765625] g
[-23.26718, 5.641222, 7.343512] °/s
24.43588 °C
[0.1967773, -0.1291504, 0.9602051] g
[-72.41985, 1.198473, 29.74809] °/s
24.38882 °C
[0.1816406, -0.3828125, 0.887207] g
[-58.71756, -8.480916, 24.15267] °/s
24.48294 °C
[0.1999512, -0.498291, 0.857666] g
[-45.42748, -12.36641, 17.40458] °/s
24.38882 °C
[0.2434082, -0.5944824, 0.7597656] g
[-18.37405, -23.00763, -4.351145] °/s
24.34176 °C
[0.291748, -0.4406738, 0.8005371] g
[85.7939, -10.73282, -39.92367] °/s
24.34176 °C
[0.3713379, -0.1601563, 0.8549805] g
[41.77099, 24.74809, -37.77099] °/s
24.43588 °C
[0.3232422, -0.0004882813, 0.9194336] g
[25.29771, 24.81679, -42.41985] °/s
24.43588 °C
[0.2033691, 0.1318359, 0.9321289] g
[7.473282, 36.29771, -17.32825] °/s
24.38882 °C
[0.08422852, 0.08032227, 0.970459] g
[-43.58016, 35.96947, 0.5267176] °/s
24.38882 °C
[0.007324219, -0.08813477, 1.010498] g
[-69.21374, -4.10687, 16.1145] °/s
24.38882 °C
[0.03222656, -0.2460938, 0.9318848] g
[-72.70992, -20.75573, 27.12214] °/s
I have to stop for today. I plan de play with this next week.

Post Reply