Cannot program two ultrasonic sensors. Please help us!

Hey everyone,

So my team followed the documentation WPI to code a single ultrasonic to the smartdashboard.

We did that with success, but now find ourselves with a problem.

We want two to show, but for some reason… The console throws an “Illegal exception” error every time we now push code. (Which means no robot code on the driverstation)

It appears that the “error” conflicts on the lines where our naming conventions are the same, but we clearly put “ultra1” and “ultra2” to be different variables.

Furthermore, we looked into another solution that said it may be the setAutomaticMode being used twice and causing the problem…

We removed that in our second sensor class, but that did not help either.

Any suggestions help! We need this issue fixed asap.

Here is the code:

package org.usfirst.frc253.Code2016.commands;

import com.ni.vision.NIVision.Image;
import edu.wpi.first.wpilibj.Ultrasonic;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
i

/**
 *
 */
public class Ultrasonic1 extends Command {
	
	Ultrasonic ultra1;
    int session;
    Image frame;
    AxisCamera camera;
    public Ultrasonic1() {
    	
    	ultra1 = new Ultrasonic(0,1);
    	ultra1.setAutomaticMode(true);
    	// turns on automatic mode
        // Use requires() here to declare subsystem dependencies
        // eg. requires(chassis);
    }

    // Called just before this Command runs the first time
    protected void initialize() {
    }

    // Called repeatedly when this Command is scheduled to run
    protected void execute() {
    	
     		//accelerationX = accel.getX();
     		//accelerationY = accel.getY();
     		//accelerationZ = accel.getZ();
     		 double range1 = ultra1.getRangeInches();
     		//String stringTEST = ultra.getSmartDashboardType();
     		
         //System.out.println(accelerationX + " " + accelerationY + " " + accelerationZ + ".");
 		//SmartDashboard.putNumber("Accelometer X", accel.getX());
 		//SmartDashboard.putNumber("Accelometer Y", accel.getY());
 		//SmartDashboard.putNumber("Accelometer Z", accel.getZ());
 		SmartDashboard.putNumber("Ultrasonic", range1);
 		  
    }

    // Make this return true when this Command no longer needs to run execute()
    protected boolean isFinished() {
        return false;
    }

    // Called once after isFinished returns true
    protected void end() {
    }

    // Called when another command which requires one or more of the same
    // subsystems is scheduled to run
    protected void interrupted() {
    }
}


Ultrasonic Sensor 2:

package org.usfirst.frc253.Code2016.commands;

import com.ni.vision.NIVision.Image;
import edu.wpi.first.wpilibj.Ultrasonic;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj.vision.AxisCamera;

/**
 *
 */
public class Ultrasonic2 extends Command {
	
	Ultrasonic ultra2;
    int session;
    Image frame;
    AxisCamera camera;
    public Ultrasonic2() {
    	
    	ultra2 = new Ultrasonic(2,3);

    	// turns on automatic mode
        // Use requires() here to declare subsystem dependencies
        // eg. requires(chassis);
    }

    // Called just before this Command runs the first time
    protected void initialize() {
    }

    // Called repeatedly when this Command is scheduled to run
    protected void execute() {
    	
     		//accelerationX = accel.getX();
     		//accelerationY = accel.getY();
     		//accelerationZ = accel.getZ();
     		 double range2 = ultra2.getRangeInches();
     		//String stringTEST = ultra.getSmartDashboardType();
     		
         //System.out.println(accelerationX + " " + accelerationY + " " + accelerationZ + ".");
 		//SmartDashboard.putNumber("Accelometer X", accel.getX());
 		//SmartDashboard.putNumber("Accelometer Y", accel.getY());
 		//SmartDashboard.putNumber("Accelometer Z", accel.getZ());
 		SmartDashboard.putNumber("Ultrasonic 2", range2);
 		  
    }

    // Make this return true when this Command no longer needs to run execute()
    protected boolean isFinished() {
        return false;
    }

    // Called once after isFinished returns true
    protected void end() {
    }

    // Called when another command which requires one or more of the same
    // subsystems is scheduled to run
    protected void interrupted() {
    }
}

Hi, I’m programming something similar for our team’s robot. For your code, I’m not sure if this was intentional or not, but in the Ultrasonic2 class default constructor, you don’t seem to turn on automatic mode? However, I don’t think that should be an issue.

Here are some possible ideas:

Automatic mode means that the sensor is continuously reading, correct? It’s possible that having two ultrasonic sensors would cause interference with each other, if that’s what’s causing the error. If this were the issue, you should try implementing them without automatic mode (getting them to ping only when prompted).

However, if you cannot find a solution to this specific code, might I suggest implementing your sensors as analog inputs? The Ultrasonic class is, after all, an extension of the AnalogInput class, and what our team has been doing is treating the sensors as basic analog inputs, taking the readings, and then multiplying the number by some constant to retrieve the data in inches.
In this case, the implementation would be nearly identical to that of encoders, in terms of reading data and putting it onto the dashboard.

I hope some of this helps.

The only difference other than the variable names and the arguments to the constructor that I see is the import of AxisCamera in the second case. I suggest commenting out the import and the camera and frame declarations from both classes, as you aren’t using them.

You’re creating new sensors every time you create new Ultra1 or Ultra 2 commands. That’s what’s causing the problem.

With WPILib, it’s assumed that your sensors don’t change during a match so whenever you create a new sensor, it will check if another sensor object has already used those channels. Your sensor variables should be in the appropriate subsystems. Look at the GearsBot example program in Eclipse to see how you should structure your code

1 Like