There’s definitely a problem with the SetPwm() (Start() calls SetPwm()…). I think some test code may have made it into production. Dobova, do you remember if the first & last lines are necessary for some reason? If I remove it then I can reliably create the correct PWM signal on both pins. I can’t make sense of why those lines are there and I suspect they were leftover from some test.
private void SetPwm(byte port, byte pin, byte period, byte pulseWidth, PWM.PwmClockSource clock, byte clockDivider = 0)
{
//_parentModule.Write(port, pin, false); // Why was this here???
_parentModule.WriteRegister(0x18, port); // Select port
var b = _parentModule.ReadRegister(0x1a);
b |= (byte)((1 << pin));
_parentModule.WriteRegister(0x1a, b); // select PWM for port output
b = _parentModule.ReadRegister(0x1C);
b &= (byte)(~(1 << pin));
_parentModule.WriteRegister(0x1C, b); // Set pin for output.
_parentModule.WriteRegister(0x28, (byte)(0x08 + pin)); // Select the PWM pin to configure.
_parentModule.WriteRegister(0x29, (byte)clock); // Config PWM (select 32kHz clock source)
if (clockDivider > 0) _parentModule.WriteRegister(0x2c, clockDivider); // Set the clock divider (if using 367.6 Hz clock)
_parentModule.WriteRegister(0x2a, period); // set the period (0-256)
_parentModule.WriteRegister(0x2b, pulseWidth); // set the pulse width (0-(period-1))
//_parentModule.Write(port, pin, true); // Why???
}
@ crutkas - please try the following code instead of your .Start() calls and let me know if you get the expected results.
// Create a function to replace .Start()
private void SetPwm(IO60P16Module _parentModule, byte port, byte pin, byte period, byte pulseWidth, PWM.PwmClockSource clock, byte clockDivider = 0)
{
_parentModule.WriteRegister(0x18, port); // Select port
var b = _parentModule.ReadRegister(0x1a);
b |= (byte)((1 << pin));
_parentModule.WriteRegister(0x1a, b); // select PWM for port output
b = _parentModule.ReadRegister(0x1C);
b &= (byte)(~(1 << pin));
_parentModule.WriteRegister(0x1C, b); // Set pin for output.
_parentModule.WriteRegister(0x28, (byte)(0x08 + pin)); // Select the PWM pin to configure.
_parentModule.WriteRegister(0x29, (byte)clock); // Config PWM (select 32kHz clock source)
if (clockDivider > 0) _parentModule.WriteRegister(0x2c, clockDivider); // Set the clock divider (if using 367.6 Hz clock)
_parentModule.WriteRegister(0x2a, period); // set the period (0-256)
_parentModule.WriteRegister(0x2b, pulseWidth); // set the pulse width (0-(period-1))
}
// Call these where you were calling .Start()
SetPwm(io60p16, 6, 0, 255, 19, ModulePWM.PwmClockSource.Clock_367Hz6, 7);
SetPwm(io60p16, 6, 1, 255, 19, ModulePWM.PwmClockSource.Clock_367Hz6, 7);
Sorry Ian, I read now your question. Yes,they are there for a good reason: the line shutdown the output of the Pwm pin then re enable after change settings.
This can avoid some glitch on output when changing period. Not necessary for duty cycle.
We finally got to this module and rewrote the driver completely. We learned much about the cypress chipset and unfortunately it was not all good. The chip has 8bit PWM. This is no good for servos. It can work with servos but you get about 50 steps on the full servo movement. Where for example, internal PWM on the mainboard and PWM on pulse inout module will give you 500 steps.
This will be detailed and new driver will be available this month.
How much has it changed? Just internal low level functions or the public ones as well? I was hoping to get the tutorial created this weekend. If our driver is no longer valid then I’ll change my plans…
@ Gus, doing some math, if you need 50Hz (20ms) period and need duty cycle from 1ms to 2ms. Using programmable clock of 93.75 in reg 29h, the best suited values are 8 in divider reg 2Ch and 234 in period reg 2Ah. This leave at best values for the dutycycle from 11 to 23 in reg 2Bh, that is to say 12 steps. Get a look at reg 2B, it gets a value from 0 to period-1, in our case from 0 to 233.
How do you get 50 steps?
Do not quote me on 50 steps as we are still testing and changing the driver. I think the plan was to offer a 100Hz option, which we tested on few servos and all worked fine… again, please do not quote me on any of this info. We will complete, test and provide all needed info.