Autor Tópico: Transmissão rf com PIC...  (Lida 36352 vezes)

Description:

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

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #45 Online: 11 de Março de 2009, 15:21 »
me desculpe Smarley, nao tinha percebido.

mas vc vai ter problemas nessa comunicacao ai.

o problema é q o receptor estara sempre recebendo dados, vc transmitindo ou nao. vc vai ter q montar um protocolo de comunicacao com caractere de inicio, de fim e arrumar um jeito pra vc confirmar se o caractere recebido é do mestre msm. um idéia é vc fazer um filtro para passar somente alguns caracteres, por ex: '!' para inicio de pacote; '#' para fim de pacote, e os digitos de 0 a 9. como esses caracteres usam somente 7 bits, vc poderá usar o oitavo bit para paridade (contaria os bits setados, se o resultado for impar, setaria o oitavo bit)

Offline kaoalex

  • Fuso
  • **
  • Posts: 128
    • DMSQUARE
Re: Transmissão rf com PIC...
« Resposta #46 Online: 11 de Março de 2009, 15:40 »
Pessoal só para tentar facilitar a compreensão dos códigos existe uma ferramenta "Inserir código" que preserva o código fonte original.

Exemplo:
Código: [Selecionar]
include "C:\Program Files\PICC\PICC\receptor 16f628A.h"

#int_timer0
void trata_to()
{
   int conta;
   static boolean led;
   set_timer0(131 + get_timer0());
   conta++;
   if(conta == 125)
   {
   conta=0;
   output_bit(PIN_B0,led);
   led=!led;
   }
}
char pacote[16],pacote_liga[16],pacote_desliga[16];
int x,y;
void carrega_valores()
{
   x=0;
   y=15;
   while(x<16)
   {
   pacote_desliga[x] =y;

   x++;
   y--;
   }
   x=0;
   while(x<16)
   {
   pacote_liga[x] =x;

   x++;
   }
}
void main()
{

   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(global|int_timer0);
   carrega_valores();
   while(true)
   {
   x=0;
   while(x<16)
   {
   pacote[x] = getc();

   x++;
   }
   x=0;
   while(x<16)
   {
   xxxx(pacote[x]);

   delay_ms(50);
   x++;
   }
   x=0;
   while(x<16)
   {
   if(pacote[x]==pacote_liga[x])

   {
   output_high(PIN_B3);
   }
   x++;
   }
   x=0;
   while(x<16)
   {
   if(pacote[x] == pacote_desliga[x])
   {
   output_low(PIN_B3);
   }
   x++;
   }
   }
}

Offline plancton81

  • Fuso
  • **
  • Posts: 185
  • Sexo: Masculino
Re: Transmissão rf com PIC...
« Resposta #47 Online: 11 de Março de 2009, 16:05 »
Smarley,

Um tempo atrás fiz um sistema de armário escuro que usa um protocolo parecido com esse que sugeri, tem o link do video dele funcionando na minha apresentação http://www.guiacnc.com.br/forum/index.php/topic,1952.

Não achei aqui na máquina do trabalho a última versão do código, essa deve ter alguns bugs e burrices...

Vou passar o código integral pra vc dar uma olhada na parte do protocolo. Tem dois arquivos, um com exemplos de dados passados pra maquina pelo hyperterminal por exemplo e outro com o código fonte. a função que tem grande parte disso é a "__interrupt void usart0_rx (void)".

Abraço


Smarley

  • Visitante
Re: Transmissão rf com PIC...
« Resposta #48 Online: 11 de Março de 2009, 16:32 »
Fiz um programa agora e botei no PIC e na placa.
Terminei de montar ela agora a pouco.
No programa mandei ele pegar o que tivesse no ar e mostrar no LCD.
Realmente a quantidade de informações é enorme.
Eu não sei o q aconteceu que ele só está recebendo 3 valores e parando.
Vou revisar o programa, mas acho que está tudo certo.

Código: [Selecionar]
#include "C:\Program Files\PICC\PICC\receptor 16f877a.h"


#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_TYPE 2
#include <lcd.c>
int x;
void main()
{
   lcd_init();



   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   while(true)
   {
   printf(lcd_putc,"\fRecebi=");
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"\n%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   x=getch();
   printf(lcd_putc,"%i ",x);
   delay_ms(100);
   }

}

Esse é o programa.

Plancton, vou dar uma olhada nos seus arquivos.
Cfreund não entendo porque colocar um caracter no começo e outro no fim.
Se da no mesmo eu colocar números ou não.

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #49 Online: 11 de Março de 2009, 16:36 »
Smarley,

vc pode sim colocar números, desde que no resto da mensagem nao os repita.

além de não permitir que isso aconteça, ficaria mais facil pra vc na hr de programar ou revisar o código.

vc precisa de um caracter fixo e único para que, na hora em que vc receber o pacote, vc saiba onde ele começa.

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #50 Online: 11 de Março de 2009, 16:38 »
o programa do plancton é um excelente exemplo.

mas como vc terá um ingrediente a mais na seu projeto, o ruído, eu te aconselho a colocar a paridade para saber se o caractere recebido faz parte do pacote ou não. fazendo isso seu pacote terá mais chances de estar íntegro com os 16 caracteres.

Smarley

  • Visitante
Re: Transmissão rf com PIC...
« Resposta #51 Online: 11 de Março de 2009, 16:57 »
Pois eh...
mas pelo que eu to vendo aqui, tem muita bobagem no ar.
Mas muita mesmo... ele não para de receber nunca.
Vai ser quase impossível os 16 bytes chegarem la sem nenhum byte estranho pelo meio.
Eu acho que vou ter que diminuir a quantidade de bytes do pacote.
1 só byte não tem como, pois assim ele iria ligar toda hora...
Tem que ser uns 5 bytes que dai ja elimina as chances de outros equipamentos ligarem ele.

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #52 Online: 11 de Março de 2009, 17:22 »
Smarley,

se vc trabalhar a 4800bps (q é maximo segundo o datashit do receptor), quando vc estiver recebendo dados do transmissor, as chances de entrar um byte intrometido é mínima. e se você usar paridade, diminui ainda mais.

tava pensando aqui e bolei um jeito facil e eficiente para essa verificacao:

se vc trabalhar com números de 0 a 7, vc usaria somente 3 bits.

definiria o número 7 como inicio de pacote e o número 0 como fim e deixaria o resto para comandos.

sobrariam 5 bits, certo? entao vamos aproveita-los:

1' ao 3' - Utilizaria para os números de 0 a 7.
4' ao 7' - Utilizaria para enviar a posição do byte atual dentro do pacote.
8'        - Paridade. Se a contagem dos bits '1' for par, setaria em '1'.

Ex.:

Pacote[00] = 0b1 0000 000; // bit8: P; bit7~4: Posição 0; bit3~0: Inicio de Pacote

Pacote[01] = 0b1 0001 001; // bit8: P; bit7~4: Posição 01; bit3~0: Número 1.
Pacote[02] = 0b1 0010 010; // bit8: P; bit7~4: Posição 02; bit3~0: Número 2.
Pacote[03] = 0b1 0011 011; // bit8: P; bit7~4: Posição 03; bit3~0: Número 3.
Pacote[04] = 0b1 0100 100; // bit8: P; bit7~4: Posição 04; bit3~0: Número 4.
Pacote[05] = 0b1 0101 101; // bit8: P; bit7~4: Posição 05; bit3~0: Número 5.
Pacote[06] = 0b1 0110 110; // bit8: P; bit7~4: Posição 06; bit3~0: Número 6.
Pacote[07] = 0b1 0111 111; // bit8: P; bit7~4: Posição 07; bit3~0: Número 7.
Pacote[08] = 0b1 1000 111; // bit8: P; bit7~4: Posição 08; bit3~0: Número 7.
Pacote[09] = 0b0 1001 111; // bit8: I; bit7~4: Posição 09; bit3~0: Número 7.
Pacote[10] = 0b0 1010 111; // bit8: I; bit7~4: Posição 10; bit3~0: Número 7.
Pacote[11] = 0b1 1011 111; // bit8: P; bit7~4: Posição 11; bit3~0: Número 7.
Pacote[12] = 0b0 1100 111; // bit8: I; bit7~4: Posição 12; bit3~0: Número 7.
Pacote[13] = 0b1 1101 111; // bit8: P; bit7~4: Posição 13; bit3~0: Número 7.
Pacote[14] = 0b0 1111 111; // bit8: I; bit7~4: Posição 14; bit3~0: Número 7.

Pacote[15] = 0b0 1111 111; // bit8: I; bit7~4: Posição 15; bit3~0: Fim de Pacote

da pra amadurecer a idéia, mas o propóstio principal é te dar uma luz das varias maneiras de que pode ser feito isso.

Offline C N C N o w !

  • CNCMASTER
  • ******
  • Posts: 6300
  • Sexo: Masculino
Re: Transmissão rf com PIC...
« Resposta #53 Online: 11 de Março de 2009, 17:35 »
... aconselho a colocar a paridade para saber se o caractere recebido faz parte do pacote ou não.

Ô dureza ...

Paridade não serve para nada neste caso. Quem inventou tava de porre e quem usa não parou pra pensar ...  ;D ;D ;D

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #54 Online: 11 de Março de 2009, 17:38 »
Jorge, poderia me explicar o porque dessa sua afirmação?

Offline C N C N o w !

  • CNCMASTER
  • ******
  • Posts: 6300
  • Sexo: Masculino
Re: Transmissão rf com PIC...
« Resposta #55 Online: 11 de Março de 2009, 17:46 »
Jorge, poderia me explicar o porque dessa sua afirmação?

Poderia. Mas antes reflita um pouco ... faça aí uma simulação, mesmo que com papel e lápis e vc vai perceber ...

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #56 Online: 11 de Março de 2009, 17:48 »
Nem preciso, sei muito bem como funciona.

não somente eu como: fabricantes de memória ecc, usuários de varios protocolos como o f2f, e uma kctada de gente...

Smarley

  • Visitante
Re: Transmissão rf com PIC...
« Resposta #57 Online: 11 de Março de 2009, 17:49 »
Cara, eu tava pensando aqui agora...
nunca isso vai funcionar!
eu fiz o seguinte, coloquei o transmissor e o receptor na placa.
Fiz um programa:

Código: [Selecionar]
#include "C:\Program Files\PICC\PICC\receptor 16f877a.h"


#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_TYPE 2
#include <lcd.c>
int y,x;
void main()
{
   lcd_init();



   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   x=0;
   while(true)
   {
   if(x>100)
   {
   x=0;
   }
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"\f%i ",y);
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"%i ",y);

   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"%i ",y);
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"%i ",y);
   
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"\n%i ",y);

   
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"%i ",y);
   
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"%i ",y);
   
   x++;
   putc(x);
   y=getch();
   if(x!=y)
   {
   printf(lcd_putc,"\fDeu erro no %i\nRecebi %i",x,y);
   delay_ms(700);
   }
   printf(lcd_putc,"%i ",y);
   }

}

E sempre da erro.
Nunca ele lia o byte certo.
Ai eu pensei, como que ele vai ler, se o byte ja foi mandado? o.O
Com 1 só PIC eu não tenho como testar essa comunicação nunca, pois ele não tem como mandar e receber ao mesmo tempo...
Vou ter que fazer a outra placa, e usar ela para enviar os bytes pro receptor.
Assim eu posso saber se está tudo ok, e calibrar o receptor.
A taxa eu botei em 4000bps.
eu tinha botado um delay no código la, mas vou tirar ele. Para não ter problemas com bytes metidos durante esse tempo.

Eu estou certo quanto a não funcionar o meu esquema de mandar e enviar neh?

Offline Cláudio F.

  • Fuso
  • **
  • Posts: 222
  • Sexo: Masculino
  • Cidade - UF: São Paulo/SP
Re: Transmissão rf com PIC...
« Resposta #58 Online: 11 de Março de 2009, 17:51 »
utilize interrupcoes e filtre logo no inicio para ser processados somente os caracteres q vc utilizar

Offline plancton81

  • Fuso
  • **
  • Posts: 185
  • Sexo: Masculino
Re: Transmissão rf com PIC...
« Resposta #59 Online: 11 de Março de 2009, 18:01 »
Pra conferir os dados eu prefiro CRC.

Vou tentar fazer um resuminho de um método simples.

Se vc tiver memória livre pode usar um algoritmo baseado em tabelas e não em calculos.

Por exemplo:

declara como global:

Código: [Selecionar]
unsigned int crc_tx;
unsigned int crc_rx;

const unsigned int tabela_crc[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0,
0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41,
0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0,
0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1,
0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341,
0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1,
0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0,
0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940,
0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1,
0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0,
0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740,
0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0,
0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0,
0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541,
0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0,
0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0,
0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40,
0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1,
0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0,
0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 };



usa essas funções:

Código: [Selecionar]
void calculo_crc(unsigned int *crc, unsigned int byte_in) {
   (*crc) = ((*crc) >> 8) ^ tabela_crc[((*crc) ^ byte_in) & 0x00FF];
}

unsigned char char_to_hex(unsigned char caracter, unsigned char H1L0) {
unsigned char saida;
saida = caracter;
if (H1L0) { saida >>=4; }
saida &= 0x0F;
if ((saida >= 10) && (saida <=15)) { saida += 7; }
saida += 48;
return saida;
}


unsigned int rx_hex_to_int(unsigned char b3, unsigned char b2, unsigned char b1, unsigned

char b0) {
unsigned int i;
i = hex_to_char(b3,b2);
i = i << 8;
i += hex_to_char(b1,b0);
return i;
}



na hora de enviar faz algo do tipo:

Código: [Selecionar]

void serial_tx_pacote(char *pacote) {
unsigned int i=0;
crc_tx = 0xffff;
while(i < 11){
tx_byte(pacote[i]);
calculo_crc(&crc_tx,(unsigned int)pacote[i]);
i++;
}
tx_byte(char_to_hex((char)(crc_tx >> 8),1));
tx_byte(char_to_hex((char)(crc_tx >> 8),0));
tx_byte(char_to_hex((char)(crc_tx & 0x00ff),1));
tx_byte(char_to_hex((char)(crc_tx & 0x00ff),0));
tx_byte('%');
}


tx_byte é a função que vc usa pra enviar pela serial seu byte.


na hora de receber usa tipo isso:

Código: [Selecionar]

crc_rx=0xffff;
for (i=0;i<11;i++) {
        calculo_crc(&crc_rx,(unsigned int)rx_chegada[i]);
}
l=rx_hex_to_int(0,0,rx_chegada[11],rx_chegada[12]);
m=rx_hex_to_int(0,0,rx_chegada[13],rx_chegada[14]);
calculo_crc(&crc_rx,l);
calculo_crc(&crc_rx,m);

se o resultado for zero em crc_rx, o pacote tá ok.

Abraços!

 

/** * */