Controlling Brushless motor with PWM using Navio2 rail

Hello,
I’m trying to control a brushless motor using PWM through the Navio2 rail (without running ardupilot). I’m using the latest emlid-raspbian-20170323 image. The picture below shows how I’ve connected the ESC to Navio2.

I’ve already managed to control the motor using the same hardware setup but connected to the Raspberry Pi rail GPIO pins. I did this using a Python script and the PIGPIO Daemon and it worked fine.

This code I’m using is just a modification of the ‘Servo’ example code on Github:

#!/usr/bin/sudo python

import sys
import time

import navio.pwm
import navio.util

navio.util.check_apm()

PWM_OUTPUT = 0
SERVO_MIN = 1.000 #ms
SERVO_MAX = 2.000 #ms
SERVO_NOM = 1.600 #ms

pwm =  navio.pwm.PWM(PWM_OUTPUT)
pwm.initialize()
pwm.set_period(50)
pwm.enable()

pwm.set_duty_cycle(SERVO_MAX)
time.sleep(2)
pwm.set_duty_cycle(SERVO_MIN)
time.sleep(2)

pwm.set_duty_cycle(SERVO_NOM)

I’ve only made a few small modifications:

  1. Changing the duty cycle parameters (SERVO_MIN, SERVO_MAX) to 1ms and 2ms.
  2. Adding in the line ‘pwm.initialise()’ which was missing from the example code.
  3. Increasing the sleep time from 1 to 2 seconds.

This approach to calibrate the ESC worked fine on the raspberry pi, but on the Navio2, the ESC beeping sequence is wrong, and the motor doesn’t spin. The ESC is a BLHELI_32 and should give one low beep followed by one high beep to indicate calibration complete. For some reason it’s doing the opposite! (one high beep and then one low beep).

Could someone please help me sort this out. As I said, it can’t be a hardware fault because the hardware was working fine, so I think my code must be wrong. Thanks very much for any help.

Hello!

Try this code snippet and let me know if it works for you!

#!/usr/bin/sudo python

import sys
import time

import navio.pwm
import navio.util
import datetime

navio.util.check_apm()

PWM_OUTPUT = 0
SERVO_MIN = 1.000 #ms
SERVO_MAX = 2.000 #ms
SERVO_NOM = 1.600 #ms


def loop_for(seconds, func, *args):
    endTime = datetime.datetime.now() + datetime.timedelta(seconds=seconds)

    while True:
        if datetime.datetime.now() >= endTime:
            break
        func(*args)


def main():
    pwm =  navio.pwm.PWM(PWM_OUTPUT)
    pwm.initialize()
    pwm.set_period(50)
    pwm.enable()

    loop_for(2, pwm.set_duty_cycle, SERVO_MAX)
    loop_for(2, pwm.set_duty_cycle, SERVO_MIN)
    loop_for(2, pwm.set_duty_cycle, SERVO_NOM)

main()

Thanks for the code George! I’ve got it working now.
For some reason the ESC had to go through throttle calibration first, before it could be armed. This wasn’t necessary when using the PIGPIO daemon on the Pi.

This is the code that worked:

#!/usr/bin/sudo python

import sys
import time

import navio.pwm
import navio.util
import datetime

navio.util.check_apm()

PWM_OUTPUT = 0
SERVO_MIN = 1.000 #ms
SERVO_MAX = 2.000 #ms
SERVO_NOM = 1.600 #ms

def loop_for(seconds, func, *args):
    endTime = datetime.datetime.now() + datetime.timedelta(seconds=seconds)

    while True:
        if datetime.datetime.now() >= endTime:
            break
        func(*args)

def main():
    pwm =  navio.pwm.PWM(PWM_OUTPUT)
    pwm.initialize()
    pwm.set_period(50)
    pwm.enable()

    loop_for(3, pwm.set_duty_cycle, SERVO_MAX)
    loop_for(5, pwm.set_duty_cycle, SERVO_MIN)
    loop_for(3, pwm.set_duty_cycle, SERVO_MIN)
    loop_for(3, pwm.set_duty_cycle, SERVO_NOM)

main()

The loop timings seem a bit abitrary but after experimenting it seems that (for my BLHELI_32 ESC) the first SERVO_MAX needs to be >=3 secs, the first SERVO_MIN >=5 and the second SERVO_MIN>=3.
Anyway thanks a lot for the help.

2 Likes

I’m glad you got it working!