Multiple Ultrasonic Sensors

We are trying to have 2 Ultrasonic sensors on our robot. We got one to work, but when we added a second one, the first one stopped working. We switched the sensors around so we know it is not a damaged sensor or a broken wire. They are both set to automatic mode, and they take a reading, and then round in to the hundredth, and then put it on the smart dashboard. It shows up like this.

When we took the second sensor out of the code to see if it was the sensor, the first one worked just fine. Why can’t we have 2 ultrasonics going at once?

How are they connected? DIOs?
If the’re on I2C or SPI or another bus, it may be that they have the same bus address. The sensors I’ve looked into in the past on these busses had jumpers to change the address.

With ultrasonic sensors you also have to be careful to avoid “crosstalking” on the ultrasound waves. If you have both sensors triggering simultaneously, the ultrasonic waves from one can be read by the other. This messes up the carefully tuned timing between the sensor sending and receiving its signal, which messes up the distance output.

Since (as I understand it) your code is supposed to return a two-digit decimal and is actually returning a full-length decimal, your problem is probably somewhere in your code. Posting that here may help locate the problem.

That is what automatic mode does. It avoids cross talking.

1 Like

Which sensor are you using? Does the sensor support an array?

Here’s the data sheet for a Maxbotix sensor that supports an array,when wired properly.

Here is most of our code that we have. We are looking into doing an array or something, but that will take some time and research.

 /*----------------------------------------------------------------------------*/
    /* Copyright (c) 2017-2018 FIRST. All Rights Reserved.                        */
    /* Open Source Software - may be modified and shared by FRC teams. The code   */
    /* must be accompanied by the FIRST BSD license file in the root directory of */
    /* the project.                                                               */
    /*----------------------------------------------------------------------------*/
    /*

    package frc.robot;

    import edu.wpi.cscore.UsbCamera;
    import edu.wpi.first.cameraserver.CameraServer;
    import edu.wpi.first.vision.VisionPipeline;
    import edu.wpi.first.vision.VisionThread;
    //import edu.wpi.first.wpilibj.AnalogInput;
    import edu.wpi.first.wpilibj.Compressor;
    import edu.wpi.first.wpilibj.DigitalGlitchFilter;
    import edu.wpi.first.wpilibj.DigitalInput;
    import edu.wpi.first.wpilibj.DriverStation;
    import edu.wpi.first.wpilibj.IterativeRobot;
    import edu.wpi.first.wpilibj.Joystick;
    import edu.wpi.first.wpilibj.RobotDrive;
    import edu.wpi.first.wpilibj.Solenoid;
    import edu.wpi.first.wpilibj.Spark;
    import edu.wpi.first.wpilibj.Timer;
    import edu.wpi.first.wpilibj.Ultrasonic;
    import edu.wpi.first.wpilibj.buttons.Button;
    import edu.wpi.first.wpilibj.drive.MecanumDrive;
    import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
    import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;



    //import edu.wpi.first.wpilibj.CameraServer;


    import org.opencv.core.Mat;
    import org.opencv.imgproc.Imgproc;

    import edu.wpi.cscore.CvSink;
    import edu.wpi.cscore.CvSource;
    import edu.wpi.cscore.UsbCamera;

    /**
     * The VM is configured to automatically run this class, and to call the
     * functions corresponding to each mode, as described in the IterativeRobot
     * documentation. If you change the name of this class or the package after
     * creating this project, you must also update the build.gradle file in the
     * project.
     */
    public class Robot extends IterativeRobot 
      {
      
       

        
        DigitalInput limitSwitch1= new DigitalInput(9);
        boolean SwitchLim = limitSwitch1.get();
       
        

        private static final double kValueToInches = 0.125;
        // private final AnalogInput m_ultrasonic = new AnalogInput(1);


        Ultrasonic ultra = new Ultrasonic(0,1);

        Ultrasonic ultra2 = new Ultrasonic(3,4); 
        //double rangeDistance = ultra.getRangeInches();
        


        Joystick Xbox0 = new Joystick(0);
        Joystick Xbox1 = new Joystick(1);
        
        Spark frontLeft = new Spark(0);
        Spark backLeft = new Spark(1);
        Spark frontRight = new Spark(2);
        Spark backRight = new Spark(3); 
        Spark TBD1 = new Spark(4);
        Spark TBD2 = new Spark(5);
        Spark extra = new Spark(6);

        Compressor noomatic = new Compressor(0);
    	  Solenoid ClawOpen = new Solenoid(0);
        Solenoid ClawClosed = new Solenoid(1);
        
       



       // boolean Switch() {
       //   return limitSwitch1.get();
       // }
        
      
        private static final String kDefaultAuto = "Default";
      private static final String kCustomAuto = "My Auto";
      private String m_autoSelected;
      private final SendableChooser<String> m_chooser = new SendableChooser<>();

      double rangeDistance1 = 0.0;
      double rangeDistance1Rounded = 0.0;
      double rangeDistance2 = 0.0;
      double rangeDistance2Rounded = 0.0;
      double FrontLeftMotor = 0.0;
      double FrontRightMotor = 0.0;
      double BackLeftMotor = 0.0;
      double BackRightMotor = 0.0;
      
      boolean pressureSwitch = false;


      /**
       * This function is run when the robot is first started up and should be
       * used for any initialization code.
       */
      @Override
      public void robotInit() {
        m_chooser.setDefaultOption("Default Auto", kDefaultAuto);
        m_chooser.addOption("My Auto", kCustomAuto);
        SmartDashboard.putData("Auto choices", m_chooser);
        
        
         
          ultra.setAutomaticMode(true); // turns on automatic mode


        
        ultra2.setAutomaticMode(true);

      
        
       







        DriveTrain = new MecanumDrive(frontLeft, backLeft, frontRight, backRight);
        // Invert the left side motors.
        // You may need to change or remove this to match your robot.
     
        
      }

      /**
       * This function is called every robot packet, no matter the mode. Use
       * this for items like diagnostics that you want ran during disabled,
       * autonomous, teleoperated and test.
       *
       * <p>This runs after the mode specific periodic functions, but before
       * LiveWindow and SmartDashboard integrated updating.
       */
      @Override
      public void robotPeriodic() {
      }

      /**
       * This autonomous (along with the chooser code above) shows how to select
       * between different autonomous modes using the dashboard. The sendable
       * chooser code works with the Java SmartDashboard. If you prefer the
       * LabVIEW Dashboard, remove all of the chooser code and uncomment the
       * getString line to get the auto name from the text box below the Gyro
       *
       * <p>You can add additional auto modes by adding additional comparisons to
       * the switch structure below with additional strings. If using the
       * SendableChooser make sure to add them to the chooser code above as well.
       */
      @Override
      public void autonomousInit() {
        m_autoSelected = m_chooser.getSelected();
        // autoSelected = SmartDashboard.getString("Auto Selector",
        // defaultAuto);
        System.out.println("Auto selected: " + m_autoSelected);
      }

      /**
       * This function is called periodically during autonomous.
       */
      @Override
      public void autonomousPeriodic() {
        switch (m_autoSelected) {
          case kCustomAuto:
            // Put custom auto code here
            break;
          case kDefaultAuto:
          default:
            // Put default auto code here
            break;
        }
      }

      /**
       * This function is called periodically during operator control.
       */
      @Override
      public void teleopPeriodic() {
        //double forward = Xbox0.getRawAxis(1);
        //frontLeft.set(forward);
     

     
      

        FrontLeftMotor = frontLeft.get();
        FrontRightMotor = frontRight.get();
        BackLeftMotor = backLeft.get();
        BackRightMotor = backRight.get();


        
        //double rangeDistance = ultra.getRangeInches();
        
      
        rangeDistance1 = ultra.getRangeInches();
        rangeDistance1Rounded = Math.round(rangeDistance1*100)/100.0;


        rangeDistance2 = ultra2.getRangeInches();
        rangeDistance2Rounded = Math.round(rangeDistance2*100)/100.0;


       


         if (limitSwitch1.get() == false)
         {
           TBD2.set(0);
         } else if (limitSwitch1.get() == true) {
           TBD2.set(.5);
         }
        
         
         
         SmartDashboard.putNumber("Ultrasonic1", rangeDistance1Rounded);
         SmartDashboard.putNumber("Ultrasonic2", rangeDistance2Rounded);

        
       
       

        pressureSwitch = noomatic.getPressureSwitchValue();
       
        
        if (Xbox0.getRawAxis(1) <= .25)
            {
              frontLeft.set(0);
              frontRight.set(0);
              backLeft.set(0);
              backRight.set(0);
            }
        if (Xbox0.getRawAxis(1) >= -.25)
          {
             frontLeft.set(0);
              frontRight.set(0);
              backLeft.set(0);
              backRight.set(0);
          }
          if (Xbox0.getRawAxis(0) <= .25)
            {
              frontLeft.set(0);
              frontRight.set(0);
              backLeft.set(0);
              backRight.set(0);
            }
         if (Xbox0.getRawAxis(0) >= -.25)
          {
             frontLeft.set(0);
              frontRight.set(0);
              backLeft.set(0);
              backRight.set(0);
          }
          if (Xbox0.getRawAxis(4) <= .25)
            {
              frontLeft.set(0);
              frontRight.set(0);
              backLeft.set(0);
              backRight.set(0);
            }
         if (Xbox0.getRawAxis(4) >= -.25)
          {
             frontLeft.set(0);
              frontRight.set(0);
              backLeft.set(0);
              backRight.set(0);
          }

          
          if (pressureSwitch = true)
          {
            noomatic.setClosedLoopControl(true);
          }
          else
          {
            noomatic.setClosedLoopControl(false);
          }

          /*if (rangeDistance2Rounded >= 12){
            do{
              frontLeft.set(-.35);
                backRight.set(.35);
                frontRight.set(-.35);
                backLeft.set(.35);
            }
            while (Xbox0.getRawButton(1) == true);
          }
          else if (rangeDistance2Rounded <= 12){
            do{
              frontLeft.set(0);
                backRight.set(0);
                frontRight.set(0);
                backLeft.set(0);
            }
            while (Xbox0.getRawButton(1) == true);
          }*/
          
         /* do{
            
                frontLeft.set(-.35);
                backRight.set(.35);
                frontRight.set(-.35);
                backLeft.set(.35);
                  
                }
          while (Xbox0.getRawButton(1) == true && rangeDistance1Rounded >= 12 && rangeDistance2Rounded >= 12);
          */
            
        // Use the joystick X axis for lateral movement, Y axis for forward
        // movement, and Z axis for rotation.(ORDER IS X,Y,Z)
        DriveTrain.driveCartesian((Xbox0.getRawAxis(1)*-1), Xbox0.getRawAxis(4), 0);

        

        if ((Xbox0.getRawAxis(2) >= .25))
        {
          frontRight.set(Xbox0.getRawAxis(2));
          backRight.set(Xbox0.getRawAxis(2)*-1);
          frontLeft.set(Xbox0.getRawAxis(2)*-1);
          backLeft.set(Xbox0.getRawAxis(2));
        }
       
        if (Xbox0.getRawAxis(3) >= .25)
        {
          frontRight.set(Xbox0.getRawAxis(3)*-1);
          backRight.set(Xbox0.getRawAxis(3));
          frontLeft.set(Xbox0.getRawAxis(3));
          backLeft.set(Xbox0.getRawAxis(3)*-1);
        }


        if (Xbox1.getRawButton(1))
    		{
    			ClawOpen.set(true);
    		}
    		else
    		{
    			ClawOpen.set(false);
    		}
    		
    		if (Xbox1.getRawButton(2))
    		{
    			ClawClosed.set(true);
    		}
    		else
    		{
    			ClawClosed.set(false);
        }

        while (Xbox0.getRawButton(6) == true) {
          frontLeft.set((FrontLeftMotor)*.5);
          frontRight.set((FrontRightMotor)*.5);
          backLeft.set((BackLeftMotor) * .5);
          backRight.set((BackRightMotor)*.5);
        }
       //
           

      }
     
      /**
       * This function is called periodically during test mode.
       */
      @Override
      public void testPeriodic() {
      }
    }