Rookie Team Help: Connection Issues

Today, we attended a tournament and experienced strange connection and motor issues at the event. we believe this is due to two separate problems, but in actuality, it may be a single problem

Robot Code (See next post [10kchar])

Problem 1: The robot only moves in some instances despite being given full green lights on the joystick. In some instances, the entire robot can be controlled by the joystick, other times it cannot. Under the instance that the robot does connect for an extended period of time, it leads to problem 2

Things we tried:
-Firmware on vexnets and cortex has been updated
-Used tether. Still experienced connection issues
-Used 6 different vexnets. Still experienced spotty connection issues. We used vexnets which consistently runs other robots
-We added a 100ms delay in task user control to see if the CPU was being hogged. No difference in result. We also have a delay in our PID code,
-Vigorously shaking battery connections to the power expander and cortex. Did not affect connection. We do not think loose wiring is the result of connection issues
-Replaced 9v backup battery. No effect. We do not think a lack of a charged back up battery led to connection issues
-Traded joysticks with our 15" robot which we know works. Had no effect on connection issues. Because of this, we don’t think it’s the competition port
-No traces of metal shavings have appeared on the cortex or wiring

Robot Specs
Drivetrain: 4m X-Drive
Shooter: 6m, 35:1, 4.1”, half pound flywheel (Largest sprocket with tank tread, weighed down with screws + nuts) (Shooter Footage: Working on the 24" | By Florida Tech VEX-U | Facebook)
Intake: 2m internally geared for speed, Joe-Johnson Style intake (Footage: Reworked the intake!! | By Florida Tech VEX-U | Facebook)
4 encoders on the drivetrain (1 for each wheel) hooked into digital ports 1-8, and 1 encoder with an arduino hooked up to UART

Problem 2: Robot experienced motor sputtering after about 15 seconds of operating the intake and flywheel from feeding balls from the preloads. Under this scenario, balls do not jam within the intake or shooter.

Things we tried
-We split the current among ports 1-5, 6-10, and a power expander. Breaker ports 1-5 has a y splitter powering 2 motors of the flywheel. Breaker ports 6-10 has another Y splitter powering 2 motors of the shooter. Power expander powers 2 motors for the intake and 2 motors of the shooter on the power expander. Because of this setup, we do not think we are breaking the 4 amp breakers on the cortex or power expander
-Previously, the robot did not use a power expander. Before, we had 3 motors of the flywheel and 1 intake motor on 1 breaker, and another 3 flywheel motors and an intake motor in the second breaker. There was no motor sputtering issue. Because of this, we do not think that this is a current draw problem.
-Previously, the flywheel could be spun by hand and still remain spinning for 15 seconds. Because of this, we do not think this is a current draw problem from excessive friction from the shooter
-Previously, we could feed 2 balls side by side to stress test the intake. There was no motor sputtering problem from the power spike. Because of this, we do not think it is a current draw issue
-We limited PID motor power so the motors do not run in reverse to slow down.
-We minimized the friction of the intake as much as possible. Loosened the bearings to the point that the screws could be turned by hand, but the pillowblocks were still flush to brackets
-We ran the robot without connection to the field prior to matches. We made it shoot 15 balls over the course of about 8 seconds and there was no motor sputtering problem. We placed our robots on the field and let them “cool off” for about a minute. Match started and we ran into sputtering problems after 8 or so shots
-We ran the robot’s flywheel and intake sparingly. We ran the intake to index balls, then ran the flywheel and the intake to shoot. We then shut off the flywheel and used the intake to index more balls then ran the flywheel and intake again to shoot. This time, we could get more shots, but still ran into a motor sputtering problem

Code:

#pragma config(Sensor, dgtl1,  Encoder1,       sensorQuadEncoder)
#pragma config(Sensor, dgtl3,  eFL,            sensorQuadEncoder)
#pragma config(Sensor, dgtl5,  eBL,            sensorQuadEncoder)
#pragma config(Sensor, dgtl7,  eFR,            sensorQuadEncoder)
#pragma config(Sensor, dgtl9,  eBR,            sensorQuadEncoder)
#pragma config(Motor,  port1,           driveFR,       tmotorVex393_HBridge, openLoop, reversed)
#pragma config(Motor,  port2,           driveBR,       tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port3,           intakeL,       tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port4,           outerL,        tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port5,           innerL,        tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port6,           innerR,        tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port7,           outerR,        tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port8,           intakeR,       tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port9,           driveBL,       tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port10,          driveFL,       tmotorVex393_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#pragma platform(VEX)

//Competition Control and Duration Settings
#pragma competitionControl(Competition)
#pragma autonomousDuration(45)																																	//changed from 20
#pragma userControlDuration(75)																																	//changed from 120

#include "Vex_Competition_Includes.c"   //Main competition background code...do not modify!

#define SHOOTER_RPM					620																													//CHANGED FROM 420   NOTE: Shot Distance
#define PID_SENSOR_INDEX    Encoder1
#define INVERT_SHOOTER_RPM	-1					// 1 for false, -1 for true
#define INVERT_SHOOTER_MOTORS -1				// 1 false, -1 for true
// For RPM calculation
#define time = 25 // Update Interval
#define ticks = 360 // Ticks per full encoder revolution

#define ENCODER_CONVERSION 	0.006 			// Encode Pulses/ms

#define UPDATE_INTERVAL  		25  				// In ms
#define MS_PER_MIN						60000			//
#define REV_PER_ENCODER_TICK  0.00277   // 1 rev / 360 ticks

#define FL_MOTOR_TUNE 0
#define BL_MOTOR_TUNE 0
#define BR_MOTOR_TUNE 0
#define FR_MOTOR_TUNE 0


#define PID_DRIVE_MAX       (127)									//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CHANGED FROM -65 NOTE: Coasting and decelleration
#define PID_DRIVE_MIN     	(0)
#define PID_INTEGRAL_LIMIT  50


static bool   pidRunning = false; 						// Enable/Disable PID, 1 for true, 0 for false
static float pidRequestedVelocity = 0; 	// Set PID RPM

static bool enableIntake = true;

#define INTAKE_SPEED 						110
#define INTAKE_SPEED_REVERSE		-110

//int Hz = 1000 / time;
float RPM;
float motorPower = 0;
int motorPowerIntake = 0;

// Task definitions

// UART Task Globals
int bufferIndex = 0;
int rcvChar;																// Received Character
int rpm = 0;
unsigned char buffer[23]; 									// Keep buffer of last 23 characters received.

task UARTReceive;
task pidController;

// Controller Input task
task ControllerInput;

// Other
task ControllerInput(){
	bool buttonHasBeenPressed = false;
		while (true)
	{
		//shooter code
	   if(!buttonHasBeenPressed){
			if(vexRT[Btn6U] ){
				buttonHasBeenPressed= true;
				if(pidRunning){
					pidRunning = false;
				}
				else{
					pidRequestedVelocity= SHOOTER_RPM;		//Increase to increase distance. Decrease to decrease distance
					pidRunning = true;
				}
			}
			else{
			}
		}

			if(vexRT[Btn6U] != 1){
				buttonHasBeenPressed = false;
			}
			wait1Msec( UPDATE_INTERVAL );
	}
}

void updateShooterRPM(){
		RPM = abs(SensorValue[Encoder1]) * REV_PER_ENCODER_TICK * (1/UPDATE_INTERVAL) * MS_PER_MIN;
}

void setShooterSpeed(int s){
	s = s * INVERT_SHOOTER_MOTORS;
		motor[outerL] = -s;
		motor[innerR] = -s;
		motor[outerR] = s;
		motor[innerL] = s;
}

void setIntakeSpeed(int s){
	motor[intakeL]=  -s;
	motor[intakeR]=  s;
}

/////////////////////////////////////////////////////////////////////////////////////////
//
//                          Pre-Autonomous Functions
//
// You may want to perform some actions before the competition starts. Do them in the
// following function.
//
/////////////////////////////////////////////////////////////////////////////////////////

void pre_auton()
{
  // Set bStopTasksBetweenModes to false if you want to keep user created tasks running between
  // Autonomous and Tele-Op modes. You will need to manage all user created tasks if set to false.
  bStopTasksBetweenModes = true;

	// All activities that occur before the competition starts
	// Example: clearing encoders, setting servo positions, ...
}


/////////////////////////////////////////////////////////////////////////////////////////
//
//                                 User Control Task
//
// This task is used to control your robot during the user control phase of a VEX Competition.
// You must modify the code to add your own robot specific commands here.
//
/////////////////////////////////////////////////////////////////////////////////////////

		float  pid_Kp = 1;																																						//CHANGED FROM 3		consider 9
		float  pid_Ki = 0.2;																																					//CHANGED FROM .32	consider lowering	(nudge)
		float  pid_Kd = .75;																																						//CHANGED FROM 1		consider P
		float  pidSensorCurrentValue;
		float  pidError;
    float  pidLastError;
    float  pidIntegral;
    float  pidDerivative;
    float  pidDrive;
    float  pidSetSensorValue;

task pidController()
{

	// These could be constants but leaving
		// as variables allows them to be modified in the debugger "live"


    // Init the variables - thanks Glenn :)
    pidLastError  = 0;
    pidIntegral   = 0;

    while( true )
        {
        // Is PID control active ?
        if( pidRunning )
            {
            // Read the sensor value and scale
            //pidSensorCurrentValue = -SensorValue PID_SENSOR_INDEX ];

						// Determine desired sensor value
            pidSetSensorValue = pidRequestedVelocity;

            // calculate error (0.006 units/ms)
            pidError = pidSetSensorValue - pidSensorCurrentValue;

            // integral - if Ki is not 0

            // calculate the derivative
            pidDerivative = pidError - pidLastError;

           // integral - if Ki is not 0
            if( pid_Ki != 0 )
                {
                // If we are inside controlable window then integrate the error
                //if( pidError < PID_INTEGRAL_LIMIT )
                    pidIntegral = pidIntegral + pidError;
                    if(pidIntegral > 800){
                    	pidIntegral = 800;
                    }
                //else
                  //  pidIntegral = 0;
                }
            else{
                pidIntegral = 0;
              }

						 pidLastError  = pidError;

            // calculate drive
            pidDrive = (pid_Kp * pidError) + (pid_Ki * pidIntegral) + (pid_Kd * pidDerivative);
					writeDebugStreamLine("PID: %d | %d | %d | %d", pidError,pidIntegral,pidDerivative, pidDrive);
            // limit drive
            if( pidDrive > PID_DRIVE_MAX )
                pidDrive = PID_DRIVE_MAX;
            if( pidDrive < PID_DRIVE_MIN )
                pidDrive = PID_DRIVE_MIN;

            // send to motor
            //motor PID_MOTOR_INDEX ] = pidDrive * PID_MOTOR_SCALE;
                setShooterSpeed(pidDrive);
            }
        else
            {
            // clear all
            pidError      = 0;
            pidLastError  = 0;
            pidIntegral   = 0;
            pidDerivative = 0;
            setShooterSpeed(0);
            }
        wait1Msec( UPDATE_INTERVAL );
        }
}



task intake(){
	while(true){
		if(enableIntake){
			if(vexRT[Btn5U]){
				setIntakeSpeed(INTAKE_SPEED);
			}
			else{
				if(vexRT[Btn5D]){
					setIntakeSpeed(INTAKE_SPEED_REVERSE);
				}
				else{
					setIntakeSpeed(0);
				}
			}
		}
	}
		wait1Msec(UPDATE_INTERVAL);
}

Code Part 2

task drive(){
	//Holonomic
while(true){
			motor[driveFL] =  vexRT[Ch3]+vexRT[Ch4]+vexRT[Ch1];
			motor[driveBL] =  vexRT[Ch3]-vexRT[Ch4]+vexRT[Ch1];
			motor[driveBR] = -vexRT[Ch3]-vexRT[Ch4]+vexRT[Ch1];
			motor[driveFR] = -vexRT[Ch3]+vexRT[Ch4]+vexRT[Ch1];
			wait1Msec(UPDATE_INTERVAL);
		}
}



/////////////////////////////////////////////////////////////////////////////////////////
//
//                                 Autonomous Task
//
// This task is used to control your robot during the autonomous phase of a VEX Competition.
// You must modify the code to add your own robot specific commands here.
//
/////////////////////////////////////////////////////////////////////////////////////////

task autonomous()
{

	startTask(pidController);

	pidRequestedVelocity= SHOOTER_RPM;		//Increase to increase distance. Decrease to decrease distance
	pidRunning = true;
	while(true){													//>>>>>>>>>>>>>>>>>>>>>CHANGED FROM while(true)
	setIntakeSpeed(INTAKE_SPEED);
		wait1Msec( UPDATE_INTERVAL );
	}
}

task usercontrol()
{
		wait1Msec(100);
		clearDebugStream();
		startTask(UARTReceive);
		startTask(pidController);
		//pidRequestedVelocity= SHOOTER_RPM;
//	pidRunning = true;
		startTask(drive);
		startTask(intake);

		startTask(ControllerInput);
		while(true){
			//setIntakeSpeed(INTAKE_SPEED);
			wait1Msec(10);
		}
}



task UARTReceive()
{
	configureSerialPort(uartOne, uartUserControl);		// Configure serial port
 	 setBaudRate(uartOne, baudRate115200);						// Start serial port
 while (true)
 {
 // Loop forever getting characters from the "receive" UART. Validate that they arrive in the expected
 // sequence.
 rcvChar = getChar(uartOne);								// Read Character
 if (rcvChar == -1)
 {
 // No character available

 wait1Msec(3); // Don't want to consume too much CPU time. Waiting eliminates CPU consumption for this task.
 continue;
 }
 else{

   if (rcvChar == ';'){
     string temp;
     stringFromChars(temp, buffer);
     pidSensorCurrentValue = atoi(temp) * INVERT_SHOOTER_RPM;											// Parse string to int
     writeDebugStreamLine("Data: %d", pidSensorCurrentValue);
     bufferIndex = 0;												// Reset Index
     memset(buffer, 0, sizeof(buffer)); 		// Empty Array
   }
   else{
     buffer[bufferIndex] = rcvChar;
     bufferIndex++;
   }
 }
 }
}

A couple of our teams were experiencing random loss of communication because the key (and cortex) were buried deep within the metal structure of the robot. A USB extender cable (a-male to a-female) to move the key out of the innards of the robot did the trick.

The cortex is 3" away from metal on 4 of the six sides. However, the problems still remain with a functional tether, which should maintain a connection to the robot despite interference