I posted a link to a thread on StackOverFlow, the code is there.
I jsut added that i've tried other things like changing the input and output stream to work with buffer reader and printwriter
here is the main class which handle the input and output stream(each one of them is another class as a thread) as shown below :
import java.awt.RenderingHints.Key;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
/**
* This Class Supports 2 way communication via USB port
* @author Tamir
*
*/
public class SerialPortHandler {
private static final String TAG = "SerialPortHandler";
private static final String PortName = "/dev/ttyACM0"; //the mounted ttyPort for Arduino
private static SerialPortHandler mSerialPortHandler;
private boolean mIsBoundedToUsbPort;
private int mTimeout;
private SerialPort mSerialPort;
private SerialInputHandler mSerialInputHandler;
private SerialOutputHandler mSerialOutputHandler;
public static SerialPortHandler getInstance(){
if(mSerialPortHandler == null){
mSerialPortHandler = new SerialPortHandler();
}
return mSerialPortHandler;
}
private SerialPortHandler(){
connect();
}
/**
* Connect to Serial Port, Define streams
*/
private void connect(){
try{
//add the port manually, because version of RXTX gaps
System.setProperty("gnu.io.rxtx.SerialPorts", PortName);
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(PortName);
if(portIdentifier.isCurrentlyOwned()){
System.out.println("Error : Port is currently in use");
}
else{
CommPort commPort = portIdentifier.open(TAG,mTimeout);
if(commPort instanceof SerialPort){
mIsBoundedToUsbPort = true;
mSerialPort = (SerialPort)commPort;
mSerialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
mSerialInputHandler = new SerialInputHandler(mSerialPort.getInputStream());
mSerialOutputHandler = new SerialOutputHandler(mSerialPort.getOutputStream());
//start threads
mSerialInputHandler.startThread();
mSerialOutputHandler.startThread();
}
}
}catch(Exception eSerialPort){
System.out.println(eSerialPort.getMessage());
}
}
/**
* add message to queue in order to write it
* @param msg - msg to send
*/
public void writeMessage(String msg){
mSerialOutputHandler.addMessageToQueue(msg);
}
/**
* close connection to serial port
*/
public void disconnect(){
mSerialInputHandler.stopThread(); //stop input thread
mSerialOutputHandler.stopThread(); //stop output thread
mSerialPort.close(); //close serial port
}
here are the inputStream and outputStream classes:
/**
* This class holds the input streams and get data from it.
* it fire the data to Logic Control;
*
*/
class SerialInputHandler extends Thread{
private static final String TAG = "SerialInputHandler";
private InputStream mReader;
private boolean mIsOnline;
public SerialInputHandler(InputStream in){
mReader = in;
}
@Override
public void run() {
while(mIsOnline){
readFromInputStream();
}
}
/**
* Read Data from Input Stream
* It Fires the data
*/
private void readFromInputStream(){
byte[] buffer;
try{
while(mReader.available() > 0){
buffer = new byte[mReader.available()];
mReader.read(buffer);
String s = new String(buffer);
System.out.println(s);
// TODO - Launch event with the msg, add string builder t
//append the message from inputStream
}
}catch(IOException e){
System.out.println(TAG + " " + e.getMessage());
}
}
/**
* start current Thread
*/
public void startThread(){
mIsOnline = true;
start();
}
/**
* stop current thread
*/
public void stopThread(){
mIsOnline = false;
}
}//end of SerialInputHandler
Output stream:
/**
* this class handles the output stream via usb
*
*/
class SerialOutputHandler extends Thread{
private static final String TAG = "SerialOutputHandler";
private OutputStream mOutputStream;
private boolean mIsOnline;
private Queue<String> mMesseagesQueue;
public SerialOutputHandler(OutputStream out){
mOutputStream = out;
mMesseagesQueue = new LinkedList<String>();
mIsOnline = true;
}
@Override
public void run() {
while(mIsOnline){
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("sent to arduino");
mMesseagesQueue.add("Coonected to Arduino :D \n");
if(mMesseagesQueue.size() > 0){
writeMessage(mMesseagesQueue.poll());
}
}
}
//write message to serial port
private void writeMessage(String msg){
byte[] msgToSent = msg.getBytes();
try{
mOutputStream.write(msgToSent);
mOutputStream.flush();
}catch(IOException e){
System.out.println(TAG + " " + e.getMessage());
}
}
//add message to Queue
public void addMessageToQueue(String msg){
mMesseagesQueue.add(msg);
}
/**
* start current Thread
*/
public void startThread(){
mIsOnline = true;
start();
}
/**
* stop current thread
*/
public void stopThread(){
mIsOnline = false;
}
}
Here is the first code on Arduino code:
String data;
void setup(){
pinMode(ledPin,OUTPUT);
Serial.begin(9600);
while(!Serial); //wait for serial
}
void loop(){
while(Serial.available()){
char ch = Serial.read();
data += ch;
if(ch == '\n'){
Serial.print("Arduino Received");
Serial.print(data);
data = "";
}
}
That code does not send anything to the serial port except for what it read from the serial port. How does that "send updated sensors data (every 0.1s) "?
The goal is to send updated sensor data,
I have to test my code first with simple strings.
under run method in OutputStream Class I created a string "connected to Arduino :D" which is sent every 2 seconds
you can see the result in the picture I posted. its corrupted message.
I though it might be something with the encoding, so I changed it to buffer reader and printwriter instead, did not work.
I'm new to Arduino, Im trying to send and receive data both ways.
you can see the result in the picture I posted. its corrupted message.
The Serial Monitor application contains two text fields - one for input and one for output. The text in both fields can be copied and pasted. Wasting bandwidth posting pictures of text is not the way to win friends.
How are the two boards connected? Post a picture (this time, a picture is preferred) of the two boards, CLEARLY showing all connections.
I'm trying to understand how the data gets from the Arduino to the Serial Monitor application. You have a SerialPort instance that has an input stream and an output stream. It appears as though the input stream thread is reading some of the data that the Arduino sends, while the Serial Monitor application is reading some data from the same stream. It's no wonder what you see in the Serial Monitor application is not all the data that the Arduino sends.
small update, I managed to send and receive data both ways , however I had to set delay on both Arduino and raspberry , around 3 seconds.
I not longer use printwrite and bufferReader, it seems that it does not work well with proper strings, I had to set an indicator like '*' at the end, to distinguish each message.
sometime the data was complete, and sometimes it was missing a char or more.
is there a better way for exchanging strings between these devices?
BTW, I think the problem is USB 2.0, its half duplex which means the data is sent one way at the time.
if it would have been full duplex it could work.