Skip to main content

Python serial interface for the Easy PID Motor Controller (EPMC)

Project description

Easy PID Motor Controller (EPMC) Python Library

Python serial interface for the Easy PID Motor Controller (EPMC). The Library Supports two and four motor EPMC controllers

you can use it in your microcomputer robotics project (e.g Raspberry Pi, PC, etc.)

Install

  • you'll need to pip install the pyserial library
      pip3 install epmc-serial   //linux or mac
    
    OR
      pip install epmc-serial  //windows
    

Uninstall

  • you'll need to pip install the pyserial library
      pip3 uninstall epmc-serial   //linux or mac
    
      pip uninstall epmc-serial  //windows
    

How to Use the Library

  • Ensure you have the EPMC MODULE interfaced with your preferred motors

  • Ensure you've already setup the encoder and PID parameters with the epmc_setup_application.

  • check the serial port the driver is connected to:

    ls /dev/ttyA* # for two motor support
    

    OR

    ls /dev/ttyU* # for four motor support
    

    you should see /dev/ttyACM0 or /dev/ttyUSB0 or ... and so on

  • use the serial port in your code

  • A simple way to get started is simply to try out the example code below

Basic Library functions and usage (Two Motor Support Control)

  • connect to EPMC module

    controller = EPMCSerialClient()

    #ensure you set/call supportedNumOfMotors() before connect() as below:

    controller .supportedNumOfMotors(SupportedNumOfMotors.TWO)

    controller.connect("port_name or port_path")

  • clear speed, position, e.t.c data buffer on the EPMC module

    controller.clearDataBuffer() # returns bool -> success

  • send target angular velocity command

    controller.writeSpeed(motor0_TargetVel, motor1_TargetVel)

  • send PWM command

    controller.writePWM(motor0_PWM, motor1_PWM)

  • set motor command timeout

    controller.setCmdTimeout(timeout_ms)

  • get motor command timeout

    controller.getCmdTimeout() # returns tuple -> (success, motor_command_timeout_ms): bool, float

  • read motors angular position and angular velocity

    controller.readMotorData() # returns bool, tuple(size=4foats) -> success, (pos0, pos1, vel0, vel1)

  • read motors angular position

    controller.readPos() # returns bool, tuple(size=2floats) -> success, (pos0, pos1)

  • read motors angular velocity

    controller.readVel() # returns bool, tuple(size=2floats) -> success, (vel0, vel1)

  • read motor maximum commandable angular velocity

    controller.getMaxVel(motor_no) # returns tuple -> (success, max_vel): bool, float maxVel0 or maxVel1 based on the specified motor number

  • while these function above help communicate with the already configure EPMC module, more examples of advanced funtions usage for parameter tuning can be found in the epmc_setup_application source code

example code (Two Motor Support Control)

from epmc_serial import EPMCSerialClient, SupportedNumOfMotors
import time

controller = EPMCSerialClient()

# variable for communication
pos0=0.0; pos1=0.0
vel0=0.0; vel1=0.0

# [4 rev/sec, 2 rev/sec, 1 rev/sec, 0.5 rev/sec]
targetVel = [1.571, 3.142, 6.284, 12.568] 
vel = targetVel[1]
v = 0.0

readTime = None
readTimeInterval = 0.02 # 50Hz

cmdTime = None
cmdTimeInterval = 5.0

# 50Hz comm setup
serial_port = '/dev/ttyACM0'
serial_baudrate = 115200
serial_timeout = 0.018 #value < 0.02 (for 50Hz comm)

controller .supportedNumOfMotors(SupportedNumOfMotors.TWO)
controller.connect(serial_port, serial_baudrate, serial_timeout)

success = controller.clearDataBuffer()
controller.writeSpeed(0.0, 0.0)
print('configuration complete')

timeout_ms = 10000
controller.setCmdTimeout(timeout_ms)
success, val0 = controller.getCmdTimeout()
if success: # only update if read was successfull
  timeout_ms = val0
  print("command timeout in ms: ", timeout_ms)
else:
  print("ERROR: could not read motor command timeout")

sendHigh = True

readTime = time.time()
cmdTime = time.time()

while True:
  if time.time() - cmdTime > cmdTimeInterval:
    if sendHigh:
      # print("command high")
      v = vel
      controller.writeSpeed(v, v)
      vel = vel*-1
      sendHigh = False
    else:
      # print("command low")
      v = 0.0
      controller.writeSpeed(v, v)
      sendHigh = True
    
    
    cmdTime = time.time()



  if time.time() - readTime > readTimeInterval:
    try:
      # controller.writeSpeed(v, v)
      success, val = controller.readMotorData()
      if success: # only update if read was successfull
        pos0 = val[0]; pos1 = val[1]
        vel0 = val[2]; vel1 = val[3]

      print(f"motor0_readings: [{pos0}, {vel0}]")
      print(f"motor1_readings: [{pos1}, {vel1}]")
      print("")
    except:
      pass
    
    readTime = time.time()

Basic Library functions and usage (Four Motor Support Control)

  • connect to EPMC module

    controller = EPMCSerialClient()

    #ensure you set/call supportedNumOfMotors() before connect() as below:

    controller .supportedNumOfMotors(SupportedNumOfMotors.FOUR)

    controller.connect("port_name or port_path")

  • clear speed, position, e.t.c data buffer on the EPMC module

    controller.clearDataBuffer() # returns bool -> success

  • send target angular velocity command

    controller.writeSpeed(motor0_TargetVel, motor1_TargetVel)

  • send PWM command

    controller.writePWM(motor0_PWM, motor1_PWM)

  • set motor command timeout

    controller.setCmdTimeout(timeout_ms)

  • get motor command timeout

    controller.getCmdTimeout() # returns tuple -> (success, motor_command_timeout_ms): bool, float

  • read motors angular position and angular velocity

    controller.readMotorData() # returns bool, tuple(size=8floats) -> success, (pos0, pos1, pos2, pos3, vel0, vel1, vel2, vel3)

  • read motors angular position

    controller.readPos() # returns bool, tuple(size=4floats) -> success, (pos0, pos1, pos2, pos3)

  • read motors angular velocity

    controller.readVel() # returns bool, tuple(size=4floats) -> success, (vel0, vel1, vel2, vel3)

  • read motor maximum commandable angular velocity

    controller.getMaxVel(motor_no) # returns tuple -> (success, max_vel): bool, float maxVel0 or maxVel1 based on the specified motor number

  • while these function above help communicate with the already configure EPMC module, more examples of advanced funtions usage for parameter tuning can be found in the epmc_setup_application source code

example code (Four Motor Support Control)

from epmc_serial import EPMCSerialClient, SupportedNumOfMotors
import time

controller = EPMCSerialClient()

# variable for communication
pos0=0.0; pos1=0.0; pos2=0.0; pos3=0.0
vel0=0.0; vel1=0.0; vel2=0.0; vel3=0.0

# [4 rev/sec, 2 rev/sec, 1 rev/sec, 0.5 rev/sec]
targetVel = [1.571, 3.142, 6.284, 12.568] 
vel = targetVel[1]
v = 0.0

readTime = None
readTimeInterval = 0.02 # 50Hz

cmdTime = None
cmdTimeInterval = 5.0

# 50Hz comm setup
serial_port = '/dev/ttyUSB0'
serial_baudrate = 115200
serial_timeout = 0.018 #value < 0.02 (for 50Hz comm)

controller.supportedNumOfMotors(SupportedNumOfMotors.FOUR)
controller.connect(serial_port, serial_baudrate, serial_timeout)

success = controller.clearDataBuffer()
controller.writeSpeed(0.0, 0.0, 0.0, 0.0)
print('configuration complete')

timeout_ms = 10000
controller.setCmdTimeout(timeout_ms)
success, val0 = controller.getCmdTimeout()
if success: # only update if read was successfull
  timeout_ms = val0
  print("command timeout in ms: ", timeout_ms)
else:
  print("ERROR: could not read motor command timeout")

sendHigh = True

readTime = time.time()
cmdTime = time.time()

while True:
  if time.time() - cmdTime > cmdTimeInterval:
    if sendHigh:
      # print("command high")
      v = vel
      controller.writeSpeed(v, v, v, v)
      vel = vel*-1
      sendHigh = False
    else:
      # print("command low")
      v = 0.0
      controller.writeSpeed(v, v, v, v)
      sendHigh = True
    
    
    cmdTime = time.time()



  if time.time() - readTime > readTimeInterval:
    try:
      # controller.writeSpeed(v, v, v, v)
      success, val = controller.readMotorData()
      if success: # only update if read was successfull
        pos0 = val[0]; pos1 = val[1]; pos2 = val[2]; pos3 = val[3]
        vel0 = val[4]; vel1 = val[5]; vel2 = val[6]; vel3 = val[7]

      print(f"motor0_readings: [{pos0}, {vel0}]")
      print(f"motor1_readings: [{pos1}, {vel1}]")
      print(f"motor2_readings: [{pos2}, {vel2}]")
      print(f"motor3_readings: [{pos3}, {vel3}]")
      print("")
    except:
      pass
    
    readTime = time.time()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

epmc_serial-1.3.0.tar.gz (6.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

epmc_serial-1.3.0-py3-none-any.whl (6.4 kB view details)

Uploaded Python 3

File details

Details for the file epmc_serial-1.3.0.tar.gz.

File metadata

  • Download URL: epmc_serial-1.3.0.tar.gz
  • Upload date:
  • Size: 6.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for epmc_serial-1.3.0.tar.gz
Algorithm Hash digest
SHA256 1149ea061837dde5b2fbcc3061313e0bee3fca01738ef8e5b0dacba06033ddbf
MD5 359cd70a951c06cf619010f98aa22171
BLAKE2b-256 9edfe6fb28517f96ab3326d6aa1366ee930d7e23e9b7af53a97f70f5e1fbced0

See more details on using hashes here.

File details

Details for the file epmc_serial-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: epmc_serial-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 6.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for epmc_serial-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 890712a043665faa168f23b4090750a6bafad50b9fa280c3662d81f066fef4f3
MD5 525bedd73d3a5766b06d265e1ca18efc
BLAKE2b-256 9fedc1d681649ee5d7c836a7d9f1d13aa2ea6c6d50cf5b6267620c3d272b5219

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page