transfer doubles between java and simulink using udp
Asked Answered
I

2

6

I need to transfer decimal values between Java program and a Simulink model, to do so i use UDP sockets, they are no problem in the java side. In Simulink i am able to send the values using 'Stream Output' block, but the problem presents while receiving from java! the 'Stream input' block doesn't receive any thing. I am using standard devices UDP protocole, with the right Local UDP port and the address is 'localhost. Please tell me how to correctly receive a double in simulink with udp, or even with other methods, what matter is to transfer the data. thanks in advance. here are some code:

localSocket = new DatagramSocket(9010);

...

 public static void localSend(String msg,int PORT) throws Exception{  
    DatagramPacket sendPacket = null,encPacket=null;
    try {
        sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getLocalHost(), PORT);
    } catch (Exception e) {
        System.out.printf("Error!");
    }
    localSocket.send(sendPacket);
}

and in the main method:

localSend(myMessage, 9005);

the 'Board setup' of the 'Input Stream' block is Simulink is as below: enter image description here

here is how i receive data from Simulink ins Java (the method):

    public static String localReceive() throws Exception{                     
     DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
     int count=0;
       try {
           localSocket.receive(receivePacket);
            return new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
            } catch (SocketTimeoutException socketTimeoutException) {
                return defaultValue;
            }
 }

and the setup of "Output Stream" block in Simulink: enter image description here

Isbell answered 30/3, 2016 at 14:1 Comment(4)
you need to tell us your block parameter setups, are you sure that the port/address are all correct?Rizo
ok, i will edit the questionIsbell
@nuser1955419 - Show us how are you sending data from Simulink, and the relevant Java code --- this much is insufficient to deduce an answer!Varlet
i added it in an editIsbell
I
0

i did a trick. 'Packet Input' Simulink block, and 'ASCII Decode', blocks connection

i adjust the parameters of these 2 blocks as follows:

the 'Packet Input' block

the 'ASCII Decoder

and in the java side, i 'reformat' the double, with this method:

public static String reformat(String str){
    double d = 0;
    DecimalFormat df=null;
    try {
        d = Double.parseDouble(str);
    } catch (NumberFormatException numberFormatException) {
        return "0.00000";
    }
    if(d>=0){
    String[] sp=str.split("\\.");
    if(sp[0].length()==0)
    df= new DecimalFormat("0.00000");
    if(sp[0].length()==1)
    df= new DecimalFormat("0.00000");
    if(sp[0].length()==2)
        df= new DecimalFormat("00.0000");
    if(sp[0].length()==3)
        df= new DecimalFormat("000.000");
    if(sp[0].length()==4)
        df= new DecimalFormat("0000.00");
    if(sp[0].length()==5)
        df= new DecimalFormat("00000.0");
    }
    else{
    String[] sp=str.split("\\.");
    if(sp[0].length()==1)
    df= new DecimalFormat("0.0000");
    if(sp[0].length()==2)
    df= new DecimalFormat("0.0000");
    if(sp[0].length()==3)
        df= new DecimalFormat("00.000");
    if(sp[0].length()==4)
        df= new DecimalFormat("000.00");
    if(sp[0].length()==5)
        df= new DecimalFormat("0000.0");
    if(sp[0].length()==6)
        df= new DecimalFormat("000000");
    }

    try {
        return df.format(d);
    } catch (Exception e) {
        return "0.00000";
    }
}

briefly: the packet input block receives 7 ASCIIs each time, and in java i reformat the double to be combined of 7 characters (including the point and the minus).

Hope this help someone.

update:

some self explanatory extra code:

//somewhere before:
//Global variables
    String defaultValue="0",ip="xxx.xx.xx.xx";
    DatagramSocket remoteSocket,localSocket;
    byte[] receiveArray,receiveKey,receiveSig,sendSig;
    int remoteSendPort=xxx,localSendport=xxx,
        remoteReceivePort=xxx,localReceivePort=xxx;    
    String feedback,control_val,ReceivedTimeStamp;
    InetAddress IPAddress;     
...
//receive message from the other java program in pc2 
    public  void remoteMsgSend(byte[] msg,InetAddress IPAddress, int PORT)  {     
        try {     
            DatagramPacket sendPacket = null;
            try {
                sendPacket = new DatagramPacket(msg, msg.length, IPAddress, PORT);
            } catch (Exception e) {
                System.out.printf("Error! check ports");
            }
            remoteSocket.send(sendPacket);
        } catch (IOException ex) {
            System.out.println("IOException! remote send");
        }
    }
    //receive message from the other java program in pc2
    public  String remoteMsgReceive() {                     
         DatagramPacket receivePacket = new DatagramPacket(receiveArray, receiveArray.length);
         byte[] r1;
         int count=0,len,offset;
           try {
               remoteSocket.receive(receivePacket);
               r1=receivePacket.getData();
               len=receivePacket.getLength();
               offset=receivePacket.getOffset();
               r1=Arrays.copyOfRange(r1, offset, len);
               remoteOk=true;
                return new String(r1);
                } catch (Exception ex) {
//                    System.out.println("remote receive time out: " +ex.getMessage());
                    remoteOk=false;
                    return defaultValue;
                }
     }

    //send data to matlab on this pc
    public  void localSend(String msg,int PORT)  {  
        DatagramPacket sendPacket = null;
        try {
            sendPacket = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getLocalHost(), PORT);
        } catch (Exception e) {
            System.out.printf("Error! check ports");
        }
        try {
            localSocket.send(sendPacket);
        } catch (IOException ex) {
            System.out.println("localsend error");
        }
    }
    //receive data from Matlab on this pc
    public  String localReceive() {                     
         DatagramPacket receivePacket = new DatagramPacket(receiveArray, receiveArray.length);

         String rec;
           try {
               localSocket.receive(receivePacket);
               rec=new String(receivePacket.getData(),receivePacket.getOffset(),receivePacket.getLength());
               localOk=true;
                return rec;
                } catch (Exception ex) {
//                          System.out.println("local receive time out " +ex.getMessage());
                          localOk=false;
                          return defaultValue;
                }
     }
Isbell answered 5/4, 2016 at 8:15 Comment(4)
Can you please show the code for this answer? I have a very similar problem and I am using the same blocks but I simply cant receive the data from the pc running to the matlab pc.Wader
Hello @Flower, sorry i were offline for a while. first ensure that your connection is well established (no firewalls, good ports...) you can use a software to test it like linkPacketSended. i will put my the requested code in an update. (btw, my second answer was better to solve the problem described in the question)Isbell
There is no need to put your code in an update. I was able to get it working. Thanks so much, you answer helped me a lot.Wader
yr welcome, i putted it before reading your comment. glade i can help.Isbell
I
0

Another solution, with the stream input in Simulink. Just add a terminator "\n" to each message from java.

Isbell answered 10/5, 2016 at 18:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.