Go Down

Topic: Comunicação RF-Protocolo (Read 25260 times) previous topic - next topic

vasr

Boa noite,

Tenho dois arduinos, um é o master e o outro é o slave (na prática serão varios slaves) e ambos têm um recetor e transmissor de 434Mhz.Pretendo criar uma trama(ou protocolo) para controlar através do master os slaves.A trama será introduzida pela porta série(uma ação para o slave fazer),como por exemplo acender um simples led.Essa trama terá que ser carregada para um char array(exemplo buf[10]) pois estou a utilizar a virtualwire.h para fazer a comunicação.
Um exemplo de trama/protocolo que tentei executar foi este:
_                                                     _ _                                                            _                                  _                    _ _ _      _fim(p8)                
Numero de inicio da trama(posição0)   ID do slave pretendido(posição1e2 que dá até99) Ação a executa(posição3) Pino(posição 4) Para leitura de retorno(5,6,7)
Em que cada "_" corresponde a uma posição no array.
Cada posição do array dá para colocar 8bits,ou seja de 0-255.Porque utilizar duas posições para colocar 99 se numa dá 256?(é o que perguntam)
Eu na porta série tenho que colocar uma sequencia para ser carregada no array e enviada.Assim seria mais facil pois seria só carregar a sequencia inteira no buffer atrasvés de um ciclo for.Alguma sugestão de reduzir a trama e de facil introdução pela porta série?

Desde já obrigado pela ajuda.

bubulindo

No meu blog http://microsrus.blogspot.com tenho alguns posts com indicacões sobre como fazer um protocolo e reduzi-lo ao máximo.

Por exemplo, quando dizes:
Quote
(posição0)   ID do slave pretendido(posição1e2 que dá até99)


Estás a pensar em ASCII e isso vai trazer-te trabalho que nunca mais acaba. Para comecar, o numero vai ser uma string e como tal tens de comparar strings e não variáveis. Isso adiciona complexidade à programacão e probabilidade de erros.

Se enviares em formato binário, um byte dá-te a possibilidade de enderecares 255 nós. Em vez dos 9 que tu julgas ser possível em ASCII. Nota que ASCII também tem letras, logo podes usar códigos de letras para enderecar nós. Ficando assim com um numero maior por byte. Se olhares aqui asciitable.com vês que tens 10 carateres com numeros e 50 com letras. Dando-te a possibilidade de enderecares 60 num formato que o utilizador compreende de forma mais simples. Mas como a comunicacõa é feita entre microcontroladores, enviar em binário é a forma mais rápida de o fazer. Quer em termos de processamento, quer em termos de tamanho de trama.

Depois o teu protocolo não tem um caracter de inicio... assim nunca sabes quando comeca uma mensagem ou acaba. Isso também é má prática.

Não percebo a tua questão final. Importas-te de explicar de novo?
This... is a hobby.

vasr

#2
Aug 09, 2013, 06:16 am Last Edit: Aug 09, 2013, 06:35 am by vasr Reason: 1
bubulindo:Eu tenho que enviar a trama/protocolo pela porta serie como uma sequência.Exemplo "12221"(exemplo de sequencia),em que coloca cada numero numa posição do array e envia.
Este é um extrado do código que coloca a sequencia no buffer de envio:
Code: [Select]
char buf1[11];
while (Serial.available()>0) {
   serialNUM = Serial.read();
   //Serial.print("aqui");  //gets one byte from serial buffer
   buf1[i]=(serialNUM-48);
   i++;
   flag=1;
   delay(2);  // allow buffer to fill with next character
   }
   if (flag==1) {
   i=2;  //so you can see the captured string
   flag=0;
   buf1[0]=1;
   buf1[1]=checksumENVIA();
   buf1[10]=1;
   vw_send((uint8_t *)buf1,11);
   vw_wait_tx();
 
 }
}

Neste caso estou a trabalhar com carateres,ou seja até nove.Estou tentar agora utilizar por bytes mas não sei como depois colocar no buffer.Tenho de dar "ordens" aos slaves por uma sequencia colocada na porta serie ou algo identico.
Dá-me um exemplo do que sugeres para entender melhor.
Obrigado pela ajuda!

bubulindo

Então tens o teu PC ligado a um Arduino com o módulo RF e do outro lado tens outro arduino com outro módulo RF e queres que este arduino execute os comandos que pretendes, correcto?

Podes criar dois protocolos... um em ASCII que é enviado pela porta série para tu perceberes melhor e depois outro para comunicacão entre os dois módulos que já pode ir em binário.

Outra seria criares um software no teu PC para falar em binário com o primeiro arduino e então não tinhas de te chatear.

This... is a hobby.

vasr

Sim bubulindo é esse sistema.
Eu terei que criar um software tal como estas a sugerir.Mas mesmo como sofware,como faço em binário?Tenho que utilizar na mesma a introdução de uma sequência via porta serie.Meu problema é que em binário fica dificil colocar a sequencia no buffer de envio.

fabio_h

faz o arduino aceitar pela serial o modo ascii em converter em binario, pode fazer assim:
você digita:
[zona/device/acao] --->  [001/001/001] que o arduino transforma em três bytes,

e para aumentar a segurança pode usar  na transmissão implementada pelo arduino:
CRC - para validar os dados,
numero sequencial ou um time stamp - para tornar o pacote valido apenas uma vez,
HASH - para impedir que alguem comande sua rede com packet replay, nos controles com rolling code mais recentes, usa-se um hash de 256 bits ou mais, acho muita coisa, creio que uma encriptação XOR sane este problema.




 

vasr

Eu utilzo este protocolo:
carater inicio+soma+informação+carater fim
informação=ID slave+ação+pino que faz ação

Apenas faço o input da informação pela porta serie.
Exemplo de sequencia ASCII informção :
03+1+01=sequencia introduzida "03101"=5bytes
Mas assim só tenho 0-9 enquanto em binario teria 0-255 ou seja, 0-255IDS+0-255açoes+0-255pinos=3bytes e o protocolo teria menos posições no buffer de envio(virtualwire.h).
fabiohbm007: [001/001/001]=sequencia"001001001"?
Que acham coloco por 5bytes(por ASCII) ou binario(3bytes)?

Obrigado pela ajuda.


fabio_h

#7
Aug 09, 2013, 05:04 pm Last Edit: Aug 09, 2013, 06:06 pm by fabiohbm007 Reason: 1
eu utilizaria apenas o caracter de inicio, o fim poderia ser o \n que toda vez que da enter o windows/linux acrescenta na string da serial
se você usar ascii como entrada na serial tem que colocar um separador para o arduino saber quando começa um campo e termina outro
03101 poderia ser 03 10 1 ou 03 1 01.
fazendo i03/1/01 o arduino sabe onde começa e termina cada campo.

no meu exemplo mando [001/001/001], treze bytes pela serial e o arduino codifica em binario: [ox01] [0x01] [0x01], três bytes...

coloque a soma ou CRC sempre na ultima posição do pacote, assim fica facil usar o for e já compara ao ultimo.

Se usar pilhas, separe um bit para sinalizar bateria fraca.
usaria a seguinte estrutura em bytes ou bits:

[master/slave] [bateria] [nome] | [tamanho mensagem] | [mensagem] | [timestamp] | [hash]|  [crc]
1bit        1bit       6bits    |                       |             |                  |              |    
              1 byte             |        1 byte        |   1 a n bytes |  4 bytes   |  8 bytes  |  1 byte      



o hash é anexado pelo master mas o slave pode optar em nao refazer a verificação do hash, apenas qaundo for questao de seguranca, portao, alarme, etc

vasr

Entao vou enviar a sequencia 001001001?Depois coloco buf[0]=001,buf[1]=001 e buf[2]=001?

fabio_h

sim pode ser, lembrando que vai até 255 byte


vasr

Ou tens outra ideia?Qual a melhor forma,a que tinha anterior ou 0-255?

fabio_h


Entao vou enviar a sequencia 001001001?Depois coloco buf[0]=001,buf[1]=001 e buf[2]=001?


Isso. Era aqui que me referia, que o valor só vai até 255 em decimal (1 byte).

vasr

Como se faz nestes casos,usa-se  código ASCII 0-9 ou 1byte(0-255)?

vasr

Como coloco a sequência na respetiva posição do array?
Por exemplo:
Sequência:"001002003"colocada por porta serie.E terei que colocar no buf[0]=001,buf[1]=002 e buf[3]=003.
Alguma ajuda?

bubulindo

Code: [Select]

unsigned int buf[3];

char temp[4];

temp[3] = '\0';


if (Serial.available>8) { //9 caracteres...
unsigned char buf_ptr = 0;

   for (buf_ptr = 0; buf_ptr <3; buf_ptr++) { corre todos os elementos de buf.
      for(int i = 0; i<3; i++) { //lê para temporário...
         temp[i] = Serial.read();
      }
   buf[buf_ptr] = atoi(temp);
   }

}
//verifica recepcão.
for (int j = 0; j<3; j++ {
   Serial.print("buf[");
   Serial.print(j);
   Serial.print("] = ");
   Serial.println(buf[j]);
}
This... is a hobby.

Go Up