Io60p16 and multiple servos

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);

@ crutkas - did this last test work for you?

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.

So does this mean that for servos this module is not a good choice and you shouldnt use it?

@ HughB - You can still use it but they wont have a smooth motion.

Correct. If you are happy with 50 steps from side to side then it is fine. Most will find it enough.

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?

This is an issue for sure if you are going to work with hires servos and I’ve sperimented few month ago [http://www.tinyclr.com/forum/topic?id=6860&page=23#msg72357].

The driver is all different now.

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.