RXTX: serial scale port connection

Asked

Viewed 2,541 times

3

I’m trying to catch the weight of the scales, but I’m not finding success in this battle.

As can be seen the connection to the SERIAL port (actually USB) is all ok:

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7

Manual can be found at this link: manual, what it says:

Protocol used: rate 9600bps, 8 data bits, no parity, 2 stop bits.

The classes I’m using are:

  • SerialCom:
import gnu.io.CommPortIdentifier;
import java.util.Enumeration;

/**
 *
 * @author DexBook
 */
public class SerialCom {

    protected String[] portas;

    protected Enumeration listaDePortas;

    public SerialCom() {
        listaDePortas = CommPortIdentifier.getPortIdentifiers();
    }

    public String[] ObterPortas() {
        return portas;
    }

    protected String[] ListarPortas() {
        int i = 0;

        portas = new String[10];

        while (listaDePortas.hasMoreElements()) {

            CommPortIdentifier ips =

            (CommPortIdentifier) listaDePortas.nextElement();

            portas = ips.getName();

            i++;
        }

        return portas;
    }

    public boolean PortaExiste(String COMp) {
        String temp;

        boolean e = false;

        while (listaDePortas.hasMoreElements()) {
            CommPortIdentifier ips = (CommPortIdentifier) listaDePortas.nextElement();

            temp = ips.getName();

            if (temp.equals(COMp) == true) {
                e = true;
            }

        }

        return e;
    }

}
  • SerialComLeitura:
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 *
 * @author DexBook
 */
public class SerialComLeitura implements Runnable, SerialPortEventListener {

    public String Dadoslidos;

    public int nodeBytes;

    private int baudrate;

    private int timeout;

    private CommPortIdentifier cp;

    private SerialPort porta;

    private OutputStream saida;

    private InputStream entrada;

    private Thread threadLeitura;

    private boolean IDPortaOK;

    private boolean PortaOK;

    private boolean Leitura;

    private boolean Escrita;

    private String Porta;

    protected String peso;

    public void setPeso(String peso) {

        this.peso = peso;

    }

    public String getPeso() {
        return peso;
    }

    public SerialComLeitura(String p, int b, int t) {
        this.Porta = p;

        this.baudrate = b;

        this.timeout = t;
    }

    public void HabilitarEscrita() {
        Escrita = true;

        Leitura = false;
    }

    public void HabilitarLeitura() {
        Escrita = false;

        Leitura = true;
    }

    public void ObterIdDaPorta() {
        try {
            cp = CommPortIdentifier.getPortIdentifier(Porta);

            if (cp == null) {

                System.out.println("Erro na porta");

                IDPortaOK = false;

                System.exit(1);

            }
            IDPortaOK = true;
        } catch (Exception e) {
            System.out.println("Erro obtendo ID da porta: " + e);

            IDPortaOK = false;

            System.exit(1);
        }
    }

    public void AbrirPorta() {
        try {
            porta = (SerialPort) cp.open("SerialComLeitura", timeout);

            PortaOK = true;

            // configurar parâmetros

            porta.setSerialPortParams(baudrate,

            porta.DATABITS_8, porta.STOPBITS_2, porta.PARITY_NONE);

            porta.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);

            System.out.println("Porta " + Porta + " aberta!");
        } catch (Exception e) {
            PortaOK = false;

            System.out.println("Erro abrindo comunicação: " + e);

            System.exit(1);
        }
    }

    public void LerDados() {
        if (Escrita == false) {
            try {
                entrada = porta.getInputStream();
            } catch (Exception e) {
                System.out.println("Erro de stream: " + e);

                System.exit(1);
            }
            try {
                porta.addEventListener(this);
            } catch (Exception e) {
                System.out.println("Erro de listener: " + e);

                System.exit(1);
            }
            porta.notifyOnDataAvailable(true);

            try {
                threadLeitura = new Thread(this);

                threadLeitura.start();

                run();
            } catch (Exception e) {
                System.out.println("Erro de Thred: " + e);
            }
        }
    }

    public void EnviarUmaString(String msg) {
        if (Escrita == true) {
            try {
                saida = porta.getOutputStream();

                System.out.println("FLUXO OK!");
            } catch (Exception e) {

                System.out.println("Erro.STATUS: " + e);
            }

            try {
                System.out.println("Enviando um byte para " + Porta);

                System.out.println("Enviando : " + msg);

                saida.write(msg.getBytes());

                Thread.sleep(100);

                saida.flush();
            } catch (Exception e) {
                System.out.println("Houve um erro durante o envio. ");

                System.out.println("STATUS: " + e);

                System.exit(1);
            }
        } else {
            System.exit(1);
        }
    }

    public void run() {
        try {
            Thread.sleep(5);
        } catch (Exception e) {
            System.out.println("Erro de Thred: " + e);
        }
    }

    // Essa procedure pode conter incompatibilidades, qualquer problema rever.

    public void serialEvent(SerialPortEvent ev) {
        StringBuffer bufferLeitura = new StringBuffer();

        int novoDado = 0;

        switch (ev.getEventType()) {

        case SerialPortEvent.BI:

        case SerialPortEvent.OE:

        case SerialPortEvent.FE:

        case SerialPortEvent.PE:

        case SerialPortEvent.CD:

        case SerialPortEvent.CTS:

        case SerialPortEvent.DSR:

        case SerialPortEvent.RI:

        case SerialPortEvent.OUTPUT_BUFFER_EMPTY:

            break;

        case SerialPortEvent.DATA_AVAILABLE:

            // Novo algoritmo de leitura.

            while (novoDado != -1) {
                try {
                    novoDado = entrada.read();

                    if (novoDado == -1) {
                        break;
                    }

                    if ('\r' == (char) novoDado) {
                        bufferLeitura.append('\n');
                    } else {
                        bufferLeitura.append((char) novoDado);
                    }
                } catch (IOException ioe) {
                    System.out.println("Erro de leitura serial: " + ioe);
                }

            }

            setPeso(new String(bufferLeitura));

            System.out.println("Peso: " + getPeso());

            break;
        }

    }

    public void FecharCom() {
        try {
            porta.close();
        } catch (Exception e) {
            System.out.println("Erro fechando porta: " + e);

            System.exit(0);
        }

    }

    public String obterPorta() {
        return Porta;
    }

    public int obterBaudrate() {
        return baudrate;
    }

}
  • TCC_Serial:
public class TCC_Serial extends SerialCom {

    /**
     * @param args
     *            the command line arguments
     */
    public static void main(String[] args) {

        SerialComLeitura leitura = new SerialComLeitura("COM3", 9600, 500);

        // Iniciando leitura serial

        leitura.HabilitarEscrita();

        leitura.ObterIdDaPorta();

        leitura.AbrirPorta();

        leitura.EnviarUmaString("0x04");

        leitura.HabilitarLeitura();

        leitura.ObterIdDaPorta();

        leitura.LerDados();

        // Controle de tempo da leitura aberta na serial

        try {

            Thread.sleep(1000);

        } catch (InterruptedException ex) {

            System.out.println("Erro na Thread: " + ex);

        }

        leitura.FecharCom();

    }

}

In the manual it says:

sending a command character(04 in hexadecimal).

In class TCC_Serial i put:

leitura.EnviarUmaString("04");

leitura.EnviarUmaString("4");

leitura.EnviarUmaString("0x04");

When I run the program appears:

Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
Porta COM3 aberta!
FLUXO OK!
Enviando um byte para COM3
Enviando : 0x04

There’s no mistake, there’s nothing, and I don’t get the weight of the scale back.

Can anyone give me a light? For I really can’t imagine what problem.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ with java JSSC

Serialport serialPort = new Serialport("COM3"); Try { System.out.println("Port opened: " + serialPort.openPort()); System.out.println("Params setted: " + serialPort.setParams(9600, 8, 2, 0)); System.out.println("successfully Writen to port: " + serialPort.writeBytes("0x04".getBytes()); byte[] buffer = serialPort.readBytes(46);//Read 10 bytes from serial port

        System.out.println(buffer.length);

        for (int i = 0; i < buffer.length; i++) {
            System.out.println(buffer[i]);
        }

        System.out.println("Port closed: " + serialPort.closePort());
    } catch (SerialPortException ex) {
        System.out.println(ex);
    }

He returns

run: COM3 Port opened: true Params setted: true successfully Writen to port: true 46 112 -10 64 2 -120 -65 -58 1 -112 -65 -58 1 24 32 -93 20 -40 31 -93 20 0 -68 -58 1 0 0 0 0 -44 21 -28 111 20 0 0 0 -4 -10 64 2 32 -9 116 106 0 -68 Port closed: true

  • Can you communicate using another program? Which of the characters you send to the balance make it return the weight?

  • It seems to me that your problem is in the form of sending the hex character of weight request (0x04). I’ll take a look here and give you a feedback.

  • Thanks for the feedback, I did a test with the local application, and the information returns.

  • I made the change according to orientation, and still not returning anything, and still not giving error. more idea friend?

3 answers

2


The problem is occurring as it is sending a set of bytes to the balance that does not correspond to the expected hexadecimal character.

Is being done:

leitura.EnviarUmaString("0x04");

Inside the Send method a string is happening:

saida.write(msg.getBytes());

Where msg is the message passed as parameter and exit is an Outputstream.

Anyway, what is being sent are the bytes of the string 0x04. This is not a hexadecimal. Basically, instead of sending 1 byte as expected, 4 bytes are being sent.

to resolve do so:

saida.write(new byte[]{0x04});
  • The problem reported above was certainly one of the code problems. I need to analyze in more detail to check others. Anyway, Voce can make the balance transmit using other software?

  • I don’t know what you’ve tried, but I usually isolate problems when I have to deal with this kind of situation. The first thing I would do is test the communication with the scale on other software that I’m sure communicates with. In Windows vc you can use Hyperterminal, open a connection to the balance specifications and then press CTRL-D. This should produce the 0x04 caraceter. If everything is correct (balance cable + parameters), then you will see the weight in the Hyperterminal. If Voce doesn’t see, it doesn’t mean there is a problem yet, because it might be that CTRL-D didn’t work. ,

  • Confirm me please 04 in hexadecimal is 04 or 0x04, or??? I took the ASC table but I saw no difference... I tested it in other software and I function correctly.... more tip?

  • @Himorrivel, yes it is 04, but the Java representation of a Hex is used 0x followed by Hex. So 04 in Java is 0x04. You have advanced well, because by confirming that it works on other software correctly you have isolated communication cable and some possible problem on the scale. My suggestion now is the following: Create a simple Java program that just sends these bytes to the balance. A very simple program. I’ve integrated many scales and I have a Java program that communicates with one of them. I don’t use RXTX, but JSSC. Although RXTX is widely used. Anyway, it’s a detail, believe me.

  • Thanks again for wanting to help me. So.... what I am doing is as simple as possible.... Is there anything simpler than what I’m doing? the communication is already ready, the only thing that is not giving is the part to send and receive and honestly I already researched the whole internet and could not find the solution.... honestly after everything I researched I’m stuck at that point and I really need a help because I don’t know how to proceed...

  • Another option is to try to communicate using Processing (Processing.org). It’s Java, very simple to use and I think it uses RXTX as the library for serial communication. Test with it.

  • I did a test with the JSSC you said. but I still do not receive the final information... I put 46 because in the manual it says that it has to be 46... more some hint??

Show 2 more comments

1

Friend, I also use RXTX for communication and I can extract information from the time balance returning different characters and time returning the weight.

There are two problems I’ve been facing:

1º - Return of special characters: I have checked all configuration data such as speed, parity among others that may be the cause of the error but are all correct and time returns these different characters.

2º - The scale has to be in the intermittent sending configuration so it will keep sending the weight while the communication is open with it, as I do the weight extraction and stop communication.

  • Hello, the RXTX is very annoying to configure because it depends on various settings for it to work, I migrated to the JSSC and I didn’t regret a bit. 1 - When I was testing I had special characters problem, I discovered later that I was missing to make the correct data return. 2 - You can do it in two ways, create a true Boolean and put a while that while true, it looks for the balance information... or else vc da request, and takes the information later. Hugs

  • I agree with @Himorrivel. RXTX is very complicated to use and configure. Differently, I migrated to Javino, which allows a very simple configuration of communication and security in receiving and sending information, since it uses two libraries and another pro controller. It is worth leaving the tip too.

0

Thanks @Cantoni got it thanks to your tips...

in case anyone needs:

* * To change this License header, Choose License Headers in Project Properties. * To change this template file, Choose Tools | Templates * and open the template in the editor. */

/** * * @Author Dexbook */

import java.io.Unsupportedencodingexception;

import jssc.Serialport;

import jssc.Serialportexception;

import jssc.Serialportlist;

public class Main {

public static void main(String[] args) throws UnsupportedEncodingException {
    String[] portNames = SerialPortList.getPortNames();
    for (String portName : portNames) {
        System.out.println(portName);
    }

    SerialPort serialPort = new SerialPort("COM3");
    try {
        System.out.println("Port opened: " + serialPort.openPort());
        System.out.println("Params setted: " + serialPort.setParams(9600, 8, 2, 0));
        System.out.println("successfully writen to port: " + serialPort.writeBytes(new byte[]{0x04}));
        byte[] buffer = serialPort.readBytes(46);//Read 10 bytes from serial port
        System.out.println(new String(buffer));
        System.out.println("Port closed: " + serialPort.closePort());
    } catch (SerialPortException ex) {
        System.out.println(ex);
    }

}

}

  • Hello, Himorrivel, if my answer has helped you, feel free to accept it as the correct one.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.