Arduino从Java读取信号并显示/使用
我最近一直在研究java和arduino之间的通信,因为我有一个项目需要它,所以我读了很多关于它的书,并开始在这方面取得一些进展,比如从java发送字符串,在arduino中读取,然后使用它,然后再次向java发送输出,无论如何,在那之后,我必须在java中设置一个滑块,以便在移动arduino时将0到1023之间的值发送到arduino,但问题开始出现在这里,我创建了滑块(使用JSlider)并使用stateChanged方法将值发送到arduino,然后arduino应该读取数据并向java报告,我已经将MinorTickSpacing设置为100,因此每当您单击滑块时,它都会从0变为100,因此arduino会正确读取数据(它读取数据3次,我不知道为什么),直到达到300。这是我在java中看到的输出(使用serialEvent和BufferReader读取arduino的输出): 我在滑块上点击了5次,所以它应该是100、200、300、400和500,但我看到了这些奇怪的数字,我不知道为什么。 这是我的Java(使用RXTX库和EclipseIDE)和Arduino程序 Java程序:Arduino从Java读取信号并显示/使用,java,arduino,rxtx,Java,Arduino,Rxtx,我最近一直在研究java和arduino之间的通信,因为我有一个项目需要它,所以我读了很多关于它的书,并开始在这方面取得一些进展,比如从java发送字符串,在arduino中读取,然后使用它,然后再次向java发送输出,无论如何,在那之后,我必须在java中设置一个滑块,以便在移动arduino时将0到1023之间的值发送到arduino,但问题开始出现在这里,我创建了滑块(使用JSlider)并使用stateChanged方法将值发送到arduino,然后arduino应该读取数据并向java
import java.io.BufferedReader; //BufferedReader makes reading operation efficient
import java.io.IOException;
import java.io.InputStreamReader; //InputStreamReader decodes a stream of bytes into a character set
import java.io.OutputStream; //writes stream of bytes into serial port
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent; //deals with possible events in serial port (eg: data received)
import gnu.io.SerialPortEventListener; //listens to the a possible event on serial port and notifies when it does
import java.util.Enumeration;
import gnu.io.PortInUseException; //all the exceptions.Never mind them for now
import gnu.io.UnsupportedCommOperationException;
import java.util.Scanner; //to get user input of name
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
public class TestingGUI implements SerialPortEventListener,ActionListener, ChangeListener {
private SerialPort serialPort ; //defining serial port object
private CommPortIdentifier portId = null; //my COM port
private static final int TIME_OUT = 2000; //time in milliseconds
private static final int BAUD_RATE = 9600; //baud rate to 9600bps
private BufferedReader input; //declaring my input buffer
private OutputStream output; //declaring output stream
private String name; //user input name string
public static String status;
JFrame frame;
JPanel panel;
JLabel label,label1;
JSlider slide;
JProgressBar progress;
JButton onButton,offButton,blinkButton;
Scanner inputName; //user input name
public TestingGUI()
{
frame = new JFrame();
frame.setSize(700, 150);
frame.setTitle("Arduino Test");
panel = new JPanel();
frame.add(panel);
slide = new JSlider();
slide.setMinimum(0);
slide.setMajorTickSpacing(5);
slide.setMaximum(1023);
slide.setMinorTickSpacing(100);
slide.setPaintLabels(true);
slide.setPaintTicks(true);
slide.setSnapToTicks(true);
slide.setToolTipText("Move the slider to desired location.");
slide.setValue(0);
slide.setValueIsAdjusting(true);
slide.addChangeListener(this);
panel.setLayout(null);
slide.setBounds(10,10, 650, 50);
panel.add(slide);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//method initialize
private void initialize()
{
CommPortIdentifier ports = null; //to browse through each port identified
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers(); //store all available ports
while(portEnum.hasMoreElements()) //browse through available ports
{
ports = (CommPortIdentifier)portEnum.nextElement();
//following line checks whether there is the port i am looking for and whether it is serial
if(ports.getPortType() == CommPortIdentifier.PORT_SERIAL&&ports.getName().equals("COM3"))
{
System.out.println("COM port found:COM3");
portId = ports; //initialize my port
break;
}
}
//if serial port am looking for is not found
if(portId==null)
{
System.out.println("COM port not found");
System.exit(1);
}
}
//end of initialize method
//connect method
private void portConnect()
{
//connect to port
try
{
serialPort = (SerialPort)portId.open(this.getClass().getName(),TIME_OUT); //down cast the comm port to serial port
//time to wait
System.out.println("Port open succesful: COM3");
//set serial port parameters
serialPort.setSerialPortParams(BAUD_RATE,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
}
catch(PortInUseException e){
System.out.println("Port already in use");
System.exit(1);
}
catch(NullPointerException e2){
System.out.println("COM port maybe disconnected");
}
catch(UnsupportedCommOperationException e3){
System.out.println(e3.toString());
}
//input and output channels
try
{
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
//adding listeners to input and output streams
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnOutputEmpty(true);
//defining reader and output stream
}
catch(Exception e){
System.out.println(e.toString());
}
}
//end of portConncet method
@Override
public void stateChanged(ChangeEvent e)
{
if(e.getSource() == slide)
{
try {
int out = slide.getValue();
output.write(out);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@Override
public void actionPerformed(ActionEvent event) {
}
//readWrite method
@Override
public void serialEvent(SerialPortEvent evt)
{
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) //if data available on serial port
{
try {
if(input.ready())
{
int testInt = input.read();
System.out.println(testInt);
}
} catch (Exception e)
{
System.err.println(e.toString());
}
}
}
//end of serialEvent method
//main method
public static void main(String[] args)
{
TestingGUI myTest = new TestingGUI(); //creates an object of the class
myTest.initialize();
myTest.portConnect();
}//end of main method
}// end of SerialTest
void setup() {
Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop() {
while(Serial.available() == 0)
{
}
int test2 = Serial.read();
Serial.write(test2);
}
和Arduino计划:
import java.io.BufferedReader; //BufferedReader makes reading operation efficient
import java.io.IOException;
import java.io.InputStreamReader; //InputStreamReader decodes a stream of bytes into a character set
import java.io.OutputStream; //writes stream of bytes into serial port
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent; //deals with possible events in serial port (eg: data received)
import gnu.io.SerialPortEventListener; //listens to the a possible event on serial port and notifies when it does
import java.util.Enumeration;
import gnu.io.PortInUseException; //all the exceptions.Never mind them for now
import gnu.io.UnsupportedCommOperationException;
import java.util.Scanner; //to get user input of name
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
public class TestingGUI implements SerialPortEventListener,ActionListener, ChangeListener {
private SerialPort serialPort ; //defining serial port object
private CommPortIdentifier portId = null; //my COM port
private static final int TIME_OUT = 2000; //time in milliseconds
private static final int BAUD_RATE = 9600; //baud rate to 9600bps
private BufferedReader input; //declaring my input buffer
private OutputStream output; //declaring output stream
private String name; //user input name string
public static String status;
JFrame frame;
JPanel panel;
JLabel label,label1;
JSlider slide;
JProgressBar progress;
JButton onButton,offButton,blinkButton;
Scanner inputName; //user input name
public TestingGUI()
{
frame = new JFrame();
frame.setSize(700, 150);
frame.setTitle("Arduino Test");
panel = new JPanel();
frame.add(panel);
slide = new JSlider();
slide.setMinimum(0);
slide.setMajorTickSpacing(5);
slide.setMaximum(1023);
slide.setMinorTickSpacing(100);
slide.setPaintLabels(true);
slide.setPaintTicks(true);
slide.setSnapToTicks(true);
slide.setToolTipText("Move the slider to desired location.");
slide.setValue(0);
slide.setValueIsAdjusting(true);
slide.addChangeListener(this);
panel.setLayout(null);
slide.setBounds(10,10, 650, 50);
panel.add(slide);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//method initialize
private void initialize()
{
CommPortIdentifier ports = null; //to browse through each port identified
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers(); //store all available ports
while(portEnum.hasMoreElements()) //browse through available ports
{
ports = (CommPortIdentifier)portEnum.nextElement();
//following line checks whether there is the port i am looking for and whether it is serial
if(ports.getPortType() == CommPortIdentifier.PORT_SERIAL&&ports.getName().equals("COM3"))
{
System.out.println("COM port found:COM3");
portId = ports; //initialize my port
break;
}
}
//if serial port am looking for is not found
if(portId==null)
{
System.out.println("COM port not found");
System.exit(1);
}
}
//end of initialize method
//connect method
private void portConnect()
{
//connect to port
try
{
serialPort = (SerialPort)portId.open(this.getClass().getName(),TIME_OUT); //down cast the comm port to serial port
//time to wait
System.out.println("Port open succesful: COM3");
//set serial port parameters
serialPort.setSerialPortParams(BAUD_RATE,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
}
catch(PortInUseException e){
System.out.println("Port already in use");
System.exit(1);
}
catch(NullPointerException e2){
System.out.println("COM port maybe disconnected");
}
catch(UnsupportedCommOperationException e3){
System.out.println(e3.toString());
}
//input and output channels
try
{
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
output = serialPort.getOutputStream();
//adding listeners to input and output streams
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnOutputEmpty(true);
//defining reader and output stream
}
catch(Exception e){
System.out.println(e.toString());
}
}
//end of portConncet method
@Override
public void stateChanged(ChangeEvent e)
{
if(e.getSource() == slide)
{
try {
int out = slide.getValue();
output.write(out);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@Override
public void actionPerformed(ActionEvent event) {
}
//readWrite method
@Override
public void serialEvent(SerialPortEvent evt)
{
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) //if data available on serial port
{
try {
if(input.ready())
{
int testInt = input.read();
System.out.println(testInt);
}
} catch (Exception e)
{
System.err.println(e.toString());
}
}
}
//end of serialEvent method
//main method
public static void main(String[] args)
{
TestingGUI myTest = new TestingGUI(); //creates an object of the class
myTest.initialize();
myTest.portConnect();
}//end of main method
}// end of SerialTest
void setup() {
Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop() {
while(Serial.available() == 0)
{
}
int test2 = Serial.read();
Serial.write(test2);
}
我应该怎么做才能得到正确的数字并超过arduino显示的限制?(显然,只有0到255之间的数字才能正确读取)根据Arduino
Serial.read()
文档:调用它返回:
输入的可用串行数据的第一个字节(如果没有可用数据,则为-1)-int
根据定义,一个字节可以有一个介于0和225之间的值,这就是这些值正常工作的原因
当您发送值300时,您会遇到一种称为“算术溢出”的情况—假设您从0计数到300,但在255时,您再次从0开始,然后达到44。500美元也是如此
我不知道你为什么400分得到65533,应该是144(400256)。如果我发现了,我会更新答案
总结-您不应该发送或期望值超出0-255范围。如果您想发送更大的数字,请将其分成字节,然后在通信通道的另一端重新组装 根据Arduino
Serial.Read()
文档:调用它返回:
输入的可用串行数据的第一个字节(如果没有可用数据,则为-1)-int
根据定义,一个字节可以有一个介于0和225之间的值,这就是这些值正常工作的原因
当您发送值300时,您会遇到一种称为“算术溢出”的情况—假设您从0计数到300,但在255时,您再次从0开始,然后达到44。500美元也是如此
我不知道你为什么400分得到65533,应该是144(400256)。如果我发现了,我会更新答案
总结-您不应该发送或期望值超出0-255范围。如果您想发送更大的数字,请将其分成字节,然后在通信通道的另一端重新组装 感谢您的输入,这真的解释了很多,因为我真的很困惑那里发生了什么,但有没有其他方法来正确发送数据,而不必做分割的事情?发送4个字节(一个整数)而不是1个字节?另外,你能解释一下为什么每次有输入时Arduino都会读取数据3次吗?我使用while(Serial.available()==0)来停止这个操作,但似乎没有任何帮助:/I我不知道如何通过串口发送整个整数,但这不是一个bug,这是一个特性。更明智的做法是使用运算符
%
和>
将整数分解为四个字节,然后使用运算符*
和将其重新组装到另一侧。至于多个读数,Arduino一侧的代码不是原因。我怀疑你捕获的事件比你预期的要多。尝试添加System.out.println(“幻灯片事件”)代码>行后int out=slide.getValue()代码>,然后我们就可以确定了。很抱歉,我不在电脑前的回复太晚了,直到现在才回到项目中,关于打破整数,我从来没有这样做过,我将阅读相关内容并完成它,谢谢。对于多次阅读,我按照你说的做了,这是我在5次点击后的输出:这让我发疯了/尝试记住最后一个值作为私有字段,并调用output.write(out)
仅当out
与记忆值不同时。感谢您的输入,这真的解释了很多,因为我真的很困惑那里发生了什么,但是有没有其他方法可以正确发送数据而不必进行分割?发送4个字节(一个整数)而不是1个字节?另外,你能解释一下为什么每次有输入时Arduino都会读取数据3次吗?我使用while(Serial.available()==0)来停止这个操作,但似乎没有任何帮助:/I我不知道如何通过串口发送整个整数,但这不是一个bug,这是一个特性。更明智的做法是使用运算符%
和>
将整数分解为四个字节,然后使用运算符*
和将其重新组装到另一侧。至于多个读数,Arduino一侧的代码不是原因。我怀疑你捕获的事件比你预期的要多。尝试添加System.out.println(“幻灯片事件”)代码>行后int out=slide.getValue()代码>,然后我们就可以确定了。很抱歉,我不在电脑前的回复太晚了,直到现在才回到项目中,关于打破整数,我从来没有这样做过,我将阅读相关内容并完成它,谢谢。对于多次阅读,我按照你说的做了,这是我在5次点击后的输出:这让我发疯了/尝试记住最后一个值作为私有字段,并调用output.write(out)代码>仅当out
与记忆值不同时。