0

I used the sample program from the arduino website in order to send and receive data via serial to my Arduino one. However, for some reason, even when I try to send only one byte, the Arduino crashes after a while. It doesn't happen if I send the chars manually via the IDE's own serial monitor.

I wrote the following method to output the character to Arduino:

public synchronized void serialWrite(char sendIt){
    try {
            output.write((byte)'0');
            output.flush();
            for (int j=0;j<1000000000;j++){
            }
        }catch (Exception e){System.out.println("Not connected...");}
    notify();
}

What I try above is to send just one character when the method is called. I send just a '0' char for testing. After manually calling the method two or three times, Arduino crashes. Is there anything I should be looking into?

The Arduino code:

#include <SoftwareSerial.h>
int buttonState=0;
int lastButtonState=0;
int buttonPushCounter=0;
long previousMillis=0;
long interval=250;
int ledState=LOW;
int ledState2=LOW;
int ledState3=LOW;
long timeElapsed=0;
SoftwareSerial portOne(10,11);

void setup(){
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(2,INPUT); 
  Serial.begin(9600);
  portOne.begin(9600);

}

boolean turnoff; 

void loop(){

  if(portOne.overflow()){
    Serial.println("There's an overflow here!");
  }
  buttonState= digitalRead(2);

  if(buttonState!=lastButtonState){
    if (buttonState==HIGH){
      buttonPushCounter++;
    }
  }
  lastButtonState=buttonState;

  if (turnoff){
    unsigned long currentMillis=millis();

    if (currentMillis-previousMillis>0 && currentMillis-previousMillis<interval){
     ledState=HIGH;
     ledState2=LOW;
     ledState3=LOW;
  }else
     if (currentMillis-previousMillis>interval && currentMillis-previousMillis<interval*2){

     ledState=LOW;
     ledState2=LOW;
     ledState3=HIGH;
  }else
     if (currentMillis-previousMillis>interval*2 && currentMillis-previousMillis<interval*3){

     ledState=LOW;
     ledState2=HIGH;
     ledState3=LOW;
  }else if (currentMillis-previousMillis>interval*3){
    previousMillis=currentMillis;  
  }

    digitalWrite(3,ledState);
   digitalWrite(4,ledState2);
   digitalWrite(5,ledState3);
  }else{
   digitalWrite(3,LOW);
   digitalWrite(4,LOW);
   digitalWrite(5,LOW);

  }


   if (buttonPushCounter==1){
     Serial.print("Button pressed!\n");
    turnoff=!turnoff;
    buttonPushCounter=0;

   }

   noInterrupts();
   char ch=Serial.read();

   delay(1);
   if(ch=='0'){

     Serial.println("Changed by serial"+turnoff);
     Serial.println(ch);
     turnoff=!turnoff;
   } 
   interrupts();


}

The part of the java program that was reading the serial interface was this:

public synchronized void serialEvent(SerialPortEvent oEvent) {
    if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
        try {
            String inputLine=input.readLine();
            System.out.println(inputLine);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }
    // Ignore all the other eventTypes, but you should consider the other ones.
}
dsolimano
  • 8,870
  • 3
  • 48
  • 63
francisaugusto
  • 1,077
  • 1
  • 12
  • 29
  • Do you have a stack trace or memory dump or some kind of logs? – Anubian Noob Jun 06 '14 at 15:41
  • @AnubianNoob The Arduino's crashing, not Java. – chrylis -cautiouslyoptimistic- Jun 06 '14 at 15:42
  • Not even a memory dump? – Anubian Noob Jun 06 '14 at 15:43
  • We're going to need to see your Arduino code, as well as a more detailed description of "crashes". I suspect it may simply be blocking on sending you back some sort of input that you aren't reading in your Java program. – chrylis -cautiouslyoptimistic- Jun 06 '14 at 15:43
  • Exactly. The Arduino is the one crashing. All good on Java's side. No exception being thrown whatsoever. – francisaugusto Jun 06 '14 at 15:43
  • The Arduino code is pretty simple and, as I said, works flawlessly with the Serial Monitor of the IDE: – francisaugusto Jun 06 '14 at 15:44
  • What is that huge empty loop? – jamp Jun 06 '14 at 15:45
  • Sorry @chrylis, tried to post it but pressed enter before. It's now on the inserted on the question. – francisaugusto Jun 06 '14 at 15:47
  • @jamp It was there when I tried to create a loop to send chars automatically, but I decided to try one character by time. – francisaugusto Jun 06 '14 at 15:48
  • Describe exactly what you mean when you say that the Arduino "crashes". – chrylis -cautiouslyoptimistic- Jun 06 '14 at 15:49
  • The sketch I made is supposed to make the leds start blinking or stop blinking whenever I press a button or send a '0' char. It works that way when I use the Serial monitor. However, when doing it via java, it suddenly becomes unresponsive, leaving one led on and ignoring either the button or the serial data. The serial led on the arduino board doesn't blink anymore when I send other chars. Then I have to reset it. – francisaugusto Jun 06 '14 at 15:54
  • Ok, @chrylis, answer below really helped. I noticed that my java program was not printing every byte on the screen - the original java program to interface with Arduino via RXTX waits for a string, which certainly was overflowing the buffer of the arduino. Now I read byte by byte, and the problem is over. Thank you @crylis! :) – francisaugusto Jun 07 '14 at 09:19

1 Answers1

1

Your Arduino code is sending data back over the serial connection, but you're not reading it from your Java program. It doesn't take long for the various buffers to fill up, and then the Arduino is waiting for you to unblock them.

You need to be reading the output from the serial port and doing something with it. I suggest running a background thread that blocks on reading the serial port and just writes the character to System.out and flushes whenever it receives one.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • I don't think that's the case. When I don't send any char, but only receive data from the Arduino, it gets displayed alright on the screen. It's only when I send data that I get the crash. – francisaugusto Jun 06 '14 at 15:56
  • @francisaugusto Because when you send data, your Arduino code sends a lot more data right back, and when you're sending from Java, you have nothing ready to receive that Arduino output. – chrylis -cautiouslyoptimistic- Jun 06 '14 at 15:57
  • but that's the problem: my java code do have to code to receive data. At least it does show the data it is supposed to when I press the button. Wouldn't it then display this data it would send back after receiving the one being sent? – francisaugusto Jun 06 '14 at 15:59
  • @francisaugusto You didn't show any such code. – chrylis -cautiouslyoptimistic- Jun 06 '14 at 16:03
  • I mentioned it was the standard java code suggested on arduino's website. This is the one: [Arduino and Java](http://playground.arduino.cc/Interfacing/Java) – francisaugusto Jun 06 '14 at 16:05
  • I just added the method above and use it calling by another thread. – francisaugusto Jun 06 '14 at 16:06
  • I can post it here if you prefer. I posted the link instead as it is pretty standard for this serial monitoring via java. – francisaugusto Jun 06 '14 at 16:20
  • Ok, found the culprit: on the original code, the input stream was being handled by a string, so the method to read it was readLine(). It probably cause the arduino serial buffer to overflow. So I changed it for a int and used read() instead. Worked great! :) – francisaugusto Jun 07 '14 at 09:22