Arduino + Jaguar Speed Controller + CIM Motor

I have connected a CIM motor to a Jaguar speed controller, powered by 12V battery. The jaguar is connected to an Arduino UNO via the signal and ground. Also, I have two switches connected to the Arduino, for forward and reverse of the motor.

In the code, for speed of the motor, I have set 90 as the mid point and 100 for forward and 80 for reverse. When I push the reverse button, the motor runs smoothly in the reverse direction at the set speed. However, the problem is, when I press the forward button, the motor runs seemingly slower in the forward direction than the set speed. My logic here was, if I have set speeds in forward and reverse at +/- 10 from the mid-point, the motor should run at the same speed in the forward and reverse direction, but this is not happening.

I am pasting my code below. Any help would be much appreciated. Thank you!

#include <Servo.h> 

int forwardPin = 2;
int reversePin = 4;
int motorPin = 10;
int fwdReading = 0;
int revReading = 0;

Servo myservo;

void setup() 
{ 
  TCCR1B = TCCR1B & 0b11111000 | 0x04; // PWM Freq. at 122Hz
  
  pinMode (forwardPin, INPUT);
  pinMode (reversePin, INPUT);
  myservo.attach(motorPin);
  myservo.write(90);  // set servo to mid-point
} 

void loop() 
{
  fwdReading = digitalRead(forwardPin);
  revReading = digitalRead(reversePin);
  
  if (fwdReading == HIGH)
  {
    myservo.write(100); // forward
  }  
   else if (revReading == HIGH)
  {
    myservo.write(80); // reverse
  }
  else
  myservo.write(90); // neutral
}

Here is my hacked code for our test box, that drives two jags, for our test box. It has two pots that are used for speed controls, to drive the servo output, there are two pots and two jags on our test box.

I did this many years ago, it uses the map command, it works. Hopefully it helps. It has been a long time since I played with it, but we use it everyday for prototyping.

The jag connected to myservo runs forward and reverse, the jag connected to the myservo1 only runs forward. Look at Map command arguments, 90 to 180.

// Controlling a servo position using a potentiometer (variable resistor) 
// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott> 

#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 
Servo myservo1;  // create servo object to control a servo 
 
int potpin = 0;  // pot in is 13 pwm analog pin used to connect the potentiometer
int potpin1 = 1;  // analog pin used to connect the potentiometerint val;    // variable to read the value from the analog pin 
int val =0;
int val1=0;
void setup() 
{ 
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object 
 myservo1.attach(10);  // attaches the servo on pin 9 to the servo object 
} 
 
void loop() 
{ 
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) //
  val1 = analogRead(potpin1);            // reads the value of the potentiometer (value between 0 and 1023) 
  val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180) 
  val1 = map(val1, 0, 1023, 90, 179);     // scale it to use it with the servo (value between 0 and 180) 
   myservo.write(val);                  // pwm 13 sets the servo position according to the scaled value 
   myservo1.write(val1);                  // sets the servo position according to the scaled value 
  delay(15);                           // waits for the servo to get there 
} 

May also need to calibrate Jag and see if you get the expected results. to calibrate you will need full forward and full reverse speeds.


To calibrate the servo-style PWM input for a specific range, connect a PWM source, then:

  1. Hold down the USER switch with a straightened paper clip for 5 seconds.
  2. The LED flashes Red and Green to indicate Calibration mode.
  3. Instruct the controller to send a full-forward signal for one or more seconds.
  4. Instruct the controller to send a full-reverse signal for one or more seconds.
  5. The LED flashes Green and Yellow quickly to indicate a successful calibration.
    The Jaguar samples these signals and centers the speed range and neutral position between these limits. A
    calibration failure signals if an out-of-range signal is detected. This condition is indicated by flashing the LED
    Red and Yellow

@tr6scott Hey thanks a lot! I will edit the code tonight and check if the map command works.
I have tried to calibrate it several times from 0 to 180 and works perfectly but when I have it from 80 to 100 with 90 as midpoint, the forward speed seems slower compared to reverse speed :confused:

It’s coming back to me, what you have looks fine, I’d be tempted to stick with it, and add the delay to the loop… that maybe the issue. From the map command it should be 0 to 179, not sure what happens when you tell it 180… maybe add the delay, set it up 0 to 179, then calibrate the jag, and then see if it behaves.

I wrote a library for this

https://sourceforge.net/projects/ardurio/files/?source=navbar

its makes running motor controllers really easy.

Hi, I think what your issue is might be with the default pulse-width of the signal coming from the Servo library.

Some manufactures decide to vary their input range from the standard timings. Also, most RC servos (what the Library was made for) have a different range from what I have seen FRC Controllers use most of the time.

I did a quick look for the Jaguar Datasheet and found this:

This is what the Datasheet says about the input range:

Minimum pulse width 0.67 ms
Neutral pulse width 1.5 ms
Maximum pulse width 2.33 ms

All We need to do now is convert the ms to us:

Minimum pulse width 670 us
Neutral pulse width 1500 us
Maximum pulse width 2330 us

Now the great thing about the servo library is the ability to skip the scaling of the normal RC servo range and just input the raw us timing values.

myservo.writeMicroseconds(UsTiming);

After that It should be pretty easy to map the values accordingly.

I hope that solves your issue!

Please don’t forget that the CIM motor has a brush bias that is optimized for one direction over the other. While it is slight, there are production variances that may make individual motors respond differently. Other motors are known to have greater bias differences.

Could you tune this by loosening the bolts, and rotating the black section that houses the permanent magnets (Not saying this would/should be legal on an FRC robot, just technically possible). There are tick marks on each of the sections so you could potentially reliably clock the magnets in relation to the brushes.