Java SerialPort kUsb

We’re attempting to use an arduino as a controller for neopixels on our robot. We figured we’d use the USB/Serial option to send our commands. So long story short, when we create a SerialPort using kUSB, we can call writeString() exactly once, and then the robot code crashes. We’ve verified that the command gets to the arduino properly too. The test project was a clean project created with the New Project -> Iterative Robot template. It contains no code at all except the declaration of the SerialPort, the object creation in robotInit, and a single call to writeString() wrapped in an if statement checking for the A button of an Xbox Controller.

The code runs happily until you tap the A button, at which point the Arduino gets that one command, does the right thing, then the robot code hangs for a few seconds, finally crashes, and restarts. The RoboRIO is just fine, as an SSH connection stayed up, just the java robot code died.

We don’t have internet access at the school and I dont have the driver station at home with me so I cant copy-pate the exception (Maybe I’ll try using my phone as a hotspot tomorrow?), but it eventually boils down to a VISA exception.

We attempted to switch to the onboard RS232, and while the arduino never received the command (Most likely because we had to cobble together a cable, and we werent sure if it needed to be a straight through, or cross-over) The robot code never crashed.

Has anyone seen anything like this? We could probably switch to the RS232 if we have no success, but we’re going to need power from the USB anyway, so we might as well not be wasteful. Besides, Not getting a serial connection to work? I’m taking that personally! :cool:

Edit::
Error Cap

ERROR Unhandled exception: java.lang.RuntimeException: Code: -1073807339. Unknown error status at [edu.wpi.first.wpilibj.hal.SerialPortJNI.serialWrite(Native Method), edu.wpi.first.wpilibj.SerialPort.write(SerialPort.java:356), edu.wpi.first.wpilibj.SerialPort.writeString(SerialPort.java:366), org.usfirst.frc.team871.robot.Robot.teleopPeriodic(Robot.java:55), edu.wpi.first.wpilibj.IterativeRobot.startCompetition(IterativeRobot.java:143), edu.wpi.first.wpilibj.RobotBase.main(RobotBase.java:241)]

Edit 2:

After several hours of experimentation (with a second roborio, loaded with a fresh image and JDK downloaded from the internets) we still have the same result. You get one successful writeString() (successful, meaning the arduino gets the command) followed by a few second halt, followed by a robot code crash and restart. I really hope someone else can reproduce this issue to get some more brains on the problem.

Took me a few seconds to find this

‘Bump’ posts, or anything similar, are not allowed and will be deleted without notice

Judging from that error, your connection between the arduino and rio is bad.

Also, an easy option to fix all of this is to use a series of dio ports and just using that set of data as preconfigured commands (e.g, 0010 - flash red quickly)

If this isn’t good enough, than as a temporary fix you can wrap the arduino write commands in a thread that just reads from a command queue.

Arduino Gets the command though. I’m going to try to use a different library, maybe JSSC, which I’ve had success with on some other projects in the past.

I’ve been too frustrated over the past two days to get out of the tunnel vision.

As far as the “few seconds” with the bump, I suppose I’m just stupid. I DID look for a rule before I did anything…

The error is telling us nothing which is why I am led to believe that the arduino either isn’t sending back success signals or the communication is failing between the time that your sending data and the time that the arduino confirms that it recieved the data.

The built in libraries are most likely the best you are going to get because they interact directly with the FPGA. It may be difficult to get a library that can interact with the RIO’s custom RSA ports correctly.

You could always do the silly thing and spawn a new thread for every command you wish to send. I’m not too familiar with the libraries provided but if there is some way to terminate the request than you simply send the command, wait 0.3 seconds, terminate the request (eating the error), than send another. (This is under the assumption that the arduino is having no problem processing and returning the data. This is also a very last case scenario! Playing with the FPGA like this is not a great idea).

Also, if you want further support, than I’d highly recommend posting code that can be troubleshooted. Theoretical guessing about your issue is to no avail for those who have not overcome the same issue that you are facing.

E/ SerialPort does indeed have a reset() command. I’m not sure of the volatility or damage of the command, though.

Well, a code snippet is easy (which is why i didn’t post one in the first place)
There isn’t any ack for this communication… Unless there’s something special I have to do with VISA? (I’ll look into that)

This is our test robot code, literally all of it ( removed some comments to not ake this post huge )


package org.usfirst.frc.team871.robot;

import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.SerialPort;
import edu.wpi.first.wpilibj.SerialPort.Port;

/**
 * Default comment
 */
public class Robot extends IterativeRobot {
	SerialPort thePort;
	Joystick joy;

	/**
	 * This function is run when the robot is first started up and should be
	 * used for any initialization code.
	 */
	public void robotInit() {
		thePort = new SerialPort(9600,Port.kUSB);
		joy = new Joystick(0);
	}

	/**
	 * This function is called periodically during operator control
	 */
	public void teleopPeriodic() {
		if(joy.getRawButton(1)) {
			//System.out.println("Red");
			thePort.writeString("!255R000G000B");  //Sends successfully, (Neopixels turn red) then crashes robot code
			thePort.readString();
		}

		if(joy.getRawButton(2)) {
			//System.out.println("Green");
			thePort.writeString("!000R255G000B"); //Sends successfully, (Neopixels turn Green) then crashes robot code
		}

		if(joy.getRawButton(3)) {
			//System.out.println("Blue");
			thePort.writeString("!000R000G255B"); //Sends successfully, (Neopixels turn Blue) then crashes robot code
		}
	}
	
	/**
	 * Default Comment
	 */
	public void autonomousInit() { }

	/**
	 * This function is called periodically during autonomous
	 */
	public void autonomousPeriodic() { }

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

}

I don’t have the laptop that’s got our arduino code on it, but it’s a simple bit of code that reads a string in from the serial, and parses out the 3 color components in the format !xxxRxxxGxxxB where ! is the start character, and the x’s are the digits of the components. It sends no response.

Most standard communcation will return a checksum with a data good/data bad signal after transmission (as I said, I haven’t used the serial port, but it is the easiest way to ensure data integrity, especially since RS232 is bidirectional)

Also, you should always post code when you have an issue regardless of how trivial or complex your issue is.

There are some options you should try, in order of when you should do them

  1. Initialize ALL variables of the serial port, not just baud rate
  2. Switch your buffer mode to flush on full than manually flush after every call with step by step debugs and try catch blocks
  3. Reflash your roboRIO
  4. Find a new arduino
  5. Refactor your flushing method to follow what I described earlier by queue threading the flush command

Serial communication is about as barebones as you can get, there’s no checksum or anything like that. Our little color protocol was intended to be very simple. I (the mentor) never touch code, it’s all my students, so I attempt to keep the tasks as simple as possible and build nicer features as their skills grow.

As for the constructor, According to the javadoc

Create an instance of a Serial Port class.

Defaults to 8 databits, no parity, and one stop bit.

Parameters
baudRate The baud rate to configure the serial port.

We did try all of the different flavors of constructor, in the off chance there’s a bug in one of them.

We tried everything else you’ve listed (with the exception of changing the default flush mode) before I made my first update to the original post, including different roborios and different ardionos.

I hesitate to complicate things with additional threads though. It’s not like we’re having trouble sending the second command, the robot code simply crashes after the first write.

I think something probably broke in the USB serial. I saw a few people talking about issues with the NavX in both LabVIEW and Java with USB serial, in code that worked in 2015. If you have an easy way to duplicate it, you should file a bug report.

1 Like

That’s a good idea actually; I’ll go do that, as soon as I can find the bug reporting page;

Edit:
Ok so Check this out; I signed up for collabnet, then decided to go ahead and pull the entire wpilib source tree. I started poking around tracing the SerialPort calls through their JNI wrappers and into the underlying C++ VISA calls, and found this:

The error I posted above maps to the VISA error, VI_ERROR_TMO (in visa.h)


#define VI_ERROR_TMO                (_VI_ERROR+0x3FFF0015L) /* BFFF0015, -1073807339 */

Doing a little poking around on the internet I found this (https://github.com/hgrecco/pyvisa/issues/157) Unrelated to FRC

Have you correctly set the read_termination character ? Visa looks for this character(s) at the end of the instrument answers. If it does not find it a timeout will occur as it will go on waiting for it.

So I went back and looked at the java class and it IS calling disableTermination() in the constructor. Tracing that down through the C++ it eventually calls viSetAttribute() with a bunch of params that look right (I’m not familiar with VISA yet)

I wonder if maybe the disableTermination method isn’t working properly for some reason. I’m still going to write up a bug, but I think I’ll also go create a branch of this source and start doing a little bit of creative debugging myself with a spare roboRio during the week. I’ll update this post if I find anything (or the bug gets acknowledged and fixed)

WPILIB says that termination is only implemented for receive, but the github bug i linked mentioned that the WRITE might still be expecting a
or \r. I’ll investigate that too.

I ran into something similar last year trying to pair an Arduinio up to our RoboRIO to use inexpensive sensors meant for Arduino. I never did figure it out but only spent an hour on it.

Reading this thread jogged some stuff loose. VISA is a serial protocol standard of sorts that I’ve dealt with a few times writing software for credit/debit card PIN pads. It’s kind of a shot in the dark but have the Arduino shoot back an ACK byte (0x06) after it receives its command. That might make the NI code on the RoboRIO happy.

Given that I’m not the only one confounded by the WPILib serial implementation I suspect they’re adding VISA rules in there but not documenting them well. It’d be nice if we had something like rxtx available but that does not appear to be easy.

It’s kind of a shot in the dark but have the Arduino shoot back an ACK byte (0x06) after it receives its command

Thanks for the suggestion, I’ll give it a shot. I’ve worked with GPIB and SCPI before, but never using a VISA device. The WPILib implementation seems straightforward enough, It’s practically a 1-1 wrapper around the VISA calls, hiding some of the option management stuff. I was planning on just trying \r and
, but now I’ll add 0x6 to that list. We’ll see what happens; It’s frustrating for me since I don’t have the thing handy with me where I could just hammer out a solution, I can only do it at the school, during our regular build meetings, and I don’t like to waste the kids’ time watching me try to debug stuff that should be “poof-magic” to them at this level.

Thanks again!

So sending an 0x6,
or \r didn’t change anything. The usbserial still seems to crash the robot code one way or the other. I guess the next step is to track down a plain-ol-jane USB-Serial adapter and remove the arduino from the loop, just in case. I’ll update again with more details.

On a secondary note, the MXP UART works just fine (which I suppose isn’t surprising). After a little BrainDead™ moment we realized that RS232 is NOT compatible with Arduino UART (WHOOPS) which explains why that didn’t work. I’m moderately surprised that we didn’t murder the Arduino. I guess we were getting a little desperate & careless.

Edit:
Google managed to find this

Which the forum search did not, somehow.

The post claims that the roboRio is documented to not be compatible with arduino, but I was unable to find said documentation. It also said the MXP port and DIO lines are 3.3v only, which scared me to death at first, but re-reading the RoboRio Manual All DIOs are 5V input compatible, so that’s fine. I’m in the process of submitting a bug report to WPI.

I feel like this thread should be stickied or something, I’ve seen a lot of people asking about serial ports and ardunios and such. It would probably be good so that people don’t have to repeatedly go though the pain we have to understand the issues here.