motor.py

2014.06.15 Important Note: I discovered that the usage of the function pwm.setservo()   it is not adeguate to  control the motor in a loop. it everytime set the pwm to zero than it set the new value. the result is a loss of  speed (and so power )  of the motor. I just start to use the pwm.add_channel_pulse() instead and it solve the problem.

Here the  link   for download the files motor.py  and qpi_test1.py  used to pilot motor M0.

The module qpi_test1.py is the basic user interface.

The module  motor.py  implements the object “motor”  that manages the angular speed of the motor and the hardware interface between raspberry pi  and the ESC.

the angular speed is defined in % instead of absolute value:

  1. to keep motor object independent from real used motor
  2. to keep motor object independent from real used battery (remember that motor speed is a function of the voltage).

Motor parameters are:

  • current angular speed (W)
  • Min and Max angular speed (WMax,WMin)
  • The speed that balances the gravity (hovering)  (Wh). This value can vary according to different factors , like altitude, air temperature, humidity, qpi weight.So it is necessary to tune this value every new flight increasing the throttle upto equilibrium than save this value and reuse it when necessary (for example after a roll).
  • the pin where I connect ESC on rpi GPIO. here  the circuit diagram.
  • The motor Kv. Right now not used but it could be used in future to estimate real angular speed or the power consumption.
  • debug mode, boolean that define the debug mode
  • simulation mode,boolean that activate the PWM (=TRUE di default)
  • mass,Right now not used but it could be used in future to create hte phisics model of the quadcopter.

If you want to pilot the motor it is necessary to remember 2 things:

  1. The used ESC could request a startup procedure ( See ESC)
  2. Set  myMotor.simulation=FALSE

The I/O interface is based on RPIO Library.(See sw installation)

By default it works at 50 HZ ( a pulse every 20 ms ).

The pulse width is the command to the motor.

With a pulse width of 1ms =1000us  , the motor stops.

With a pulse width of 2ms =2000us  , the motore  rotates at maximum speed.

The increment can be of  10us.So the pulse width PW:

PW=(1 + (self.__RPM / 100)) * 1000

self.__IO.set_servo(self.pin,PW)

self.PWM.add_channel_pulse(1,self.pin,0,PW)

(with   self.pin=18,  it means  GPIO18, and physical pin 12)

Link:

http://pythonhosted.org/RPIO/pwm_py.html

main functions:

def __init__(self, name, pin, kv=1000, WMin=0, WMax=100, debug=True, simulation=True)

def setWLimits(self, WMin, WMax):

set the W limits for each motor

def saveWh(self):

Save Wh = current W%

def setWh(self):

Sets current W =Wh

def getWh(self):

returns current Wh

def start(self):

Run the procedure to init the PWM

def stop(self):

Stop PWM signal

 

 

5 thoughts on “motor.py

  1. jasomo

    Hi

    Im trying to control my ESC/motor through this RPIO.PWM methods.

    Tested your motor_test.py working good.
    My esc enters the throttle range setting option…

    I tried to develop my own c program to achieve the same result, but it doesn work. The esc seems not to detect the full throttle.

    The ESC protocol:
    – Throttle at upper limit
    – Connect ESC
    – Wait tones… Throttle at lower limit
    – Wait tones…

    So my pseudocode:

    #define GPIO			17
    #define CHANNEL			0
    #define SUBCYCLE_TIME	SUBCYCLE_TIME_US_DEFAULT // 20000 setup(PULSE_WIDTH_INCREMENT_GRANULARITY_US_DEFAULT, DELAY_VIA_PWM);
    init_channel(CHANNEL, SUBCYCLE_TIME);
    add_channel_pulse(CHANNEL, GPIO, 0, 1999);
    getchar();
    add_channel_pulse(CHANNEL, GPIO, 0, 0);
    

    I analyzed your code and i saw you are sending…
    set_servo(self.__pin, PW)
    where PW=2000

    When I send 2000:
    add_channel_pulse: channel=0, gpio=17, start=0, width=2000
    Error: cannot add pulse to channel 1999: width_start+width exceed max_width of 0

    Or 1000 starting at 1000:
    add_channel_pulse: channel=0, gpio=17, start=1000, width=1000
    Error: cannot add pulse to channel 1999: width_start+width exceed max_width of 0

    1999 send without error.
    I dont know if this is the problem but sending 1999 it doesnt work.

    What am i doing wrong?

    Thanks!

    Reply
    1. solenerotech Post author

      Hello jasomo
      I don’t have any experiance in c developing.
      Just a comment regarding the error message, it seems that propbaly you need a function in someway to set the parameter max_width, or try start=1

      Reply
  2. Mial

    Hi Oscar,

    I don’t understand how to “setWh” when “increase > a | decrease > z | save Wh > n | set Wh > h|quit > 9” is displayed. If I want to set the motor to maximum what do I type in, 100h?

    Thanks

    Reply
  3. jasomo

    Hello

    Solved. The problem was my pulse range limits. Instead of 100-200 i was using 1000-2000.
    A pwm-motor concept problem. I thought full throtlle was all the pulse sending ‘1’. Instead of the entire pulse, it seems it’s only 10% of the pulse?

    Thanks!

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s