首页 > 解决方案 > 在连接电机的 Raspberry PI 上使用 Python 进行多线程/多处理

问题描述

我是这个社区的新手,也是编程的新手。我在 Arduino 编程和 Python 方面有一些基本知识(没什么特别的,只是闪烁的 LED 等等)。

所以我现在有一个相当大的项目。我知道这可能是一个艰难的开始。基本计划是将 6 个带 6 个旋转编码器的步进电机连接到 Raspberry PI。为了获得所需的 I/O,我使用了一些 I2C 端口扩展器。

我现在有了使用两个步进器和两个编码器进行测试的基本设置。当我在 Python 程序中单独使用步进器或编码器时,一切正常。一旦我将所有内容组合到一个程序中,电机就会减速。据我了解,python 只是从上到下处理代码。所以我可以理解为什么我的步进器的速度变慢了。有没有办法避免这种情况?我已经阅读了多线程并尝试使用它,但它并没有改变任何东西。多处理会是一个解决方案吗?

任何帮助或提示将不胜感激 =)

#importiere Libraries

from threading import Thread
import threading
import time
from time import sleep
import RPi.GPIO as GPIO
import smbus
import sys

#PinOut

Ro1APin = 14                                        # Encoder 1 Pin A
Ro1BPin = 4                                         # Encoder 2 Pin B

Ro2APin = 18                                        # Encoder 1 Pin A
Ro2BPin = 17                                        # Encoder 2 Pin B

b = smbus.SMBus(1)                                  # Bus Aktiv

#Variablen festlegen

globalCounter1 = 0
flag1 = 0
Last_RoB1_Status = 0
Current_RoB1_Status = 0

globalCounter2 = 0
flag2 = 0
Last_RoB2_Status = 0
Current_RoB2_Status = 0

#GPIO Setup

def setup():

        b.write_byte_data(0x21,0x00,0x00)                   # I2C Device 21 alle IOS aktiv schalten (Motor 1)
        b.write_byte_data(0x20,0x00,0x00)                   # I2C Device 20 alle IOS aktiv schalten (Motor 2)

        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(Ro1APin, GPIO.IN)
        GPIO.setup(Ro1BPin, GPIO.IN)
        GPIO.setup(Ro2APin, GPIO.IN)
        GPIO.setup(Ro2BPin, GPIO.IN)

#Klasse Motor1 Rotation

class M1Rotation:

    def __init__(self):
        self._running = True

    def terminate(self):
        self._running = False

    def run(self):
        while True:
            b.write_byte_data(0x21,0x14,0x01)       # I2C Device 21, Bank A, Bit 0 High => Motor Stp
            sleep(0.005)
            b.write_byte_data(0x21,0x14,0x00)       # I2C Device 21, Bank A, Alle Bits 0


#Klasse Motor2 Rotation

class M2Rotation:

    def __init__(self):
        self._running = True

    def terminate(self):
        self._running = False

    def run(self):
        while True:
            b.write_byte_data(0x20,0x14,0x01)       # I2C Device 21, Bank A, Bit 0 High => Motor Stp
            sleep(0.005)
            b.write_byte_data(0x20,0x14,0x00)       # I2C Device 21, Bank A, Alle Bits 0


#Funktion Encoder1 Auslesen

def rotaryDeal1():
    global flag1
    global Last_RoB1_Status
    global Current_RoB1_Status
    global globalCounter1

    Last_RoB1_Status = GPIO.input(Ro1BPin)
    while(not GPIO.input(Ro1APin)):
        Current_RoB1_Status = GPIO.input(Ro1BPin)
        flag1 = 1
    if flag1 == 1:
        flag1 = 0
        if(Last_RoB1_Status == 1) and (Current_RoB1_Status == 0):
            globalCounter1 = globalCounter1  + 1
            return globalCounter1
            sleep(1)
        if(Last_RoB1_Status == 0) and (Current_RoB1_Status == 1):
            globalCounter1 = globalCounter1 -1
            return globalCounter1
            sleep(1)


#Funktion Encoder2 Auslesen

def rotaryDeal2():
    global flag2
    global Last_RoB2_Status
    global Current_RoB2_Status
    global globalCounter2

    Last_RoB2_Status = GPIO.input(Ro2BPin)
    while(not GPIO.input(Ro2APin)):
        Current_RoB2_Status = GPIO.input(Ro2BPin)
        flag2 = 1
    if flag2 == 1:
        flag2 = 0
        if(Last_RoB2_Status == 1) and (Current_RoB2_Status == 0):
            globalCounter2 = globalCounter2  + 1
            return(globalCounter2)
            sleep(1)
        if(Last_RoB2_Status == 0) and (Current_RoB2_Status == 1):
            globalCounter2 = globalCounter2 -1
            return(globalCounter2)
            sleep(1)


#Klasse Encoder1 Auslesen

class ReadEncoder1:

    def __init__(self):
        self._running = True

    def terminate(self):
        self._running = False

    def run(self):
        global globalCounter1
        while self._running:
            rotaryDeal1()


#Klasse Encoder2 Auslesen

class ReadEncoder2:

    def __init__(self):
        self._running = True

    def terminate(self):
        self._running = False

    def run(self):
        global globalCounter2
        while self._running:
            rotaryDeal2()


#Funktion zum Beenden

def destroy():
        GPIO.cleanup()

#Funktion Motor Threads starten

def MotorStart():
        M1Rot = M1Rotation()
        M1RotThread = Thread(target=M1Rot.run)
        M1RotThread.start()
        #M1RotThread.join()

        M2Rot = M2Rotation()
        M2RotThread = Thread(target=M2Rot.run)
        M2RotThread.start()
        #M2RotThread.join()

#Funktion Encoder Threads starten

def EncStart():
        Enc1Rd = ReadEncoder1()
        Enc1RdThread = Thread(target=Enc1Rd.run)
        Enc1RdThread.start()
        #Enc1RdThread.join()

        Enc2Rd = ReadEncoder2()
        Enc2RdThread = Thread(target=Enc2Rd.run)
        Enc2RdThread.start()
        #Enc2RdThread.join()


#Programm Start

if __name__ == '__main__':
    setup()
    MotorStart()
    EncStart()
    print(threading.enumerate())

    while True:

        print('A', globalCounter1)
        print('B', globalCounter2)

标签: python-3.xraspberry-pipython-multiprocessingpython-multithreadingstepper

解决方案


会不会是您没有足够的电池电量来运行所有六个电机?这将是一个简单的解决方法,也是一个很好的起点。


推荐阅读