Porta Serial Array

Estou fazendo um programa que recebera comandos da porta serial, como estou ainda esta em desenvolvimento estou-me detento agora no protocolo em si é criar uma lista de comandos para fazer algumas funções, no código inicial abaixo que é só um teste, eu digito três dígitos na porta serial com uma terminação com vírgula ou outro qualquer quarto caractere. Ao receber o comando "yui,", ele envia em retorno na Porta serial o buffer armazenado que deve ser "yui", Caractere por Caractere e depois envia a matriz inteira que deve retornar também "yui", após fazer isso ele retornara a mensagem "ok", como na imagem.

// Matriz C_1 3 caracter
char C_1[2];

void setup()
{
// Taxa de Trasnferencia da porta serial
Serial.begin(9600);
}

void loop()
{

}

//----------------------------------------------------------------

void serialEvent ()
{
// Matriz buffer 3 caracter
char buffer[2];
//Ler Porta serial
if ( Serial.available ()>=4)
{
// armazena na matriz buffer o Buffer da porta serial
Serial.readBytesUntil (',', &buffer[0], 4 );
//Redimenciona Buffer Serial para Matriz C_1
C_1[0]= buffer[0];
C_1[1]= buffer[1];
C_1[2]= buffer[2];
//Imprimi 1º da matriz C_1
Serial.print(C_1[0]);
//Imprimi 2º da matriz C_1
Serial.print(C_1[1]);
//Imprimi 3º da matriz C_1
Serial.print(C_1[2]);
//Coloca quebra de linha
Serial.print("\n");
//Imprimi C_1 inteira
Serial.print(C_1);
//Coloca quebra de linha
Serial.print("\n");
//Imprimi ok se a matriz C_1 for igual a yui
if (C_1=="yui")
{
Serial.print("ok");
Serial.print("\n");
}
}
}

Acontece que ao invés de receber os dados como na Imagem1 ele recebe como na Imagem2. Como não tenho tanta familiaridade com o Arduino acredito que seja o redimensionamento da matriz buffer para a C_1. Logo se for isso como eu faço certo se não é isso o pode estar dando errado.

Imagem1.jpg

Imagem2.jpg

Boas,

Não sou um pro do arduino nem de longe mas penso que o teu erro esta na declaração do tamanho do teus array, se vires a docs esta la escrito

Note that when declaring an array of type char, one more element than your initialization is required, to hold the required null character.

Cpts

Zé tretas

o teu buffer tem 2 posições... estás a escrever em 4 posições.

lol

boas 2 não ... são 3 ... é que o gajo que inventou o C deveria ter sido tropa ... logo o zero também conta ... apesar de o buffer[2] ser para o " null character "

Cpts

Zé tretas

isso depende de como inicializas o array.

a forma que ele fez foi criar apenas 2 posições, nada para o terminador.

ups ups ups

bubulindo tens razão ... mais uma vez estava a errar o "zero" apenas serve para aceder

Estava sem internet por isso não Respondi antes, mas obrigado por colaborarem com meu primeiro post. Há desculpe te inserido o código em um objeto Quote , o certo é Code, né.
Não Entendi muito bem, mas, pelo que vocês disseram é o tamanho do Array “buffer” ou “C_1” que se encontra errado. Dai fui eu lá testar e fiquei com mais duvidas.
Primeiro Declarei tamanho do “buffer” juntamente com “C_1” tamanho três. Se contar do o array do Zero é uma matriz Unidimensional de quatro posições, se descontar a posição zero, seria uma matriz de três posições.

char C_1[3];
char buffer[3];

Porem para minha supressa obtive um resultado como a Imagem 3.
Novamente mudei o valor para:

char C_1[3];
char buffer[2];

Obtive o resultado da Imagem 4.
Novamente mudei o valor para:

char C_1[1];
char buffer[2];

Obtive o resultado da Imagem 5.
Novamente mudei o valor para:

char C_1[0];
char buffer[2];

Obtive o resultado da Imagem 6.

Primeira consideração: Se o tamanho da matriz “buffer” esta erado como que ela guarda e transfere corretamente para a “C_1”, os seus valores, e além disso o primeio parâmetro de resposta da porta serial ao comando “yui,” é “yui”, ou seja, o correto pois quero guardar o comando de Três letras sem o caractere terminador. Pois o código abaixo e uma forma que fiz para um debug.

    C_1[0]= buffer[0];
    C_1[1]= buffer[1];
    C_1[2]= buffer[2];
    //Imprimi 1º da matriz C_1
    Serial.print(C_1[0]);
    //Imprimi 2º da matriz C_1
    Serial.print(C_1[1]);
    //Imprimi 3º da matriz C_1
    Serial.print(C_1[2]);

Segunda consideração: Mudando o tamanho da matriz “C_1” ,para zero, ela só tem uma posição e como eu consigo compilar o código sem, mantendo o código abaixo, e ainda trás como resposta “yui,”, três posições sendo que ele só pode ler um , além de apresentar um só problema no retorno da porta serial o caractere”,” ou seja, “yui,”.
Terceira consideração: Já compilei o mesmo código nas taxas de transferência serial de 300, 9600, 19200, 115200. E na IDE do arduino versão 1.0.2 e 1.0.4.E o problema já persiste.
Quarta consideração: O mesmo código que postei no inicio do tópico eu o alterei e compilei na IDE 1.0.4. Na alteração troquei de lugar a declaração da matriz ”buffer”, a declarei juntamente com a ”C_1”, no inicio do código, a tornando ela publica a todas as funções. E sabe o que obtive em vez de uma imagem igual a Imagem2, da minha primeira postagem no tópico eu obtive um resultado como a Imagem 7.

// Matriz C_1 3 caracter
char C_1[2];
// Matriz buffer 3 caracter
char buffer[2];

void setup()
{
  // Taxa de Trasnferencia da porta serial
  Serial.begin(9600);
}

void loop()
{

}

//----------------------------------------------------------------

void serialEvent ()
{  
  //Ler Porta serial
  if ( Serial.available ()>=4)
  {
    // armazena na matriz buffer o Buffer da porta serial
    Serial.readBytesUntil (',', &buffer[0], 4 );
    //Redimenciona Buffer Serial para Matriz C_1
    C_1[0]= buffer[0];
    C_1[1]= buffer[1];
    C_1[2]= buffer[2];
    //Imprimi 1º da matriz C_1
    Serial.print(C_1[0]);
    //Imprimi 2º da matriz C_1
    Serial.print(C_1[1]);
    //Imprimi 3º da matriz C_1
    Serial.print(C_1[2]);
    //Coloca quebra de linha
    Serial.print("\n");
    //Imprimi C_1 inteira
    Serial.print(C_1);
    //Coloca quebra de linha
    Serial.print("\n");
    //Imprimi ok se a matriz C_1 for igual a yui
    if (C_1=="yui")
    {
      Serial.print("ok");
      Serial.print("\n");
    }
  }
}

Não sei, qual é o problema, é a programação (to sendo tão burro que não sei fazer) ou é meu arduino Uno.

Imagem 3.jpg

Imagem 3.jpg

Imagem 5.jpg

Imagem 6.jpg

Faltou uma imagem.

Imagem 7.jpg

Comparar strings é feito com strcmp... Não com ==.

Ok, mas o principal problema não é esse. O comparador que se encontra no código imprimi na porta serial a palavra “ok”, porem ele não consegue ler corretamente a Matriz char “C_1”, pois as colunas individuais então certas, porem todo o conteúdo dela é esta errado , isso é perceptível a ser enviado esse valor na porta serial, como se pode ver nas imagens.
Mas mesmo assim obrigado pela dica.

Há talvez essa informação, também ajude a todos que estiverem dispostos a responder a minha dúvida.
Ao trocar a ordem de declaração das Matrizes "buffer" e "C_1", como também o local que esta sendo declarada, destro/fora das funções(public ou private) ou até de modo misto, ela envia valores diferente de resposta pela porta serial, e nunca é o correto. E olha que eu sempre declaro antes de elas serem usadas. Também já fiz o teste de tirar o código da função "serialEvent" e colocá-lo na função "loop" e também nada de dar certo.

Rapaz ta difícil.

Experimenta este...

Como disseste, tens de ter um quarto caracter para isto funcionar.
Lê os comentários.

// Matriz C_1 3 caracter
char C_1[5]; //4 caracteres e um terminador... eventualmente pode ser menor.

void setup()
{
// Taxa de Trasnferencia da porta serial
Serial.begin(9600);
}

void loop()
{
//comunicação série....
if ( Serial.available ()>=4) //Repara neste problema... precisas de ter 4 caracteres... no entanto, apenas lês 3. Olha para o que coloquei em baixo.
{
//podes fazer um ciclo.
C_1[0]= Serial.read();
C_1[1]= Serial.read();
C_1[2]= Serial.read();

for (int i = 0; i < 3; i++) {
Serial.print(C_1*);*
}

  • //Coloca quebra de linha*
    _ Serial.print("\n");_
    C_1[3] = '\0'; //Strings em C precisam dum terminador... Isto que eu coloquei aqui é um terminador.
  • //Imprimi C_1 inteira*
    Serial.print(C_1);
  • //Coloca quebra de linha*
    _ Serial.print("\n");_
  • //Imprimi ok se a matriz C_1 for igual a yui*
  • if (0 == strcmp(C_1, "yui"))*
  • {*
  • //Disseste que havia um quarto caracter... aqui será a altura de veres se o caracter é o que tu queres.*
    _ Serial.read(); //para garantir que o código funciona correctamente, tens de ler o quarto caracter, senão isto só funciona uma vez._
    _ Serial.println("ok");_
  • }*
  • }*
    //Faz Coisas...
    }
    [/quote]

Deu Certo, e identifiquei o erro do meu código (como sou burro :astonished:), agradeço muito ao “bubulindo”.
Os problemas eram:
1º Matriz com tamanho errado: estava contando a posição 0.
2º Comparação dentro de uma condição “If” errada: não estava usando a função “strcmp”.
3º Matriz sem caractere Terminado: esse era o principal problema, como estou aprendendo, não sabia que se necessitava de um caractere terminador no caso “\0”. Devido a isso que a matriz era impressa na porta seria com caracteres aleatórios e ficava muito louca.

Resolvi colocar um código, no post que espero que ajude iniciantes como eu. Consiste em um sistema que recebe pela porta serial comandos com 8 Bytes:

Grupo 1: é um grupo de 4 caracteres (4 bytes).
Grupo 2: é um grupo de 4 números (4 bytes).
Ao se enviar uma comando deve ser seguido do caracter “,” que é um limitador de comando.
Ex: Enviando um comando : S01V9999,
Enviando dois comando : S01V9999, SV010001,

/*---------------------------------------------------------------
Declaração das Variaveis Publicas
--------------------------------------------------------------*/
//Declaração da matriz C_1 5 caracter (0 não conta)
char C_1[5];
//Declaração da matriz C_1 5 caracter (0 não conta)
char C_2[5];
//Declaração da variavel de valor do grupo numerico da leitura da porta serial
int C_3;
char C_4[5];

/*---------------------------------------------------------------
Função Executada na iniciação do arduino
--------------------------------------------------------------*/
void setup()
{
  //Velocidade da porta serial
  Serial.begin(9600);
}
/*---------------------------------------------------------------
Função principal do arduino
--------------------------------------------------------------*/
void loop()
{
	//chama função Teste
	Test_Print_Frases();
}

/*---------------------------------------------------------------
Função Teste Print Frases
--------------------------------------------------------------*/
int Test_Print_Frases()
{
	/*Apenas para Teste para verificar se a porta serial está lendo corretamente
		- Terminador de envio é "," . Ex:S01V0000,S01V0001,
		- Se enviado S01V0000 = (Executando Comando 0)
		- Se enviado S01V0001 = (Executando Comando 1)
		- Se enviado S01V9999 = (Executando Comando 9999)*/
	if (strcmp(C_1, "S01V") == 0)
    {		switch (C_3)
		{
	 case 0:
		Serial.print("Executando Comando 0");
		Serial.print("\n");
		break;
	 case 1:
		Serial.print(C_4);
		Serial.print("Executando Comando 1");
		Serial.print("\n");
		break;
	 case 9999:	 
		Serial.print("Executando Comando 9999");
		Serial.print("\n");
		break;
		} 
		delay(1000);
	 }
	return 0;
}


/*---------------------------------------------------------------
Função de manipulação da porta Serial (caso ocorra algum evento na mesma)
--------------------------------------------------------------*/
void serialEvent ()
{  
  // Matriz buffer 8 caracter
  char buffer[8];
  //Ler Porta serial caso esta esteja com 9 o mais caracteres no Buffer real da porta
  if ( Serial.available ()>=9)
  {
    // armazena na matriz buffer, o Buffer real da porta serial, caso seja encontado o caracter ',' ou um 9º caracter
    Serial.readBytesUntil (',', &buffer[0], 9 );
    //Redimenciona Buffer Serial para Matriz C_1, os 4 primeiros caracteres
    C_1[0]= buffer[0];
    C_1[1]= buffer[1];
    C_1[2]= buffer[2];
	C_1[3]= buffer[3];
	//caracter terminador da matriz C_1
	C_1[4] = '\0';
	//Redimenciona Buffer Serial para Matriz C_2, os ultimos 4 caracteres
	C_2[0]= buffer[4];
	C_2[1]= buffer[5];
	C_2[2]= buffer[6];
	C_2[3]= buffer[7];
	//caracter terminador da matriz C_2
	C_2[4]= '\0';
	//Converte a matriz C_2 (caracteres) para a matriz C_3 (numeros)
	C_3=atoi (C_2);
  }
}

Algum motivo especial para usares o SerialEvent????

Sabes o que é o SerialEvent?

Para que é isto:

    C_1[0]= buffer[0];
    C_1[1]= buffer[1];
    C_1[2]= buffer[2];
    C_1[3]= buffer[3];

Não podias copiar para o C_1 directamente? Ou melhor, se fizesses como eu mostrei (sem o SerialEvent) poupavas memória pois não precisavas de duplicar variáveis.

bubulindo:
Algum motivo especial para usares o SerialEvent????

Não,
Usei SerialEvent por estava usando anteriormente.

bubulindo:
Sabes o que é o SerialEvent?

Se for o que eu entendi, trata-se de uma função executada depois da função “loop”, quando se tem uma entrada e dado no buffer do chip. Como ela e desenvolvida para isso, tem um código de biblioteca, que assimila essa função somente na presença de valores no buffer, de fato tende a tornar o código mais lento.
Foi isso que compreendi porem o jeito que você fez, torna mais rápido o tempo de scan geral do arduino.

bubulindo:
Para que é isto:

    C_1[0]= buffer[0];

C_1[1]= buffer[1];
    C_1[2]= buffer[2];
    C_1[3]= buffer[3];



Não podias copiar para o C_1 directamente? Ou melhor, se fizesses como eu mostrei (sem o SerialEvent) poupavas memória pois não precisavas de duplicar variáveis.

Primeiro obrigado, por essa otimização do código.

Pra finalidade que irei usar o arduino não tem problema, em relação ao tamanho da memoria flash usada, no entanto, isso vai ajuda a gastar menos SRam.
Vou fazer como tu disseste, só fiz duas matrizes para ficar mais organizado (para mim). Só espero não atrapalha iniciantes como eu.