NAVIO2 Low PWM Voltage

Hello, I need to create a pulse with amplitude at least 3.3V. I’ve read other topics and it seems that PWM maximum voltage is 3.3V. For experiment i launched C++ example Servos.cpp, but changed frequency of pulses to 1 HZ

pwm->set_frequency(PWM_OUTPUT, 1);

Internally 1Hz transformed to period in nanoseconds, so we have full period 10^9 nanoseconds
In order to get maximum voltage we should set 100% duty cycle.

while (true) {
    pwm->set_duty_cycle(PWM_OUTPUT,  1000000);
}

That value internally divided by 1000 then multiplied by 10^6, so we have 100% duty cycle. I expected that voltage should have been near 3.3V , but it’s 1.39V. I measure DCV within 20V range , with plus on Signal Pin and minus on ground pin.

Could you assist with that issue? May be i did something wrong? Thank you.
Rasp image : emlid-raspbian-20220608
Hardware: Raspberry 4

1 Like

Hi Sergey,

Kernel driver for Navio2 that generates PWM needs to be fed with data at least every 100 ms. So it is necessary to update the value in set_duty_cycle every 100 ms or less to make PWM output works. Can you share the full code you use so I can take a look?

Hi Olesia,
Thank you, but i’ve read about 100ms and taken it into account. I use simple loop and i think it iterates much less than 100 ms, only if some interruptions take place it would be more. Of course, the full code :

#include <unistd.h>
#include "Navio2/PWM.h"
#include "Navio+/RCOutput_Navio.h"
#include "Navio2/RCOutput_Navio2.h"
#include "Common/Util.h"
#include <unistd.h>
#include <memory>

#define SERVO_MIN 1250 /*mS*/
#define SERVO_MAX 1750 /*mS*/

#define PWM_OUTPUT 13


using namespace Navio;

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

}

int main(int argc, char *argv[])
{

        auto pwm = get_rcout();

        if (check_apm()) {
            return 1;
        }

        if (getuid()) {
            fprintf(stderr, "Not root. Please launch like this: sudo %s\n", argv[0]);
        }


        if( !(pwm->initialize(PWM_OUTPUT)) ) {
            return 1;
        }
        
	pwm->set_frequency(PWM_OUTPUT, 1);

	if ( !(pwm->enable(PWM_OUTPUT)) ) {
	    return 1;
	}

        while (true) {
            pwm->set_duty_cycle(PWM_OUTPUT, 1000000);            
        }

    return 0;
}

Sergey,

Thank you for the code. I see you’ve made some changes. If you want 100%, you should set the period to 50 (this is 20ms) and duty-cycle to 20.

Hi Olesia,
I understand , thank you, but what if i need 1Hz wave? Or this is because PWM frequency immutable at all on Navio2? 50Hz wave it’s very frequent for my task. Is it possible to set frequency other than 50Hz?

Sergey,

The lowest frequency you can set is 25Hz. Navio2 won’t allow lower settings.

Olesia,
Thank you, now it becomes clear. Which PWM frequencies can we use else? It’s something like ± 25 Hz from current frequency? Is there some law?

Sergey,

We have tested 25 and 400 Hz, and they should work. We haven’t tested any other frequencies, so it is difficult to say which ones to use. You will need to test the one you need to determine which frequencies will work.

1 Like