0
\$\begingroup\$

So I use MPU6050 to get acceleration from stepper motor linear rail movement(steper motor working in thread, I use pigpio for the motor) by make the MPU6050 can work on threading and it can show data on gui graphic (I use pyqt to create GUI dan pyqtgraph for create a graph) with time delay 0,1 . Th problem is I suddently getting an error message when the script is running for the moment OSError: [Errno 121] Remote I/O error when use smbus library so I change it to pigpio but get an error message pigpio.error: 'I2C read failed'

smbus error message:

Traceback (most recent call last):


File "/home/pi/Desktop/mejaGetar/ThreadAccelerator.py", line 33, in run
    self.startAccelerator()
  File "/home/pi/Desktop/mejaGetar/ThreadAccelerator.py", line 22, in startAccelerator
    getData = ThreadAccelerator.accelerator.get_accelerator()
  File "/home/pi/Desktop/mejaGetar/accel.py", line 43, in get_accelerator
    x = self.read_i2c_word(self.ACCEL_XOUT0)
  File "/home/pi/Desktop/mejaGetar/accel.py", line 32, in read_i2c_word
    high = self.bus.read_byte_data(self.address,register)
OSError: [Errno 121] Remote I/O error

pgpio error message:

Traceback (most recent call last):


File "/home/pi/Desktop/mejaGetar/ThreadAccelerator.py", line 33, in run
    self.startAccelerator()
  File "/home/pi/Desktop/mejaGetar/ThreadAccelerator.py", line 22, in startAccelerator
    getData = ThreadAccelerator.accelerator.get_accelerator()
  File "/home/pi/Desktop/mejaGetar/mmpu.py", line 48, in get_accelerator
    z = self.read_i2c_word(self.ACCEL_ZOUT0)
  File "/home/pi/Desktop/mejaGetar/mmpu.py", line 36, in read_i2c_word
    low = self.pi.i2c_read_byte_data(self.h,register + 1)
  File "/usr/local/lib/python3.4/dist-packages/pigpio.py", line 2792, in i2c_read_byte_data
    return _u2i(_pigpio_command(self.sl, _PI_CMD_I2CRB, handle, reg))
  File "/usr/local/lib/python3.4/dist-packages/pigpio.py", line 975, in _u2i
    raise error(error_text(v))
pigpio.error: 'I2C read failed'

and this is my code (using smbus): accel.py

import smbus

class accel:

    ACCEL_SCALE_MODIFIER_2G = 16384.0
    GRAVITIY_CMS2 = 980.665
    address = None
    bus = None

    #register MPU-6050
    PWR_MGMT_1 = 0x6B
    PWR_MGMT_2 = 0x6C

    #register accelerator
    ACCEL_CONFIG = 0x1C
    ACCEL_XOUT0 = 0x3B
    ACCEL_YOUT0 = 0x3D
    ACCEL_ZOUT0 = 0x3F
    CONFIG = 0x1A
    INT_ENABLE = 0x38

    def __init__(self,address,bus = 1):
        self.address = address
        self.bus = smbus.SMBus(bus)


        self.bus.write_byte_data(self.address,self.PWR_MGMT_1,0x00)
        self.bus.write_byte_data(self.address, self.ACCEL_CONFIG, 0x00)

    def read_i2c_word(self,register):

        high = self.bus.read_byte_data(self.address,register)
        low = self.bus.read_byte_data(self.address,register + 1)

        value = (high << 8) + low

        if(value > 32768):
           return -((65535 - value) + 1)
        else:
            return value

    def get_accelerator(self):
        x = self.read_i2c_word(self.ACCEL_XOUT0)
        y = self.read_i2c_word(self.ACCEL_YOUT0)
        z = self.read_i2c_word(self.ACCEL_ZOUT0)

        scale_modifier = self.ACCEL_SCALE_MODIFIER_2G

        x = x/scale_modifier
        y = y/scale_modifier
        z = z/scale_modifier

        x = x * self.GRAVITIY_CMS2
        y = y * self.GRAVITIY_CMS2
        z = z * self.GRAVITIY_CMS2

        return {'x': x, 'y': y, 'z': z}

threading implementation ThreadAccelerator.py

import time
import sys
from accel import accel
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QTime, QTimer
from write import write
import datetime

class ThreadAccelerator(QtCore.QThread):
    dataAccelerator = QtCore.pyqtSignal(object)
    accelerator = accel()
    time.sleep(1)
    collectData = []
    tulisRecord = write()
    run = False

    def __init__(self,parent=None):
        QtCore.QThread.__init__(self,parent)

    def startAccelerator(self):
        self.accelerator.setup()
        x = 0 
        while self.run == True:

            getData = self.accelerator.get_accelerator()
            self.dataAccelerator.emit({'x': getData['x'],'xx':x})
            print("hasil ",abs(getData['x']))
            x = x + 1

            time.sleep(0.1)


    def run(self):

        self.startAccelerator()

    def start(self):
        self.run = True
        super(ThreadAccelerator,self).start()

    def stop(self):
        self.run = False

and this is pigpio version: mmpu.py

import time
import sys

import pigpio

class mmpu:

    #default accell adalah 2G
    ACCEL_SCALE_MODIFIER_2G = 16384.0
    GRAVITIY_CMS2 = 980.665
    address = 0x68
    bus = None

    #register MPU-6050
    PWR_MGMT_1 = 0x6B
    PWR_MGMT_2 = 0x6C

    #register accelerator
    ACCEL_CONFIG = 0x1C
    ACCEL_XOUT0 = 0x3B
    ACCEL_YOUT0 = 0x3D
    ACCEL_ZOUT0 = 0x3F

    h = None

    pi=None

    def __init__(self):
        self.pi = pigpio.pi()

    def setup(self):
        self.h = self.pi.i2c_open(1, self.address)
        self.pi.i2c_write_byte_data(self.h,self.PWR_MGMT_1,0x00)
        self.pi.i2c_write_byte_data(self.h,self.ACCEL_CONFIG, 0x00)
        time.sleep(1)

    def read_i2c_word(self,register):
        high = self.pi.i2c_read_byte_data(self.h,register)
        low = self.pi.i2c_read_byte_data(self.h,register + 1)

        value = (high << 8) + low

        if(value > 32768):
           return -((65535 - value) + 1)
        else:
            return value

    def get_accelerator(self):
        x = self.read_i2c_word(self.ACCEL_XOUT0)
        y = self.read_i2c_word(self.ACCEL_YOUT0)
        z = self.read_i2c_word(self.ACCEL_ZOUT0)

        scale_modifier = self.ACCEL_SCALE_MODIFIER_2G

        x = x/scale_modifier
        y = y/scale_modifier
        z = z/scale_modifier

        x = x * self.GRAVITIY_CMS2
        y = y * self.GRAVITIY_CMS2
        z = z * self.GRAVITIY_CMS2

        return {'x': x, 'y': y, 'z': z}

    def close(self):
        self.pi.i2c_close(self.h)
        time.sleep(1)

threading implementation ThreadAccelerator.py

import time
import sys
from mmpu import mmpu
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QTime, QTimer
from write import write
import datetime

class ThreadAccelerator(QtCore.QThread):
    dataAccelerator = QtCore.pyqtSignal(object)
    accelerator = mmpu()
    time.sleep(1)
    collectData = []
    tulisRecord = write()
    run = False

    def __init__(self,parent=None):
        QtCore.QThread.__init__(self,parent)

    def startAccelerator(self):
        self.accelerator.setup()
        x = 0 
        while self.run == True:

            getData = self.accelerator.get_accelerator()
            self.dataAccelerator.emit({'x': getData['x'],'xx':x})
            print("hasil ",abs(getData['x']))
            x = x + 1

            time.sleep(0.1)


        self.accelerator.close()

    def run(self):

        self.startAccelerator()

    def start(self):
        self.run = True
        super(ThreadAccelerator,self).start()

    def stop(self):
        self.run = False

and this is the picture of my sensor connected with raspberry pi (it has been connected correcly)

using jumper cable

imlementation

implementation 2

So, what the error cause? Is that cause by too much using threading (there're around 3 thread: one for stepper motor,one for accelerometer mpu6050,and the last for some program)? Or by the bad quality of cable? Or the delay on threading accelerator MPU6050 is too fast? If the elay on threading accelerator MPU6050 is too fast then what should I do? I need it to fast generate data to grapic. That's all of my question, thank you. (I run it on raspbian jessie,pigpio library is already up to date)

\$\endgroup\$
  • \$\begingroup\$ What's your actual goal here? If you are using the accelerometer to study the stepper, that's one thing, but you'd really be much better off using a quadrature encoder, either rotary or linear, or just running the steppers far enough within specs that you can mostly rely on them to do what they are asked. Your actual issue could be anything from unreasonable timing expectations to flaky wiring to noise induced by the motor currents. \$\endgroup\$ – Chris Stratton Dec 14 '18 at 18:37
  • \$\begingroup\$ Generally speaking, using a pi or any multitasking system in the core of this is a severe mistake - you should be using a hard realtime solution for generating step pulses and reading the sensor, either one or more MCUs acting as delegates to a larger system, or a real time kernel above Linux, or a processor with auxiliary realtime MCU cores in it. \$\endgroup\$ – Chris Stratton Dec 14 '18 at 18:39
  • \$\begingroup\$ @ChrisStratton I use accelerometer to get stepper motor accceleration on stepper motor linear rail movement. I still get OSError: [Errno 121] Remote I/O error when use smbus or pigpio.error: 'I2C read failed' when use pigpio even I implement it without python thread (using ordinary python loop, no other thread running in that time) \$\endgroup\$ – Jan sebastian Dec 15 '18 at 5:04
  • \$\begingroup\$ Just repeating the error you already posted won't get you anywhere. Spend some time actually thinking about the comments above. \$\endgroup\$ – Chris Stratton Dec 15 '18 at 5:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.