python-3.x - 在连接电机的 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)
解决方案
会不会是您没有足够的电池电量来运行所有六个电机?这将是一个简单的解决方法,也是一个很好的起点。
推荐阅读
- .net-core - 使用 Gmail API 添加范围需要验证,但它是一个控制台应用程序
- python - NoReverseMatch 错误 - 在我的 urls.py 中看起来一切正常我做错了什么
- javascript - 在列表元素 Javascript 上设置随机背景
- vuex - NUXT 将数据传递给动态端点中的道具
- java - 如何检查互联网是否在 Android 中实际可用?
- apache-zookeeper - Zookeper 中的法定人数与多数人
- c# - 如何在 WPF MVVM 的视图模型中访问代码隐藏中分配的属性?
- django - Django中index_together字段的慢查询
- sql - Python 脚本中 SQL 语法中的未知列
- c - 如果哈希映射是键和值的列表,那么什么是唯一键的列表(无值)?