lancaster-university / microbit-dal

http://lancaster-university.github.io/microbit-docs
Other
256 stars 130 forks source link

PWM Duty Cycle Value Reversed #405

Open kiate opened 5 years ago

kiate commented 5 years ago

Hi, I'm working on a 2-wheel robot with micro:bit and MakeCode and controlling it with locked anti-phase method at 20kHz PWM frequency. The motors will stop when PWM duty cycle is set at around 50%, while duty cycle lower or higher than 50% will drive them in opposite direction.

The issue comes when I'm programming the robot to perform line following. I noticed that the two motors will occasionally reverse the rotating direction while line following. So I checked the PWM signal from micro:bit P8 & P16 which are used to control motors and found something strange.

Then I tried to alternate the PWM values between 10% and 30% duty cycles every 100ms on P0. This is what I've got from OSC: https://photos.app.goo.gl/kfzyUYaDSKGrCrvr8. You can see that many times it outputs 90% and 70%, instead of the desired 10% and 30%. This is the code I use: https://makecode.microbit.org/_3mdgE2J5TFWb

Gradually lowering the PWM frequency from 20kHz to 10kHz seems to bring down the rate of occurrence but it still happens. I've updated my micro:bit to the latest firmware, currently running "0250_kl26z_microbit_0x8000.hex" and also tested on the latest hardware version with combined magnetometer and accelerator chip, but the issue persists. Also tested on different pins like P1, P2 & etc. Another observation is this issue prone to occur when the duty cycle is below 30%.

Have anyone of you encountered such problem? Did I setup the PWM wrongly? Then I found this issue https://devzone.nordicsemi.com/f/nordic-q-a/7371/sometimes-pwm-signal-is-reversed/26144#26144. Is it related?

finneyj commented 5 years ago

thanks for reporting @kiate, and for supplying such a good amount of detail. Definitely looks like something wrong here. I can't see anything wrong in your setup or test case.

The firmware version shouldn't make any difference to this issue (the firmware update only changes the USB interface chip, not the main CPU).

This is probably indirectly related to the Nordic article, yes. The nrf51 CPU doesn't have a "real" hardware PWM module - it's emulated using GPIOTE (a kind of software configurable GPIO hardware module).

Let me see if I can reproduce this in C++ when I get a moment, as that will rule out MakeCode potentially building against an old version of the PWM code etc...

kiate commented 5 years ago

@finneyj Thanks for your prompt response! Looking forward to your findings.

andrew-littlebits commented 4 years ago

I can corroborate this issue. It seems like something around modifying the PWM driver or re-initializing it during runtime can cause the duty cycle to invert. Still not 100% sure of the root cause, but it seems to be correlated to code that executes pins.analogSetPeriod() while PWM is active.

Funny enough, I don't care about the duty cycle flipping during the section of code when i'm calling pins.analogSetPeriod() repeatedly (the duty is set to 50%, i'm just generating square waves). But when I then try to recover and switch to a constant-frequency but variable-duty sequence, I can't get the duty cycle to reliably be uninverted.