Converts String to Arduino int in C

0

Good people, I'll try to explain my problem. I am developing a small software in NetBeans that communicates with Arduino via Serial Port.

My problem is that in NetBeans I'm sending String, and I need to convert this String to integer and I'm not getting it. The Serial port is declared as an integer. But you still do not get the NetBeans String.

I do not know if I was clear on the question, but please help me.

Arduino code:

 void loop(){

     // Loop Função main  
     if(Serial.available()>0){  // Vericando se Existe conexão 

         //declarando variável que irá recebe comandos do NetBeans

          int  byteEntrada = 0; // A variável byteEntrada irá  recebe Bits do NetBeans , Esses Bits sera transforma em  comandos para o Acendimento de LEDS.
          int  Porta1 =0;    
          int  Porta2 =0;          // A variável Por1, por2,port3, Será ultizada para indicar as portas que vão  se usada no Arduino.
          int  Porta3 =0; 


             byteEntrada =  Serial.read();      // Fazendo Leitura da porta Serial  para o Comando byteEntrada
                  Porta1 =  Serial.read();     // Fazendo Leitura da porta Serial  para o Comando porta1
                  Porta2 =  Serial.read();    // Fazendo Leitura da porta Serial  para o Comando porta2
                  Porta3 =  Serial.read();  // Fazendo Leitura da porta Serial  para o Comando porta3



          if(byteEntrada == '1')
           {  // Se o Bit que veio do NetBeans for igual a 1
             Desligado(Porta1,Porta2,Porta3,'h','h','l'); // Sera passado por parametro  as portas, e a situação para cada led   se ( H )  ligado se (L) desligado.
           } 

    }
}

Here is the NetBeans code where you are sending:

public void enviarDados(String dados, String p1,String p2,String p3){
    try{
    output.write(dados.getBytes());
    output.write(p1.getBytes());
    }catch(IOException e){
        Exibir_ERRO("Erro");
        System.exit(ERROR);
    }
}

The function Desligado :

void  Desligado (int x,int y,int z,char st1,char st2,char st3){

    if ( st1 == 'l' ) {
        digitalWrite (x,LOW); 
     } else {
        digitalWrite (x,HIGH);
     }
    if ( st2 == 'l' ) {
       digitalWrite (y,HIGH); 
     } else {
       digitalWrite (y,HIGH);
     }
    if ( st3 == 'l' ) {
       digitalWrite (z,HIGH); 
     } else {
      digitalWrite (z,HIGH);
     }
}

The part of NetBeans that is configuring communication with Arduino:

public void iniciarConexao(){
    CommPortIdentifier portaId = null;
    Enumeration portaEnum = CommPortIdentifier.getPortIdentifiers();

    while(portaEnum.hasMoreElements()){
        CommPortIdentifier atualPortaId =(CommPortIdentifier) portaEnum.nextElement();
        if(porta.equals(atualPortaId.getName())){
            portaId=atualPortaId;
            break;
        }
    }
    if(portaId == null){
        Exibir_ERRO("Não se pode conectar a porta");
        System.exit(ERROR);
    }

    try{
        serialPort = (SerialPort) portaId.open(this.getClass().getName(), timeOut);
        //parametros da porta serial

        serialPort.setSerialPortParams(dataRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        output = serialPort.getOutputStream();
    }catch(Exception e){
        Exibir_ERRO(e.getMessage());
        System.exit(ERROR);
    }
}

public void enviarDados(String dados,String p1,String p2,String p3){
    try{
    output.write(dados.getBytes());
    output.write(p1.getBytes());
    output.write(p2.getBytes());
    output.write(p3.getBytes());

    }catch(IOException e){
        Exibir_ERRO("Erro");
        System.exit(ERROR);
    }
}
    
asked by anonymous 03.11.2016 / 04:23

2 answers

3

The first thing I see wrong is in its Desligado function:

void  Desligado (int x,int y,int z,char st1,char st2,char st3){

    if ( st1 == 'l' ) {
        digitalWrite (x,LOW); 
     } else {
        digitalWrite (x,HIGH);
     }
    if ( st2 == 'l' ) {
       digitalWrite (y,HIGH); 
     } else {
       digitalWrite (y,HIGH);
     }
    if ( st3 == 'l' ) {
       digitalWrite (z,HIGH); 
     } else {
      digitalWrite (z,HIGH);
     }
}

Note the second if-else : If st2 is equal to l then it places HIGH in y . Otherwise, it also puts HIGH in the same way! I think it had to be LOW and HIGH instead of HIGH and HIGH . The same goes for the third if-else .

So your code looks like this:

void Desligado(int x, int y, int z, char st1, char st2, char st3) {
    if (st1 == 'l') {
        digitalWrite(x, LOW); 
    } else {
        digitalWrite(x, HIGH);
    }
    if (st2 == 'l') {
        digitalWrite(y, LOW); 
    } else {
        digitalWrite(y, HIGH);
    }
    if (st3 == 'l') {
        digitalWrite(z, LOW);
    } else {
        digitalWrite(z, HIGH);
    }
}

However, it would still be easier to simplify thanks to the ternary operator:

void Desligado(int x, int y, int z, char st1, char st2, char st3) {
    digitalWrite(x, st1 == 'l' ? LOW : HIGH);
    digitalWrite(y, st2 == 'l' ? LOW : HIGH);
    digitalWrite(z, st3 == 'l' ? LOW : HIGH);
}

On the other hand, we do not really need the ternary operator. It is being used to translate from char to the constants LOW or HIGH . If we pass the parameters themselves as a parameter, we eliminate the need to have the ternary operator:

void Desligado(int x, int y, int z, int st1, int st2, int st3) {
    digitalWrite(x, st1);
    digitalWrite(y, st2);
    digitalWrite(z, st3);
}

And from the outside instead:

Desligado(Porta1,Porta2,Porta3,'h','h','l');

We have this:

Desligado(Porta1, Porta2, Porta3, HIGH, HIGH, LOW);

However, this function is only associating three ports to three logical levels directly and independently. That is, it is not encapsulating any complex logic and is not contributing much to the simplicity of the code. So we can delete it and then the loop function looks like this (I took the comments):

void loop() {
    if (Serial.available() > 0) {
        int byteEntrada = 0;
        int Porta1 = 0;
        int Porta2 = 0;
        int Porta3 = 0;
        byteEntrada = Serial.read();
        Porta1 = Serial.read();
        Porta2 = Serial.read();
        Porta3 = Serial.read();

        if (byteEntrada == '1') {
            digitalWrite(Porta1, HIGH);
            digitalWrite(Porta2, HIGH);
            digitalWrite(Porta3, LOW);
        }
    }
}

You can simplify the loop function by seeing that the zeros used at startup are never used, so they can be deleted:

void loop() {
    if (Serial.available() > 0) {
        int byteEntrada = Serial.read();
        int Porta1 = Serial.read();
        int Porta2 = Serial.read();
        int Porta3 = Serial.read();

        if (byteEntrada == '1') {
            digitalWrite(Porta1, HIGH);
            digitalWrite(Porta2, HIGH);
            digitalWrite(Porta3, LOW);
        }
    }
}

You can simplify a little more by realizing that if the stream does not enter if , then the function will reach the end without doing anything else (and we can take a short cut):

void loop() {
    if (Serial.available() <= 0) return;
    int byteEntrada = Serial.read();
    int Porta1 = Serial.read();
    int Porta2 = Serial.read();
    int Porta3 = Serial.read();

    if (byteEntrada != '1') return;
    digitalWrite(Porta1, HIGH);
    digitalWrite(Porta2, HIGH);
    digitalWrite(Porta3, LOW);
}

Well, as for the "Netbeans side", this does not exist. The correct one would be to say "Java side". Who performs this is Java, not NetBeans. NetBeans is just an anabolic text editor, he is not the one who runs his real programs. What happens is that NetBeans gives you some little buttons to run the program, but all it actually does underneath is asking the operating system to run the JVM and ask the JVM to run its program. This is more or less the same as asking your nephew to turn on the fan in the room, who will give you the wind is the fan and not your nephew, the nephew just turned it on.

Well, let's look at the Java side:

public void enviarDados(String dados,String p1,String p2,String p3){
    try{
    output.write(dados.getBytes());
    output.write(p1.getBytes());
    output.write(p2.getBytes());
    output.write(p3.getBytes());

    }catch(IOException e){
        Exibir_ERRO("Erro");
        System.exit(ERROR);
    }
}

This will not do what you want. What you want is to send the bytes 1, 2, 3, not the strings "1", "2", "3". This is quite different because the character "1" is encoded with the byte 49, the character "2" is coded with byte 50 and "3" with 51 . So we need to do the conversion in Java.

I do not know where you use the enviarDados function, but suppose you want to use it like this:

enviarDados(1, 3, 4, 5);

So, you would have to use type int instead of String :

public void enviarDados(int dados, int p1, int p2, int p3) {
    try {
        output.write((byte) dados);
        output.write((byte) p1);
        output.write((byte) p2);
        output.write((byte) p3);
    } catch (IOException e) {
        Exibir_Erro("Erro");
        System.exit(ERROR);
    }
}

But if you want to use it like this:

enviarDados("1", "3", "4", "5");

So, you would have to do this:

public void enviarDados(String dados, String p1, String p2, String p3) {
    try {
        output.write(Byte.parseByte(dados));
        output.write(Byte.parseByte(p1));
        output.write(Byte.parseByte(p2));
        output.write(Byte.parseByte(p3));
    } catch (IOException e) {
        Exibir_Erro("Erro");
        System.exit(ERROR);
    }
}

Or, if you already have it in bytes:

byte a = ..., b = ..., c = ..., d = ...;
enviarDados(a, b, c, d);

So, you would not need any conversion:

public void enviarDados(byte dados, byte p1, byte p2, byte p3) {
    try {
        output.write(dados);
        output.write(p1);
        output.write(p2);
        output.write(p3);
    } catch (IOException e) {
        Exibir_Erro("Erro");
        System.exit(ERROR);
    }
}

You can separate the location of the serial port from the aperture in two separate methods. The only annoying thing is that the javax.comm API is so stuck in the time that does not even offer the generics of Java 5 (which is already very old with its 12 years):

private CommPortIdentifier localizarPortaSerial() {
    CommPortIdentifier portaId = null;
    List<CommPortIdentifier> portas = Collections.list((Enumeration<CommPortIdentifier>) CommPortIdentifier.getPortIdentifiers());

    for (CommPortIdentifier portaId : portas) {
        if (porta.equals(portaId.getName())) return portaId;
    }
    Exibir_ERRO("Não se pode conectar a porta");
    System.exit(ERROR);
    throw new AssertionError(); // Nunca será executado por causa do System.exit.
}

public void iniciarConexao() {
    CommPortIdentifier portaId = localizarPortaSerial();

    try {
        serialPort = (SerialPort) portaId.open(this.getClass().getName(), timeOut);
        serialPort.setSerialPortParams(dataRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        output = serialPort.getOutputStream();
    } catch (Exception e) {
        Exibir_ERRO(e.getMessage());
        System.exit(ERROR);
    }
}

There should be a lot more possible improvements, but for this I would need to know more details of the class that has methods iniciarConexao() and enviarDados() and field porta . In particular, using System.exit is a bad programming practice - never use that - but without seeing the rest of the class, I can not tell you how you could eliminate it.

    
05.11.2016 / 04:41
0

It does not matter what kind of variable you get on the NetBeans side because it's "converted" to serial communication.

According to what I noticed, you want to read integers from a string sent by NetBeans. I will use a case of my own as an example. I would send 3 integer values through the serial port and read as follows:

int t1=0, t2=90, t3=0;
String a;
a=Serial.readString();
sscanf(a,"%d %d %d",&t1,&t2,&t3);

Did you help?

    
04.11.2016 / 01:59