0

I am creating a prorgram for my old school for their school bell, and I am using java. Currently on my arduino I have a program which when it receives a number from the serial port it turns on the bell for how ever long it says. This program works in the Serial Monitor, but not in Java. These are my 2 programs:

import java.io.OutputStream;

import gnu.io.SerialPort;



public class Main {
    public static void main(String[] args) throws Exception {
        SerialPort sP = Arduino.connect("COM3");

        Thread.sleep(1500);

        OutputStream out = sP.getOutputStream();

        Thread.sleep(1500);

        out.write("3000".getBytes());
        out.flush();
        Thread.sleep(1500);
        out.close();
    }
}

And my Arduino conenct program;

import gnu.io.*;

public class Arduino {
    public static SerialPort connect(String portName) throws Exception {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

        if(portIdentifier.isCurrentlyOwned()) {
            System.out.println("ERROR!!! -- Port already in use!");
        }else{
            CommPort commPort = portIdentifier.open("XBell", 0);

            if(commPort instanceof SerialPort) {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(38400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

                return serialPort;
            }else{
                System.out.println("wait wat");
            }
        }
        return null;
    }
}

Here's the Arduino code:

int Relay = 13;
//The pin that the relay is attached to
int time;
//Creates temp variable

void setup() {
    //Initialize the Relay pin as an output:
    pinMode(Relay, OUTPUT);
    //Initialize the serial communication:
    Serial.begin(9600);
}

void loop() {
    while(true) {
        //Check if data has been sent from the computer:
        if (Serial.available()) {
            //Assign serial value to temp
            time = Serial.parseInt();
            //Output value to relay
            digitalWrite(Relay, HIGH);
            delay(time);
            digitalWrite(Relay, LOW);

        }
    }
}

If you could please tell me what I am doing wrong that would be very helpful. Thanks!

dsolimano
  • 8,870
  • 3
  • 48
  • 63
cheese5505
  • 962
  • 5
  • 14
  • 30
  • Are you sure the number is meant to be encoded as *text*? – Jon Skeet Aug 05 '13 at 06:03
  • I have done it that way before, but I lost that program because of hard drive failures. – cheese5505 Aug 05 '13 at 06:04
  • For the same input? It just sounds like an odd way of passing a number over a serial port... Additionally, you've give no indication as to what's going wrong. Presumably it's not working, but in what *way* is it not working? Does the bell not ring? Ring for too long? Ring for too short a time? – Jon Skeet Aug 05 '13 at 06:06
  • On the arduino I am currently using the built-in LED on port 13 for debugging. When I connect, it blinks a couple times fast for I guess the connection, and then it never does anything again. – cheese5505 Aug 05 '13 at 06:08
  • Well without seeing the code running on the Arduino, we can't really tell why that is... – Jon Skeet Aug 05 '13 at 06:14
  • Just updated the post with the Arduino code. – cheese5505 Aug 05 '13 at 06:27

1 Answers1

2

A few problems.

  • The Java code sets 38400, the Arduino 9600 baud.

  • The getBytes() is not ensured to give you ASCII. It will return whatever your default encoding is subject to a bunch of caveats. In general, you cannot count on this method and should always prefer explicit control of the encoding. There is endless people burned by this, here is just one random reference. try getBytes("UTF-8")

  • You have no terminator that defines the end of the number. You may think "3000" is sent, but you should think in terms "3" is sent, then "0", then "0", then "0". On the Arduino side, the call to Serial.available() can occur at any time in this sequence. So the code could get to the parseInt() line when just the "3" has been received. The Arduino is spinning through the loop() much faster than a single character transmission time. At 9600 bits per second and 10 bits for a character, N81, that is more than 1 millisecond for 1 character to move across the wire. At 16 MHz clock, the Arduino will spin through the loop() many times. You need to change your command protocol to include a terminator, and only parseInt() when you have the full number.

Community
  • 1
  • 1
jdr5ca
  • 2,809
  • 14
  • 25