Robótica Livre
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

Ir para baixo
Thiaguin
Thiaguin
Mensagens : 177
Data de inscrição : 03/03/2020

Exercício 4.6 Empty Exercício 4.6

Seg Ago 23, 2021 4:41 pm
/*
* CURSO DE ROBOTICA 2020
*
* Exercicio: 4.6
* Tema: Texto terminal para display
* Atividade: Utilizando as strings receber o texto do terminal e enviar para o display
* Descrição: Declarar duas strings de 16 bytes, uma para cada linha do display e usar uma terceira de 32 bytes para receber o texto do terminal
* Hardware: Montar o display e a porta serial para as entradas e saídas de dados
* Comandos: Serial.avaiable(); Serial.read(); lcd.print(); if(); while(); for()
* Dica1: string é uma cadeia de caracteres, podemos até mesmo dizer um vetor de caracteres. Trás a linguagem C a capacidade de lidar com frases e palavras.
* Dica2: Quando declaramos string com s minusculo refere-se a uma variável, e quando String está com S maiusculo refere-se a objeto
* Dica3: Declaração da variavel string char nome_vetor[tamanho]{'a','b','c'}; tipo dos dados, sempre char. Nome do vetor identifica a variável. Entre conchetes vai o tamanho do vetor, depois
* Dica4: Lembrando que na linguagem C caractere é colocado entre ' ' (aspas simples), frases podem ser declaradas usando " " (aspas duplas)
* Dica5: Toda string termina com um caractere nulo no final(código ASCII 0), por isso na declaração deve considerar um elemento a mais no tamanho,
* * Resolução do Exercício
* Dica6: Receber o caractere na porta serial e guardar em uma string na posição 0
* Dica7: Testar se esse caractere é alphanumerico, se não for descartar, sinalizar erro e recomeçar a coleta dos dados
* Dica8: A primeira letra deve ser maiúscula, se não for converter para maiusculo, se for número ignorar a conversão.
* Dica9: Para apresentar o texto no display dividir a string recebida em duas strings de 16 caracteres e escrever cada uma em uma linha do terminal
* Dica10: o último caractere recebido pelo terminal deverá ser um \n , indicando nova linha ou enter.
*/

//DEFINICOES INICIAIS
#include //A biblioteca com as funções do display está carregada

//DECLARAcAO DE VARIAVEIS GLOBAIS
LiquidCrystal lcd(12,11,10,9,8,7);//Os pinos serão ligados nessa sequência ao display
char stringEnt[32];//String sem tamanho definido para receber os valores da porta serial
char stringComp[32];//String com 32 posições para armazenar todos os valores
char string1[16];//String com 16 posições para ser usada na primeira linha do display
char string2[16];//String com 16 posições para ser usada na segunda linha do display
byte posicao = 0;//Variável de incremento
byte contador = 0;//Variável de incremento
byte i = 0;//Variável de incremento
//INICIALIZAÇÃO DO HARDWARE
void setup() {
Serial.begin(9600);//Porta serial inicializada com velocidade de 9600 bps
lcd.begin(16,2);//Display inicializado, o display usado possui 16 colunas e 2 linhas
}

//FUNÇÕES COMPLEMENTARES


//PROGRAMA PRINCIPAL
void loop() {
if(Serial.available() > 0){//Se houver algum valor ou caracter na Porta serial, irá rodar o bloco abaixo
stringEnt[posicao] = Serial.read();//O conteúdo da string1 será os valores lidos na porta serial
for(contador = 0; contador < strlen(stringEnt); contador ++){//Incrementa as posições para teste
if(isalnum(stringEnt[contador]) == 0){//Testa se o valor da posição selecionada da stringEnt não é alfanumérico(letra ou número), ser retornar verdadeiro, roda o bloco abaixo
Serial.print("Erro! ");
Serial.print("Caractere ");
Serial.print(stringEnt[contador]);//Informa o caractere deletado
Serial.println(" foi deletado");
stringEnt[0] = '\0';//Limpa a stringEnt
break;//Sai do bloco
}
}
if(strlen(stringEnt) <= 32){//Testa se o valor da stringEnt ultrapassou o tamanho desejado, se retornar verdadeiro, roda o bloco abaixo
strcat(stringComp, stringEnt);//Concatena os valores da stringEnt na stringComp
if(strlen(stringComp) > 16){//Se o tamanho da stringComp for maior que 16, roda o bloco abaixo
strncpy(string1, stringComp, 16);//Copia o conteúdo da stringComp para a string1, até a 16º posição
for(i = 16; i < strlen(stringComp); i ++){//Incrementa o contador a partir da 17º posição
strcat(string2,stringComp[i]);//concatena o valor da posição i da stringComp para a string2
}
}else{//Se o tamanho da stringComp for menor que 16, roda o bloco abaixo
strcpy(string1, stringComp);//Copia o conteúdo da stringComp para a string1
}
if(islower(string1[0]) != 0)string1[0] = toupper(string1[0]);//Testa se o primeiro caractere é minúsculo, se for, converte pra maiúsculo
lcd.clear();//Limpa o display
lcd.setCursor(0,0);//O cursor irá para o início da primeira linha do display
lcd.print(string1);//O conteúdo da string1 será mostrado no display
lcd.setCursor(0,1);//O cursor irá para o início da segunda linha do display
lcd.print(string2);//O conteúdo da string2 será mostrado no display
}else{//Se ultrapassou o valor desejado, roda o bloco abaixo
Serial.print("Erro! digite novamente\n");
stringEnt[0] = '\0';//Limpa a stringEnt
}
}
}
Thiaguin
Thiaguin
Mensagens : 177
Data de inscrição : 03/03/2020

Exercício 4.6 Empty Re: Exercício 4.6

Seg Ago 23, 2021 4:42 pm
Professor, não consegui arrumar esse bug do display, ele só passa a string1, a string2 não recebe valores, e eu não consegui arrumar sozinho
Ent, gostaria da sua ajuda
Paulo Augusto Batista
Paulo Augusto Batista
Admin
Mensagens : 5115
Data de inscrição : 11/02/2019
Idade : 52
Escola : Colegio Lindaura
https://roboticalivre.forumeiros.com

Exercício 4.6 Empty Re: Exercício 4.6

Qui Set 02, 2021 11:11 pm
Oi Thiago, Na primeira parte do programa precisa receber os dados e testar se são válidos, e o for() que usou não é a melhor estratégia para isso,
Minha sugestão é ler o caractere da serial, testar e guardar na string stringEnt[32];
Se estiver seguindo o fluxograma vai ver que tem uma decisão que avalia se é \n ou fim da string, aqui cabe uma variável de controle para passar para o segundo bloco que faz o tratamento.

No tratamento aqui sim vai o for(), pois vai contar 16 caracteres para primeira linha e colocar numa string da primeira linha e assim também para segunda linha

Na terceira parte do programa escreve as strings no display, uma em cada linha.

Espero ter esclarecido melhor.

No sabado passei o grip para vc, mas se quiser tratar os exercícios fique a vontade para recusar e concluir suas atividades. Até mesmo falarmos sobre esse programa.
Esse podemos considerar como um dos mais difíceis de resolver.
Thiaguin
Thiaguin
Mensagens : 177
Data de inscrição : 03/03/2020

Exercício 4.6 Empty Re: Exercício 4.6

Ter Set 07, 2021 7:31 pm
/*
* CURSO DE ROBOTICA 2020
*
* Exercicio: 4.6
* Tema: Texto terminal para display
* Atividade: Utilizando as strings receber o texto do terminal e enviar para o display
* Descrição: Declarar duas strings de 16 bytes, uma para cada linha do display e usar uma terceira de 32 bytes para receber o texto do terminal
* Hardware: Montar o display e a porta serial para as entradas e saídas de dados
* Comandos: Serial.avaiable(); Serial.read(); lcd.print(); if(); while(); for()
* Dica1: string é uma cadeia de caracteres, podemos até mesmo dizer um vetor de caracteres. Trás a linguagem C a capacidade de lidar com frases e palavras.
* Dica2: Quando declaramos string com s minusculo refere-se a uma variável, e quando String está com S maiusculo refere-se a objeto
* Dica3: Declaração da variavel string char nome_vetor[tamanho]{'a','b','c'}; tipo dos dados, sempre char. Nome do vetor identifica a variável. Entre conchetes vai o tamanho do vetor, depois
* Dica4: Lembrando que na linguagem C caractere é colocado entre ' ' (aspas simples), frases podem ser declaradas usando " " (aspas duplas)
* Dica5: Toda string termina com um caractere nulo no final(código ASCII 0), por isso na declaração deve considerar um elemento a mais no tamanho,
* * Resolução do Exercício
* Dica6: Receber o caractere na porta serial e guardar em uma string na posição 0
* Dica7: Testar se esse caractere é alphanumerico, se não for descartar, sinalizar erro e recomeçar a coleta dos dados
* Dica8: A primeira letra deve ser maiúscula, se não for converter para maiusculo, se for número ignorar a conversão.
* Dica9: Para apresentar o texto no display dividir a string recebida em duas strings de 16 caracteres e escrever cada uma em uma linha do terminal
* Dica10: o último caractere recebido pelo terminal deverá ser um \n , indicando nova linha ou enter.
*/

//DEFINICOES INICIAIS
#include //A biblioteca com as funções do display está carregada

//DECLARAcAO DE VARIAVEIS GLOBAIS
LiquidCrystal lcd(12,11,10,9,8,7);//Os pinos serão ligados nessa sequência ao display
char reset[32]{'\0'};//String de reset
char stringEnt[2];//String sem tamanho definido para receber os valores da porta serial
char stringComp[32];//String com 32 posições para armazenar todos os valores
char string1[16];//String com 16 posições para ser usada na primeira linha do display
char string2[16];//String com 16 posições para ser usada na segunda linha do display
bool controle = 0;//Variável de controle
byte i;//Variável de incremento

//INICIALIZAÇÃO DO HARDWARE
void setup() {
Serial.begin(9600);//Porta serial inicializada com velocidade de 9600 bps
lcd.begin(16,2);//Display inicializado, o display usado possui 16 colunas e 2 linhas
Serial.println("Escreva uma frase usando caracteres alfanumericos");
}

//FUNÇÕES COMPLEMENTARES


//PROGRAMA PRINCIPAL
void loop() {
if(Serial.available()){//Se houver algum valor na porta serial, roda o bloco abaixo
 stringEnt[0] = Serial.read();//Os dados recebidos pela porta serial, serão armazenados na posição 0 da string de entrada
 if(stringEnt[0] == '\r'){//Se o caractere for um \r, roda o bloco abaixo
  controle = 1;//A variável controle passará a ser 1
 } else if(!isalnum(stringEnt[0])){//Se não for um número ou uma letra ou tem mais que 31 dígitos, roda o bloco abaixo
    Serial.print("Erro! ");
    Serial.print("Caractere ");
    Serial.print(stringEnt[0]);//Informa o caractere deletado
    Serial.println(" foi deletado");
    stringEnt[0] = '\0';//Limpa a stringEnt
   
 } else if(strlen(stringComp) >= 31){//Se tiver mais que 31 dígitos, roda o bloco abaixo
    Serial.print("\n");//
    Serial.println("Dados invalidos! Digite novamente");//
    strcpy(stringComp, reset);//Apaga a string completa
    stringEnt[0] = '\0';//Apaga a string de entrada
    while(Serial.available()){//Enquanto houver valor na porta serial, roda o bloco abaixo
     Serial.flush();//Descarta os dados da porta serial
    }
 }
 else{//Se for um número ou letra e tiver menos que 31 dígitos, roda o bloco abaixo
  strcat(stringComp,stringEnt);//Concatena os valores da string de entrada na string completa
 }
}
if(controle == 1){//Se a variável controle for igual a 1, roda o bloco abaixo
 strncat(string1,stringComp,16);//concatena o valor da posição i da stringComp para a string2
 for(i = 16; i < 32; i ++){//Incrementa o contador a partir da 17º posição
  string2[i - 16] = stringComp[i];//Os valores a partir da 17ª posição da stringComp serão passados para a string2
 }
 if(islower(string1[0])){//Testa se o primeiro caractere é minúsculo
  string1[0] = toupper(string1[0]);//Converte o caractere para maiúsculo
 }
 lcd.clear();//Limpa o display
 lcd.setCursor(0,0);//O cursor irá para o início da primeira linha do display
 lcd.print(string1);//O conteúdo da string1 será mostrado no display
 lcd.setCursor(0,1);//O cursor irá para o início da segunda linha do display
 lcd.print(string2);//O conteúdo da string2 será mostrado no display  
 controle = 0;
 strcpy(string1, reset);//Apaga a string1
 strcpy(string2, reset);//Apaga a string2
 strcpy(stringComp, reset);//Apaga a string completa
 stringEnt[0] = '\0';//Apaga a string de entrada
 while(Serial.available()){//Enquanto houver valor na porta serial, roda o bloco abaixo
  Serial.flush();//Descarta os dados da porta serial
 }
Serial.print("\n");
Serial.println("Escreva uma frase usando caracteres alfanumericos");
}
}
Thiaguin
Thiaguin
Mensagens : 177
Data de inscrição : 03/03/2020

Exercício 4.6 Empty Re: Exercício 4.6

Ter Set 07, 2021 7:41 pm
Prontinho professor

Só uma observação, não estava rodando com o \n, como no exercício 4.10, ent eu usei o \r que no caso, vc usou no exercício 4.10

Além disso, ficou um bug quando vc escreve algo que vá para a 2ªlinha daí na próxima quando escreve algo que só usa a 1ª linha, a 2ªlinha fica com os antigos caracteres que ela tinha, e só some se a cada vez que vc escrever vc tenha que apagar um único dígito, até que não tenha mais caractere na 2ªlinha
Isso eu não soube resolver
Paulo Augusto Batista
Paulo Augusto Batista
Admin
Mensagens : 5115
Data de inscrição : 11/02/2019
Idade : 52
Escola : Colegio Lindaura
https://roboticalivre.forumeiros.com

Exercício 4.6 Empty Re: Exercício 4.6

Qua Set 08, 2021 12:08 am
Oi Thiago, Estou muito orgulhoso que realmente está aprendendo a desenvolver os programas.
Analisei o programa e vi que funcionou e realmente tem esse bug. Então vou dar nota 9.0 e as dicas para chegar na nota máxima.

1) O problema acontece pela forma que está tratando as strings, usou uma estratégia de colocar os dados da serial na stringComp[32];
2) Depois da primeira volta, para apagar stringComp[32]; usou uma string de reset que tem 32 posições, mas tem somente um \0 na posição [0], o comando ficou strcpy(stringComp, reset);//Apaga a string completa
3) Na segunda volta, após receber os dados Para separar nas duas strings usou o codigo abaixo:
strncat(string1,stringComp,16);//concatena o valor da posição i da stringComp para a string2
for(i = 16; i < 32; i ++){//Incrementa o contador a partir da 17º posição
string2[i - 16] = stringComp[i];//Os valores a partir da 17ª posição da stringComp serão passados para a string2
}
Quando carrega um \0 na primeira posição da string na verdade não apaga todo o conteúdo dela. Como o programa le uma string até chegar num \0 e ele está na primeira posição, é interpretada que acabou. Mas se passar por um ponteiro ou por um for() como fez a leitura vai ver que os dados não foram apagados, por isso os dados voltam para a segunda linha. Então uma solução seria:
a) correr a stringComp usando o for() para todas as posições
b) se o contador do for() estiver entre 0 e 15 os dados vão para string1
c) se o contador do for estiver entre 16 e 31 os dados vão para a string2 na posição contador -15
d) se encontrar um \0 roda um break e sai do for()

Mas podemos também falar de otimização e poderia ter apagado a string1 assim como apagou a stringEnt, ficaria assim:
string1[0] = '\0'; //fica mais otimizado

Para resolver o problema do bug da segunda linha vou dar outra sugestão:
testa o tamanho da stringComp[], se ela for maior que 15 roda o for(), um if(strlen > 15) resolve, com o for() dentro

Thiaguin
Thiaguin
Mensagens : 177
Data de inscrição : 03/03/2020

Exercício 4.6 Empty Re: Exercício 4.6

Sex Set 10, 2021 7:35 pm
/*
* CURSO DE ROBOTICA 2020
*
* Exercicio: 4.6
* Tema: Texto terminal para display
* Atividade: Utilizando as strings receber o texto do terminal e enviar para o display
* Descrição: Declarar duas strings de 16 bytes, uma para cada linha do display e usar uma terceira de 32 bytes para receber o texto do terminal
* Hardware: Montar o display e a porta serial para as entradas e saídas de dados
* Comandos: Serial.avaiable(); Serial.read(); lcd.print(); if(); while(); for()
* Dica1: string é uma cadeia de caracteres, podemos até mesmo dizer um vetor de caracteres. Trás a linguagem C a capacidade de lidar com frases e palavras.
* Dica2: Quando declaramos string com s minusculo refere-se a uma variável, e quando String está com S maiusculo refere-se a objeto
* Dica3: Declaração da variavel string char nome_vetor[tamanho]{'a','b','c'}; tipo dos dados, sempre char. Nome do vetor identifica a variável. Entre conchetes vai o tamanho do vetor, depois
* Dica4: Lembrando que na linguagem C caractere é colocado entre ' ' (aspas simples), frases podem ser declaradas usando " " (aspas duplas)
* Dica5: Toda string termina com um caractere nulo no final(código ASCII 0), por isso na declaração deve considerar um elemento a mais no tamanho,
* * Resolução do Exercício
* Dica6: Receber o caractere na porta serial e guardar em uma string na posição 0
* Dica7: Testar se esse caractere é alphanumerico, se não for descartar, sinalizar erro e recomeçar a coleta dos dados
* Dica8: A primeira letra deve ser maiúscula, se não for converter para maiusculo, se for número ignorar a conversão.
* Dica9: Para apresentar o texto no display dividir a string recebida em duas strings de 16 caracteres e escrever cada uma em uma linha do terminal
* Dica10: o último caractere recebido pelo terminal deverá ser um \n , indicando nova linha ou enter.
*/

//DEFINICOES INICIAIS
#include //A biblioteca com as funções do display está carregada

//DECLARAcAO DE VARIAVEIS GLOBAIS
LiquidCrystal lcd(12,11,10,9,8,7);//Os pinos serão ligados nessa sequência ao display
char reset[32]{'\0'};//String de reset
char stringEnt[2];//String sem tamanho definido para receber os valores da porta serial
char stringComp[32];//String com 32 posições para armazenar todos os valores
char string1[16];//String com 16 posições para ser usada na primeira linha do display
char string2[16];//String com 16 posições para ser usada na segunda linha do display
bool controle = 0;//Variável de controle
byte i;//Variável de incremento

//INICIALIZAÇÃO DO HARDWARE
void setup() {
Serial.begin(9600);//Porta serial inicializada com velocidade de 9600 bps
lcd.begin(16,2);//Display inicializado, o display usado possui 16 colunas e 2 linhas
Serial.println("Escreva uma frase usando caracteres alfanumericos");//
}

//FUNÇÕES COMPLEMENTARES


//PROGRAMA PRINCIPAL
void loop() {
if(Serial.available()){//Se houver algum valor na porta serial, roda o bloco abaixo
 stringEnt[0] = Serial.read();//Os dados recebidos pela porta serial, serão armazenados na posição 0 da string de entrada
 if(stringEnt[0] == '\r'){//Se o caractere for um \r, roda o bloco abaixo
  controle = 1;//A variável controle passará a ser 1
 } else if(!isalnum(stringEnt[0])){//Se não for um número ou uma letra ou tem mais que 31 dígitos, roda o bloco abaixo
    Serial.print("Erro! ");
    Serial.print("Caractere ");
    Serial.print(stringEnt[0]);//Informa o caractere deletado
    Serial.println(" foi deletado");
    stringEnt[0] = '\0';//Limpa a stringEnt
   
 } else if(strlen(stringComp) >= 31){//Se tiver mais que 31 dígitos, roda o bloco abaixo
    Serial.print("\n");//
    Serial.println("Dados invalidos! Digite novamente");//
    strcpy(stringComp, reset);//Apaga a string completa
    stringEnt[0] = '\0';//Apaga a string de entrada
    while(Serial.available()){//Enquanto houver valor na porta serial, roda o bloco abaixo
     Serial.flush();//Descarta os dados da porta serial
    }
 }
 else{//Se for um número ou letra e tiver menos que 31 dígitos, roda o bloco abaixo
  strcat(stringComp,stringEnt);//Concatena os valores da string de entrada na string completa
 }
}
if(controle == 1){//Se a variável controle for igual a 1, roda o bloco abaixo
 if(strlen(stringComp) > 17){//Se tiver menos que 17, roda o bloco abaixo
 strncat(string1,stringComp,16);//concatena o valor da posição i da stringComp para a string2
 for(i = 16; i < 32; i ++){//Incrementa o contador a partir da 17º posição
  string2[i - 16] = stringComp[i];//Os valores a partir da 17ª posição da stringComp serão passados para a string2
 }
 }else{//Se tiver mais que 16 caracteres, roda o bloco abaixo
   strcpy(string1, stringComp);//Copia o conteúdo da stringComp pra string1
 }
 if(islower(string1[0])){//Testa se o primeiro caractere é minúsculo
  string1[0] = toupper(string1[0]);//Converte o caractere para maiúsculo
 }
 lcd.clear();//Limpa o display
 lcd.setCursor(0,0);//O cursor irá para o início da primeira linha do display
 lcd.print(string1);//O conteúdo da string1 será mostrado no display
 lcd.setCursor(0,1);//O cursor irá para o início da segunda linha do display
 lcd.print(string2);//O conteúdo da string2 será mostrado no display  
 controle = 0;
 strcpy(string1, reset);//Apaga a string1
 strcpy(string2, reset);//Apaga a string2
 strcpy(stringComp, reset);//Apaga a string completa
 stringEnt[0] = '\0';//Apaga a string de entrada
 while(Serial.available()){//Enquanto houver valor na porta serial, roda o bloco abaixo
  Serial.flush();//Descarta os dados da porta serial
 }
 Serial.print("\n");//
 Serial.println("Escreva uma frase usando caracteres alfanumericos");//
}
}
Paulo Augusto Batista
Paulo Augusto Batista
Admin
Mensagens : 5115
Data de inscrição : 11/02/2019
Idade : 52
Escola : Colegio Lindaura
https://roboticalivre.forumeiros.com

Exercício 4.6 Empty Re: Exercício 4.6

Qui Set 16, 2021 12:27 am
Agora sim, funcionou. Tudo certo. Parabéns. Nota 10.0
Conteúdo patrocinado

Exercício 4.6 Empty Re: Exercício 4.6

Ir para o topo
Permissões neste sub-fórum
Não podes responder a tópicos