ESC through RCOutput on Navio2

I’m trying to control a brushless motor with ESC with Navio2.
The only possible way I found to do that is through the RCOutput library, nevertheless I haven’t made it to work yet.
I ran the Servo example and I notice through an oscilloscope that just after the sentence pwm->set_duty_cycle is executed, the PWM value returns immediately to 0.
That way it wouldn’t be possible to control the motor, neither to implement a low-level controller for the quadcopter.
I need a function that retains the PWM value in order to maintain the throttle while the controller calculates other things.
I saw in another post a function that uses the time.h library and calculates the desire time that the PWM value will be hold, but that way isn’t useful either.

Please someone could help me solve that issue?

Hi Alejandro,

The behavior you’ve described is a safety feature of Navio2. The only way to avoid it is to update the PWM value every 100 ms or less.

Ok, I achieved to hold the PWM value updating it with a thread.
Now the problem is, in this firts example I’m only using the PWM output 1, nevertheless when I say

pwm->set_duty_cycle( 0, 1000);

the value applies to the four firts outputs: 1, 2, 3 and 4 on the board, not only output 1.
What is this about?
I need to control 4 PWM outputs by separate.

Hi Alejandro,

Could you please share your script?

Ok, finally with this code I can control each motor, but the use of a thread for this purpose I think is inefficient.

Is there a better idea?


#include <Common/MS5611.h>
#include <Common/Util.h>
#include <unistd.h>
#include <stdio.h>
#include <Navio2/PWM.h>
#include <Navio2/RCOutput_Navio2.h>
#include <Navio+/RCOutput_Navio.h>
#include <pthread.h>
#include

#define PWM_OUTPUT1 2
#define PWM_OUTPUT2 1
#define PWM_OUTPUT3 3
#define PWM_OUTPUT4 0

std::unique_ptr get_rcout()
{
if( get_navio_version() == NAVIO2 )
{
auto ptr = std::unique_ptr { new RCOutput_Navio2() };
return ptr;
}
else
{
auto ptr = std::unique_ptr { new RCOutput_Navio() };
return ptr;
}
}

auto pwm = get_rcout();
double PWM1 = 0, PWM2 = 0, PWM3 = 0, PWM4 = 0;

void *PWM_Refresh( void *barom )
{

while (true)
{
pwm->set_duty_cycle( PWM_OUTPUT1, PWM1 );
pwm->set_duty_cycle( PWM_OUTPUT2, PWM2 );
pwm->set_duty_cycle( PWM_OUTPUT3, PWM3 );
pwm->set_duty_cycle( PWM_OUTPUT4, PWM4 );

//sleep(0.5);
}

pthread_exit(NULL);
}

int main()
{
MS5611 baro;

if ( check_apm() )
{
return 1;
}

if( !(pwm->initialize(PWM_OUTPUT1)) || !(pwm->initialize(PWM_OUTPUT2)) || !(pwm->initialize(PWM_OUTPUT3)) || !(pwm->initialize(PWM_OUTPUT4)) )
{
return 1;
}

pwm->set_frequency( PWM_OUTPUT1, 50 );
pwm->set_frequency( PWM_OUTPUT2, 50 );
pwm->set_frequency( PWM_OUTPUT3, 50 );
pwm->set_frequency( PWM_OUTPUT4, 50 );

if( !(pwm->enable(PWM_OUTPUT1)) || !(pwm->enable(PWM_OUTPUT2)) || !(pwm->enable(PWM_OUTPUT3)) || !(pwm->enable(PWM_OUTPUT4)) )
{
return 1;
}

pthread_t pwm_thread;

if( pthread_create( &pwm_thread, NULL, PWM_Refresh, (void*)&baro) )
{
printf(“Error: Failed to create barometer thread\n”);
return 0;
}

PWM1 = 1000;
PWM2 = 1000;
PWM3 = 1000;
PWM4 = 1000;
sleep(3);
PWM1 = 1150;
sleep(3);
PWM1 = 1000;
sleep(1);
PWM2 = 1150;
sleep(3);
PWM2 = 1000;
sleep(1);
PWM3 = 1150;
sleep(3);
PWM3 = 1000;
sleep(1);
PWM4 = 1150;
sleep(3);
PWM4 = 1000;

while(true)
{

}

pthread_exit(NULL);

return 1;
}


I’ve got a short video of the output of this code, how can I upload it?

Also, is there a better way to post code in this forum instead of copy-paste?

1 Like

Hi Alejandro,

Glad to hear you’ve dealt with it!

You can upload video to youtube and share it here. It would be great to see the result of your work!

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.