1

I'm controlling a Nema 17 stepper motor with an L298n driver via BCM pins 5, 6, 26, 25. Basically, all I'm doing is alternating them between HIGH and LOW.

Alongside, I'm reading the acceleration measurements of a MPU6050 sensor.

However, as soon as I start setting the speed of the engine to more than 0, the readings go crazy and are unreliable. Motor vibrations as a cause of the issue can be excluded as a possibility since the problem also occurs if the two are physically separated. In addition, the readings are fluctuating way too much (taping the sensor on my vibrating phone did not cause the readings to fluctuate this much!).

Here are some readings of the x-acceleration when speed is at 0:

-9.311050256347656 -8.566453540039062 -9.70369932861328 -9.272743029785156 -8.33182177734375 -9.548076220703125 -9.227253198242186

Here, when I let it spin a little

-2.4205378784179685 -9.04050546875 -9.409212524414063 -11.001356628417968 -14.951789367675781 -2.3822306518554686 -9.313444458007812

The purpose of the project is to build a self-balancing robot.

The raspberrypi 4 is supplied with an independent 5V power supply, the L298N shield 5V pin with an additional, independent 5V power supply, L298N shield 12V pin with an independent 12V power supply. The RaspberryPi is connected to the motor only through the 4 pins attached to the L298N pins IN1, IN2, IN3, IN4

For completeness, I've included an MME of a python script that combines the engine control with MPU6050 reading as well as a foto of my setup.

enter image description here

import time
from threading import Thread

import RPi.GPIO as GPIO
import adafruit_mpu6050
import board


class Motor:
    def __init__(self, out1, out2, out3, out4):
        self.out1 = out1
        self.out2 = out2
        self.out3 = out3
        self.out4 = out4

        GPIO.setmode(GPIO.BCM)
        GPIO.setup(out1, GPIO.OUT)
        GPIO.setup(out2, GPIO.OUT)
        GPIO.setup(out3, GPIO.OUT)
        GPIO.setup(out4, GPIO.OUT)

    def start(self):
        runtime = Thread(target=self._run, daemon=True)
        runtime.start()

    def _run(self):
        while True:
            GPIO.output(self.out1, GPIO.LOW)
            GPIO.output(self.out2, GPIO.LOW)
            GPIO.output(self.out3, GPIO.LOW)
            GPIO.output(self.out4, GPIO.LOW)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.HIGH)
            GPIO.output(self.out2, GPIO.LOW)
            GPIO.output(self.out3, GPIO.LOW)
            GPIO.output(self.out4, GPIO.LOW)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.HIGH)
            GPIO.output(self.out2, GPIO.HIGH)
            GPIO.output(self.out3, GPIO.LOW)
            GPIO.output(self.out4, GPIO.LOW)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.LOW)
            GPIO.output(self.out2, GPIO.HIGH)
            GPIO.output(self.out3, GPIO.LOW)
            GPIO.output(self.out4, GPIO.LOW)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.LOW)
            GPIO.output(self.out2, GPIO.HIGH)
            GPIO.output(self.out3, GPIO.HIGH)
            GPIO.output(self.out4, GPIO.LOW)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.LOW)
            GPIO.output(self.out2, GPIO.LOW)
            GPIO.output(self.out3, GPIO.HIGH)
            GPIO.output(self.out4, GPIO.LOW)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.LOW)
            GPIO.output(self.out2, GPIO.LOW)
            GPIO.output(self.out3, GPIO.HIGH)
            GPIO.output(self.out4, GPIO.HIGH)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.LOW)
            GPIO.output(self.out2, GPIO.LOW)
            GPIO.output(self.out3, GPIO.LOW)
            GPIO.output(self.out4, GPIO.HIGH)
            time.sleep(0.01)

            GPIO.output(self.out1, GPIO.HIGH)
            GPIO.output(self.out2, GPIO.LOW)
            GPIO.output(self.out3, GPIO.LOW)
            GPIO.output(self.out4, GPIO.HIGH)
            time.sleep(0.01)


if __name__ == "__main__":

    motor = Motor(5, 6, 26, 25)
    motor.start()
    last_speed = 0
    try:
        i2c = board.I2C()  # uses board.SCL and board.SDA
        mpu = adafruit_mpu6050.MPU6050(i2c)

        while True:
            print(mpu.acceleration[0])
            time.sleep(0.1)

except KeyboardInterrupt:
    print('Stopped.')
    GPIO.cleanup()

How can I ensure accurate readings?

2
  • 2
    Could you explain why this is not the result of vibration from the motor? That's pretty much what an accelerometer measures.
    – joan
    Oct 19, 2021 at 19:59
  • 1
    Thanks, I've extended my question to answer this... Motor vibrations as a cause of the issue can be excluded as a possibility since the problem also occurs if the two are physically separated. In addition, the readings are fluctuating way too much (taping the sensor on my vibrating phone did not cause the readings to fluctuate this much!).
    – cheesus
    Oct 20, 2021 at 7:41

1 Answer 1

1

Try disconnecting the motor driver from the Pi and repeating the measurements. If they become unstable the moment you start controlling the motor, there is likely a software bug in your code.

Otherwise, you have either an actual acceleration (something expected if the IMU and the motor are mechanically coupled) or perhaps an electrical problem. It's hard to tell what is connected to what without a schematic, e.g. is the ground of all modules connected to the Pi?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.