Multiple motorControllerL298 modules on Cerberus - supported?

I had assumed since Cerberus has 4 PWM sockets that it would be possible to use more than 1 motorControllerL298 at a time on the same board.

I’m trying to drive 4 motors on a Dagu Rover 5 chassis, and I’m only able to get a single module functioning at a time. If I plug in both modules, only 1 will work (I think whichever one was initialized last).

Here’s the code I’m using (I’m using the IR receiver module for control):

        void irreceiver_IREvent(object sender, IR_Receiver.IREventArgs e)
        {
            switch (e.Button)
            {
                case 11: // ignore AV/TV button
                    break;
                case 12: // Power button - stop motors if they're running
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor1, 0);
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor2, 0);
                    break;
                case 13: // Mute button - spin;
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor1, 100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor1, -100);
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor2, 100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor2, -100);
                    break;
                case 16: // Right (vol) button - slide right
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor1, -100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor1, -100);
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor2, -100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor2, -100);
                    break;
                case 17: // Left (vol) button - slide left
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor1, 100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor1, 100);
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor2, 100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor2, 100);
                    break;
                case 32: // Channel Up button - forward
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor1, -100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor1, -100);
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor2, 100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor2, 100);
                    break;
                case 33: // Channel Down button - back
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor1, 100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor1, 100);
                    motorLeft.MoveMotor(MotorControllerL298.Motor.Motor2, -100);
                    motorRight.MoveMotor(MotorControllerL298.Motor.Motor2, -100);
                    break;
                default:
                    break;
            }
        }

Here’s the initialization code for the modules:

        private void InitializeModules()
        {   
            // Initialize GTM.Modules and event handlers here.		
            motorLeft = new GTM.GHIElectronics.MotorControllerL298(3);
		
            motorRight = new GTM.GHIElectronics.MotorControllerL298(4);
		
            irreceiver = new GTM.GHIElectronics.IR_Receiver(7);

        }

Any notion what’s wrong?

Following up:

[ul]I tested switching around the initialization, and confirmed that it looks like whichever module is initialized last, is the one that works. So it would appear that only one motorControllerL298 can function at the same time, or there’s a bug in the initialization, anyway.
I tested on FEZ Spider running 4.1, and got the same results. Whichever module is initialized last, works fine, the other module does not work. So it does not seem to be a problem that’s specific to NETMF/Gadgeteer 4.2, nor specific to Cerberus.
I had a look at the source for the driver, and saw these lines:[/ul]

m_Direction1 = new OutputPort(socket.CpuPins[9], false);
m_Direction2 = new OutputPort(socket.CpuPins[6], false);

Is it possible that the use of these CpuPin values only allows one module to be used at a given time?

PWM pins are shared on couple sockets. I think the one with S function as these are the SPI pins. Try different sockets.

@ Gus - Should have mentioned that I’ve tried on all the available P sockets (even the ones that aren’t marked, but are noted in the wiki).

From what I can tell from the product page, only sockets 5 & 6 should be shared. Currently, I have the motor modules on sockets 3 & 4, so shared pins should not be an issue.

And as noted, I also tested this on Spider running 4.1, and found the exact same behavior.

All PWM share the same requency but not duty cycle. You can use PWM directly and we will check the gadgeteer drivers soon.

I know you’re on the road tomorrow, Gus, so perhaps I’ll discuss with you further at MADExpo, but I’m not clear on whether by “use PWM directly” I would have to drop down to just a regular NETMF project, or if I can do PWM directly from a Gadgeteer project.

I should probably know the answer, but I’ve been fighting with this bot so long today, my eyes are starting to cross.

At least I’ll have my Blinkies, the MeeBlipiator, and the helicopter. And I’ll bring the bots along just in case I can manage to get one or the other of them working.

Add Microsoft.SPOT.Hardware.PWM to your Gadgeteer project and it should work as below. You may have to play around with the channel parameter. I’m not certain how that aligns to the individual boards.

var pwm2 = new Microsoft.SPOT.Hardware.PWM(Cpu.PWMChannel.PWM_7, 8000, 4000, Microsoft.SPOT.Hardware.PWM.ScaleFactor.Nanoseconds, false);

Awesome. Thanks, Ian!

May help me salvage my demo.

On a related note, do you know if it’s best to avoid driving DC motors at their full duty cycle for any length of time?

A decent motor should handle running at full tilt just fine. Not indefinitely, of course, but longer than the most onboard batteries hold out. There’s a lot of junk out there, though, and it’s hard to tell good from bad. Once you find a brand that behaves, stick with it. My experience with model train motors has been fairly painless, as there are well established good (and bad) brands, which are put through their paces and rated by the community.

Good to know, though I was more concerned with whether running at full duty cycle might put too much strain on either the motor controller or mainboard, as I managed to fry something last night, either the motor controller(s), the mainboard, or possibly both. :frowning:

The good news is that I had a backup bot, which I now have working. :slight_smile: Just means I’ll have to swap mainboards for demoing the bot.

We have discovered the issue with the driver. If you would like a patch let us know.

Yes, please!

I believe you should have my email address, if you want to send via email.