Go Down

Topic: Adicionar separador em uma matriz de caracteres (Read 2821 times) previous topic - next topic

FernandoGarcia

Nov 24, 2012, 11:05 pm Last Edit: Nov 24, 2012, 11:25 pm by FernandoGarcia Reason: 1
Olá!

Gostaria que me ajudassem a resolver um problema no meu código.

A questão é a seguinte:

Tenho um sensor que enviar valores para a porta serial 3 separados por  '\r'
(carro de retorno).
Quero inserir uma vírgula "," toda vez que o '\r' for encontrado para poder separar a matriz usando o strtok_r.

Code: [Select]

char inData[100];
char *inParse[100];
int index = 0;
int contador = 0;
boolean stringComplete = false;

    do
    {
      if (Serial3.available()>3)
      {
        char inChar = Serial3.read();
        inData[index] = inChar;
        index++;     
        if (inChar == '\r')
        {
          contador ++;
          inData[index] = ; //Adicionar carácter aqui? como?
        }
        if(contador == 10)
        {
          inData[index] = '\0';
          contador = 0;
          index = 0;
          stringComplete = true;
        }
      }
    }
    while(stringComplete == false);
   
char *p = inData;

    if (stringComplete == true)
    {

      while ((str = strtok_r(p, ",", &p)) != NULL)
      {   
        inParse[count] = str;
        count++;     
      }
   }


Existe outra maneira de separar os valores?

Grato.
Fernando Garcia

bubulindo

Porque é que não usas o strtok com o '\r' ? strtok();

O que pretendes com isto:

Code: [Select]
char *inParse[100];

O código que tens no post compila?

This... is a hobby.

ErickPC


FernandoGarcia


Porque é que não usas o strtok com o '\r' ? strtok();

O que pretendes com isto:

Code: [Select]
char *inParse[100];

O código que tens no post compila?





Olá!
Obrigado pela resposta.

Sim, o código compila.

aqui está o código completo.

Code: [Select]

const int multiplexPIN1 = A14; // S0
const int multiplexPIN2 = A15; //S1

char inData[100];
char *inParse[100];
int index = 0;
int contador = 0;
boolean stringComplete = false;

int  int_valor_1 = 0;

short ph1=0; //Y0
short ph2=1; //Y1
short orp=2; //Y2
short ec=3; //Y3

int ORP = 0;
char limpar_valor[100] = "";

void setup()
{                                                             
  Serial.begin(38400);                                                     
  Serial3.begin(38400);
  pinMode(multiplexPIN1, OUTPUT);
  pinMode(multiplexPIN2, OUTPUT);

  Open_channel(orp);
  Serial3.print("L0");
  Serial3.print('\r');
  delay(500);

  Open_channel(orp);
  Serial3.print("c");
  Serial3.print('\r');
  delay(500);
}

void loop()
{
  check_parametros_3(); 
}

void check_parametros_3()
{
  char *str;   
  int count = 0;

   Serial3.flush();
   
    Open_channel(orp);
    do
    {
      if (Serial3.available()>3)
      {
        char inChar = Serial3.read();
        inData[index] = inChar;
        index++;     
        if (inChar == '\r')
        {
          contador ++;
          inData[index] = *",";
        }
        if(contador == 10)
        {
          inData[index] = '\0';
          contador = 0;
          index = 0;
          stringComplete = true;
        }
      }
    }
    while(stringComplete == false);
   
char *p = inData;

    if (stringComplete == true)
    {

      while ((str = strtok_r(p, ",", &p)) != NULL)
      {   
        inParse[count] = str;
        count++;     
      }
      p = NULL;
      Serial.print("ORP:");
      Serial.print("[");
      Serial.print(inParse[0]);
      Serial.println("]");
      int_valor_1 = atoi(inParse[0]);
      memcpy(inParse, limpar_valor, sizeof(limpar_valor));
      stringComplete = false;
      ORP = int_valor_1;
      Serial.print("ORP:");
      Serial.println(ORP);
      int_valor_1 = 0;
  }
}


void Open_channel(short channel)
{
  switch (channel)
  {
  case 0:
    //open channel Y0
    //S0=0
    //S1=0
    digitalWrite(multiplexPIN1, LOW);
    digitalWrite(multiplexPIN2, LOW);
    break;

  case 1:
    //open channel Y1
    //S0=1
    //S1=0
    digitalWrite(multiplexPIN1, HIGH);
    digitalWrite(multiplexPIN2, LOW);
    break;

  case 2:
    //open channel Y2
    //S0=0
    //S1=1
    digitalWrite(multiplexPIN1, LOW);
    digitalWrite(multiplexPIN2, HIGH);
    break;

  case 3:
    //open channel Y3
    //S0=1
    //S1=1
    digitalWrite(multiplexPIN1, HIGH);
    digitalWrite(multiplexPIN2, HIGH);
    break;
  }
  Serial3.print('\r');
  return;
}



Para:
Code: [Select]

      Serial.print("ORP:");
      Serial.print("[");
      Serial.print(inParse[0]);
      Serial.println("]");
      int_valor_1 = atoi(inParse[0]);
      memcpy(inParse, limpar_valor, sizeof(limpar_valor));
      stringComplete = false;
      ORP = int_valor_1;
      Serial.print("ORP:");
      Serial.println(ORP);


Recebo essa resposta:



Para:
Code: [Select]

      Serial.print("ORP:");
      Serial.print("[");
      Serial.print(inParse[1]);
      Serial.println("]");
      int_valor_1 = atoi(inParse[1]);
      memcpy(inParse, limpar_valor, sizeof(limpar_valor));
      stringComplete = false;
      ORP = int_valor_1;
      Serial.print("ORP:");
      Serial.println(ORP);


Recebo essa resposta:



O que significa que o programa não separa os valores.

Como tenho 4 sensores enviando valores para a porta serial, as vezes as primeiras leituras não é do sensor que quero.
Então quero descartar os primeiros valores.

Também quero fazer uma média de algumas leituras.

Assim:
Code: [Select]

int_valor_1 = ((atoi(inParse[15]) + atoi(inParse[16]) + atoi(inParse[17]) +atoi(inParse[18]) + atoi(inParse[19])) / 5);


Abraço.

FernandoGarcia


Dê uma olhada neste tópico, eles estão discutindo justamente isso!

http://arduino.cc/forum/index.php/topic,41389.0.html


Olá!

Obrigado pela resposta.

Se os meus valores fossem separados por espaços seria mais fácil.

Abraço.

bubulindo


Porque é que não usas o strtok com o '\r' ? strtok();


Respondeste a isto?


Olá!

Obrigado pela resposta.

Se os meus valores fossem separados por espaços seria mais fácil.

Abraço.

E quais são exactamente os teus valores? Podes dar um exemplo? Talvez seja mais fácil para contextualizar o teu código. :\

Em todo o caso, quando tens um array conhecido... podes fazer isto:

Code: [Select]


char STR_array[20];
.....
for (int i = 0; i<20; i++) {
    if (STR_array[i] == '\r')
        STR_array[i] = ',';
}
....

E fica tudo separado por virgulas em vez de \r
This... is a hobby.

FernandoGarcia

Quote
Respondeste a isto?


Porque penso que esta função vai transformar os valores em uma string e não conseguirei buscar uma posição específica.
Algo do tipo:

(225.24325.24295.24275.24625.24525.24265.24825.24125.24)

Quote
E quais são exactamente os teus valores? Podes dar um exemplo? Talvez seja mais fácil para contextualizar o teu código. :\


Os valores podem ser qualquer um.

Algo do tipo:

(225.24'\r'325.24'\r'295.24'\r'275.24'\r'625.24'\r'525.24'\r'265.24'\r'825.24'\r'125.24'\r')

Quote
Em todo o caso, quando tens um array conhecido... podes fazer isto:


Não consigo saber quantos caracteres vão estar disponíveis no momento da leitura.

Obrigado.


bubulindo

Isso não é resposta... já experimentaste o strtok com o \r?

Se não sabes quantos vais receber, sabes o tamanho da trama? Se sabes, esperas por ter esse número de caracteres disponível no buffer e sabendo lês até encontrares o \r...

No teu exemplo:

Code: [Select]


char num[8];
num[6] = '\0';
num[7] = '\0';

if (Serial.available() >= 7) { //225.24\r 7 caracteres...
   for (int i = 0; i < 6; i++) {
      num[i] = Serial.read();
   }
   int val = atoi(num);
   Serial.print("number: ");
   Serial.println(val);
}
 


This... is a hobby.

FernandoGarcia


Isso não é resposta... já experimentaste o strtok com o \r?


Desculpe, a resposta completa para sua pergunta é:

Não, porque penso que esta função vai transformar os valores em uma string e não conseguirei buscar uma posição específica.

Abraço.

bubulindo

Ok...

Eu continuo confuso com o que pretendes (ou se tens em atenção as limitações do chip...). Importas-te de explicar exactamente o que pretendes com isto para que possamos dar uma ideia melhor de como resolver o teu problema?

Eu já te mostrei como trocar o \r por uma vírgula... Se não sabemos como o sistema funciona, ou pretendes que funcione, não podemos fazer muito mais, né?
This... is a hobby.

FernandoGarcia

Olá!
bubulindo,obrigado pelas suas resposta.
Com base na sua sugestão consegui resolver o meu problema.

Fica aqui o código completo caso alguém necessite.

Code: [Select]

const int multiplexPIN1 = A14; // S0
const int multiplexPIN2 = A15; //S1

char inData[150];
char *inParse[150];
int index = 0;
int contador = 0;
boolean stringComplete = false;

int  int_valor_1 = 0;
float  float_valor_1 = 0;

short ph1=0; //Y0
short ph2=1; //Y1
short orp=2; //Y2
short ec=3; //Y3

int ORP = 0;
int DEN = 0;
float PHA = 0.0;
float PHR = 0.0;

void setup()
{                                                             
  Serial.begin(38400);                                                     
  Serial3.begin(38400);
  pinMode(multiplexPIN1, OUTPUT);
  pinMode(multiplexPIN2, OUTPUT);

  Open_channel(ph1);
  Serial3.print("L0");
  Serial3.print('\r');
  delay(500);
  Serial3.flush();
  Serial3.print("c");
  Serial3.print('\r');

  Open_channel(ph2);
  Serial3.print("L0");
  Serial3.print('\r');
  delay(500);
  Serial3.flush();
  Serial3.print("c");
  Serial3.print('\r');

  Open_channel(orp);
  Serial3.print("L0");
  Serial3.print('\r');
  delay(500);
  Serial3.flush();
  Serial3.print("c");
  Serial3.print('\r');
/*   
   Open_channel(ec);
   Serial3.print("L0");
   Serial3.print('\r');
   delay(500);
   Serial3.flush();
   Serial3.print("c");
   Serial3.print('\r');*/
}
long millis_antes = 0;

void loop()
{
  if((millis() - millis_antes) >= 10000)
  {
    millis_antes = millis();
    check_parametro_ph_aquario();
    check_parametro_ph_reator();
    check_parametro_orp();
   // check_parametro_densidade();
  }
}

void check_parametro_ph_aquario()
{
  char *str;   
  int count = 0;

  Serial3.flush();

  Open_channel(ph1);
  do
  {
    if (Serial3.available()>3)
    {
      char inChar = Serial3.read();
      inData[index] = inChar;
      index++;     
      if (inChar == '\r')
      {
        contador ++;
      }
      if(contador == 20)
      {
        inData[index] = '\0';
        contador = 0; 
        stringComplete = true;
      }
    }
  }
  while(stringComplete == false);

  for (int i= 0; i <= index; i++)
  {
    if (inData[i] == '\r')
    {
      inData[i] = ',';
    }
  }
  index = 0;
  char *p = inData;

  if (stringComplete == true)
  {

    while ((str = strtok_r(p, ",", &p)) != NULL)
    {   
      inParse[count] = str;
      count++;     
    }
    p = NULL;

    for(int i= 12;i <=19; i++)
    {
      float_valor_1 += atof(inParse[i]);
    }
    float_valor_1 /= 8;

    stringComplete = false;
    PHA = float_valor_1;
    Serial.print("PH do aquario:");
    Serial.println(PHA);
    Serial.print("[");
    Serial.print(inParse[12]);
    Serial.print(", ");
    Serial.print(inParse[13]);
    Serial.print(", ");
    Serial.print(inParse[14]);
    Serial.print(", ");
    Serial.print(inParse[15]);
    Serial.print(", ");
    Serial.print(inParse[16]);
    Serial.print(", ");
    Serial.print(inParse[17]);
    Serial.print(", ");
    Serial.print(inParse[18]);
    Serial.print(", ");
    Serial.print(inParse[19]);
    Serial.println("]");
    float_valor_1 = 0;
  }
}

void check_parametro_ph_reator()
{
  char *str;   
  int count = 0;

  Serial3.flush();

  Open_channel(ph2);
  do
  {
    if (Serial3.available()>3)
    {
      char inChar = Serial3.read();
      inData[index] = inChar;
      index++;     
      if (inChar == '\r')
      {
        contador ++;
      }
      if(contador == 20)
      {
        inData[index] = '\0';
        contador = 0; 
        stringComplete = true;
      }
    }
  }
  while(stringComplete == false);

  for (int i= 0; i <= index; i++)
  {
    if (inData[i] == '\r')
    {
      inData[i] = ',';
    }
  }
  index = 0;
  char *p = inData;

  if (stringComplete == true)
  {

    while ((str = strtok_r(p, ",", &p)) != NULL)
    {   
      inParse[count] = str;
      count++;     
    }
    p = NULL;

    for(int i= 12;i <=19; i++)
    {
      float_valor_1 += atof(inParse[i]);
    }
    float_valor_1 /= 8;

    stringComplete = false;
    PHR = float_valor_1;
    Serial.print("PH do reator:");
    Serial.println(PHR);
    Serial.print("[");
    Serial.print(inParse[12]);
    Serial.print(", ");
    Serial.print(inParse[13]);
    Serial.print(", ");
    Serial.print(inParse[14]);
    Serial.print(", ");
    Serial.print(inParse[15]);
    Serial.print(", ");
    Serial.print(inParse[16]);
    Serial.print(", ");
    Serial.print(inParse[17]);
    Serial.print(", ");
    Serial.print(inParse[18]);
    Serial.print(", ");
    Serial.print(inParse[19]);
    Serial.println("]");
    float_valor_1 = 0;
  }
}

void check_parametro_orp()
{
  char *str;   
  int count = 0;

  Serial3.flush();

  Open_channel(orp);
  do
  {
    if (Serial3.available()>3)
    {
      char inChar = Serial3.read();
      inData[index] = inChar;
      index++;     
      if (inChar == '\r')
      {
        contador ++;
      }
      if(contador == 20)
      {
        inData[index] = '\0';
        contador = 0; 
        stringComplete = true;
      }
    }
  }
  while(stringComplete == false);

  for (int i= 0; i <= index; i++)
  {
    if (inData[i] == '\r')
    {
      inData[i] = ',';
    }
  }
  index = 0;
  char *p = inData;

  if (stringComplete == true)
  {

    while ((str = strtok_r(p, ",", &p)) != NULL)
    {   
      inParse[count] = str;
      count++;     
    }
    p = NULL;

    for(int i= 12;i <=19; i++)
    {
      int_valor_1 += atoi(inParse[i]);
    }
    int_valor_1 /= 8;

    stringComplete = false;
    ORP = int_valor_1;
    Serial.print("ORP:");
    Serial.println(ORP);
    Serial.print("[");
    Serial.print(inParse[12]);
    Serial.print(", ");
    Serial.print(inParse[13]);
    Serial.print(", ");
    Serial.print(inParse[14]);
    Serial.print(", ");
    Serial.print(inParse[15]);
    Serial.print(", ");
    Serial.print(inParse[16]);
    Serial.print(", ");
    Serial.print(inParse[17]);
    Serial.print(", ");
    Serial.print(inParse[18]);
    Serial.print(", ");
    Serial.print(inParse[19]);
    Serial.println("]");
    int_valor_1 = 0;
  }
}

void check_parametro_densidade()
{
  char *str;   
  int count = 0;

  Serial3.flush();

  Open_channel(ec);
  do
  {
    if (Serial3.available()>0)
    {
      char inChar = Serial3.read();
      inData[index] = inChar;
      index++;     
      if (inChar == '\r')
      {
        contador ++;
      }
      if(contador == 20)
      {
        inData[index] = '\0';
        contador = 0; 
        stringComplete = true;
      }
    }
  }
  while(stringComplete == false);

  for (int i= 0; i <= index; i++)
  {
    if (inData[i] == '\r')
    {
      inData[i] = ',';
    }
  }
  index = 0;
  char *p = inData;

  if (stringComplete == true)
  {

    while ((str = strtok_r(p, ",", &p)) != NULL)
    {   
      inParse[count] = str;
      count++;     
    }
    p = NULL;

    for(int i= 12;i <=19; i++)
    {
      int_valor_1 += atoi(inParse[i]);
    }
    int_valor_1 /= 8;

    stringComplete = false;
    DEN = int_valor_1;
    Serial.print("Densidade");
    Serial.println(DEN);
    Serial.print("[");
    Serial.print(inParse[12]);
    Serial.print(", ");
    Serial.print(inParse[13]);
    Serial.print(", ");
    Serial.print(inParse[14]);
    Serial.print(", ");
    Serial.print(inParse[15]);
    Serial.print(", ");
    Serial.print(inParse[16]);
    Serial.print(", ");
    Serial.print(inParse[17]);
    Serial.print(", ");
    Serial.print(inParse[18]);
    Serial.print(", ");
    Serial.print(inParse[19]);
    Serial.println("]");
    int_valor_1 = 0;
  }
}

void Open_channel(short channel)
{
  switch (channel)
  {
  case 0:
    //open channel Y0
    //S0=0
    //S1=0
    digitalWrite(multiplexPIN1, LOW);
    digitalWrite(multiplexPIN2, LOW);
    break;

  case 1:
    //open channel Y1
    //S0=1
    //S1=0
    digitalWrite(multiplexPIN1, HIGH);
    digitalWrite(multiplexPIN2, LOW);
    break;

  case 2:
    //open channel Y2
    //S0=0
    //S1=1
    digitalWrite(multiplexPIN1, LOW);
    digitalWrite(multiplexPIN2, HIGH);
    break;

  case 3:
    //open channel Y3
    //S0=1
    //S1=1
    digitalWrite(multiplexPIN1, HIGH);
    digitalWrite(multiplexPIN2, HIGH);
    break;
  }
  Serial3.print('\r');
  return;
}



Os circuitos utlizados são esses:

http://atlas-scientific.com/product_pages/embedded/rs-232.html
http://atlas-scientific.com/product_pages/embedded/ph.html
http://atlas-scientific.com/product_pages/embedded/orp.html
http://atlas-scientific.com/product_pages/embedded/ec.html

Aqui o esquema da ligação



Caso alguém queira conhecer meu projeto pode encontrá-lo aqui: https://github.com/FernandoGarcia/Ferduino

Abraço.
Fernando Garcia

Go Up