Go Down

Topic: Problem sending datas from Arduino to the computer. (Read 3076 times) previous topic - next topic

iceman_f5

I am doing a program which I sent an instruction from the computer to Arduino, and Arduino respond sending a short text to the computer.
My problem is that there is a line where if I try to send something different from "mas", Arduino doesn't send anything. Even the other Serial.println() instructions don't work.
When I send "mas" everything works right. I don't understand what is the problem and how to solve it.

The problematic line has a comment in the end, where I explain briefly the problem.

Code: [Select]
//Codigo adapted to Arduino Mega2560

int led = 13;
int dispCentenas = 6;
int dispDecenas = 7;
int dispUnidades = 8;
int A_1 = 2;
int B_1 = 3;
int C_1 = 4;
int D_1 = 5;
int A_2 = 9;
int B_2 = 10;
int C_2 = 11;
int D_2 = 12;
int sonda = A0;
int ledGrill = 14;
int ledRestAbajo = 15;
int ledEncendido = 16;
int ledRestEncendidas = 17;
int elegirRest = 18;
int marcha= 19;
int dismTemp = 20;
int aumTemp = 21;
int actGrill = 22;
int actRestAbajo = 23;
int tempSeleccionada = 100;
int tempHorno = 0;
int numero1[3] = {0,0,0};
int numero2[3] = {0,0,0};
int restElegidas;
boolean funcionando = false;
char recibido[11];
String instruccion;
int longitud;
int valorSonda;
int valores[4]={0,0,0,0};
int puntero=0;

void setup() {   
   
  pinMode(led, OUTPUT);
  pinMode(dispCentenas, OUTPUT);
  pinMode(dispDecenas, OUTPUT);
  pinMode(dispUnidades, OUTPUT);
  pinMode(A_1, OUTPUT);
  pinMode(B_1, OUTPUT);
  pinMode(C_1, OUTPUT);
  pinMode(D_1, OUTPUT);
  pinMode(A_2, OUTPUT);
  pinMode(B_2, OUTPUT);
  pinMode(C_2, OUTPUT);
  pinMode(D_2, OUTPUT);
  pinMode(ledGrill, OUTPUT);
  pinMode(ledRestAbajo, OUTPUT);
  pinMode(ledEncendido, OUTPUT);
  pinMode(ledRestEncendidas, OUTPUT);
  pinMode(elegirRest, INPUT);
  pinMode(marcha, INPUT);
  pinMode(dismTemp, INPUT);
  pinMode(aumTemp, INPUT);
  pinMode(actGrill, OUTPUT);
  pinMode(actRestAbajo, OUTPUT);
  analogReference(DEFAULT);
  Serial.begin(9600);
}

void loop() {
// number=analogRead(A0);
  //number=/4;
  tempHorno=analogRead(A0);
  trocear(tempHorno, numero1);
  trocear(tempSeleccionada, numero2);
  digitalWrite(actGrill, LOW);
  digitalWrite(actRestAbajo, LOW);

  while (!funcionando)
  {
    if (Serial.available() > 0)
    {
      for (int i=0; i<12; i++)
      {
        recibido[i]='\0';
      }
      longitud=Serial.readBytesUntil('\0',recibido,11);
      instruccion=recibido;
    }
   
    valorSonda=analogRead(A0);
    convTemperatura();
    trocear(tempHorno, numero1);
    mostrar();
   
  if (digitalRead(elegirRest) || instruccion=="resist")
  {
    instruccion[0]='\0';
   
    if (restElegidas==2)
    {
      restElegidas=0;
    }
    else
    {
      restElegidas++;
    }
    switch (restElegidas)
    {
      case 1:
        digitalWrite (ledGrill, HIGH);
        break;
      case 2:
        digitalWrite (ledRestAbajo, HIGH);
        break;
       
      default:
        digitalWrite (ledGrill, LOW);
        digitalWrite (ledRestAbajo, LOW);
    }
    while (digitalRead(elegirRest))
    {
      mostrar();
    } 
    Serial.println("I resist");
  }
  if (digitalRead(marcha) || instruccion=="marcha")
  {
    instruccion[0]='\0';
    funcionando = true;
    digitalWrite(ledEncendido, HIGH);
    Serial.println("I marcha");
    while (digitalRead(marcha))
    {
      mostrar();
    }
  }
 
  if (digitalRead(dismTemp) || instruccion=="menos")
  {
    instruccion[0]='\0';
    tempSeleccionada = tempSeleccionada-10;
    trocear(tempSeleccionada, numero2);
    while (digitalRead(dismTemp))
    {
    delay(10);
    mostrar();
    }
    Serial.println("I menos");
  }
 
  if (digitalRead(aumTemp) || instruccion=="mas")
  {
    instruccion[0]='\0';
    tempSeleccionada = tempSeleccionada+10;
    trocear(tempSeleccionada, numero2);
    while (digitalRead(aumTemp))
    {
    delay(10);
    mostrar();
    }

    Serial.print("mas");  // If I try to send something different from "mas" in this line, Arduino doesn't send anything
  }

  }
  //-------------------FUNCIONANDO-----------------------
  while (funcionando)
  {   
    if (Serial.available() > 0)
    {
      for (int i=0; i<12; i++)
      {
        recibido[i]='\0';
      }
      longitud=Serial.readBytesUntil('\0',recibido,11);
      instruccion=recibido;
    }
    tempHorno=analogRead(A0);
    convTemperatura();
    trocear(tempHorno, numero1);
    mostrar();
    Serial.println(tempHorno);
    if (tempHorno < tempSeleccionada && restElegidas!=0)
    {
      tempHorno=analogRead(A0);
      trocear(tempHorno, numero1);
      mostrar();
      Serial.println(tempHorno);
      digitalWrite(ledRestEncendidas, HIGH);
      switch(restElegidas)
      {
        case 1:
          digitalWrite(actGrill, HIGH);
          break;
        case 2:
          digitalWrite(actGrill, HIGH);
          digitalWrite(actRestAbajo, HIGH);
          break;
        default:
          delay (20);
      }
    }
    else
    {
      tempHorno=analogRead(A0);
      Serial.println(tempHorno);
      digitalWrite(ledRestEncendidas, LOW);
      digitalWrite(actGrill, LOW);
      digitalWrite(actRestAbajo, LOW);
    }
    if (digitalRead(marcha) || instruccion=="paro")
    {
      instruccion[0]='\0';
      funcionando = false;
      digitalWrite(ledEncendido, LOW);
      digitalWrite(ledRestEncendidas, LOW);
      digitalWrite(actGrill, LOW);
      digitalWrite(actRestAbajo, LOW);
      Serial.println("parada");   
      while (digitalRead(marcha))
      {
        mostrar();
        delay(10);
      }     
    }
   
  }
}
//-----------------FIN DEL BUCLE LOOP---------------------
void trocear(int numero, int trozos[3])
{
  trozos[0]=numero %10;
  numero/=10;
  trozos[1]=numero % 10;
  numero/=10;
  trozos[2]=numero %10;
}

void mostrar()
{
  digitalWrite(dispUnidades, LOW);
  digitalWrite(dispDecenas, LOW);
  digitalWrite(dispCentenas, LOW);
  digitalWrite(A_1, numero2[0] & B0001);
  digitalWrite(B_1, numero2[0] & B0010);
  digitalWrite(C_1, numero2[0] & B0100);
  digitalWrite(D_1, numero2[0] & B1000);
  digitalWrite(A_2, numero1[0] & B0001);
  digitalWrite(B_2, numero1[0] & B0010);
  digitalWrite(C_2, numero1[0] & B0100);
  digitalWrite(D_2, numero1[0] & B1000);
  digitalWrite(dispUnidades, HIGH);
  delay(10);
 
  digitalWrite(dispUnidades, LOW);
  digitalWrite(dispDecenas, LOW);
  digitalWrite(dispCentenas, LOW);
  digitalWrite(A_1, numero2[1] & B0001);
  digitalWrite(B_1, numero2[1] & B0010);
  digitalWrite(C_1, numero2[1] & B0100);
  digitalWrite(D_1, numero2[1] & B1000);
  digitalWrite(A_2, numero1[1] & B0001);
  digitalWrite(B_2, numero1[1] & B0010);
  digitalWrite(C_2, numero1[1] & B0100);
  digitalWrite(D_2, numero1[1] & B1000);
  digitalWrite(dispDecenas, HIGH);
  delay(10);
 
  digitalWrite(dispUnidades, LOW);
  digitalWrite(dispDecenas, LOW);
  digitalWrite(dispCentenas, LOW);
  digitalWrite(A_1, numero2[2] & B0001);
  digitalWrite(B_1, numero2[2] & B0010);
  digitalWrite(C_1, numero2[2] & B0100);
  digitalWrite(D_1, numero2[2] & B1000);
  digitalWrite(A_2, numero1[2] & B0001);
  digitalWrite(B_2, numero1[2] & B0010);
  digitalWrite(C_2, numero1[2] & B0100);
  digitalWrite(D_2, numero1[2] & B1000);
  digitalWrite(dispCentenas, HIGH);
  delay(10);
  digitalWrite(led, LOW);
}

void convTemperatura()
{
  if (puntero==4) puntero=0;
  valores[puntero]=valorSonda;
  puntero++;
  for (int i=0; i<4; i++)
  {
    tempHorno+=valores[i];
  }
  tempHorno/=5;
  // queda realizar la conversion a grados
}

PaulS

Code: [Select]
String instruccion;
First thing to do is get rid of that line.

Code: [Select]
      longitud=Serial.readBytesUntil('\0',recibido,11);
What is sending the serial data? None of the standard methods sends a NULL.

Code: [Select]
      instruccion=recibido;
Completely unnecessary.

You have a lot of Serial.print() statements. Perhaps the issue is that you are running out of SRAM. Wasting it using the String class does not help.
http://playground.arduino.cc/Code/AvailableMemory

iceman_f5


Code: [Select]
String instruccion;
First thing to do is get rid of that line.

Code: [Select]
      longitud=Serial.readBytesUntil('\0',recibido,11);
What is sending the serial data? None of the standard methods sends a NULL.

Code: [Select]
      instruccion=recibido;
Completely unnecessary.

You have a lot of Serial.print() statements. Perhaps the issue is that you are running out of SRAM. Wasting it using the String class does not help.
http://playground.arduino.cc/Code/AvailableMemory


I will look at all you say. I think you are right and I am creating unnecessary variables wasting memory.
I don't know much C language, so the most of the times I do the things in a long and complicate way; not efficient way.
However, I think that the code is in program memory (flash memory) and the variables are in the data memory (SRAM).

iceman_f5

#3
Mar 09, 2013, 08:05 pm Last Edit: Mar 09, 2013, 11:52 pm by iceman_f5 Reason: 1
I have changed:
Code: [Select]
longitud=Serial.readBytesUntil('\0',recibido,11);

For:
Code: [Select]
longitud=Serial.readBytes(recibido,11);

And the program works right.

I have to save 'recibido' in a String because and array has the character '\0' at the end, so if I use 'recibido' in the statement of 'if' function, this doesn't works.
Then:
Code: [Select]
String instruccion;
instruccion=recibido;

Are necessary.

This is the way that I have been able to make that the program works.

PaulS

Quote
I have to save 'recibido' in a String because and array has the character '\0' at the end, so if I use 'recibido' in the statement of 'if' function, this doesn't works.

No, you don't. The NULL at the end of a char array makes it a string, and people dealt with strings for 40 years before there were Strings. The strcmp() function will tell you if two strings are equal, with wasting ANY resources.

iceman_f5


Quote
I have to save 'recibido' in a String because and array has the character '\0' at the end, so if I use 'recibido' in the statement of 'if' function, this doesn't works.

No, you don't. The NULL at the end of a char array makes it a string, and people dealt with strings for 40 years before there were Strings. The strcmp() function will tell you if two strings are equal, with wasting ANY resources.



Code: [Select]
longitud=Serial.readBytes(recibido,11);
I tried using 'recibido' in the stament of 'if' functions and this didn't work and in the way that I am doing now the program works.
I don't know much about programming, so many times I try in a way or in another way until I get that the program works.
I don't know much English too, so I am sure that my explanations are no clear and my grammar is not good enough.

I will use the function that you say to compate 'recibido' and what I need in the 'if' statement in order to understand what is the problem.

Thank you for your help.
I will write my progress.

iceman_f5


Quote
I have to save 'recibido' in a String because and array has the character '\0' at the end, so if I use 'recibido' in the statement of 'if' function, this doesn't works.

No, you don't. The NULL at the end of a char array makes it a string, and people dealt with strings for 40 years before there were Strings. The strcmp() function will tell you if two strings are equal, with wasting ANY resources.


I have make some changes in the program based in your advices, but I have found another "problem"; if I write 'recibido=="mas"' in the 'if' statement, the statement is never true. I solved it writting '!strcmp(recibido,"mas")'.
For example:
Code: [Select]
if (recibido == "mas") is never true.
Code: [Select]
if (!strcmp(recibido,"mas")) is true when I have sent 'mas' through the serial port.

Could you explain me why I can't use the first form?
*recibido is a char array.

Now, I think that the program works right.
Thank you very much for your help.

PaulS

Quote
Could you explain me why I can't use the first form?

recibido is a pointer to the start of a block of memory.

"mas" is a string literal. Is there any way that a pointer and string literal can possibly be equal?

Only in the same way that a tennis shoe and an elephant can be equal.

strcmp() returns -1 if the strings are in one order, 0 if they are equal, and +1 if they are in the opposite order. It does NOT return a boolean, so the boolean usage is wrong.

iceman_f5


Quote
Could you explain me why I can't use the first form?

recibido is a pointer to the start of a block of memory.

"mas" is a string literal. Is there any way that a pointer and string literal can possibly be equal?

Only in the same way that a tennis shoe and an elephant can be equal.

strcmp() returns -1 if the strings are in one order, 0 if they are equal, and +1 if they are in the opposite order. It does NOT return a boolean, so the boolean usage is wrong.



The use of a int as a boolean is not a good way in programming, but sometimes works. In this cases probably works, and it is easy to use. But I understand that is not correct. I'll change it.
I didn't know that 'recibido' was a pointer, I thought that 'recibido' was the contents of the array. Because of that I didn't understand what was the problem.

PaulS

Pointers and arrays are very closely related. You can think of an array as a collection of objects, but in reality the declaration itself is nothing more than the address of the first element of the array. Perhaps this makes it clear(er) why you can't simply use == to compare a string literal (stored in one location in memory) with an array (a pointer to another location in memory).

iceman_f5


Pointers and arrays are very closely related. You can think of an array as a collection of objects, but in reality the declaration itself is nothing more than the address of the first element of the array. Perhaps this makes it clear(er) why you can't simply use == to compare a string literal (stored in one location in memory) with an array (a pointer to another location in memory).


I undestand what you say, but I don't know how to solve it.
I have another doubt with Java.
When I execute this code I see that the length of contenido is two bytes bigger that I expected, so I can't compare it with the array that I am looking for.
Why is the length bigger and what are the character that have been added?
Code: [Select]
inString = puerto.readString();
  println(inString);
  tipo = inString.charAt(0);
   if (tipo == 'I')
    {
      contenido = inString.substring(2);
      println(contenido.length());
      println(tipo);
      println(contenido);
  }

PaulS

Quote
Why is the length bigger and what are the character that have been added?

Send me your computer so I can see the screen, and I'll tell you. Otherwise, you'll need to print each character in hex to find out. I'd guess that a carriage return and line feed were added somewhere.

iceman_f5


Quote
Why is the length bigger and what are the character that have been added?

Send me your computer so I can see the screen, and I'll tell you. Otherwise, you'll need to print each character in hex to find out. I'd guess that a carriage return and line feed were added somewhere.


Sending my computer to Seattle will takes too much time; time to go and time to go back to Spain, and I need the computer.
Probably you're right and the characters added are carriage return and line feed. I will try to convert the string to hex to see what character are.
Thank you for the idea. I am a bit lost sometimes.

Go Up