LusoRobótica - Robótica em Português

Software => Software e Programação => Tópico iniciado por: guibot em 13 de Dezembro de 2008, 20:47

Título: separar valores de vários sensores
Enviado por: guibot em 13 de Dezembro de 2008, 20:47
estou a inciar-me em comunicação wireless entre 2 arduinos, usando os módulos XBee Pro.

no arduino 1, tenho 2 potenciómetros a enviar valores.

no arduino 2 recebo os valores dos potenciómetros assim:

100,234
100,230
100,228
etc...

agora não estou a conseguir separar estes valores para continuar a minha programação.
gostava de assignar os valores do 1º potenciómetro a uma variável e os valores do 2º potenciómetro a outra variavel

alguem me sabe dar uma ajuda com isto?   :geek:
Título: Re: separar valores de vários sensores
Enviado por: TigPT em 13 de Dezembro de 2008, 20:52
Não sei como funcionam os módulos, mas a primeira coisa que tens que fazer é mete-los a valores completamente diferentes para poderes verificar se esta mesmo a enviar de um e de outro alternadamente, depois talvez num loop que afecte a cada um, mas tens que nos dizer mais, protocolo, como estás a enviar os dados, etc... ;)
Título: Re: separar valores de vários sensores
Enviado por: defer em 13 de Dezembro de 2008, 21:16
A maneira mais rápida é provavelmente enviares os dados byte a byte, isto implica saberes quantos bytes ocupa cada valor que queres enviar. Explicar bitwise logic de repente num post seria complicado, no entanto há muita informação por aí.
De outra forma, se quiseres passar strings separadas por ',' podes usar a função strtok, fica um exemplo rápido:

Código: [Seleccione]
char *ptr = strtok(bufferin,",");
while (ptr) {
  int val = atoi(ptr);
  ptr = strtok(NULL, ",");
}
O código deve ser auto-explicável, dentro do ciclo while a tua variável val vai ter cada um dos tokens da string bufferin que passas para função.
Título: Re: separar valores de vários sensores
Enviado por: guibot em 13 de Dezembro de 2008, 23:16
para quem não tem boas bases de programação isto torna-se um pouco abstracto.

na minha função loop tenho o seguinte:

Código: [Seleccione]
void loop() {
  if (mySerial.available()) {
    Serial.println((char)mySerial.read());
  }
}

isto printa para a janela de output os valores de ambos os potenciómetros, agora não sei como usar o pedaço de código que escreveste.

obrigado por ajudares defer!  ;)
Título: Re: separar valores de vários sensores
Enviado por: TigPT em 13 de Dezembro de 2008, 23:23
Partido do principio que estás a enviar os dois seguidos, podes fazer:
Código: [Seleccione]
void loop() {
  if (mySerial.available()) {
    pot1 = mySerial.read();
    pot2 = mySerial.read();
  }
}
Visto que os dados vêm seguidos, ele lê os dois, mas isto depende de como estão a ser enviados.
Título: Re: separar valores de vários sensores
Enviado por: defer em 13 de Dezembro de 2008, 23:27
Ok, pelo que tou a ver já estas a enviar o resultado byte a byte (um char é um byte) tem cuidado que só podes enviar valores até 255 desta forma, nesse caso podes ler os dois valores fazendo uma modificação simples, a funcao available da classe serial retorna o numero de bytes disponíveis, logo só tens que ver se tens 2 e ler esses dois

Código: [Seleccione]
void loop() {
      if (mySerial.available() >= 2) {
        Serial.println((char)mySerial.read());
        Serial.println((char)mySerial.read());
      }
    }
Suponho que do outro lado estejas a fazer
Código: [Seleccione]
myserial.write((char)v1);
myserial.write((char)v1);

EDIT: não vi o post acima, sorry. De qualquer forma, deves verificar se tens pelo menos 2 bytes para ler, senão um dos valores pode retornar -1 (ve a documentação do read)
Título: Re: separar valores de vários sensores
Enviado por: TigPT em 13 de Dezembro de 2008, 23:31
Citação de: "defer"
a funcao available da classe serial retorna o numero de bytes disponíveis, logo só tens que ver se tens 2 e ler esses dois

Não sabia que retornava os bytes a ler, tenho estado um pouco ausente da programação do arduino ultimamente, só na faculdade estou a dar 4 linguagens diferentes e os trabalhos tem apertado nos últimos dias :P

Obrigado defer.
Título: Re: separar valores de vários sensores
Enviado por: guibot em 13 de Dezembro de 2008, 23:47
ok se calhar devia ter feito isto logo no inicio, o código que se segue é o que estou a usar.. espero que entendam, e desde já muito obrigado por estarem a ajudar  :geek:
Título: Re: separar valores de vários sensores
Enviado por: defer em 14 de Dezembro de 2008, 00:33
A função read() lê um byte, tu estás a mandar vários através do println, o que te aconselho a fazer é o seguinte:

Arduino 1:
Código: [Seleccione]
Serial.write (val1); //escreve 1 byte
Serial.write (val2); //escreve outro byte

Arduino 2:
Código: [Seleccione]
void loop() {
  if (myserial.available >= 2) { //estas a mandar 2 bytes, ver se estao disponiveis
    char val1 = myserial.read (); //ler o primeiro
    char val2 = myserial.read (); //ler o segundo
  }
}

Apenas tens que assumir que isto é o teu protocolo, envias sempre 2 bytes, recebes sempre 2
Título: Re: separar valores de vários sensores
Enviado por: guibot em 14 de Dezembro de 2008, 01:01
parece ser este o caminho, mas quando faço Serial.print ele só me lê um número de cada vez, em vez de me ler os 3 números de cada variavel ('val1'   e    'val2')    :(

Código: [Seleccione]
if (mySerial.available() >= 2) {
    char val1 = mySerial.read();
    char val2 = mySerial.read();
   
    Serial.print(val1);
    Serial.println(val2);
  }

Citar
55
25
52
55
25
52
55
Título: Re: separar valores de vários sensores
Enviado por: TigPT em 14 de Dezembro de 2008, 01:15
3 números?

já agora em vez de:
Código: [Seleccione]
int a1 = analogValue1 / 4;
int a2 = analogValue2 / 4;

experimenta:
Código: [Seleccione]
int a1 = analogValue1>>2;
int a2 = analogValue2>>2;

Faz o mesmo gasta menos memória de código, e demora menos tempo a processar, visto o atmega poder fazer shifts como operação elementar da sua ALU. (até trocaria o int a1 e a2 para chars).
Título: Re: separar valores de vários sensores
Enviado por: defer em 14 de Dezembro de 2008, 01:32
Quanto aos shifts, qualquer compilador faz isso automaticamente, mas sim, é boa prática.
Quanto aos resultados, estas a uasr um print e um println, os numeros estao seguidos, poe espaços e faz mais algum debug, com o que deste não tou a ver qual possa ser o problema.
Título: Re: separar valores de vários sensores
Enviado por: guibot em 14 de Dezembro de 2008, 09:34
tenho estado a alterar vários parametros mas de certeza algo me está a escapar.

se fizer isto consigo vizualizar o que envio sem quaisquer problemas:
Código: [Seleccione]
char incomingByte;

void loop() {
if (mySerial.available()) {  
    incomingByte = mySerial.read();
    Serial.print(incomingByte);
  }
}

Citar
val1 = 122     val2 = 255
val1 = 123     val2 = 253
val1 = 125     val2 = 252
val1 = 126     val2 = 250
val1 = 127     val2 = 249

vou continuar a luta  :mrgreen:
Título: Re: separar valores de vários sensores
Enviado por: TigPT em 14 de Dezembro de 2008, 12:33
O problema de leres um a um, é que depois podes ter apenas um byte para ler, e não sabes a que variável afectar, a menos que tenhas uma flag interna que diga qual é o próximo a ler.

Foi por isso que aconselhamos ler logo os dois valores ;)
Título: Re: separar valores de vários sensores
Enviado por: guibot em 16 de Dezembro de 2008, 15:53
confesso que me está a custar compreender a parte dos "char" e dos "bytes", como se processam, analisam, interpretam, etc..    :mrgreen:
Título: Re: separar valores de vários sensores
Enviado por: guibot em 16 de Dezembro de 2008, 15:56
já agora.. sabem como se usam certas funções de C no arduino?   por exemplo:

sscanf
atoi
strchr

já tentei importar as livrarias mas não estou a conseguir
Título: Re: separar valores de vários sensores
Enviado por: TigPT em 16 de Dezembro de 2008, 16:09
Duvido que essas funções existam por requererem bastante espaço, iria gastar a memoria toda do arduino. Porque não fazes esse processamento no pc? tenta baixar o nível de complexidade, afinal é hardware ;)
Título: Re: separar valores de vários sensores
Enviado por: defer em 16 de Dezembro de 2008, 16:16
o sscanf é um monstro de função, mas as outras podes re-implementar facilmente sem ter que usar as libs standard, algo do género:

Código: [Seleccione]
int my_atoi (char *s) {
  int result = 0;
  while (*s) {
    result = result * 10 + *s-'0';
    s++;
  }
  return result;
}


char *my_strchr (char *s, int chr) {
  while (*s) {
    if (*s == chr) return s;
    s++;
  }
  return NULL;
}

Atenção que a primeira não faz qualquer tipo de verificação se é mesmo um número e tambem nao funciona para números negativos, mas a adaptação não é difícil, era só um proof of concept
Título: Re: separar valores de vários sensores
Enviado por: guibot em 16 de Dezembro de 2008, 19:20
vou ter que aprofundar, já tenho material para me entreter, obrigado defer  ;)
Título: Re:separar valores de vários sensores
Enviado por: guibot em 19 de Dezembro de 2008, 00:43
depois de pesquisar como se processa a interpretação dos 'bytes' e como se convertem em 'ints', consegui chegar a uma resolução.

para já parece ser relativamente estável.
estou desejando chegar a casa e experimentar controlar os motores do farrusco remotamente   8)


Arduino que envia:
Código: [Seleccione]
int analogValue2, analogValue5;
int val2, val5;

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
}

void loop()
{
  // read analog input
  analogValue2 = analogRead(5);
  analogValue5 = analogRead(2);

  val2 = map(analogValue2, 0, 1023, 253, 0); //254 e 255 para SYNC
  val5 = map(analogValue5, 0, 1023, 253, 0);

  Serial.print(254, BYTE); //SYNC char
  Serial.print(val2, BYTE);
  Serial.print(255, BYTE); //SYNC char
  Serial.print(val5, BYTE);

  // pause for 100 milliseconds:
  delay(100);      //
}

Arduino que recebe:
Código: [Seleccione]
#include <AFSoftSerial.h>
 AFSoftSerial mySerial =  AFSoftSerial(3, 2);

 byte incomingByte;
 byte sensor1, sensor2;

 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void setup() {
  Serial.begin(9600);         // connect to the serial port
  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  mySerial.println("Hello, world?");

 }

 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 void loop() {
   
   if (mySerial.available()) {
      incomingByte = mySerial.read();

      Serial.println(int(incomingByte));

      if ((int(incomingByte) == 254)) {
        sensor1 = mySerial.read();
        Serial.print("Sensor 1 = ");
        Serial.println(int(sensor1));       
      }

      if ((int(incomingByte) == 255)) {
        sensor2 = mySerial.read();
        Serial.print("Sensor 2 = ");
        Serial.println(int(sensor2));             
      }
   
   }

 }