collapse

* Posts Recentes

Amplificador - Rockboard HA 1 In-Ear por almamater
[Ontem às 19:13]


O que é isto ? por KammutierSpule
[26 de Março de 2024, 19:35]


Bateria - Portátil por almamater
[25 de Março de 2024, 22:14]


Emulador NES em ESP32 por dropes
[13 de Março de 2024, 21:19]


Escolher Osciloscópio por jm_araujo
[06 de Fevereiro de 2024, 23:07]


TP4056 - Dúvida por dropes
[31 de Janeiro de 2024, 14:13]


Leitura de dados por Porta Serie por jm_araujo
[22 de Janeiro de 2024, 14:00]


Distancia Cabo por jm_araujo
[08 de Janeiro de 2024, 16:30]


Meu novo robô por josecarlos
[06 de Janeiro de 2024, 16:46]


Laser Engraver - Alguém tem? por almamater
[16 de Dezembro de 2023, 14:23]

Autor Tópico: Manipulando dados inseridos via Serial Monitor  (Lida 11192 vezes)

0 Membros e 1 Visitante estão a ver este tópico.

Offline Junior Frota

  • Mini Robot
  • *
  • Mensagens: 39
Manipulando dados inseridos via Serial Monitor
« em: 27 de Janeiro de 2011, 22:46 »
Olá amigos, primeiramente peço desculpas se já existe algum tópico com esse mesmo assunto, no entanto, procurei muito e não achei nada muito específico para o meu problema.

Então vamos lá!

Eu estou desenvolvendo um projeto de um braço robótico que usa cinemática inversa. Ele funcionará da seguinte forma:

1º - será digitado no terminal Serial Monitor do Arduino as coordenadas do ponto a que se quer atingir com o braço no formato (x, y, z, a), onde "x", "y" e "z" são as coordenadas do ponto e "a" é o ângulo do último seguimento do braço em relação ao eixo "x" da base do braço;
2º - o programa desenvolvido receberá essas coordenadas e salvará em quatro variáveis (x, y, z e a);
3º - o programa calculará os valores dos demais ângulos;
4º - a extremidade do braço será localizado no ponto determinado previamente.

Minha dúvida é:

Como faço para que o meu programa receba os dados via Serial Monitor e salve cada informação em uma variável diferente?

Eu pensei em algo do tipo:

"Digite a coordenada x"...
"Digite a coordenada y"...
"Digite a coordenada z"...
"Digite o ângulo"...

Mas eu queria que o programa recebesse os dados no formato (x, y, z, a) e separasse cada informação pra sua variável correspondente.

Se alguém puder me ajudar com esse algoritmo, ficarei muito agradecido.

Um abraço...
"Nossa maior fraqueza está em desistir. A forma mais certa de vencer, é tentar mais uma vez" (Thomas Edson)

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Manipulando dados inseridos via Serial Monitor
« Responder #1 em: 27 de Janeiro de 2011, 23:21 »
E vais usar um terminal qualquer ou fazer um pequeno programa para isso?

Se vais usar um terminal simples, pedes cada variavel, e antes de pedires a próxima, fazes um read da porta serial e guardas esse numero lido, convertes de ascii para inteiro usando a função atoi() e muito basicamente é isso, como é para ler assim sequencialmente se calhar até é mais simples guardar os dados num array.
Avr fanboy

Offline beirao

  • Mini Robot
  • *
  • Mensagens: 1.531
Re: Manipulando dados inseridos via Serial Monitor
« Responder #2 em: 27 de Janeiro de 2011, 23:48 »
E vais usar um terminal qualquer ou fazer um pequeno programa para isso?

Se vais usar um terminal simples, pedes cada variavel, e antes de pedires a próxima, fazes um read da porta serial e guardas esse numero lido, convertes de ascii para inteiro usando a função atoi() e muito basicamente é isso, como é para ler assim sequencialmente se calhar até é mais simples guardar os dados num array.

Metes isso num array... basta depois fazeres um ciclo que percorra o array (um ciclo for por exemplo) e separas os valores.
"O único lugar onde o sucesso vem antes do trabalho, é no dicionário" - Albert Einstein

Offline Junior Frota

  • Mini Robot
  • *
  • Mensagens: 39
Re: Manipulando dados inseridos via Serial Monitor
« Responder #3 em: 28 de Janeiro de 2011, 00:12 »
Obrigado Senso e obrigado Beirao!

Certo! A primeira sugestão é válida, mas a segunda é que me anima mais.

Vocês deram a sugestão de eu usar uma array, mas não tenho a mínima ideia de como alocar cada componente de coordenada nos campos da matriz.

Se alguém puder me ajudar com algum algoritmo, ficarei agradecido.

Um abraço...
"Nossa maior fraqueza está em desistir. A forma mais certa de vencer, é tentar mais uma vez" (Thomas Edson)

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Manipulando dados inseridos via Serial Monitor
« Responder #4 em: 28 de Janeiro de 2011, 00:25 »
Mostra ai o teu código actual, para sabermos como juntar o resto.
Avr fanboy

Offline Junior Frota

  • Mini Robot
  • *
  • Mensagens: 39
Re: Manipulando dados inseridos via Serial Monitor
« Responder #5 em: 28 de Janeiro de 2011, 00:57 »
Na verdade ainda não comecei o código, mas tenho uma ligeira noção de programação em Arduino, que queria um norteamento para eu começar.

Minhas ideias são as que eu postei mais acima, então o que eu queria era uma sugestão de como conseguir essa proeza.

Um abraço...
"Nossa maior fraqueza está em desistir. A forma mais certa de vencer, é tentar mais uma vez" (Thomas Edson)

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Manipulando dados inseridos via Serial Monitor
« Responder #6 em: 28 de Janeiro de 2011, 01:05 »
Fazes uma função para ler caracteres da porta série para um array global (não é bom método de programação, mas é mais fácil se for global), até atingir um número máximo de caracteres ou ser lido o caracter 13 ('\n', ou seja, o ENTER). Qualquer coisa do género (pode não compilar, é um exemplo)

const int cTamanhoDoArray = 8;
char entrada[cTamanhoDoArray];

void lerDados (void)
{
    int  indice = 0;
    while (indice < cTamanhoDoArray - 1)
    {
        byte  caracter = Serial.read();
        entrada[indice] = caracter;
        indice++;
        if (caracter == '\n')
            break;    // sair do ciclo while se o caracter lido for um ENTER
    }
    entrada[indice] = '\0';    // terminar a string, com o caracter nulo (0)
}


Depois basta usares a atoi() como disse o senso para converteres os caracteres (texto) no array entrada para uma variável de tipo inteiro (int).

Isto é muito simplificado (por exemplo não processa erros) e assume que as coordenadas são números inteiros.
« Última modificação: 28 de Janeiro de 2011, 01:11 por Njay »

Offline Junior Frota

  • Mini Robot
  • *
  • Mensagens: 39
Re: Manipulando dados inseridos via Serial Monitor
« Responder #7 em: 28 de Janeiro de 2011, 02:04 »
Olá companheiros! Abaixo segue um pequeno código que eu julgo dar certo:

char x, y, z, a3;     // variáveis que serão lidas pelo Serial Monitor
int a1, a2 = 0;     // variáveis que serão calculadas por cinemática inversa

const int r1 = 20;     // refere-se ao comprimento do primeiro segmento do braço
const int r2 = 20;     // refere-se ao comprimento do segundo segmento do braço
const int r3 = 20;     // refere-se ao comprimento do terceiro segmento do braço

void setup(){
  Serial.begin(9600);     // inicia a comunicação serial com o PC
}

void loop(){
  Serial.print("Entre com a coordenada x: ");
  x = Serial.read();     // lê a coordenada "x" e salva-a na variável de mesmo nome
  Serial.println(" ");     // passa para a próxima linha
  Serial.print("Entre com a coordenada y: ");
  y = Serial.read();     // lê a coordenada "y" e salva-a na variável de mesmo nome
  Serial.println(" ");     // passa para a próxima linha
  Serial.print("Entre com a coordenada z: ");
  z = Serial.read();     // lê a coordenada "z" e salva-a na variável de mesmo nome
  Serial.println(" ");     // passa para a próxima linha
  Serial.print("Entre com o ângulo: ");
  a3 = Serial.read();     // lê o angulo "a3" e salva-a na variável de mesmo nome
  Serial.println(" ");     // passa para a próxima linha
 
}

Daqui eu teria condição suficiente para desenvolver o restante do código, mas o que eu queria mesmo era não ter que entrar com as coordenadas de uma por uma. Sei que dá certo, mas eu gostaria que a entrada de dados seguisse o estilo "x, y, z, a", assim teria que ter uma função pra pegar essa entrada e dividir cada caracte para sua respectiva variável e depois transformar em inteiro. Só lembrando, não sei usar a função atoi(), é preciso incluir alguma biblioteca?

Como esse código poderia ser escrito usando array, pegando as coordenadas na forma "x, y, z, a" e colocando cada coordenada em sua variável correspondente?

Desculpe minha ignorância, é que ainda estou engatinhando nesse maravilhoso ramo da robótica.

Um abraço...
"Nossa maior fraqueza está em desistir. A forma mais certa de vencer, é tentar mais uma vez" (Thomas Edson)

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Manipulando dados inseridos via Serial Monitor
« Responder #8 em: 28 de Janeiro de 2011, 02:12 »
Isso assim não funciona, tens de usar a função que o Njay fez, pois não recebes numeros do computador, mas sim caracteres ASCII, depois para ler a porta serial tens de fazer primeiro Serial.available().
Aconselho-te a aprenderes primeiro a usar o Serial.read/available() e assim para ler coisas da porta serial antes de ter meteres num programa tão complexo, é da fundação que se começa uma casa e não do telhado ;)
Tens muitos blogs brasileiros sobre esse assunto e muitos bons exemplos.
Avr fanboy

Offline ricardo-reis

  • Administrator
  • Mini Robot
  • *****
  • Mensagens: 1.338
Re: Manipulando dados inseridos via Serial Monitor
« Responder #9 em: 28 de Janeiro de 2011, 02:18 »
senso, pk dizes que não funciona? a ideia dele, pelo que percebi, não seria algo deste género:

no código ter uma chamada à função:
getVars();


e dps ter a função:
void getVars(){
  x = analogRead(pinX);
  y = analogRead(pinY);
  z = analogRead(pinZ);
  a3 = analogRead(pinA3);
}

EDIT: ignorem, não tinha lido desd'o início.. :X
« Última modificação: 28 de Janeiro de 2011, 02:20 por ricardo-reis »

Offline Njay

  • Mini Robot
  • *
  • Mensagens: 3.598
    • Tróniquices
Re: Manipulando dados inseridos via Serial Monitor
« Responder #10 em: 28 de Janeiro de 2011, 02:18 »
Serial.read() lê apenas 1 caracter. É preciso acumular numa cadeia de caracteres (cadeia = array = grupo, sequência) os vários caracteres que compõem um número. Por exemplo, o número -34 é composto por 3 caracteres, o sinal -, o 3 e o 4. O caracter de valor zero ('\0') é um sinalizador que indica o final da cadeia (senão não saberiamos onde termina nem quantos caracteres "úteis" lá estão guardados).

Se pegares na função lerDados() que deixei e mudares o caracter de terminação de input de dados, que actualmente é '\n' (ENTER), para ',' (virgula), já obténs o que queres. Melhor ainda, é passar como parametro para a função lerDados() qual é o caracter de terminação. Com esta alteração, a função pára de ler caracteres quando for introduzido pelo utilizador o caracter indicado, e o array entrada terá os caracteres lidos (supostamente um número).

A função atoi usa-se assim:

int x;
x = atoi(entrada);


Portanto ficarias com algo como

int x, y, z, a;
Serial.print("Entre com o primeiro ponto: ");
lerDados(',');
x = atoi(entrada);
lerDados(',');
y = atoi(entrada);
... etc...
lerDados('\n');   // na última coordenada, o que termina a entrada de dados do utilizador é a tecla ENTER e não uma virgula
a = atoi(entrada);
« Última modificação: 28 de Janeiro de 2011, 02:20 por Njay »

Offline Junior Frota

  • Mini Robot
  • *
  • Mensagens: 39
Re: Manipulando dados inseridos via Serial Monitor
« Responder #11 em: 28 de Janeiro de 2011, 02:46 »
E aí pessoal, legal pelas ajudas, mas tenham paciência, isso tudo é um desafio para mim e espero que pensem o mesmo. A final, ensinar alguém que é quase leigo em um determinado assunto, não deixa de ser um desafio.

Vamos para o que interessa!

Tentei juntar os códigos que o Njay postou e resultou no seguinte:

const int cTamanhoDoArray = 8;
char entrada[cTamanhoDoArray];
int x, y, z, a;

void setup(){
  Serial.begin(9600);
}

void loop(){

Serial.print("Entre com o primeiro ponto: ");
lerDados(',');
x = atoi(entrada);
lerDados(',');
y = atoi(entrada);
lerDados(',');
z = atoi(entrada);
lerDados('\n');   // na última coordenada, o que termina a entrada de dados do utilizador é a tecla ENTER e não uma virgula
a = atoi(entrada);

}

void lerDados (void){
  int  indice = 0;
  while (indice < cTamanhoDoArray - 1){
    byte  caracter = Serial.read();
    entrada[indice] = caracter;
    indice++;
    if (caracter == '\n'){
      break;    // sair do ciclo while se o caracter lido for um ENTER
    }
    entrada[indice] = '\0';    // terminar a string, com o caracter nulo (0)
  }
}

Só que quando compilo dá esse erro:

In function 'void loop()':
error: too many arguments to function 'void lerDados()'

Acho que é sobre o argumento da função lerDados() que não foi bem definido.

Njay, você poderia fazer um teste nesse código, já que ele é praticamente de autoria sua?

Mais uma vez, desculpem minha ignorância.

Um abraço...
"Nossa maior fraqueza está em desistir. A forma mais certa de vencer, é tentar mais uma vez" (Thomas Edson)

Offline senso

  • Global Moderator
  • Mini Robot
  • *****
  • Mensagens: 9.733
  • Helpdesk do sitio
Re: Manipulando dados inseridos via Serial Monitor
« Responder #12 em: 28 de Janeiro de 2011, 03:18 »
const int cTamanhoDoArray = 8;
char entrada[cTamanhoDoArray];
int x, y, z, a;

void setup(){
  Serial.begin(9600);
}

void loop(){

Serial.print("Entre com o primeiro ponto: ");
lerDados(',');
x = atoi(entrada);
lerDados(',');
y = atoi(entrada);
lerDados(',');
z = atoi(entrada);
lerDados('\n');   // na última coordenada, o que termina a entrada de dados do utilizador é a tecla ENTER e não uma virgula
a = atoi(entrada);

}

void lerDados (uint8_t terminador){
  int  indice = 0;
  while (indice < cTamanhoDoArray - 1){
    byte  caracter = Serial.read();
    entrada[indice] = caracter;
    indice++;
    if (caracter == terminador){
      break;    // sair do ciclo while se o caracter lido for um ENTER
    }
    entrada[indice] = '\0';    // terminar a string, com o caracter nulo (0)
  }
}

Experimenta assim.
Avr fanboy

Offline Junior Frota

  • Mini Robot
  • *
  • Mensagens: 39
Re: Manipulando dados inseridos via Serial Monitor
« Responder #13 em: 28 de Janeiro de 2011, 21:45 »
Olá senso, experimentei o código que você postou e realmente não apresentou mais o erro. Muito obrigado pela ajuda e paciência!

O problema agora não é mais de compilação, mas sim na hora de entrar com os dados.

Quando executo o código no Arduino Duemilanove com a janela do Serial Monitor, na janela dos resultados, não para de imprimir a frase "Entre com o primeiro ponto: ", ou seja, não dá chance pra gente colocar as informações.

Acho que é preciso entrar com um código que pare o procedimento e só continue quando for pressionado o ENTER.

Outra coisa, nesse mesmo projeto eu irei movimentar servos com os dados que resultarão dessas entradas, e também será preciso reconhecer a cor de alguns objetos para poder selecioná-los.

Sobre a movimentação dos servos, já tenho todo o código fonte, mas para identificar a cor de um objeto seria melhor eu usar um sensor de infravermelho ou LDR?

Eu tenho um par de fotodiodos (emissor e receptor), mas até então, não consegui usá-los de forma eficiente. Eles trabalham com sinal digital ou analógico?

Mas uma vez agradeço pela paciência e ajuda que estão tendo comigo. Ainda bem que existem pessoas que se prestam a ajudar a quem lhes pedem ajuda.

Um abraço...
"Nossa maior fraqueza está em desistir. A forma mais certa de vencer, é tentar mais uma vez" (Thomas Edson)

Offline XicoMBD

  • Mini Robot
  • *
  • Mensagens: 571
    • FranciscoDias.net
Re: Manipulando dados inseridos via Serial Monitor
« Responder #14 em: 28 de Janeiro de 2011, 23:28 »
Quanto à identificação da cor, não estou bem a ver como se possa fazer com um sensor IV, mas com LDR existem bons exemplos, aqui fica um http://letsmakerobots.com/node/23768 (em inglês).