How to drive more motors from a Vex!

The subject of driving more motors/servos, or using more batteries, has come up many times on this forum. It occurred to me that the signal splitter is a nice 6-motor controller with its own battery supply. If only I could get the Vex microcontroller to generate the PPM signal that the signal splitter needs. Turns out, it isn’t that hard!

Using a simple cable (servo extension -> RJ11/4P4C) you can attach Vex signal splitter or secondary Vex microcontroller to motor port1. Using software, you can send the PPM signal (which contains 6 PWM settings) to the secondary controller. This lets you drive 6 motors but only takes up one motor port on your main controller.

In fact, you can use motor ports 1-4 to drive FOUR additional splitters. If you wanted to wire all this up, you could drive up to 28 motors/servos using 5 batteries from a single Vex microcontroller program!

I’ve written a library in MPLAB called PPM4VEX that handles driving a single motor port. I’m still cleaning up the full version of the library that drives up to 4 ports. It is very straight forward to use, and the only custom hardware you need is a simple cable.

I’ll post the code and cable wiring diagram later tonight. Please give it a look and let me know what you think. Any feedback would be appreciated, and I’d love to hear if anybody else gets this working.

BTW, I’ve only done this for MPLAB, but if somebody wants to try to port this to EasyC Pro or Robot C, let me know!

[EDIT] The code is now posted here [/EDIT]


  • Dean

cool! so it’s like a secondary source for motors! i hope to see you creating HUGE robots…

For those of you familiar with diffs, here are the diffs for user_routines.c and user_routines_fast.c, so that you can get an idea how to use the PPM4VEX library:


--- VexCode/user_routines.c	2008-11-30 16:37:39.000000000 -0800
+++ PPM4VEX/user_routines.c	2008-11-30 16:45:25.000000000 -0800
@@ -15,6 +15,7 @@
 #include "ifi_utilities.h"
 #include "user_routines.h"
 #include "printf_lib.h"
+#include "PPM4VEX.h"
 #define CODE_VERSION            2     /* Use this def. to keep track of your version # */
@@ -190,13 +191,13 @@
   pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
 /* SEVENTH: Choose which processor will control which PWM outputs. */
 /* EIGHTH: Set your PWM output type.  Only applies if USER controls PWM 1, 2, 3, or 4. */
   /*   Choose from these parameters for PWM 1-4 respectively:                          */
   /*     IFI_PWM  - Standard IFI PWM output generated with Generate_Pwms(...)          */
   /*     USER_CCP - User can use PWM pin as digital I/O or CCP pin.                    */
      Example: The following would generate a 40KHz PWM with a 50% duty cycle
@@ -226,6 +227,7 @@
   printf("VEX - Master v%d, User v%d\n",(int)rxdata.master_version,(int)CODE_VERSION);        
+  PPM_Initialization();
@@ -241,13 +243,53 @@
   Getdata(&rxdata);   /* Get fresh data from the master microprocessor. */
+#define PPM_DEMO1
+/* PPM Demo 1 - This demo simply duplicates the pwm settings for the built-in
+ *   motor ports to the corresponding channels on the PPM port.
+ *   Note that Motor Port 1 is used for the PPM signal to the slave controller.
+ */
+#ifdef PPM_DEMO1
   Default_Routine();  /* Optional.  See below. */
   /* Add your own code here. */
-  printf("%2x : %2x %2x %2x %2x %2x %2x  %2x %2x %2x %2x %2x %2x\n",(int)rxdata.rc_receiver_status_byte.allbits,
-    (int)PWM_in1,(int)PWM_in2,(int)PWM_in3,(int)PWM_in4,(int)PWM_in5,
-    (int)PWM_in6,(int)PWM_in7,(int)PWM_in8,(int)PWM_in9,(int)PWM_in10,
-    (int)PWM_in11,(int)PWM_in12);  /* printf EXAMPLE */
+  ppm1[1] = pwm01;
+  ppm1[2] = pwm02;
+  ppm1[3] = pwm03;
+  ppm1[4] = pwm04;
+  ppm1[5] = pwm05;
+  ppm1[6] = pwm06;
+  PPM_Generate_Pwms();
+//#define PPM_DEMO2
+/* PPM Demo 2 - This demo slowly ramps motor port 4 from 0 to 255 and back in
+ *   a pattern that looks like a triangle wave.  Motor port 3 switches between
+ *   0 and 255 every 5 seconds or so.  PPM channels 3&4 track motor ports 3&4.
+ *   Note that Motor Port 1 is used for the PPM signal to the slave controller.
+ */
+#ifdef PPM_DEMO2
+  if (pwm03) {
+	if (pwm04 < 255) {
+		pwm04++;
+	} else {
+		pwm03 = 0;
+		printf("PPM Demo 2 - reversing direction -\n");
+	}
+  } else {
+	if (pwm04 > 0) {
+		pwm04--;
+	} else {
+		pwm03 = 255;
+		printf("PPM Demo 2 - reversing direction +\n");
+	}
+  }
+  ppm1[3] = pwm03;	// gang ppm channel 3 to motor port 3
+  ppm1[4] = pwm04;	// gang ppm channel 4 to motor port 4
+  PPM_Generate_Pwms();
   Putdata(&txdata);             /* DO NOT CHANGE! */


--- VexCode/user_routines_fast.c	2008-11-30 16:37:39.000000000 -0800
+++ PPM4VEX/user_routines_fast.c	2008-11-30 16:42:51.000000000 -0800
@@ -19,6 +19,7 @@
 #include "user_routines.h"
 #include "printf_lib.h"
 #include "delays.h"
+#include "PPM4VEX.h"	// ppm interrupt handler(s)
@@ -73,6 +74,10 @@
     int_byte = PORTB;          /* You must read or write to PORTB */
     INTCONbits.RBIF = 0;     /*     and clear the interrupt flag         */
   }                                        /*     to clear the interrupt condition.  */
+  else
+  {
+    PPM_Interrupt();
+  }


  • Dean

And here is a drawing of the required cable:

(if the image link gets broken, click here).


  • Dean

wow. now that is a great idea. too bad i dont have a signal splitter.

It works equally well with a 2nd Vex microcontroller. Also, I’ve got it working with a hacked VEXplorer receiver - I’ll be posting details on that in a few days.

Also, I’m thinking about making up a batch of the adapter cables - PM me if interested.


  • Dean

This is too cool. All I have is Easy C 2.0. Is there a way I can get this code? Also the cables might be something I would be interested in. Thanks for the great idea.

I don’t think this would work with Easy C 2.0, though it might work with Easy C Pro. The library takes over a timer and ccp module, and requires an interrupt handler. If there are any Easy C (or Robot C) experts out there that want to work with me on a port of PPM4VEX, please let me know.


  • Dean

could you make two microcontrollers communicate in this way? i know i don’t have two but you could make one micro the “master” and the others the “slaves” like with legos.

You could have one “master” microcontroller send PPM signals to as many as four “slave” microcontrollers. Of course, you won’t get perfect transfer of info. When you send “17”, the receiving controller may read that as anything in a small range (say, 15-19). I really don’t know how accurate it is, but it isn’t perfect.

Honestly, it would be MUCH more straightforward to just link the microcontrollers using serial ports. It would take less code in MPLAB, and it would be bidirectional, faster, and more reliable.


  • Dean

An alternative could be to use the TTL serial (tx/rx) to control a serial servo controller e.g.

Apparently stackable up to 32 units of them. there are many other similar products around too.

Certainly, there are an almost unlimited number of options if you look around. But this, for instance doesn’t use the same servo and battery connectors as vex, and it doesn’t mount cleanly to the Vex metal. It wouldn’t be hard to get it to work with Vex, but I was trying to find a solution that trivially fit into the Vex product lineup.


  • Dean

Yup, though it would be great if Vex could package this as a “Motor expander” to add to their product lineup too! :slight_smile:

Would it be possible to upload that code to the microcontroller with the IFI loader?

That is how I installed it:
[INDENT]MPLAB -> IFI Loader -> VEX Microcontroller[/INDENT]


  • Dean

Just to recap, it may also be possible to ‘daisy chain’ controllers together over TTL serial. Personally haven’t tried it out, but read about other daisy-chained TTL serial controllers. Would be fun if someone with more than 2 sets can try this out :slight_smile:

I will look into seeing if I can implement this in easyC Pro. The only issue I see in switching the pins from the master to the user processor as that is hard coded into the library. We might be able to add this when we do the Vex WIFI update. That or we could setup a way to link Vex controllers via the serial ports.

That would be outstanding! I’m still working on changes to the PPM4VEX library to support up to 4 ports and to support the slightly different timings needed to drive a mod’d VEXplorer receiver.

Please feel free to PM me about this if you have any questions or suggestions.

  • Dean

Great work ! I look forward to your Vexplorer solution. I am using 4 Vexplorer motors to drive current robot using a home made Y connector and 2 motor controllers allowing 2 Dual motor pairs. But I still have 4 unused motors and I hate to see anything go to waste.

I have the VEXplorer solution working, but still need to document it (getting good pictures of the small SMT parts is really hard).

The VEXplorer microcontroller has a 27MHz receiver that feeds a signal through a resistor (R12) to a small microprocessor that decodes it and generates individual PWM signals for the motors. I added a standard 1/8" (3.5mm) audio jack with a built-in switch to select between the normal 27MHz receiver and an external signal. Here is a block-diagram of the mod:



The PPM4VEX library also has to change, because there are 8 signal channels instead of 6 (2 of them are ignored), and the channel order is different. Other than tweaking these constants a bit, the code is otherwise the same.


  • Dean