Ir ao conteúdo
  • Cadastre-se

Acionar rele a distancia com PIC e RF 433mhz


Posts recomendados

Boa noite, estou tentando fazer um PIC16F628A enviar um sinal pelo RF 433,92mhz (esses vendidos no mercadolivre) e receber em um PIC12F683 e receptor, porém não obtive sucesso.

Não utilizo oscilador externo, utilizo um regulador 7805 nos pics+módulos (um por circuito) e gravador icsp.

Estou utilizando o MikroC PRO v4.60 e a biblioteca MANCHESTER e BUTTON, pois eu achei que seria fácil de desenvolver.

Código do Transmissor:

//Conexão do módulo de transmissão (Manchester)
sbit MANRXPIN at RA0_bit;
sbit MANRXPIN_Direction at TRISA0_bit;
sbit MANTXPIN at RA4_bit;
sbit MANTXPIN_Direction at TRISA4_bit;

void main() {

int readytosend = 0, x = 0; // inicializa as variáveis
TRISA = 0x00; // define saidas e entradas
TRISB = 0xFF;
PORTA.B2 = 0;

Man_Send_Init(); // inicializa a transmisão

while (1) { // loop infinito
readytosend = 0; // flag de controle de botão
do {
if (Button(&PORTB, 5, 1, 0)) { // verifica se o botão esta pressionado (B5)
x = 0x01; // variável x recebe o valor do botão
readytosend = 1; // flag de controle recebe o valor 1 para sair da rotina
}
if (Button(&PORTB, 4, 1, 0)) { // verifica se o botão esta pressionado (B4)
x = 0x02; // variável x recebe o valor do botão
readytosend = 1; // flag de controle recebe o valor 1 para sair da rotina
}
} while(readytosend == 0); // continua se o flag for diferente de 0

PORTA.B2 = 1; // Acende LED
Man_Send(0x0B); // Envia byte de inicio
Delay_ms(100); // Aguarda 100ms
Man_Send(x); // Envia X
Delay_ms(90); // Aguarda 90ms
Man_Send(0x0E); // Envia byte de final
Delay_ms(1000); // Aguarda 100ms
PORTA.B2 = 0; // Apaga LED
}
}

Código do Receptor:

// Manchester module connections
sbit MANRXPIN at GP0_bit;
sbit MANRXPIN_Direction at GP0_bit;
sbit MANTXPIN at GP3_bit;
sbit MANTXPIN_Direction at GP3_bit;
// End Manchester module connections

char error, ErrorCount, temp;

void main() {
ErrorCount = 0; // limpa variavel contadora de erros

TRISIO= 0x01; // define entradas e saidas

Man_Receive_Init(); // Initialize Recepção

while (1) { // Loop infinito

while (1) { // Loop infinito
temp = Man_Receive(&error); // Tenta receber o byte
if (temp == 0x0B) // Byte de inicio foi recebido?
break; // Quebra o laço infinito
if (error) // Ocorreu erro?
break; // Quebra o laço infinito
}

do
{
temp = Man_Receive(&error); // Tenta receber o byte
if (error) { // Ocorreu erro?
ErrorCount++; // Incrementa contador de erros
if (ErrorCount > 20) { // Errou mais de 20 vezes?
temp = Man_Synchro(); // Tenta sincronizar novamente
//Man_Receive_Init(); // ou reinicia novamente o recebimento
ErrorCount = 0; // Limpra o contador de erros
}
}
else { // Não ocorreu erros...
if (temp != 0x0E) // Se um byte diferente do byte de fim de transmissão
while (1){
if (temp == 0x01){ // Recebeu 0x01?
GPIO.B1 = 0; // limpa GP1
break; // quebra o loop infinito
}
if (temp == 2){ // Recebeu 0x02?
GPIO.B1=1; // seta GP1
break; // quebra o loop infinito
}
}
}
Delay_ms(25);
}
while (temp != 0x0E) ; // Sai do looop se receber byte de fim de transmissão
}

}

Postarei daqui a pouco porque esqueci a cabo do iPhone no trabalho.

Circuito do Transmissor:

Circuito do Receptor:

Esquema eletrônico do Transmissor:

Esquema eletrônico de Receptor:

Eu acho que o problema esta no código ou no mikroC porque eu observei que quando eu aperto o botão para comunicar o led não acende ou fica aceso fraco como se fosse PWM oscilando 30% e 50%, aguardo a ajuda de todos.

Obrigado.

Link para o comentário
Compartilhar em outros sites

Com certeza serve.... poste por favor... eu consigo utilizar no MikroC? porque você usa o CCS? é melhor?

Me explica uma coisa... eu tento no MikroC e não consigo usar esta função para inverter o estado do pino "PORTB.B3 = ~PORTB.B3;" porque não funciona?

Obrigado e aguardo o código.

Link para o comentário
Compartilhar em outros sites

Uso o CCS pois comecei a estudar ele. Aí com o tempo aprendi mais sobre ele que sobre os outros.

Ta aí:

Transmissor:

//Código de exemplo para transmissão de IDs por RF
//Feito por MatheusLPS - [email protected]

#include <18f4550.h>
#include <STRING.H>
#include <STDIO.H>
#include <STDLIB.H>

#define WireTX PIN_C6
#define WireRX PIN_C7


#FUSES HS, NOWDT, NOPROTECT,NOLVP,BROWNOUT, PUT
#use delay (clock = 12000000)
#use rs232(baud=2400, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless)

int8 i;

void main()
{
while(1)
{
if(!input(PIN_D2)) //Só enviar quando o botão for precionado.
{
output_high (PIN_C2); //Ligo o transmissor (IMPORTANTE)
delay_ms (50);
fprintf(Wireless, "%c", 0xBA); // LAM - algo para que o RX's USART "lock onto", algo do tipo, olhe receptor, estoua qui
fprintf(Wireless, "%c", 0xBE); // LAM - algo para que o RX's USART "lock onto", algo do tipo, olhe receptor, estoua qui
fprintf(Wireless, "%c", 0xFA); // LAM - algo para que o RX's USART "lock onto", algo do tipo, olhe receptor, estoua qui
fprintf(Wireless, "%c", 0xCE); // LAM - algo para que o RX's USART "lock onto", algo do tipo, olhe receptor, estoua qui
fprintf(Wireless,"Dave "); // Vou enviar isso ao recptor e ele vai procurar por Dave como sendo a senha, se for correta, ele interpreta a variável temp_1

output_low (PIN_C2); //Desligo o tnsmissor (MAIS IMPORTANTE AINDA)
output_high (PIN_D1); //Ligo um LED para ver que voi enviado os dados
delay_ms(1000);
output_low (PIN_D1); //desligo o led
delay_ms(1000);
}
}
}

Receptor:

#include <18f4550.h>

#define WireTX PIN_C6
#define WireRX PIN_C7

#FUSES HS, NOWDT, NOPROTECT,NOLVP,BROWNOUT, PUT
#use delay(clock = 12000000)
#use rs232(baud=2400, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless)

#define RX_BUFFER_SIZE 80
#define TX_BUFFER_SIZE 80

int8 x;
int8 temperatura[7];
float temp;

int8 rx_wr_index = 0, tx_rd_index = 0, tx_wr_index = 0, tx_counter = 0, received = 0;
int8 lock_state = 0, rxd, i, valid_data_count;
unsigned int8 rx_buffer[RX_BUFFER_SIZE + 1], tx_buffer[TX_BUFFER_SIZE + 1];
int1 data_avail = FALSE, got_id = FALSE;

#int_RDA
void RDA_isr(void)
{
rx_buffer[rx_wr_index] = getc();
rxd = rx_buffer[rx_wr_index];
rx_wr_index++;

if (rx_wr_index > RX_BUFFER_SIZE) {
rx_wr_index = 0;
}

// now look for unique ID: "Dave "
if (rxd == 'D' && lock_state == 0) {
lock_state++;
}
else if (rxd == 'a' && lock_state == 1) {
lock_state++;
}
else if (rxd == 'v' && lock_state == 2) {
lock_state++;
}
else if (rxd == 'e' && lock_state == 3) {
lock_state++;
}
else if (rxd == ' ' && lock_state == 4) { // got the entire string "Dave ", in that order
lock_state = 0; // reset our "combination lock"
got_id = TRUE;
valid_data_count = 0xff; // get ready to count the number of data bytes - we know we have to expect 5 (Rocks)
// also going to reset the buffer write index back to 0, so that I know where my valid data will be
rx_wr_index = 0;
}
else { // we didn't receive "Dave ", so reset the lock back to the beginning
lock_state = 0;
}

if (got_id && ++valid_data_count == 7) {
data_avail = TRUE;
got_id = FALSE;
}
}

#int_TBE
void TBE_isr(void) {
if (tx_counter != 0) {
putc(tx_buffer[tx_rd_index]);
if (++tx_rd_index > TX_BUFFER_SIZE) {
tx_rd_index = 0;
}
tx_counter--;
if (tx_counter == 0) {
disable_interrupts(INT_TBE);
}
}
}

void bputc(int c) {
int restart = 0;

while (tx_counter > (TX_BUFFER_SIZE - 1));

if (tx_counter == 0) {
restart = 1;
}
tx_buffer[tx_wr_index++] = c;
if (tx_wr_index > TX_BUFFER_SIZE) {
tx_wr_index = 0;
}
tx_counter++;
if (restart == 1) {
enable_interrupts(INT_TBE);
}
}

void main()
{
enable_interrupts(INT_RDA);

enable_interrupts(global);


while (TRUE) {
restart_wdt();
if (data_avail)
{
data_avail = FALSE;

output_high (PIN_c2);
delay_ms (1000);
output_low (PIN_C2);
}
}
}

NO transmissor, a alimentação do módulo vai no PIC, no pino C2.

Falou

Link para o comentário
Compartilhar em outros sites

Exatamente.

Uso a RS232 como comunicação serial. O pino de DATA do transmissor vai no pino TX do PIC e o de alimentação do transmisssor vai no pino C2.

O grande lance que descobri é q você envia os dados e logo em seguida você desliga o transmissor.

Pode colocar um botao p teste. Aperta um botao ele envia... e pisca um led do outro lado.

Falou

Link para o comentário
Compartilhar em outros sites

Segue os esquemas:

Meu recptor é esse:

receptor_pic.png

Ligo ele parecido com isso, sem esse CI aí debaixo. Apenas ele e o PIC. Nesse caso, pino 2, digital.:

recptor.png

Meu transmissor é igual a esse:

transmissor_pic.png

Ligo ele assim, mais uma vez, sem o CI debaixo, apenas ele e o PIC. A Alimentação é VCC mas coloco em um pino qualquer do PIC para poder ligar e desligar.

transmissor.png

Falou

Link para o comentário
Compartilhar em outros sites

então matheus ainda nao consegui fazer funcionar... vamos lá!

meu novo código

Transmissor:

void main() {

int readytosend = 0, x = 0; // inicializa as variáveis
TRISA = 0x00; // define saidas e entradas
TRISB = 0xFF;
PORTA.B2 = 0;
UART1_Init(2400);

while (1) { // loop infinito
readytosend = 0; // flag de controle de botão
do {
if (Button(&PORTB, 5, 1, 0)) { // verifica se o botão esta pressionado (B5)
x = 0x01; // variável x recebe o valor do botão
readytosend = 1; // flag de controle recebe o valor 1 para sair da rotina
}
if (Button(&PORTB, 4, 1, 0)) { // verifica se o botão esta pressionado (B4)
x = 0x02; // variável x recebe o valor do botão
readytosend = 1; // flag de controle recebe o valor 1 para sair da rotina
}
} while(readytosend == 0); // continua se o flag for diferente de 0

PORTA.B2 = 1; // Liga Transmissor
UART1_Write(0x0B); // Envia byte de inicio
UART1_Write(0x0B); // Envia byte de inicio
UART1_Write(0x0B); // Envia byte de inicio
UART1_Write(0x0B); // Envia byte de inicio
UART1_Write(x); // Envia X
PORTA.B2 = 0; // Desliga transmissor
}
}

Receptor:

unsigned char u_received;

void interrupt(){
if(PIR1.B5) // INTERRUPÇÃO POR RECEBIMENTO NA UART
{
if(uart1_read() != 0x0B)
{
u_received = uart1_read();
}
}
}

void main()
{
UART1_Init(2400); // Inicializa módulo UART
Delay_ms(100); // Atraso para estabilização UART
TRISA = 0x00; // PORTA todos saídas
TRISB = 0xFF; // PORTB todos saídas exceto RB0

//ATIVAÇÃO DE INTERRUPÇÃO DA UART
PIE1.B5 = 1; // RECEBIMENTO NA UART
INTCON.B6 = 1; // ATIVA INT. DOS PERIFERICOS
INTCON.B7 = 1; // ATIVA INT. GERAL

while(1){
if (u_received == 0x01) {
PORTA.B4 = 1;
}
else if (u_received == 0x02) {
PORTA.B4 = 0;
}

}
}

Conectei a saida do receptor no RX do PIC16f628A com um resistor de 1K.

Conectei a entrada do transmissor no TX do PIC16f628A com um resistor de 150ohms.

Coloquei o pino A2 do PIC direto no VCC do módulo de transmissão.

Módulo receptor

img0596g.jpg

Módulo transmissor

img0597mn.jpg

Eu vi um video que o cara usou a saída linear do receptor!

Ainda não consegui fazer funcionar!!!!! :(

Link para o comentário
Compartilhar em outros sites

Esse seu código é para o CCS? Está tão parecido e ao mesmo tempo muito diferentes.

Seguinte, experimenta ligar tanto o transmissor e o recptor sem resistor algum no PIC.

OUtra coisa de suma importancia.: Vejo que você liga o pino B2 no transmissor:

PORTA.B2 = 1;                  // Liga Transmisso

Experimenta colocar um delay pequeno logo depois desse comando.

Uma outra coisa que não vi nas suas imagens são as ANTENAS.

Quando fiz o meu, sem antena ele não funciona de jeito nenhum.

Pega um fio de cobre comum meio rígido e descasca ele, uns 15~20cm é suficiente.

Testa aí.

Falou

Link para o comentário
Compartilhar em outros sites

Sem problemas Caroline...

Então Matheus, coloquei a antena e coloquei o transmissor com delay, fiz tudo certinho e nada de funcionar...

tem como você compilar o seu programa ai no seu pc e me enviar para verificar se o problema esta no meu compilador? se sim, coloque uma saida no pino B5 do receptor e coloque um botão no B5 do transmissor.

Detalhe: você pode notar que eu não estou utilizando oscilador externo!

estou testando os perifericos (trocando os pinos, testando se a uart esta recebendo...) mais creio que vai dar certo logo...

tenho um controle da positron que é de alarme de carro, você sabe como funciona (protocolo, dados pela uart ou outros) pois pode ser que seja mais pratico usa-lo!

Obrigado.

Até mais.

Link para o comentário
Compartilhar em outros sites

Modifiquei e funcinou na simulação. Espero que funcione na prática também. Veja se declarei os pinos corretamnte:

Cristal interno de 4Mhz.

Botão do transmissor no PINO B5.

Alimentação do Transmissor no PINO B0.

Pino TX do transmissor é o padrão, PINO B2.

No receptor:

Pino RX padrão, PINO B1.

Pino para piscar um led, PINO B0.

SS da simulação:

sfsfsdf.png

.hex:

http://www.4shared.com/file/Mws58seL/Codigos.html

Espero que funcione.

Todos para 16F628A.

SE não der certo, vou fazer para o 2550.

Falou

Link para o comentário
Compartilhar em outros sites

manda dos dois jeitos, reduzido para pic16f628a e normal para 18f2550!

ai eu vejo se deu certo!

Obrigado.

eng.viniciuspais

Eu to achando que é o código, eu usei esse código que Matheus passou ai e funcionou uma beleza, usei para o transmissor o PIC16F628A e para o receptor o PIC16F877A, não coloque essas resistências! A alimentação de tudo é 5V e o pic tb recebe 5V sem problema... coloque as antenas.

PS.: faça o teste de um pic para outro tb, sem os módulos! ai você elimina as possibilidades de problemas uma de cada vez, não só no Proteus, faça na prática tb sem os módulos, só os PICs.

Falou

Link para o comentário
Compartilhar em outros sites

Gente, vou hoje na loja de um amigo meu olhar no osciloscópio a comunicação a 1200bps entre pics e depois vou analisar com os módulos rf.... testei meu programa(já editei varias vezes, postarei mais detalhes quando concluir) e no proteus funcionou 100% agora falta analisar o funcionamento fisico.

Obrigado a todos que estão me ajudando!

Link para o comentário
Compartilhar em outros sites

Olá Amigo ... vou dar uma sugestão ... olha , nunca tive bons resultados com oscilador interno do pic ... ainda mais pra comunicação serial ... um cristalzinho ia ajudar e talvez até resolver o problema, já que como nesse caso não tem um sinal de sincronismo, a unica coisa que se tem é o clock dos PICs ... abraços

Link para o comentário
Compartilhar em outros sites

Israel no momento eu estou analisando no osciloscópio os tempos e os niveis e parece estar com um desvio admissivel.... vou colocar os cristais como pediu para verificar se melhora ainda mais...

Posto os resultados completos dos testes esta noite... Obrigado a todos que estão me ajudando!

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!