좋아요, 제 문제로 가능한 한 명확하게하려고 노력하겠습니다. 저속 라디오 링크를 통해 직렬 데이터를 전송하고 있습니다 (라스베리 파이의 UART 컨트롤러 및 가정용 라디오 사용). 요구 사항의 철자가 이고 범위가이고 속도가 그다지 중요하지 않은 매우 구체적인 프로젝트입니다. 프로그램 (Radio.java)이 두 개의 스레드를 실행 중입니다. 하나의 스레드 (수신기)는 TCP 소켓을 사용하여 다른 프로그램에서 원격 측정 데이터를 수신합니다 (실제로는 매우 고속입니다. 실제로는 100mbit입니다). 이 스레드는 다른 스레드 (송신기)가이 데이터에 도달 할 수 있도록 ArrayBlockingQueue (크기 = 1)의 TCP 소켓에서 수신 한 데이터를 지속적으로 저장합니다. 수신자 스레드가 데이터를받는 속도는 꽤 빠릅니다. 이제, 송신기 스레드가 데이터 을 전송하기를 원합니다. 완료되면 수신자 스레드로부터 최신 데이터를 다시 얻고 저속 무선 링크를 통해 다시 전송하기를 원합니다.다른 스레드의 데이터 전송, Java 및 RXTX 라이브러리와의 느린 직렬 링크
수신기 스레드에서 최신 데이터를 가져옵니다
전송 무선 링크합니다 (하여 SerialPort를 사용하여)
돈을 통해 데이터 ' 그래서 송신기 스레드에서 나는 다음과 같이 작업 할 데이터가 실제로 전송 될 때까지 아무 일도하지 마십시오.
반복.
이제 프로그램을 실행할 때 Receiver-thread에 관한 모든 것이 잘 작동합니다. 하지만 송신기 스레드 내부에서 "this.out.write (output.getBytes());" 몇 밀리 초 내에 OutputStream 내부에 모든 것을 넣은 다음 다시 똑같은 작업을 수행합니다. 데이터는 전송 될 가능성이 없습니다! 여기에 내가 (단지 "SerialWriter"-thread 사용) 예를 시도했습니다
: http://rxtx.qbang.org/wiki/index.php/Two_way_communcation_with_the_serial_port
그리고 모든 50baud에 잘 전달 근무 -text 긴 "Lirum Ipsum 제품"을 사용. 그래서 기본적으로, 내 프로그램에서 System.in.read> -1을 사용하는 것과 동일한 동작이 필요합니다. (차단하고있는 이유는 그것이 작동하는 이유입니다).
어떻게해야합니까?
2015년 1월 1일 편집 내가 문제를 발견했습니다
을 BEGIN! SRobertz가 나를 올바른 방향으로 인도합니다! 문제는 실제로 UART 버퍼에 쓰기 속도가 아닙니다. "TwoWayComm"-example과 내 자신의 코드를 실행하는 것의 차이점은 Raspberry Pi의 UART-RX-port에 연결된 GPS를 실행하고 있다는 것입니다. GPS에서 데이터를 읽으려면 "GPSD"- 소프트웨어 (JSON 형식의 데이터를 출력 함)를 사용하십시오. GPSD- 소프트웨어는 9600baud (특히이 GPS 장치 용)로 GPS에 연결하는 반면, 동일한 포트에서 (GPSD가 실행중인 열린 연결을 닫지 않고) 50 보오 전환합니다! 두 가지 다른 전송 속도로 UART를 열려고하면 모든 것을 엉망으로 만드는 것입니다.
- 열기 UART 9600 보드에
- 읽기 GPS 데이터
- UART에 50 보드에
- 전송 원격 측정 데이터를 UART
- 열기 UART를 닫습니다 : I 있도록 나는 코드를 다시 작성했습니다
- 닫기 UART
- 반복
이제 모든 것이 여기에 ...
2015년 1월 1일 편집 END
그래서 ... 마법처럼 작동하는 코드입니다 :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class RADIO {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier
.getPortIdentifier(portName);
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
int timeout = 2000;
CommPort commPort = portIdentifier.open(this.getClass().getName(),
timeout);
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(50, SerialPort.DATABITS_7,
SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);
// Open outputstream to write to the serial port
OutputStream out = serialPort.getOutputStream();
(new Thread(new Receiver(queue))).start();
(new Thread(new Transmitter(out, queue))).start();
} else {
System.err.println("Error: Not serial port.");
}
}
}
public static class Receiver implements Runnable {
OutputStream out;
protected ArrayBlockingQueue<String> queue = null;
public Receiver(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
public void run() {
// Open TCP-connection
try {
ServerSocket serverSocket = new ServerSocket(1002);
Socket clientSocket = serverSocket.accept(); // Wait for the client to start up
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
while ((inputLine = in.readLine()) != null) {
queue.clear();
queue.put(inputLine);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static class Transmitter implements Runnable {
OutputStream out;
protected ArrayBlockingQueue<String> queue = null;
String output = "";
public Transmitter(OutputStream out, ArrayBlockingQueue<String> queue) {
this.out = out;
this.queue = queue;
}
public void run() {
try {
while (true) {
output = queue.take();
this.out.write(output.getBytes());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
(new RADIO()).connect("/dev/ttyAMA0");
} catch (Exception e) {
e.printStackTrace();
}
}
}
아차, 내 모니터에 오타가 있었다 예, 지금 편집 됨. 죄송합니다. – drRobertz