Boa tarde galera.

Estou com o seguinte problema, tem um arduino Mega e um UNO. Preciso através da comunicação serial entre eles passar uma string do mega para o uno. Fazer a ligação entre eles não é o problema, mas sim a programação. Alguém tem ideia de como realizar essa comunicação?

Obrigado a todos.

Exibições: 23263

Responder esta

Respostas a este tópico

Galera para aqueles que estão com o mesmo problema que é ja temos a solução.

Primeiramente os dois arduinos tem que estar ligados pela mesma fonte de alimentação, se não estiver a referencia de tensão e corrente de um arduino vai ser diferente do outro, contudo a comunicação não ocorre.

O TX de um tem que estar ligado do RX do outro e vice-versa.

O programa desenvolvido para a comunicação segue abaixo:

Emissor:

void setup (){
Serial.begin(9600);
pinMode(13, OUTPUT);
}

void loop(){
Serial.println("testes");
digitalWrite(13, HIGH);
delay(50);
digitalWrite(13, LOW);
delay(500);
}

Receptor:

void setup(){
Serial.begin(9600);
pinMode(13, OUTPUT);
}

void loop(){

if(Serial.available()){
digitalWrite(13, HIGH);
}
digitalWrite(13, LOW);
}

-----------------------------------------------

Alem da alimentação a velocidade de comunicação das dos dois arduinos tem que ser iguais.

Vlw galera.

Obrigado a todos que me ajudaram.

Abraço

Tem como saber se o texto enviado pela serial bate com um texto interno e aí sim fazer o pino 13 alternar??? Porque por este fonte, qualquer coisa que vier pela serial será tratada como se estivesse havendo alguma comunicação, ou estou errado???

tranquilamente Euclides,

Você usa o Serial.read() pra ler os caracteres e armazenar em um buffer e depois compara com a "variável interna" (caso seja uma String).

Este programa exemplo estaria acendendo o LED a qualquer sinal de comunicação.

Um exemplo, 2 funçoes de um programa que faz exatamente isso: Recebe comandos de um outro Arduino ou um PC via Serial (TTL).

No caso,a função Protocolo faz a leitura da serial e armazena no buffer input[].

Já a leComando() processa esses dados recebidos.

//------------- Protocolo Serial
// Formato:  [!][Id][Comando][x]
void protocol(){
  memset(input, '\0', 5);
  byte inByte = '\0';
  delay(100);
  while(inByte != 33) {
    inByte= Serial.read(); // Wait for the start of the message
  }
  if(inByte == 33) {
    while(Serial.available() < 3){ // Wait until we receive 5 characters
      ;  
    }
    for (int i=0; i < 3; i++) {
      input[i] = Serial.read(); // Read the characters into an array

    }
  }
}

//------------- Le Comando : Interpreta os valores recebidos pela serial
void leComando(){
  int id = input[0]; //lê a posição 0 do vetor de buffer e salva na variável de Identificação do pino.
    if (input[1] == 1) {     
      PinStatus[id]=1; //lê a posição 0 do vetor de buffer e atualiza o valor da saida no vetor de status.
    }
    if (input[1] == 0) {      
      PinStatus[id]=0;
    }
    if (input[1] == 2) {     
      Serial.print('!');  //Retorna o Status do ID
      Serial.print(id);
      Serial.print(PinStatus[id]);
      Serial.print('x');
    }
    beep();
    lcd.clear();
    lcd.print("ID - Status");
    lcd.setCursor(0, 1);
    lcd.print(id);
    lcd.print("  - ");
    if(PinStatus[id] == 1){
      lcd.print("ON");
    }
    else {
      lcd.print("OFF");
    }
 }

--------------------

Esse programa recebia uma instrução do tipo [ID][Comando] e acionava as portas de 2 Registradores (74hc595). Caso alguém queira o código completo, só solicitar por Mensagem.

Faço das minhas palavras as do  Jonatas Freitas, somente completando que os dois arduinos tem que estar ligado no mesmo terra da fonte de alimentação, pois a tensão de referencia deles tem que ser a mesma. Se cada um tiver uma fonte de alimentação independente os valores de tensão recebidas pela porta serial não vão bater, contudo o arduino não consegue interpretar as informações recebidas.

Bem lembrado! GND dos 2 interligados.

Isso ocorre quando se pensa em termos de pino a pino (neste caso rx no tx e vice-versa), ou seja somente 2 pinos. Mas se levarmos em conta que o GND faz parte do circuito aí se chega a conclusão que ele é necessário, correto?

Pensem nos PCs ligados as impressoras seriais, aquelas antigas. Este detalhe nem era percebido pois os cabos já tinham fios ligados as 2 carcaças.

Sim, é algo que é transparente muitas vezes até para o projetista quando se tem a blindagem ou a carcaça do conector sendo aterrada nas duas pontas (gerando um GND em comum), seja o DB9 de uma impressora serial, o cilindro externo do conector minidin de um teclado PS2 ou a "capa" metálica de um conector USB,...

Um exemplo disso, mais cedo enquanto auxiliava o Caio, estava alimentando 2 Arduinos pela USB do meu note mesmo. Como o ponto de aterramento do note é comum entre todos os periféricos, eu NEM me toquei que ele (trabalhando com 2 Arduinos com fontes independentes) deveria ligar o GND.

Boa noite Jonatas,

Estou com dois Arduinos Uno para fazer uma experiência mandando linhas de um arquivo texto de um SD para o outro Arduino que está carregado com o firmware Gbrl ( https://github.com/grbl/grbl ) para controle de CNC.

Estou acompanhando o trabalho feito por Edward no link http://www.shapeoko.com/archives/86 o qual deu apresentou uma implementação para controle do buffer, cujo fragmento de código é o seguinte:

------------------------

1) Conecte o fio entre arduinos (Escravo: pino 7 ao Mestre: Pin13)
2) Mestre:. após cada byte recebido, verifique o estado do buffer. Emitindo o comando serialAvailable () retorna o número de bytes disponível para ser lido do buffer. Sabemos que o buffer é apenas 128bytes de tamanho, para que possamos fazer uma declaração simples se:

if(serialAvailable()>= 128) {LEDPORT |= _BV(LEDBIT);} //turn on LED13

3) Escravo: antes de enviar bytes, verificar o estado do pino 7

while ((c = file.read()) > 0)
{
while(val = digitalRead(flowpin) == HIGH)
{
delay(100);
}
Serial.print((char)c);
}

---------------------

Vale lembrar que para cada mudança de linha devem ser enviados os caracteres \n\r necessários para o firmware Grbl entender a mudança de linha.

Você tem idéia de como aproveitar esse fragmento de código para o controle do fluxo na serial sem ultrapassar o limite de 128bytes do buffer?

Desde já agradeço pela sua atenção!

Abç,

Milton Vilela

Eu encontrei algo parecido esses dias envolvendo SD+I²C+RF(433mhz).

A solução que geralmente uso é parecida com a dele. Só que ele usa uma mudança de estado na I/O para interromper a transmissão.

while(val = digitalRead(flowpin) == HIGH)
{
delay(100);
}

Com o objetivo de economizar I/O, eu faço isso pela serial mesmo.

Antes de enviar um novo byte, o Emissor verifica se existe algo em seu buffer Serial. Se existir, verifica se é o caractere* que simboliza o estouro do buffer do receptor. Se for o caractere* especificado para alertar o estouro  o transmissor para de transmitir e fica aguardando que o receptor informe que o buffer está livre enviando um outro caractere*, como tentei ilustrar abaixo.

Primeiro a solução que você citou, usando o pino de I/O. Depois a que costumo usar.

Como poder ver, o algoritmo é basicamente o mesmo, só que em vez de verificar o pino 7 no While, eu verifico o valor na serial.

Não sei se me fiz entender. Qualquer dúvida só perguntar.

*uso um dos primeiros 37 caracteres da ASCII, evitando as de quebra de linha, movimentação de carro, e outros que poder ser significativas pro sistema. Geralmente os relativos a Device Control (021-024).

Boa tarde Jonatas,

Agradeço pela sua atenção e explicação.

No caso que estou estudando, eu não tenho ainda como modificar o firmware gravado no Arduino que controla os motores, então, quando eu mando os bytes do arduino "A" para o Arduino "B", preciso saber quantos bytes do byffer de 1278 bytes do Arduino "B" estão disponíveis para eu continuar o envio de bytes do Arduino "A" e não perder informação, imagino que seja assim o funcionamento adequado.

                  TX ---------------------> RX

Arduino "A"                                   Arduino "B"

                  

Será que existe uma forma de se saber o tamanho do byffer do Arduino "B" apenas pela serial?

Abç,

Milton

Quanto ao buffer, não são só 64bytes?

Serial
available()
Description

Get the number of bytes (characters) available for reading from the serial port. This is data that's already arrived and stored in the serial receive buffer (which holds 64 bytes). available() inherits from the Stream utility class.

http://arduino.cc/en/Serial/Available

---

A principio nem a Stream implementa uma função no protocolo de comunicação que permita conhecer o estado do buffer do receptor (algo como uma instrução Ready to Read). Isso teria que ser implementado via Serial ou via GPIO como feito pelo Edward.

Sem alterar o código do Arduino B (receptor) a única solução que consigo pensar para REDUZIR estouro de buffer seria baixar a velocidade de transmissão.

Olá Jonatas,

Agradeço pela rápida resposta,

Eu testei o envio de dados pela serial com o código abaixo:

-------------

int i = 0;
void setup(){
Serial.begin(9600);
}

void loop(){
Serial.print("G91 G28 X0 Y0 Z0");
Serial.print("\n");
Serial.print("\r");

for (i=1;i<=100;i++){
Serial.print("G1 X1"); //01
Serial.print("\n");
Serial.print("\r");
delay(20);

Serial.print("G1 X-1"); //02
Serial.print("\n");
Serial.print("\r");
delay(20);
}
delay(100000);
}

-------------

Em seguida, acompanhei a execução e o motor efetuou aproximadamente 40 movimentos, o que significa que aproximadamente 380bytes foram enviados.

Vídeo da montagem: http://www.youtube.com/watch?v=sko7Ayz-ZGo

Então, não sei explicar ainda, foram passados muito mais bytes do que o limite do buffer (que na matéria do Edward é igual a 128bytes -> http://www.shapeoko.com/archives/86| )

Realmente eu não sei como o Edward fez, visto que quando o firmware Grbl é instalado é ocupada praticamente toda a memória flash.

Talvez ele tenha modificado o firmware incluindo a rotina que testa o tamanho do buffer, não sei!

Entendo que, como o Edward está desenvolvendo esse projeto para um produto  com finalidade comercial, os detalhes não foram fornecidos.

Até +,

Milton Vilela

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço