基于JSch通过树莓派(RPI)串口控制目标设备的自动化命令执行问题排查与解决
问题1:JSch执行串口命令时,后续命令跑在树莓派本地而非目标设备
我之前也碰到过类似的串口自动化问题,你的代码里犯了一个典型的shell命令执行逻辑错误——你把microcom和touch用换行放在同一个setCommand里,这相当于让树莓派的shell先启动microcom,等microcom退出之后才会执行touch命令。但microcom是交互式程序,启动后会接管终端,shell会一直等它关闭,所以touch根本没机会被发送到目标设备上。
解决这个问题的关键是:要把命令通过microcom的标准输入传递给目标设备,而不是让shell串行执行。修改后的代码应该只启动microcom,然后通过JSch的OutputStream直接往里面写命令:
logger.info("Connecting to RPI") JSch jsch = new JSch(); session = jsch.getSession(USER, HOST); session.setPassword(PASSWD); session.setConfig("StrictHostKeyChecking", "no"); session.connect(60 * 1000); try { ChannelExec channel = session.openChannel("exec"); channel.setErrStream(System.out, true); // 仅启动microcom进程,接管串口连接 channel.setCommand("nice microcom -s 115200 -p /dev/ttyUSB3"); OutputStream out = channel.getOutputStream(); channel.connect(); // 将命令通过microcom的标准输入发送到目标设备 out.write(("touch mytestfile.txt\n").getBytes()); out.flush(); // 若需要退出目标设备的串口会话,可发送exit命令 // out.write(("exit\n").getBytes()); // out.flush(); } finally { session.disconnect(); }
问题2:无回显+本地行编辑的设备不响应JSch发送的命令
这个问题我也踩过坑!这类串口设备对命令结束符的要求特别严格,很多设备只认回车符(\r),而不是我们常用的换行符(\n)。你手动操作时按回车,实际上发送的是\r,而代码里用的是\n,设备根本没识别到这是命令结束的信号,自然不会执行。
把代码里的换行符换成回车符就搞定了,最终的工作代码如下:
ChannelExec channel = session.openChannel("exec"); channel.setErrStream(System.out, true); channel.setCommand("nice microcom -s 9600 -p /dev/ttyUSB0"); OutputStream out = channel.getOutputStream(); channel.connect(); // 用\r作为命令结束符,匹配设备的输入要求 out.write(("SOUT001\r").getBytes()); out.flush(); out.write(("SOUT000\r").getBytes()); out.flush();
内容的提问来源于stack exchange,提问作者shestar
相关产品推荐
相关产品推荐

