Declaring Two Ultrasonic Sensors

16 public UltrasonicSensor() {
17 sensor1 = new Ultrasonic(2, 1);
18 sensor1.setAutomaticMode(true);
19 reading1 = 0;
20 inRange1 = false;
21
22 sensor2 = new Ultrasonic(5, 4);
23 sensor2.setAutomaticMode(true);
24 reading2 = 0;
25 inRange2 = false;
26 }

I’m getting an error on line 22 that says “Illegal Thread State Exception”. The second ultrasonic sensor is wired exactly the same as the first in the appropriate ports, and I checked the physical sensors as well. Should I be declaring the second sensor differently?

It looks like that is supposed to work, but you could try instantiating both of the Ultrasonic objects before setting automatic mode to true for either of them.

A bit more information about where this is and how and where it is used might be useful. I’m Also not sure what language you are using.
If this is Java, which it seems to be, you should specify that sensor1 and sensor2 are of the type Ultrasonic at the beginning of the line, giving something like the following:

Ultrasonic sensor1 = new Ultrasonic(2, 1);

In C++, you technically should do the same, but C++ allows that to be done before the constructor is called.

Also, in the example, the setAutomaticMode() call is made in the robotInit() method, but the constructor is called outside of it (possibly in the RobotTemplate constructor, I’m unsure of where that is supposed to be).
I don’t think that attempting to do both in robotInit() would cause the error that you are getting, but I’m not sure that it wouldn’t cause an issue with scope.

In the future, you might find it useful to create a new class for handling multiple ultrasonic sensors at once, or anything else similar to this. That would allow you to organize your status variables, constructors, and methods in a manner more in line with how they are organized in the Ultrasonic class. Your constructor would call the constructors for the two ultrasonic sensors, and the other actions you are trying to perform could be distributed between the constructor, and an initialization method. This change might be a bit radical at this point in the season, that is for you to decide.

*Full disclosure: I’m more familiar with hardware than software, and my familiarity with WPIlib is minimal. While everything I have stated is, to my knowledge, reasonably accurate, I do not claim it to be perfect.

I think cramming all the ultrasonics together would not be efficient. The Java Ultrasonic class from WPILib already manages all of the U’s together in a separate thread.
I haven’t looked any closer, but I suspect getting all the U’s constructed before configuring with them might be good. There may yet be a bug in Ultrasonic.

This appears to be a bug in the Ultrasonic class. The solution for now is to call setautomaticmode on sensor2 only. It will actually enable automatic mode for both sensors.

If it’s Java, I’m assuming that sensor1 and sensor2 are class variables, and are already typed outside of the constructor?

The Ultrasonics are class variables declared within an UltrasonicSensor class I created and constructed within the UltrasonicSensor constructor, which is what that excerpt is. I’ll try seeing tomorrow if removing the setAutomaticMode() from before the second sensor fixes the problem.

Try not calling setAutomaticMode until you have created both of the sensors. The code will not handle adding a new sensor after automatic mode has been enabled.

Be sure you are using sensors that can be paired. For example, some MaxBotix sensors can be paired and others can’t.

This did work, problem solved. Thank you all.

Wish I’d seen this sooner. We struggled with this too back in February and made the same discovery. Kudos to our grade 10 software student for tracing through and finding the root cause.

On that note is there an official way to submit bug reports or feature suggestions?

You can open an issue on the GitHub repository