Adicionar separador em uma matriz de caracteres

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.

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

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

O que pretendes com isto:

char *inParse[100];

O código que tens no post compila?

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

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

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

O que pretendes com isto:

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.

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:

      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:

      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:

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

Abraço.

ErickPC:
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?

FernandoGarcia:
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:

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

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)

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')

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.

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:

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);
}

bubulindo:
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.

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é?

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.

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