I have a Uno R4 and a Motor Shield Rev3. I am trying to use the pwm.h library and use the pwmOut object to set both motor outputs to be 16khz (period set to 62us).
If I use either motor A (Pin D3) or motor B (Pin D11) then everything works as expected, but the moment I initialise both motors nothing works anymore.
I am initialising using:
#include "pwm.h"
PwmOut motorA(D3); PwmOut motorB(D11);
then in setup() I am setting:
motorA.begin(62.0, 0.0); motorB.begin(62.0, 0.0);
When used individually it all works, but initialise them both and it stops (neither motor responds). If I move motorB from pin 11 to pin 5 then it works again and both motors respond, so it is something to do with trying to use pin 3 and 11 at the same time.
I can't easily move from pin 11 to 5 because the rev3 motor shield is hard wired to use 3 and 11.
I think it is something to do with pins 3 and 11 sharing a clock, but I was hoping that wouldn't be an issue as I am running both motors at the same frequency.
Any advice on getting this working with ping 3 and 11 would be most appreciated.
The motor shield only has one power in that is used for both motors. If I comment out the pwm config on D3 then the pwm on D11 works fine. If I comment out the pwm config on D11 then the pwm on D3 works fine. If I move D11 to D5 then both work fine simultaneously.
I think that proves the power is ok and the code is ok, and the issue is using D3 and D11 at the same time.
If I use the standard analogWrite option it all works, but 490hz isn’t fast enough for my application and results in a terrible whine from the motors whereas the 16khz is silent.
I think it may be an issue with the pwm.h library so hopefully someone who understands that code can advise.
Thank you for your response, your article was most helpful.
I moved on from trying to make this work, and instead I am using an SX1509 via I2C to generate the PWM signals for my motor controllers, which is working well.
BTW, if you return to the Arduino UNO R4 Minima or WiFi, be sure to check out the Renesas FSP. From what I can tell, Arduino is built on top of FSP. It allows a good way to leverage the power of the UNO's RA4M1.
It fails even when the PWMs are set to the same frequency. As I recall, the PWM hangs and the gdb debugger throws a "Fault on interrupt or bare metal(no OS) environment" error.
I could be wrong, but this appear to be a constrained resource problem. The GPT1 PWM timer can be sent to one and only one I/O pin. As I understand the RA4M1 literature and the Arduino schematic, the UNO R4 Minima GPT1 resource can be sent to D2, D3, D11, or D12 and no others. It is overassigned if we simultaneously attempt D3 and D11.
In the future I'll take another look by exploring the Renesas FSP.
Sincerely,
Aaron
P.S. One thing I have yet to resolve is why the default analogWrite( ) function operates on both Minima D3 and D11.
I've also written libraries that use PWM output to direct drive servos. That all works on both pins at the same time.
The way the library you are using works, it can only do one pin at a time. But using FspTimer.h you have access to the entire timer configuration and you can set both pins to output. They have to use the same frequency to use the same timer but they don't have to have the same duty cycle.
Because it isn't a limitation of the timer. It's a limitation of the way your code is trying to use it.
If I had more time tonight I'd show you the code. Maybe if the thread is still around tomorrow afternoon.
On this thread I have the pins picked out from the table in section 1.7 so you can see just the Arduino pins.
You'll see that pin 3 is GTIOC1B and pin 11 is GTIOC1A. They are separate outputs. They are not overlapping. Each timer is capable of driving two pins. If you tried to make two pins GTIOC1A then you'd have a problem. If you tried to make two pins GTIOC1B you'd have a problem. But you can have one of each.
The 5th bullet point down says that it has two IO pins per channel.
I work bare metal with the R4. I know what I'm talking about here. This isn't a hardware limitation. I've done what you say can't be done. So you must be wrong about this.
// FIXME instantiate and initialize as applicable
R_GPT_OutputEnable(FIXME Arduino D3); // GTIOC1B
R_GPT_OutputEnable(FIXME Arduino D11); // GTIOC1A
R_GPT_PeriodSet(FIXME); // Common frequency for both GTIOC1A and GTIOC1B
R_GPT_DutyCycleSet(FIXME Arduino D3);
R_GPT_DutyCycleSet(FIXME Arduino D11);
I'll try to flesh this out over the next few days.
BTW, it appears that the pwm.h and FSP have different ways of handling this situation. On that same note, there is good reason to recommend pwm.h as it is significantly easier to understand. The only drawback appears limited to the D3 /D11 assignment on the Minima. The WiFi has no such problem.
I should go back and explore the C33 implimentation.
What good is easy to understand if it doesn't work? I can make lots of libraries that don't work but are easy to understand.
For what you want to do pwm.h isn't going to get you there. But it isn't because the GPT timer can't output to both of its pins. It can most definitely do that.
Amen - I make all kinds of things that don't work.
Question: What is your implication(s) for "doesn't work?"
Near as I can tell, the problem is limited to Minima and then, only if we desire to use the Default D3, D5, D6, D9, D10, and D11 PWM configuration. We can still get seven independent/configerable PWM signals out of the Minima and eight from the WiFi.
Here is my understanding of the PWM mapping for the WiFi and the Minima. It does not include the alternative I/O such as ICSP, Qwicc, etc.