Pages: [1] 2   Go Down
Author Topic: Envio de informação via Serial para outro arduino  (Read 2192 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Boas malta.

Tou aqui com umas duvidas.
O que pretendo é o seguinte.
 Tenho 2 Arduinos. O 1º lê um certo valor de uma entrada analógica. Em seguida envia esse valor para o outro Arduino, que depois escreve o mesmo em um lcd. O meu problema esta na transmissão entre os dois.

No 1º

....
loop()
{
valor = analogRead(0);
Serial.println(valor);
}

Até aqui tudo bem e agora no segundo como faço o tratamento da informação?

Desde já obrigado.
Logged

'round the world...
Offline Offline
Faraday Member
**
Karma: 41
Posts: 3108
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Primeiro ligas o RX ao TX e vice-versa. Depois fazes isto no segundo:

Code:

void loop(){
char valor[5];
unsigned int fromOther = 0;

 
   if (Serial.available() > 3) { //não é ideal...
      for (int i = 0; i <5; i++) {
          if ((valor[i] = Serial.read()) != '\n') {
             valor[i] = '\0';
             break; //sai deste for.
          }//end if
      }//end for
   fromOther = atoi(valor);
   }
}

Não sei o que se vai passar com os chips USB ainda ligados nos dois controladores...

Há uma maneira mais simples... sem teres de enviar dados em ASCII.
Logged

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Offline Offline
God Member
*****
Karma: 12
Posts: 508
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Como os dois arduinos estão ligados, por cabo nos pinos TX/RX -> RX/TX?

Presumo que já sabes como imprimir no LCD, então o que te falta é ler a serial?

se for isso, testa o abaixo:
Code:
String SerialBuffer = "";

void setup(){
  SerialBuffer.reserve(200);

  Serial1.begin(9600); //os dois devem ter o mesmo rate
}

void loop(){
  if (Serial1.available() > 0){
    while (Serial1.available() != 0) {
      char inChar = (char)Serial1.read();
      
      if (inChar == '\n') {
        //Imprime no LCD a string do SerialBuffer
        SerialBuffer = "";
      }
      else {
        SerialBuffer += inChar; \\Add to buffer
      }
    }
  }
}

Assim o primeiro arduino imprime uma linha na serial e o segundo recebe todos os bytes, armazena no buffer (string) e quando encontrar a quebra de linha você pega o conteúdo do buffer e imprime no LCD.
Logged

Offline Offline
God Member
*****
Karma: 12
Posts: 508
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bubulindo, the flash again kkkk Ou eu é que sou lento? lol
Logged

Portugal
Online Online
Edison Member
*
Karma: 27
Posts: 1414
Tomorrow I will know a BIT more than yesterday
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
String SerialBuffer = "";
String , de todo evitavel sendo que o pretendido é apenas ler uns bytes da Serial
Usa apenas isso em ultimo recurso a tudo.
Nao sei se sabes mas isso e um objecto e nao um tipo de dados nativo do C!
Quote
fromOther = atoi(valor);
Visto ele querer colocar isso num LCD e o LCD apenas recebe strings se calhar aqui será desnecessario converter para int
« Last Edit: March 20, 2013, 12:06:58 pm by HugoPT » Logged

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B


Offline Offline
God Member
*****
Karma: 12
Posts: 508
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
String SerialBuffer = "";
String , de todo evitavel sendo que o pretendido é apenas ler uns bytes da Serial
Usa apenas isso em ultimo recurso a tudo.
Nao sei se sabes mas isso e um objecto e nao um tipo de dados nativo do C!


Olá HugoPT!

Estás correto! Eu uso o acima para alguns comandos e variáveis via serial, o uso de string nesse caso facilita a comparação, exemplo SerialBuffer == "IrSensor(99,99,99)".

Neste último caso, você sugere um char array no lugar de string?
Logged

Portugal
Online Online
Edison Member
*
Karma: 27
Posts: 1414
Tomorrow I will know a BIT more than yesterday
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Neste último caso, você sugere um char array no lugar de string?
Sim sem duvida.Para fazer comparaçoes podes sempre usar o strcmp() para fazeres comparaçoes entre strings
Logged

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B


Offline Offline
God Member
*****
Karma: 12
Posts: 508
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sim sem duvida.Para fazer comparaçoes podes sempre usar o strcmp() para fazeres comparaçoes entre strings

Valeu a Dica!!! Farei testes com strcmd() smiley-grin

Quando programamos no ambiente Windows temos certos hábitos que levamos para outra linguagens.

Obrigado!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Como os dois arduinos estão ligados, por cabo nos pinos TX/RX -> RX/TX?

Presumo que já sabes como imprimir no LCD, então o que te falta é ler a serial?

se for isso, testa o abaixo:
Code:
String SerialBuffer = "";

void setup(){
  SerialBuffer.reserve(200);

  Serial1.begin(9600); //os dois devem ter o mesmo rate
}

void loop(){
  if (Serial1.available() > 0){
    while (Serial1.available() != 0) {
      char inChar = (char)Serial1.read();
      
      if (inChar == '\n') {
        //Imprime no LCD a string do SerialBuffer
        SerialBuffer = "";
      }
      else {
        SerialBuffer += inChar; \\Add to buffer
      }
    }
  }
}

Assim o primeiro arduino imprime uma linha na serial e o segundo recebe todos os bytes, armazena no buffer (string) e quando encontrar a quebra de linha você pega o conteúdo do buffer e imprime no LCD.

Sim estão ligados TX/RX -> RX/TX
Desculpem a minha ignorância mas sou novo nestas coisas... smiley

Quanto ao codigo, Serial1 é por algum motivo em especial? As placas que estou a usar são Uno, não será apenas Serial?

Não existe uma maneira mais simples?
Por exemplo...

Arduino 1 lê valor de 975 na analógica 0
leituraa = analogRead(0);
envia para Arduino 2
Serial.println(leituturaa);

No Arduino 2 algo tipo do género
leiturab = Serial.read();  sendo o valor de "leituraa" igual a 975...
lcd.setCursor(0,0);
lcd.print(leiturab,1);

Isto é possível?
Logged

Portugal
Online Online
Edison Member
*
Karma: 27
Posts: 1414
Tomorrow I will know a BIT more than yesterday
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
leiturab = Serial.read();  sendo o valor de "leituraa" igual a 975...
975 ao serem enviados pela porta serie cada digito ocupa um byte.
logo tens de ler todos os bytes e reconstruir o numero.
Nao é possivel duma só vez
Logged

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B


Offline Offline
God Member
*****
Karma: 12
Posts: 508
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quanto ao codigo, Serial1 é por algum motivo em especial? As placas que estou a usar são Uno, não será apenas Serial?

Perdoa-me, mas eu copiei partes do meu código e eu uso o Mega, que possui mais portas seriais.  smiley-roll

Sobre ser novato, eu também sou, então não se preocupe! Mas logo mais deixaremos de ser smiley-wink

Arduino 1 lê valor de 975 na analógica 0
leituraa = analogRead(0);
envia para Arduino 2
Serial.println(leituturaa);

No Arduino 2 algo tipo do género
leiturab = Serial.read();  sendo o valor de "leituraa" igual a 975...
lcd.setCursor(0,0);
lcd.print(leiturab,1);

Isto é possível?

Bom, primeiro você precisa saber se tem dados na serial, então não tem como fugir do Serial.available()

O segundo o HugoPT já respondeu, você terá de passar pelo Serial.read() três vezes, uma para cada byte, logo não tem como fazer de forma diferente daquela que o bubulindo exemplificou.
Logged

'round the world...
Offline Offline
Faraday Member
**
Karma: 41
Posts: 3108
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok... depois de ler um pouco sobre o Serial... experimenta algo assim:


Arduino 1
Code:

void loop() {

unsigned int valor = 0;

valor = analogRead(A0);
Serial.write(valor >> 8);
Serial.write(valor);
Serial.println(); //importante
}

no Arduino 2

Code:
void loop() {
  unsigned int value = 0;
  if (Serial.available() >=3) {//dois bytes do int mais carriage return
    value = (Serial.read()<<8) + Serial.read();
    Serial.read();//skip \n
    Serial.print("received ");
    Serial.println(value);
  }
}

Assim é melhor porque são sempre apenas enviados 2 bytes. Se enviares em ASCII podes enviar entre 2 a 5 bytes (ou 6 se olhares ao tamanho dum int) e isso é bem mais complicado de programar. Também é mais rápido...

Nota que não coloquei aqui protecções para sincronizar ambos os arduinos. Ou seja, têm de ser ligados ambos ao mesmo tempo para garantir que um está a ouvir o que o outro está a mandar, mas isso é simples de fazer colocando o Arduino 2 à espera do \n.

Esta é uma maneira mais simples e correcta de fazer isto. smiley
Logged

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Offline Offline
God Member
*****
Karma: 12
Posts: 508
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bom, abaixo como ficaram meus códigos, para o Joaquim Lopes pode ser um próximo passo, passar o valor de vários sensores e ou comandos entre os arduinos (?).

Eu executo uma série de comandos via bluetooth, esse é para eu gravar os valores de referencia para sensores IR de um seguidor de linhas, valores usados para aumentar ou reduzir a sensibilidade das condições.

Lembrando que ainda sou muito noob!  smiley-sad-blue

Code:
char SerialBuffer[100]; //sem String aqui rs
byte CharIndex = 0;

int paramR = 0; //Right Sensor ref
int paramC = 0; //Center Sensor ref
int paramL = 0; //Left Sensor ref

void setup(){
  Serial1.begin(57600);
}

void loop(){
  if (Serial1.available() > 0){
    while (Serial1.available() != 0) {
      char inChar = (char)Serial1.read();
     
      if (inChar == '\n') {
        ExecuteCommand(SerialBuffer);

        CharIndex = 0;
        memset(SerialBuffer, 0, 100);
      }
      else {
        SerialBuffer[CharIndex] = inChar;
        CharIndex++;
      }
    }
  }
}

void ExecuteCommand(char Value[]){
  char Command[100];

  strcpy(Command, Value);

  char *chpt = strtok(Value, "("); //Split string into tokens
  if (chpt == NULL) {
      Serial1.println("No Command in the First strok");
      return;
  }
 
  if(strcmp(chpt, "SetSensorParams") == 0)
    SetSensorParams(Command);
}

void SetSensorParams(char Params[]){
  int newParamL,newParamC,newParamR;

  Serial1.print("Values: ");
  Serial1.println(Params);

  int errors = 0;
 
  char *chpt = strtok(Params, "("); //Split string into tokens
  if (chpt == NULL) {
      Serial1.println("Params strok returns NULL");
      ++errors;
  }
 
  if (errors == 0) {
      chpt = strtok(NULL, ",");
      if (chpt == NULL) {
          Serial1.println("First param strok returns NULL");
          ++errors;
      }
      else {
          newParamL = atoi(chpt); //Convert to integer
      }
  }
 
  if (errors == 0) {
      chpt = strtok(NULL, ",");
      if (chpt == NULL) {
          Serial1.println("Second param strok returns NULL");
          ++errors;
      }
      else {
          newParamC = atoi(chpt);
      }
  }
 
  if (errors == 0) {
      chpt = strtok(NULL, ")");
      if (chpt == NULL) {
          Serial1.println("Third Param strok returns NULL");
          ++errors;
      }
      newParamR = atoi(chpt);
  }
 
  if (errors == 0) {
    paramL = newParamL;
    paramC = newParamC;
    paramR = newParamR;
  }
}

o que vocês acham?

HugoPT, esta melhor assim?

PS: Lembrando que eu uso o Serial1 do arduino mega, assim posso trabalhar com a serial usb e bluetooth simultaneamente
Logged

Portugal
Online Online
Edison Member
*
Karma: 27
Posts: 1414
Tomorrow I will know a BIT more than yesterday
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Assim por uma vista de olhos rapida parece que está la tudo.
Ha algumas coisas que podem ser melhoradas a titulo de uma boa programaçao.
Vejamos aqui:
Quote
Code:
void ExecuteCommand(char Value[]){
Estas a passar um parametro com o Value[].Quando passas um array ele por si só é um ponteiro para a primeira posiçao do vector.Eu teria colocado ou esperar um ponteiro em vez de Value[]
Eu modificava para:
Quote
ExecuteCommand(char * Value)
Agora ha aqui outra questao. O vector que estas a passar é global o que poderá nao fazer muito sentido passa-lo como argumento na funçao...
Irá funcionar na mesma assim.
Quote
  char Command[100];

  strcpy(Command, Value);
Se passas o vector por parametro porque é que depois o copias para outro array dentro da funçao?
A idea é usalo la dentro nao copia-lo.
Assim comeste mais 100 bytes de RAM para nada.Faz uso dos ponteiros!
« Last Edit: March 21, 2013, 04:47:53 am by HugoPT » Logged

Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B


'round the world...
Offline Offline
Faraday Member
**
Karma: 41
Posts: 3108
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, acho que nos estamos a deixar levar por dois problemas diferentes.

O do Mortis em que uma pessoa comunica com o Arduino (já agora, tens um código extremamente complexo para algo tão simples) e o do joaquim em que dois arduinos comunicam entre si.
No problema do Mortis, os humanos preferem ASCII então a comunicação é feita assim e como tal tem um overhead maior e é mais complexo.
No caso do Joaquim é escusado colocar duas máquinas a falar linguagem de humanos (ASCII) já que elas se entendem melhor em binário e a programação é bem menos complexa como exemplifiquei em cima.

A única coisa que me preocupa é o efeito que o chip FTDI tem na comunicação... Alguém experimentou os dois códigos?
Logged

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Pages: [1] 2   Go Up
Jump to: