For some reason our motors are "breaking" and not going forward. Why?

When we send the code to the board, our left and right motors definitely get the signal because they have a steady yellow light instead of a blinking yellow light, but that indicates that they’re breaking, not going forward. What is wrong with this?

Code for user_routines_fast.c:


/*******************************************************************************
* FILE NAME: user_routines_fast.c <FRC VERSION>
*
* DESCRIPTION:
*  This file is where the user can add their custom code within the framework
*  of the routines below. 
*
* USAGE:
*  You can either modify this file to fit your needs, or remove it from your 
*  project and replace it with a modified copy. 
*
* OPTIONS:  Interrupts are disabled and not used by default.
*
*******************************************************************************/

#include "ifi_aliases.h"
#include "ifi_default.h"
#include "ifi_utilities.h"
#include "user_routines.h"
#include "user_Serialdrv.h"


/*** DEFINE USER VARIABLES AND INITIALIZE THEM HERE ***/
enum {s_start, //drive forward full speed, turn left and right 
	  s_stop, //come to full stop, button 1 creeps, turns left and rgiht in place, allows raising and lowering arm.
	  s_raising, //raises arm, allows reversal
	  s_lowering, //lowers arm, allows reversal
	  s_hang};//holds arm up, allows lowering

/*******************************************************************************
* FUNCTION NAME: InterruptVectorLow
* PURPOSE:       Low priority interrupt vector
* CALLED FROM:   nowhere by default
* ARGUMENTS:     none
* RETURNS:       void
* DO NOT MODIFY OR DELETE THIS FUNCTION 
*******************************************************************************/
#pragma code InterruptVectorLow = LOW_INT_VECTOR
void InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow  /*jump to interrupt routine*/
  _endasm
}


/*******************************************************************************
* FUNCTION NAME: InterruptHandlerLow
* PURPOSE:       Low priority interrupt handler
* If you want to use these external low priority interrupts or any of the
* peripheral interrupts then you must enable them in your initialization
* routine.  Innovation First, Inc. will not provide support for using these
* interrupts, so be careful.  There is great potential for glitchy code if good
* interrupt programming practices are not followed.  Especially read p. 28 of
* the "MPLAB(R) C18 C Compiler User's Guide" for information on context saving.
* CALLED FROM:   this file, InterruptVectorLow routine
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD /* You may want to save additional symbols. */

void InterruptHandlerLow ()     
{                               
  unsigned char int_byte;       
  if (INTCON3bits.INT2IF && INTCON3bits.INT2IE)       /* The INT2 pin is RB2/DIG I/O 1. */
  { 
    INTCON3bits.INT2IF = 0;
  }
  else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE)  /* The INT3 pin is RB3/DIG I/O 2. */
  {
    INTCON3bits.INT3IF = 0;
  }
  else if (INTCONbits.RBIF && INTCONbits.RBIE)  /* DIG I/O 3-6 (RB4, RB5, RB6, or RB7) changed. */
  {
    int_byte = PORTB;          /* You must read or write to PORTB */
    INTCONbits.RBIF = 0;     /*     and clear the interrupt flag         */
  }                                        /*     to clear the interrupt condition.  */
  else
  { 
    CheckUartInts();    /* For Dynamic Debug Tool or buffered printf features. */
  }
}


/*******************************************************************************
* FUNCTION NAME: User_Autonomous_Code
* PURPOSE:       Execute user's code during autonomous robot operation.
* You should modify this routine by adding code which you wish to run in
* autonomous mode.  It will be executed every program loop, and not
* wait for or use any data from the Operator Interface.
* CALLED FROM:   main.c file, main() routine when in Autonomous mode
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void User_Autonomous_Code(void)
{
  unsigned char auto_state = s_start;
  unsigned char user_button = 0;
  /* Initialize all PWMs and Relays when entering Autonomous mode, or else it
     will be stuck with the last values mapped from the joysticks.  Remember, 
     even when Disabled it is reading inputs from the Operator Interface. 
  */
  pwm01 = pwm02 = pwm03 = pwm04 = pwm05 = pwm06 = pwm07 = pwm08 = 127;
  pwm09 = pwm10 = pwm11 = pwm12 = pwm13 = pwm14 = pwm15 = pwm16 = 127;
  relay1_fwd = relay1_rev = relay2_fwd = relay2_rev = 0;
  relay3_fwd = relay3_rev = relay4_fwd = relay4_rev = 0;
  relay5_fwd = relay5_rev = relay6_fwd = relay6_rev = 0;
  relay7_fwd = relay7_rev = relay8_fwd = relay8_rev = 0;

  while (autonomous_mode)   /* DO NOT CHANGE! */
  {
    if (statusflag.NEW_SPI_DATA)      /* 26.2ms loop area */
    {
        Getdata(&rxdata);   /* DO NOT DELETE, or you will be stuck here forever! */

        /* Add your own autonomous code here. */
        if (ir_button1) user_button = 1;
		else if (ir_button2) user_button = 2;
		else if (ir_button3) user_button = 3;
		else if (ir_button4) user_button = 4;
		else user_button = 0;
		
		switch (auto_state)
		{
			case s_start:	//forward
				if (user_button == 0 || user_button == 2)
				{
					left_drive = FULL_FORWARD;
					right_drive = FULL_FORWARD;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_start;
				}
				if (user_button == 1)
				{
					left_drive = LOW_FORWARD;
					right_drive = LOW_FORWARD;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_stop;
				}
				if (user_button == 3)
				{
					left_drive = MEDIUM_FORWARD;
					right_drive = FULL_FORWARD;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_start;
				}
				if (user_button == 4)
				{
					left_drive = FULL_FORWARD;
					right_drive = MEDIUM_FORWARD;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_start;
				}
			break;
			case s_stop: //left
				if (user_button == 0)
				{
					left_drive = IDLE;
					right_drive = IDLE;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_stop;
				}
				if (user_button == 1)
				{
					left_drive = LOW_FORWARD;
					right_drive = LOW_FORWARD;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_stop;
				}
				if (user_button == 2)
				{
					left_drive = IDLE;
					right_drive = IDLE;
					lift_motor1_up = 1;
					lift_motor1_down = 0;
					auto_state = s_raising;
				}
				if (user_button == 3)
				{
					left_drive = LOW_REVERSE;
					right_drive = LOW_FORWARD;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_stop;
				}
				if (user_button == 4)
				{
					left_drive = LOW_FORWARD;
					right_drive = LOW_REVERSE;
					lift_motor1_up = 0;
					lift_motor1_down = 0;
					auto_state = s_stop;
				}
			break;
			case s_raising:
				left_drive = IDLE;
				right_drive = IDLE;
				lift_motor1_up = 1;
				lift_motor1_down = 1;
			break;
			case s_lowering:
				left_drive = IDLE;
				right_drive = IDLE;
				lift_motor1_up = 0;
				lift_motor1_down = 1;
			break;
			case s_hang:
				if (user_button == 0 || user_button == 3 || user_button == 4)
				{
					left_drive = IDLE;
					right_drive = IDLE;
					lift_motor1_up = 1;
					lift_motor1_down = 1;
					auto_state = s_hang;
				}
				if (user_button == 1)
				{
					left_drive = LOW_FORWARD;
					right_drive = LOW_FORWARD;
					lift_motor1_up = 1;
					lift_motor1_down = 1;
					auto_state = s_hang;
				}
				if (user_button == 2)
				{
					left_drive = IDLE;
					right_drive = IDLE;
					lift_motor1_up = 0;
					lift_motor1_down = 1;
					auto_state = s_lowering;
				}
			break;
		} Generate_Pwms(pwm13,pwm14,pwm15,pwm16);

        Putdata(&txdata);   /* DO NOT DELETE, or you will get no PWM outputs! */
    }
  }
}

/*******************************************************************************
* FUNCTION NAME: Process_Data_From_Local_IO
* PURPOSE:       Execute user's realtime code.
* You should modify this routine by adding code which you wish to run fast.
* It will be executed every program loop, and not wait for fresh data 
* from the Operator Interface.
* CALLED FROM:   main.c
* ARGUMENTS:     none
* RETURNS:       void
*******************************************************************************/
void Process_Data_From_Local_IO(void)
{
  /* Add code here that you want to be executed every program loop. */

}

/*******************************************************************************
* FUNCTION NAME: Serial_Char_Callback
* PURPOSE:       Interrupt handler for the TTL_PORT.
* CALLED FROM:   user_SerialDrv.c
* ARGUMENTS:     
*     Argument             Type    IO   Description
*     --------             ----    --   -----------
*     data        unsigned char    I    Data received from the TTL_PORT
* RETURNS:       void
*******************************************************************************/

void Serial_Char_Callback(unsigned char data)
{
  /* Add code to handle incomming data (remember, interrupts are still active) */
}


/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

Code for user_routines.h:


/*******************************************************************************
* FILE NAME: user_routines.h
*
* DESCRIPTION: 
*  This is the include file which corresponds to user_routines.c and
*  user_routines_fast.c
*  It contains some aliases and function prototypes used in those files.
*
* USAGE:
*  If you add your own routines to those files, this is a good place to add
*  your custom macros (aliases), type definitions, and function prototypes.
*******************************************************************************/

#ifndef __user_program_h_
#define __user_program_h_

/*******************************************************************************
                            MACRO DECLARATIONS
*******************************************************************************/
/* Add your macros (aliases and constants) here.                              */
/* Do not edit the ones in ifi_aliases.h                                      */
/* Macros are substituted in at compile time and make your code more readable */
/* as well as making it easy to change a constant value in one place, rather  */
/* than at every place it is used in your code.                               */
/*
 EXAMPLE CONSTANTS:
#define MAXIMUM_LOOPS   5
#define THE_ANSWER      42
#define TRUE            1
#define FALSE           0
#define PI_VAL          3.1415

 EXAMPLE ALIASES:
#define LIMIT_SWITCH_1  rc_dig_int1  (Points to another macro in ifi_aliases.h)
#define MAIN_SOLENOID   solenoid1    (Points to another macro in ifi_aliases.h)
*/

/* Used in limit switch routines in user_routines.c */
#define OPEN        1     /* Limit switch is open (input is floating high). */
#define CLOSED      0     /* Limit switch is closed (input connected to ground). */
#define left_drive    pwm02
#define right_drive   pwm01
#define right_flipper pwm03
#define left_flipper  pwm04
#define arm_up        rc_dig_in01
#define arm_down      rc_dig_in02
#define ir_button1    rc_dig_in03
#define ir_button2    rc_dig_in04
#define ir_button3    rc_dig_in05
#define ir_button4    rc_dig_in06
#define lift_motor1_up    relay1_fwd
#define lift_motor1_down  relay1_rev  

#define FULL_FORWARD 254
#define MEDIUM_FORWARD 187
#define LOW_FORWARD 147
#define IDLE 127
#define MEDIUM_REVERSE 67
#define LOW_REVERSE 87
#define FULL_REVERSE 0

/*******************************************************************************
                            TYPEDEF DECLARATIONS
*******************************************************************************/
/* EXAMPLE DATA STRUCTURE */
/*
typedef struct
{
  unsigned int  NEW_CAPTURE_DATA:1;
  unsigned int  LAST_IN1:1;
  unsigned int  LAST_IN2:1;
  unsigned int  WHEEL_COUNTER_UP:1;
  unsigned int  :4;
  unsigned int wheel_left_counter;
  unsigned int wheel_right_counter;
} user_struct;
*/


/*******************************************************************************
                           FUNCTION PROTOTYPES
*******************************************************************************/

/* These routines reside in user_routines.c */
void User_Initialization(void);
void Process_Data_From_Master_uP(void);
void Default_Routine(void);

/* These routines reside in user_routines_fast.c */
void InterruptHandlerLow (void);  /* DO NOT CHANGE! */
void User_Autonomous_Code(void);  /* Only in full-size FRC system. */
void Process_Data_From_Local_IO(void);


#endif
/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

Any help is appreciated.

Thanks,
Bensky

The robot defaults into teleoperated mode unless you have a competition port dongle to let you switch into autonomous mode. The code you posted is entirely for autonomous mode, so if you aren’t using a dongle to switch to that mode, you won’t see any output from it!

Also, the steady yellow light just means that the Victors are getting a signal of 127 from the RC - the only time they’ll blink is if they’re not getting a signal, which happens (for example) when it’s in programming mode or loses its connection to the OI (due to a lack of radio or tether)

The thing is though, we do have a dongle, and the lights show that it is in autonomous mode. :confused:

The easiest way to debug an issue like this is to add a printf statement into each “if” statement like this:

printf(“We made it into 1”);

in the next if:

printf(“We made it into 2”);

and so on. Then you can watch the terminal window and determine which if/thens are setting it to what values.