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

PWM stability issues (resetting)

I'm using: nrf52832, SDK 15.0, SoftDevice S132 v6.0.

I'm trying to control a motor using an H-Bridge. If I simply do a nrf_gpio_pin_write to set forward/reverse to 1/0 or vice versa, there is no issue. I can change motor directions quickly.

However, I want to control the motor speed as well. When I use PWM outputs to control forward/reverse, the system will crash/reset when I try to change the motor direction. I can add a delay in the code where, between changing direction, I set both forward and reverse to 0 and wait 600ms. When I add this delay, everything works, but I want to minimize or remove this delay (400ms in unstable, 500ms is mostly stable, 600ms is stable).

I've tried two different h-bridge boards with different chips (L9110S with simply forward/reverse and TB6612FNG with 0/1 on forward/reverse and a single PWM input for speed) and have seen the same issue.

Why is the PWM output so much more sensitive to noise/back-emf? And can I do something to avoid it? Or should I be using something other than PWM? (I've tried both the PWM driver and the low power PWM code).

A few notes: I've tried capacitors across the motor. The design requires a single shared power source (batteries). I'm regulating it to 3.3v.

UPDATE: I decided to do my own PWM type code without using the library and had the same problem. I then realized I've been using certain pins for PWM and when I could successfully reverse the motor before, I was using two different pins. After some testing [simply using nrf_gpio_pin_write] pins P0.11 and P0.14 are working for forward/reverse (and combinations using P0.12 and P0.13 are not). I am using a board I bought online, so there's a possibility that it's a factor.

UPDATE 2018-07-24: For testing, I'm just having it alternate forward/reverse every 2 seconds and it will sometimes reset. It might run for 10 seconds, it might run for more than a minute. I thought RTT might give me some insight but I don't see any error info--I do see debug messages I added. Any thoughts on why this is happening are appreciated.

Also, after the chip resets, I've read NRF_POWER->RESETREAS, and I get a value of 0.

  • Hi,

    Typically, a reset is caused by an error caught by an error handler. The default error handler in the SDK will trigger a system reset unless DEBUG is defined for the project. Can you define DEBUG, enable logging  and build without optimization and use a debugger to check the state of the system at the time of the error? It should give some indication of what went wrong.

    Also, I would not expect the RESETREAS to be 0 after a reset. It should only be 0 after a brownout reset or power on reset, unless you clear it in your application before you read it.

     

     

  • First, thanks for the response. I changed to use -O0 -g3 and -DEBUG. I also found a reference to -DDEBUG and tried it as well--not sure which is correct. Should I be able to see the errors in RTT? Or will I have to attach a full debugger.. I'm just building with gcc and no real IDE.

    If I do a soft reset, through the reset pin, I get 1 for RESETREAS .. and after a flash I see a 4, but still a 0 when it resets when running the motor.

  • The reason I suggest this approach is that the device does not simply reset itself under normal situations, so it is likely that an error has been caught by an error check, and that the error handler is resetting the device as a consequence. From there, you can see what caused the error (file name, line number and error code) when you build the project with debug defined (-DDEBUG in your Makefile). See An introduction to error handling in nRF5 projects for details.

    By default, most SDK examples use UART logging, but you can configure RTT logging (via a debugger) instead if you want in the projects sdk_config.h. You can see information about logger configuration here. Alternatively, if you struggle with logging, you can put a breakpoint in the error handler instead and read the relevant data (file, line, error code) from memory directly with the debugger.

  • I mean, I'm getting log data from RTT... I added the segger code and am only getting additional lines for the segger statements. When the chip resets, I have to reconnect RTT, and I see initialization info and still 0 for resetreas (he's some output)...

    0> ###### Testing SEGGER_printf() ######
    0> <info> GPIOTE: Function: nrfx_gpiote_init, error code: NRF_SUCCESS.
    0> <info> GPIOTE: Function: nrfx_gpiote_in_init, error code: NRF_SUCCESS.
    0> <info> GPIOTE: Function: nrfx_gpiote_in_init, error code: NRF_SUCCESS.
    0> <info> pwr_mgmt: Init
    0> <debug> nrf_sdh: State request: 0x00000000
    0> <debug> nrf_sdh: Notify observer 0x0003B8D8 => ready
    0> <debug> nrf_sdh: State change: 0x00000000
    0> <debug> nrf_sdh: State change: 0x00000001
    0> <debug> nrf_sdh_ble: RAM starts at 0x20002A98
    0> <info> app: RESETREAS 0

  • Perhaps the reset reason really is brown-out, as indicated by the RESETREAS register? I don't know anything about your HW, but could it be that when the PWM signal causes the motor to run, the increased current consumption causes the supply voltage to drop below the minimum supply voltage (1.7 V)? Have you tried to meassure the supply voltage for the nRF52832 using an oscilloscope to see that it never drops below 1.7 V when you control the motor? Also, you could test and see if disconnecting the motor will prevent the resets.

Related