0

I am following a simple example found here (example one), to have an Arduino connected to a Raspberry Pi and read some data from the Arduino on the Pi in Java.

The issue is that the SerialEvent method is never called, which implies that no data is coming in. However, when I open the Serial Monitor I can see that data is being read correctly.

The correct serial port is being used as well.

Here is the Java code.

//This class:
// - Starts up the communication with the Arduino.
// - Reads the data coming in from the Arduino and
//   converts that data in to a useful form.
// - Closes communication with the Arduino.

//Code builds upon this great example:
//http://www.csc.kth.se/utbildning/kth/kurser/DH2400/interak06/SerialWork.java
//The addition being the conversion from incoming characters to numbers. 

//Load Libraries
import java.io.*;
import java.util.TooManyListenersException;

//Load RXTX Library
import gnu.io.*;

class ArduinoComm implements SerialPortEventListener
{

   //Used to in the process of converting the read in characters-
   //-first in to a string and then into a number.
   String rawStr="";

   //Declare serial port variable
   SerialPort mySerialPort;

   //Declare input steam
   InputStream in;

   boolean stop=false;

   public void start(String portName,int baudRate)
   {

      stop=false; 
      try 
      {
         //Finds and opens the port
         CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(portName);
         mySerialPort = (SerialPort)portId.open("my_java_serial" + portName, 2000);
         System.out.println("Serial port found and opened");

         //configure the port
         try 
         {
            mySerialPort.setSerialPortParams(baudRate,
            mySerialPort.DATABITS_8,
            mySerialPort.STOPBITS_1,
            mySerialPort.PARITY_NONE);
            System.out.println("Serial port params set: "+baudRate);
         } 
         catch (UnsupportedCommOperationException e)
         {
            System.out.println("Probably an unsupported Speed");
         }

         //establish stream for reading from the port
         try 
         {
            in = mySerialPort.getInputStream();
         } 
         catch (IOException e) 
         { 
            System.out.println("couldn't get streams");
         }

         // we could read from "in" in a separate thread, but the API gives us events
         try 
         {
            mySerialPort.addEventListener(this);
            mySerialPort.notifyOnDataAvailable(true);
            System.out.println("Event listener added");
         } 
         catch (TooManyListenersException e) 
         {
            System.out.println("couldn't add listener");
         }
      }
      catch (Exception e) 
      { 
         System.out.println("Port in Use: "+e);
      }
   }

   //Used to close the serial port
   public void closeSerialPort() 
   {
      try 
      {
         in.close();
         stop=true; 
         mySerialPort.close();
         System.out.println("Serial port closed");

      }
      catch (Exception e) 
      {
      System.out.println(e);
      }
   }

   //Reads the incoming data packets from Arduino. 
   public void serialEvent(SerialPortEvent event) 
   { 

      //Reads in data while data is available
      while (event.getEventType()== SerialPortEvent.DATA_AVAILABLE && stop==false) 
      {
         try 
         {
            //------------------------------------------------------------------- 

            //Read in the available character
            char ch = (char)in.read();

            //If the read character is a letter this means that we have found an identifier.
            if (Character.isLetter(ch)==true && rawStr!="")
            {
               //Convert the string containing all the characters since the last identifier into an integer
               int value = Integer.parseInt(rawStr);

               if (ch=='A')
               {
                  System.out.println("Value A is: "+value);
               }

               if (ch=='B')
               {
                  System.out.println("Value B is: "+value);
               }

               //Reset rawStr ready for the next reading
               rawStr = ("");
            } 
            else 
            {
               //Add incoming characters to a string.
               //Only add characters to the string if they are digits. 
               //When the arduino starts up the first characters it sends through are S-t-a-r-t- 
               //and so to avoid adding these characters we only add characters if they are digits.

               if (Character.isDigit(ch))
               {
                  rawStr = ( rawStr + Character.toString(ch));
               } 
               else 
               {
                  System.out.print(ch);
               } 
            }
         } 
         catch (IOException e) 
         {
         }
      }
   }

}

And here is the Arduino Sketch

//Arduino code for Part 01

//First we will define the values to be sent
//Note: The java code to go with this example reads-
//-in integers so values will have to be sent as integers
int valueA = 21;
int valueB = 534;

void setup()
{
   Serial.begin(115200);
   Serial.println("Start");
}

void loop()
{ 

   //We send the value coupled with an identifier character
   //that both marks the end of the value and what the value is.

   Serial.print(valueA);
   Serial.print("A");

   Serial.print(valueB);
   Serial.print("B");

   //A delay to slow the program down to human pace.
   delay(500);  

}

I have read that changing Serial.print() to Serial.write() is the new way to do this, but changing this had no result.

1 Answer 1

1

So the reason for no events being triggered was due to the program exiting and ending before it had the chance to.

To solve this i added a thread with a loop inside it inside the main thread.

public static void main(String[] args) throws Exception {
 ArduinoComm = new ArduinoComm ();
 main.start("/dev/ttyUSB0",115200);
 Thread t=new Thread() {
 public void run() {
 try {
 //Messy implementation but it works for this demo purpose
    while(true){
      //optional sleep  
      thread.Sleep(500);
    }
 } catch (InterruptedException ie) {}
 }
 };
 t.start();
 System.out.println("Started");
 }

Bit of an oversight on my part.

1
  • Good to see you fixed your problem already! You might want to accept this as your answer (when you can, I know, it takes some time ;) ). A thing I like to do is add debug printlines/cout's at the start and end of my program. So you can see whenever your program finishes or starts. I've had troubles with a microcontroller restarting itself (so the start of a program is an interesting event). And sometimes a device can cause undefined behaviour when breaking out of the main loop. So a while(true); (with debug lines) might indeed do the trick.
    – aaa
    Commented Nov 23, 2015 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.