商标查询天眼查杭州网站优化企业
1、配置
线路连接:pc通过网线连接USR-TCP232-410S,USR-TCP232-410S另一端使用RS232串口连接麦创可编程直流电源。
电源设置:波特率9600,SCPI协议,命令模式:CR+LF
USR-TCP232-410S设置
2、 程序
2.1、pom.xml
<!-- netty --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.86.Final</version></dependency>
2.2 、配置文件
tcp:client:host: 192.168.0.7port: 502timeout: 5000pool:maxTotal: 10maxIdle: 5minIdle: 2
2.3、配置类
package com.base.tcp;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;@Data
@Configuration
@ConfigurationProperties(prefix = "tcp.client")
public class TcpClientConfig {private String host;private int port;private Pool pool;private int timeout;// Getters and Setters@Datapublic static class Pool {private int maxTotal;private int maxIdle;private int minIdle;// Getters and Setters}
}
2.4、nettyclient
package com.base.tcp;import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.Promise;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;@Slf4j
@Component
public class NettyClient {private final TcpClientConfig config;private Channel channel;private EventLoopGroup workerGroup;private final ResponseHandler responseHandler = new ResponseHandler();public NettyClient(TcpClientConfig config) {this.config = config;}@PostConstructpublic void start() throws InterruptedException {workerGroup = new NioEventLoopGroup();try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(workerGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline pipeline = ch.pipeline();// 使用换行符作为消息分隔符ByteBuf delimiter = Unpooled.copiedBuffer("\n".getBytes());pipeline.addLast(new DelimiterBasedFrameDecoder(8192, delimiter));//pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));pipeline.addLast(new IdleStateHandler(0, 10, 0, TimeUnit.SECONDS));pipeline.addLast(responseHandler);}});ChannelFuture future = bootstrap.connect(config.getHost(), config.getPort()).sync();channel = future.channel();channel.closeFuture().addListener(f -> workerGroup.shutdownGracefully());} catch (InterruptedException e) {workerGroup.shutdownGracefully();throw e;}}public String sendSync(String command)throws TimeoutException, ExecutionException, InterruptedException {// 添加终止符String fullCommand = command.endsWith("\r\n") ? command : command +"\r\n";Promise<String> promise = workerGroup.next().newPromise();log.info("send command==> {}", fullCommand);responseHandler.setCurrentPromise(promise);channel.writeAndFlush(fullCommand).addListener(f -> {if (!f.isSuccess()) {promise.tryFailure(f.cause());}});return promise.get(5, TimeUnit.SECONDS);}public void sendSyncNoResponse(String command){// 添加终止符String fullCommand = command.endsWith("\r\n") ? command : command +"\r\n";log.info("send command==> {}", fullCommand);channel.writeAndFlush(fullCommand);}@ChannelHandler.Sharableprivate static class ResponseHandler extends ChannelInboundHandlerAdapter {private Promise<String> currentPromise;public void setCurrentPromise(Promise<String> promise) {this.currentPromise = promise;}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {log.info("receive msg ==> {}", msg);if (currentPromise != null) {String response = (String) msg;currentPromise.trySuccess(response.trim());currentPromise = null;}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {if (currentPromise != null) {currentPromise.tryFailure(cause);currentPromise = null;}ctx.close();}@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) {// 空闲时发送查询保持连接ctx.writeAndFlush("*IDN?\n");}}}
2.5、service
package com.web.task.service;import java.util.List;public interface LowerVoltageSourceService {List<Double> getVoltageAll();List<Double> getCurrentAll();void setVoltage(int channel, double voltage);void setCurrent(int channel, double current);void setVoltages(List<Double> voltageList);void setCurrents(List<Double> currentList);void setAllChannelOut(boolean open);void setChannelOut(int channel, boolean open);}
2.6、ServiceImpl
package com.web.task.service.impl;import com.base.tcp.NettyClient;import com.base.utils.TimeUtil;
import com.web.task.service.LowerVoltageSourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;@Slf4j
@Service
public class LowerVoltageSourceServiceImpl implements LowerVoltageSourceService {@Autowiredprivate NettyClient nettyClient;/*** 麦创SPI命令模式 CR+LF*/private List<Double> getFromDevice(String command){List<Double> resultList = new ArrayList<>();try{String response = nettyClient.sendSync(command);resultList = Arrays.stream(response.split(",")) // 分割字符串.map(String::trim) // 去除前后空格.map(Double::parseDouble) // 转换为Double.collect(Collectors.toList()); // 收集为List}catch (Exception e){log.info("LV has error =>{}", Arrays.toString(e.getStackTrace()));log.info("LV error message =>{}",e.getMessage());}return resultList;}private void exeCommand(String command){try{nettyClient.sendSyncNoResponse(command);}catch (Exception e){log.info("LV has error =>{}", Arrays.toString(e.getStackTrace()));log.info("LV error message =>{}",e.getMessage());}}/***此命令同时查询电源三通道的实际输出电压值*/@Overridepublic List<Double> getVoltageAll(){String command = "MEAS:VOLT:ALL?";return getFromDevice(command);}/***此命令同时查询电源三通道的实际输出电流值*/@Overridepublic List<Double> getCurrentAll() {String command = "MEAS:CURR:ALL?";return getFromDevice(command);}@Overridepublic void setVoltage(int channel, double voltage) {String command1 = "INST "+ channel;String command2 = "VOLT "+ voltage;exeCommand(command1);TimeUtil.delayMillisecond(30);exeCommand(command2);}@Overridepublic void setCurrent(int channel, double current) {String command1 = "INST "+ channel;String command2 = "CURR "+ current;exeCommand(command1);UnisicTimeUtil.delayMillisecond(30);exeCommand(command2);}@Overridepublic void setVoltages(List<Double> voltageList) {String voltages = voltageList.stream().map(String::valueOf) // 将Double转为String.collect(Collectors.joining(","));String command = "APP:VOLT "+ voltages;exeCommand(command);}@Overridepublic void setCurrents(List<Double> currentList) {String currents = currentList.stream().map(String::valueOf) // 将Double转为String.collect(Collectors.joining(","));String command = "APP:CURR "+ currents;exeCommand(command);}@Overridepublic void setAllChannelOut(boolean open) {// 全关String command = "APP:OUT 0,0,0,0,0";if(open){// 全开command = "APP:OUT 1,1,1,1,1";}exeCommand(command);}@Overridepublic void setChannelOut(int channel, boolean open) {String command1 = "INST "+ channel;String command2 = "OUTP 0";if(open){command2 = "OUTP 1";}exeCommand(command1);TimeUtil.delayMillisecond(30);exeCommand(command2);}
}
2.7、测试
package com.web.controller;import com.base.response.ResponseMessage;
import com.web.task.service.LowerVoltageSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Arrays;
import java.util.List;@RestController
@RequestMapping("/netty")
public class TestNettyController {@Autowiredprivate LowerVoltageSourceService lowerVoltageSourceService;@GetMapping("/getVoltage")public ResponseMessage<?> getVoltage() {return ResponseMessage.ok(lowerVoltageSourceService.getVoltageAll());}@GetMapping("/getCurrent")public ResponseMessage<?> getCurrent() {return ResponseMessage.ok(lowerVoltageSourceService.getCurrentAll());}@GetMapping("/setVoltage/{channel}/{votagel}")public void setVoltage(@PathVariable int channel, @PathVariable double votagel) {lowerVoltageSourceService.setVoltage(channel, votagel);}@GetMapping("/setCurrent/{channel}/{current}")public void setCurrent(@PathVariable int channel, @PathVariable double current) {lowerVoltageSourceService.setCurrent(channel, current);}@GetMapping("/setVoltages")public void setVoltages() {List<Double> Voltages = Arrays.asList(11.1d, 22.2d, 33.3d, 44.4, 50.0);lowerVoltageSourceService.setVoltages(Voltages);}@GetMapping("/setCurrents")public void setCurrent() {List<Double> currents = Arrays.asList(1.1, 2.2, 3.3, 4.4, 5.0);lowerVoltageSourceService.setCurrents(currents);}
}