This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Outputting a PWM signal and it's inverse thru gpio pins

Hello,

I have two questions:

How do I access the gpio pins of nrf52840 dk? what example program from nrf5 sdk can I use as example?

Is there a simpler example program to output a pwm signal of example like 400kHz and it's inverse in the pins?I'm looking at the PWM driver example of nrf5 sdk and it's a really big leap for someone like me who's use to programming via Arduino IDE

Parents
  • Hello,

    How do I access the gpio pins of nrf52840 dk? what example program from nrf5 sdk can I use as example?

    The description of the application above sounds very similar to the functionality demonstrated in our PWM Library example from the SDK. I highly recommend checking out this example, to see how you may go about setting up two inverted PWM's using the PWM library provided in the SDK.

    pwm signal of example like 400kHz

    Unfortunately, the pwm library instances are limited to 200 kHz. If you need 400 kHz, you will need to make use of the PWM peripheral. You could see how this can be used in the PWM driver example - however, this example might seem a little intense for someone who's most used to Arduino development. The example contains multiple demons, which in turn makes it seem daunting to familiarize with.

    To make things easier, you could instead have a look at the project I have included below, which is made for the nRF52840 DK. This project is the same as the one referenced by my colleague Torbjørn in this ticket. It showcases a much simpler approach to setting up the PWM peripheral, with a much less complex output. Once you get the hang of this example and how it works, you can begin looking at modifying it for your application needs.
    Mind you that this example uses the legacy nrf_drv driver, but in never SDK's this is using the nrfx driver behind the scenes through forwarding macros.
    2627.pwm_driver_simple.zip
    You should have a look at the nrfx_pwm API Reference when you start modifying the example.

    I'm looking at the PWM driver example of nrf5 sdk and it's a really big leap for someone like me who's use to programming via Arduino IDE

    No worries at all - we've all been new to this at some point! :) 
    Please do not hesitate to ask, if you should encounter any issues or questions.

    Best regards,
    Karl

  • You could see how this can be used in the PWM driver example

    Oh so I should use the pwm driver example rather than the pwm library when going to output 400kHz?

    The example contains multiple demons, which in turn makes it seem daunting to familiarize with

    By any chance you can provide me some resource I could read on or guidance so I could learn to handle these demons? I'm really new in this embedded programming stuff

    This project is the same as the one referenced by my colleague Torbjørn in this ticket

    Are you referring to the zip file you attached?

  • refer_pin said:
    Oh so I should use the pwm driver example rather than the pwm library when going to output 400kHz?

    Yes, this part might seem a little bit confusing, but the PWM library actually does not use the PWM peripheral - it uses the GPIOTE + TIMER peripherals to create a low-power PWM. This is better to use if the application only requires a simple, low-frequency, low-power PWM instance.

    In your case, you will rather need to use the PWM peripheral - which gives you much more options to configure the waveform generation. The PWM peripheral comes with a driver already made for it to make things easier- the PWM driver - which you should use, since you need a 400 kHz waveform.

    refer_pin said:
    By any chance you can provide me some resource I could read on or guidance so I could learn to handle these demons? I'm really new in this embedded programming stuff

    Before looking at the PWM driver demos I would recommend that you read through the PWM peripheral documentation to understand what is being done 'behind the scenes' of the PWM driver.
    Then, you could move on to the simple PWM example from the .zip file, to see if you can recognize how the things from the Peripheral documentation is being applied, in order to generate the PWM waveforms.

    The functionality of the different demos are described in the PWM driver example documentation. When you begin to look into these demos I highly recommend looking at only 1 at the time, and understanding how they perform the task as described in the documentation.

    Is there anything else in particular you would like know more about when it comes to embedded programming?
    The source code behind complex embedded example might seem daunting at first glance, when you come directly from Arduino development, but please know that it get better fast.

    In my opinion, one of the best examples to start looking at when you come directly from Arduino is probably the TIMER peripheral example. The reason why I would recommend this one in particular is because it demonstrates core functionality ( config and init of a peripheral, event handler, and LEDs ) and coding practices ( Wait-for-interrupt, error checks ), while also being contained within 108 lines of main.c code.
    When you understand every line of the TIMER peripheral example, you will be well prepared to familiarize with most of the other peripheral examples.

    refer_pin said:
    Are you referring to the zip file you attached?

    Yes. Sorry, I should have been more explicit. The .zip file I attached contains the simple pwm example.
    You will need to use the PCA10056 version for your nRF52840 DK.

    Best regards,
    Karl

Reply
  • refer_pin said:
    Oh so I should use the pwm driver example rather than the pwm library when going to output 400kHz?

    Yes, this part might seem a little bit confusing, but the PWM library actually does not use the PWM peripheral - it uses the GPIOTE + TIMER peripherals to create a low-power PWM. This is better to use if the application only requires a simple, low-frequency, low-power PWM instance.

    In your case, you will rather need to use the PWM peripheral - which gives you much more options to configure the waveform generation. The PWM peripheral comes with a driver already made for it to make things easier- the PWM driver - which you should use, since you need a 400 kHz waveform.

    refer_pin said:
    By any chance you can provide me some resource I could read on or guidance so I could learn to handle these demons? I'm really new in this embedded programming stuff

    Before looking at the PWM driver demos I would recommend that you read through the PWM peripheral documentation to understand what is being done 'behind the scenes' of the PWM driver.
    Then, you could move on to the simple PWM example from the .zip file, to see if you can recognize how the things from the Peripheral documentation is being applied, in order to generate the PWM waveforms.

    The functionality of the different demos are described in the PWM driver example documentation. When you begin to look into these demos I highly recommend looking at only 1 at the time, and understanding how they perform the task as described in the documentation.

    Is there anything else in particular you would like know more about when it comes to embedded programming?
    The source code behind complex embedded example might seem daunting at first glance, when you come directly from Arduino development, but please know that it get better fast.

    In my opinion, one of the best examples to start looking at when you come directly from Arduino is probably the TIMER peripheral example. The reason why I would recommend this one in particular is because it demonstrates core functionality ( config and init of a peripheral, event handler, and LEDs ) and coding practices ( Wait-for-interrupt, error checks ), while also being contained within 108 lines of main.c code.
    When you understand every line of the TIMER peripheral example, you will be well prepared to familiarize with most of the other peripheral examples.

    refer_pin said:
    Are you referring to the zip file you attached?

    Yes. Sorry, I should have been more explicit. The .zip file I attached contains the simple pwm example.
    You will need to use the PCA10056 version for your nRF52840 DK.

    Best regards,
    Karl

Children
  • In your case, you will rather need to use the PWM peripheral - which gives you much more options to configure the waveform generation.

    Sure, I'll study pwm_driver example for outputting 400kHz

    Before looking at the PWM driver demos I would recommend that you read through the PWM peripheral documentation

    Yes, I think I'm somehow in a way grasping how pwm is generated here but like a really vague understanding to begin with

    Is there anything else in particular you would like know more about when it comes to embedded programming?

    I think from my part I understand the C programming part. What comes confusing for me are the terminologies behind the explanation. It's honestly my first time dealing with terms such as prescalers, registers, and countertops and while I think I can grasp it, I would somehow slip as I read further along the document. This is something I am not good at right now and I was wondering if you could provide guidance on what possible resource I can look up to better understand these terminologies or what topic/subject are they tackled in.

    one of the best examples to start looking at when you come directly from Arduino is probably the TIMER peripheral example.

    Yup, I think it's a really simple program to start studying to get familiar with. I'm a bit confuse where I can read up on "_WFI()" and "NRF_SUCCESS"? It's my first time seeing them in C

  • refer_pin said:
    Yes, I think I'm somehow in a way grasping how pwm is generated here but like a really vague understanding to begin with

    Great! It might seem like a ton of things to familiarize with, but it gets easier fast.

    refer_pin said:
    This is something I am not good at right now and I was wondering if you could provide guidance on what possible resource I can look up to better understand these terminologies or what topic/subject are they tackled in.

    For figuring out the meaning of specific words being used, like prescaler, I think the best way to go about it is to google it as you encounter them. I do not know of a single source that covers these from start to finish, but I also think that would be a very tiresome way of learning their meaning.
    Instead, I recommend that you google each of them as they are encountered, and make a small note to yourself about their meaning.
    Registers for example is a central topic in embedded programming, which basically boils down to literal transistor states.

    I highly recommend reading an introduction to embedded programming to better grasp the concepts of registers and register manipulation.

    refer_pin said:
    Yup, I think it's a really simple program to start studying to get familiar with. I'm a bit confuse where I can read up on "_WFI()" and "NRF_SUCCESS"? It's my first time seeing them in C

    _WFI (wait for event) is a CPU function that places the CPU in a low-power POWER ON mode. The CPU will thus use less power while nothing is happening, but as soon as something happens ( an event is generated ) it will be ready to go. You will see that in most of the examples from the SDK the main loop of the program primarily does one thing - such as calling the idle_state_handler function - which essentially is to go into this low-power POWER ON mode. This is one of the main differences between Arduino programming and embedded C programming - while the program in Arduino often is based on a sequential execution of the loop function, the embedded C programs are rather based on an interrupt-event system. In short, this means that the main loop is just going to sleep ( and has the lowest priority ), and instead being interrupted from doing so whenever something needs to be done.

    Lastly, NRF_SUCCESS is one of the error codes we use in the SDK, to signal that a function call was successful. This is also likely a new element when coming from Arduino development, but different driver functions might fail for different reasons, and when that happens there needs to be a proper error handling in place for the particular failure.
    You will learn more about this as you go, but make sure that you have defined DEBUG in your preprocessor defines, like shown in the included image, to have a detailed error message be printed to your logger output whenever such an error is encountered.

    It is therefore also essential that you pass every returned error code to an APP_ERROR_CHECK in order to verify whether the function call was successful.

    This all might be a lot to take in right now, but please do not hesitate to ask if anything should be unclear - then I will try to answer as best I can.

    Hope the above explanations makes things at least somewhat clearer! :) 

    Best regards,
    Karl

Related