Search code examples
javacomserial-portserial-communicationmodbus

Trouble in writing data on microcontroller using serial communication


I am trying to send a command to the Microcontroller using serial communication, I can compile and run following code without any error but values are not being written on the register. What am I doing wrong?

code

import java.io.*;

import javax.comm.*;

import net.wimpi.modbus.net.SerialConnection;
import net.wimpi.modbus.util.SerialParameters;

import java.util.*;

public class SerTest {

public static void main(String[] args)  {



Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();

CommPortIdentifier portId = null;  
while (portIdentifiers.hasMoreElements())
{
  CommPortIdentifier pid = (CommPortIdentifier) portIdentifiers.nextElement();
  if(pid.getPortType() == CommPortIdentifier.PORT_SERIAL &&
     pid.getName().equals("COM4")) 
  {
      portId = pid;
      break;
  }
}
if(portId == null)
{
  System.err.println("Could not find serial port "); // + wantedPortName);
  System.exit(1);
}

SerialPort port = null;

try {
  port = (SerialPort) portId.open(
      "name", // Name of the application asking for the port 
      10000   // Wait max. 10 sec. to acquire port
  );
} catch(PortInUseException e) {
  System.err.println("Port already in use: " + e);
  System.exit(1);
}

try {
port.setSerialPortParams(

    9600 , SerialPort.DATABITS_8,
    SerialPort.STOPBITS_1,
    SerialPort.PARITY_EVEN);
}   catch (UnsupportedCommOperationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}


BufferedReader is = null;  
PrintStream    os = null;

try {
is = new BufferedReader(new InputStreamReader(port.getInputStream()));
} catch (IOException e) {
System.err.println("Can't open input stream: write-only");
is = null;
}



try {
os = new PrintStream(port.getOutputStream(), true);

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}



// Actual data communication would happen here
os.print("08050080FF008D4B");


os.flush(); 


if (is != null)
try {
    is.close();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
if (os != null) os.close();
if (port != null) port.close();

} 

}

I suspect problem is in this line

os.print("08050080FF008D4B");

is this a right method of sending command to the microcontroller?

Meaning of command

08- Controller ID,
05- MODBUS function for coil writing,
0080- Address of a register where value is to be written,
FF00- Boolean value,
8D4B- CRC checksum ,

Solution

  • You're sending the string 08050080FF008D4B. You probably want to be sending those as bytes instead of the string value. The first byte that you are sending to the device is 0, which is 0x30 in hex. From your string and meaning of command, you probably want the first byte to be 0x08.

    So, something like this would probably work(note that without knowing anything more about what you're working with, I can't say for certain):

    byte[] bytes = new byte[]{ 0x08,0x05,0x00,(byte)0x80,(byte)0xFF,0x00,(byte)0x8D,(byte)0x4B };
    //Later on in your code....
    os.write( bytes );