Ir ao conteúdo

Posts recomendados

Postado

Boa noite Pessoal

 

Gostaria da ajuda de vocês , quero fazer comunicação rf com pic(modulo  TX e RX) para que o PIC TX envia o sinal de PWM para o PIC RX

para controla a velocidade de  um motor CC e de um servomotor. por favor se alguém pode mim ajudar com código de exemplo

Postado

A referencia...da referencia... da referenciainception. Minha prova de laboratório era controlar um servo motor através de pulsos um curto para virar para um lado e uma mais longo para virar para outro ou permanecer no meio... você procurar tem várias forma de fazer esse controle inclusive sem usar pulsos (se não me engano usando de forma indireta através de um comando sem ter que ficar calculando).

 

Ou seja no link abaixo você tem uma forma de fazer teu projeto de enviar informação e na net dá para achar como controla o servo motor e outros... 

 

 

Postado

Ainda não tentei isso, mas você poderia definir uma porta do pic de transmissão como #define servo1  RC0_bit

criar uma rotina de interrupção TMR0 para controlar o motor e já que isso vai ser transmitido via rádio pela porta do servo também seria realizado pelo receptor já que se você movimenta a porta de saída do transmissor isso significa que o receptor também receberia esse movimento.... o mesmo sinal PWM?

 

Se não for o caso, você pode esperar por outra pessoa para lhe responder melhor ^^ pois eu teria que fazer esse projeto para testar hehehe eu vou fazer, mas só no futuro. Talvez nessas minhas férias ^^ 

 

 

esperando aqui também outra pessoa X) 

  • Membro VIP
Postado

Vá por partes. estude 1 pouco o datasheet do seu mc....

1º faça 1 pisca led.

//setup do hw
unsigned int dl=0xffff;
for(;;) {RA0^=1;while(dl--);}

...........................

estude 1 pouco+ o datasheet do seu mc....

.........................

 

Depois faça 2 pic´s se conversarem por fio mesmo: tx de 1 no rx do outro
 

//TX
//setup do hw
for(;;) putc(PORTA);

//RX
//setup do hw
for(;;) PORTA=getc();

e observe a "mágica": PORTA de um vai se "teletransportar" pro PORTA do outro.

 

Depois ao invés de fio, tente modular o tx com rf e recebê-lo com rádio no rx. Há muitas opções na net. Hás de te introduzires nos conceitos do wifi.

Postado

@Isadora Ferraz

Esse povo com sua mágica uhauhahuaa Então o PWM criado em um* vai para o outro , não ? X) Como minha teoria doida ^^ 

  • Membro VIP
Postado

sim você pode enviar o dado que quiser

no tx

for(;;) putc(adcread(0));//p.ex. um potenciômetro

 

no rx

for(;;) setpwm(getc()); //o potenciômetro "vem pra cá" em forma de largura de pulso

 

A mágica na verdade está nas funções que devem fazer bom uso do hw do mc. Não há outra opção a não ser dar uma estudada no datasheet e circuitos (hw) do bixo.

Postado

include "modedefs.bas"

DEFINE ADC_BITS 8       ' Set number of bits in result

DEFINE ADC_CLOCK 3     ' Set clock source (rc = 3)

DEFINE ADC_SAMPLEUS 50

 

trisio =%00011111 'input=mclr,pot´s , output= serial

ansel = %00111111

 

b0 var byte

b1 var byte

b2 var byte

b3 var byte

b4 var byte

w0 var word

w1 var word

 

'------------------------------------------------------------

loop:

'Potenciometros:

'Aceleração:5k4

'

'acel=2k14, meio=2k73, desac.=3k14

'405          512        594     '10bit´s

'101          128        148     '8bit´s

'Direção: 5k

'

'esquerda=1k82, meio=2k54, direita=3k3

' 368           512         675   '10bit´s

' 92            128         168    '8bit´s

'

'Trimmer´s = pot´s de 10k (8k real)       

pause 5        ' estava 5

adcin 0,b0'acel '101 a 148

adcin 1 ,b1  'direcao  '92 a 168

ADCiN 2 ,b2  'trimmer acel  '0 a 255  (/5 = 51)

adcin 3,b3  'trimmer direcao  '0 a 255  (/6 = 42)

 

w0 = b0 + (b2/5)

b0 = w0

 

w1 = b1 + (b3/6)

b1 = w1

 

gosub limites

 

b4 = b0+b1'valor truncado

 

SEROUT gpio.5,N2400,[204,B0,b1,b4]   '20.8ms a 2400bps    '204 = 11001100

 

goto loop

'--------------------------------------------------

limites:

if b0 < 100 then

b0 = 100

endif

 

if b1 < 100 then

b1 = 100

endif

 

if b0 > 200 then

b0 = 200

endif

 

if b1 > 200 then

b1 = 200

endif

 

return

'---------------------------------------------------
 

 

receptor

modulo RX    

 

include "modedefs.bas"

 

trisio =%00001001 'serin,mclr

ansel = 0

cmcon0 = 7

 

b0 var byte

b1 var byte

b4 var byte

soma var byte

c1 var byte

c2 var byte

 

 

'------------------------------------------------------------

loop:

 

SERIN gpio.0,N2400,20,continua,[204],B0,b1,b4  '204 = 11001100

 

continua: 

soma = b0+b1 'valor truncado

if soma <> b4 then

gosub saida

goto loop

endif

 

c1 = b0

c2 = b1

gosub saida

 

goto loop

 

'----------------------------------------------------------------

saida:

high gpio.4

pauseus c1*10

low gpio.4

 

high gpio.5

pauseus c2*10

low gpio.5

 

return

'-----------------------------------------------------------------
 olhai tentei no proteus mas ele não fucionor...

adicionado 3 minutos depois

eu ja fiz um led acender

porém quero pwm 

Postado

Não é promessa minha de resolver teu caso, mas eu coloquei aqui por curiosidade no meu "mikro C pro" e notei que está faltando estruturas básicas como "void main ()"  se pode programar assim? Ou você só está dando uma mostra do teu código recortado? 

 

ah ... escreva teus códigos* com  aferramenta do forum chamada "Code" que está ai em cima na barra de ferramenta no bloco que você escreve. 

#includeDaVida

void main ()
{
 
  codigoDavida...
    
}

 

 

Postado

Transmissor

#include <mainjk.h>


void main()
{
  while(TRUE)
  {
  if(input(pin_a7)){printf("a");delay_ms(400);}
  if(input(pin_a6)){printf("b");delay_ms(400);}
 }

}
 

receptor

#include <mainkk.h>
char letra;

void main()
{
  while(TRUE)
  { 
  if (kbhit()){
   letra=getc();
   
   if (letra=="a"){ output_toggle(pin_a0);}
   if (letra=="b"){ output_toggle(pin_a1);}
  }
  
  
  }


}
 

e também não obtive sucesso nesse código feito ccs compile

Postado

Pesquisei aqui um pouquinho e vi que é possível fazer o código sem esse void... (apesar de que eu já usei void para fazer controle pwm) como nesse aqui em baixo... 

/*
   Controle Suave para Servo Motores  (site: www.wrkits.com.br)
   Gerar pulso para controle do servo a partir do estouro do Timer0
   Período típico para servo motores: 20ms
   MCU: PIC16F876A   Clock: 16MHz   Ciclo de máquina: 250ns
   Estouro Timer0 = TMR0 x prescaler x ciclo de máquina
   Estouro Timer0 = 256  x   256     x    250E-9        = 16,384ms
*/
// --- Mapeamento de Hardware ---
#define servo1  RC0_bit                        //Servo1 ligado ao pino RC0

// --- Variáveis Globais ---
unsigned char duty = 0x00;                     //Variável para alterar o ciclo de trabalho
int adc = 0x00;                                //Variável para leitura AD

// --- Rotina de Interrupção ---
void interrupt()
{
      if(TMR0IF_bit)                           //Houve estouro do Timer0?
      {                                        //Sim...
         TMR0IF_bit = 0x00;                    //Limpa flag
             if(servo1)                        //Saída servo1 em high?
             {                                 //Sim...
               TMR0 = duty;                    //TMR0 recebe valor atual do duty
               servo1 = 0x00;                  //Saída do servo1 em low
             } //end if servo1
            else                               //Senão...
            {
             TMR0 = 255 - duty;                //TMR0 recebe valor máximo menos valor do duty
             servo1 = 0x01;                    //Saída do servo1 em high
           } //end else
   } //end if TMR0IF
}

 //end interrupt

// --- Função Principal ---

void main()
{
     CMCON      = 0x07;                        //Desabilita comparadores
     OPTION_REG = 0x87;                        //Res Pull-Ups desabilitados, Prescaler 1:256 associado ao Timer0
     GIE_bit    = 0x01;                        //Habilita interrupção global
     PEIE_bit   = 0x01;                        //Habilita interrupção por periféricos
     TMR0IE_bit = 0x01;                        //Habilita interrupção do Timer0
     ADON_bit   = 0x01;                        //Habilita módulo de conversão AD
     ADCON1     = 0x0E;                        //Apenas AN0 como analógico
     TRISA      = 0xFF;                        //Todo PORTA como entrada
     TRISC      = 0xFE;                        //Somente RC0 como saída
     PORTC      = 0xFE;                        //Inicializa PORTC

     duty = 16;                                //Duty cycle aprox. 50%   256 - 16ms
                                               //                        x   - 1ms  = 16 (valor min)

     while(1)                                  //Loop infinito
     {
       adc = (adc_read(0))/64;                 //Variável adc recebe valor adc do AN0
       duty = adc + 16;
     } //end while
} //end main

Mas esse código não é para esse controle via rádio... é só para o servo motor e se fazer algumas modificações na variável duty você vai poder controlar melhor...

 

Eu achava que você deveria dar uma melhor olhada no link que coloque ai em cima que vai parar >AQUI<

E tentar fazer algo sem dar tiro no escuro... 

 

Se eu for fazer isso, e se eu conseguir (nunca se sabe posso não conseguir também hehehe ), vai ser eu que vou fazer o trabalho e nem sei se você vai aprender algo com isso... 

 

 

Mas se alguém tiver afim de fazer o trabalho pode ficar à vontade e postar mais ajuda para o código ai em baixo. 

Postado

deu pra entende o código mas como enviar esse código para outro pic..

quero aprende a envia o pwm de um pic para outro 

já conseguir acender um led de um pic para outro

mas agora quero o pwm 

  • Membro VIP
Postado

tipo isso...

Isso fica no pic transmissor

8 horas atrás, Bommu Perneta disse:

adc = (adc_read(0))/64; //Variável adc recebe valor adc do AN0 duty = adc + 16;

 

e isto no receptor

8 horas atrás, Bommu Perneta disse:

duty = adc + 16;

 

Desculpe mas a ajuda que obtiveres eventualmente de minha parte sempre será implícita forçando-te a pensar 1 pouco, ok?

 

Mas como dica, tente (de novo) ir por partes. Faça primeiro com apenas 1 mc. Faça-o controlar seu servo com sucesso, dominando e entendendo todas as etapas dele tanto no hw como no sw. Não se atropele queimando esta etapa.

  • Curtir 1
  • Membro VIP
Postado

Vamos tentar abordar de outra forma...

 

você já conseguiu controlar com sucesso absoluto e total um servo ou motor cc com pwm? com um (01) microcontrolador (vulgo mc) apenas? Como fez? Pode mostrar? Responda isso e depois leia a seguir...

 

você já conseguiu enviar algum dado pela serial de um mc? Como fez? Responda isso e depois...

 

Já conseguiu receber com absoluto e total sucesso o dado enviado? Na outra parte? noutro mc, computador, terminal e afins...Como fez?

 

Lembrando que preferencialmente hás de provar e mostrar o serviço ok?

 

Caso apenas uma (01) resposta seja negativa, estamos em apuros! Pouco ou nada vamos nos ajudar ok?

Postado

sim com pic 12f675 pwm tanto o código com na pratica inclusive já apresentei em sala de aula em que o assunto era pwm 

aqui foi o código ccs

#include<12F675.h>
#device adc = 8
 
#FUSES NOWDT      // No assista Dog Timer
#FUSES INTRC_IO    // Cristal internal = 4MHZ
#FUSES PUT         // Power up Temporizador
#FUSES NOPROTECT    // Código não protegido contra leitura
#FUSES NOMCLR
#FUSES BROWNOUT    // Repor quando brownout detectado
#FUSES NOCPD       // Sem proteção EE

#use delay(CLOCK = 4000000)

#define fim 100

int8 periodo=0;
int8 ciclo1=0;

#int_timer1
void Timer_isr(void)
{
    /*=====================
    Teste para ciclo = 0
    =====================*/
    
    if(ciclo1 == 0)
    {
        output_low (PIN_A2);
    }
    if(ciclo1 == fim)
    {
        output_high(PIN_A2);
    }
    
    
    /*=============================
    Já que o ciclo e diferente de 0
    ===============================*/
    
    if(periodo < ciclo1)
    {
        output_high(PIN_A2);
    }
    else
    {
        output_low(PIN_A2);
    }
    if(periodo >= fim-1)
    {
        periodo=0;
    }
    periodo++;
    set_timer1(65440);   //65440
}

void main()
{
    SETUP_ADC_PORTS(sAN0);
    SETUP_ADC(ADC_CLOCK_DIV_8);
    
    SETUP_TIMER_1 (T1_INTERNAL|T1_DIV_BY_1);    // Configurar timer1 para clock interno/8
    enable_interrupts (INT_TIMER1);             // Habilitar Interrupções
    enable_interrupts (GLOBAL);
    set_timer1(65440);                          // Preload do timer1
    
    set_adc_channel(0);
    delay_ms(20);
    
    
  
    
    while(TRUE) 
    {
        ciclo1 = 0.4 * read_adc();
        delay_ms (50);
    }

  • Membro VIP
Postado

ok.. Então você já deve ter entendido que a variável ciclo1 é a que controla a largura do pulso né? Reserve.

Agora publique algo que já fez sobre comunicação serial...

Tarefa: envie a variável ciclo1 pela porta serial

Ah .. registre-se que o ccs não vai muito com minha cara e isto é recíproco

  • Curtir 1
Postado

Isadora Ferraz

float v;

void main()
{

   setup_adc_ports(AN0_TO_AN1|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);    
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
 //setup_oscillator parameter not selected from intr oscillator config tab
   
   //TODO: USER CODE!!
   
   
   while (TRUE){
   output_high(pin_c0);
   delay_ms(1000);
   set_adc_channel(0); //0
   delay_us(10);
   v=read_adc();
   v=v*0.0048875855327468;
   
   printf("%f \n \r " ,v);
   }
   
   
   
   
   
   
}

  • Membro VIP
Postado

ok. Com isso você demonstrou que conseguiu conversar, ou melhor, 'falar' com um terminal.

Foquemos no mc de TX e por hora tentemos só na moleza (software) mesmo. Por seu caso, printf não vai servir. você precisa enviar o dado "puro" do potenciometro. Tente com a função putc() ou putchar(). Estude-as.

Algo como a tarefa que você não fez:

for(;;)//o mesmo que while(TRUE)
{
v=read_adc(); //considero resultado sai em 10 bits
putc(v/4);//me interessa 8 bits
//printf("\n");pula linha opcional
}

Teoricamente você vai ver o resultado do potenciometro de 000 a 255 na tela

Dica: configure seu terminal pra mostrar em decimal ou hexa

 

Tarefa: receba um dado do teclado do terminal, some +1 e devolva pra tela: introdução ao RX

  • Membro VIP
Postado

Nem eu.  Se em alguns meses você não conseguir me avise. Mas permita-me observar que tal tarefa é muito simples se comparada ao desafio do seu tópico: sua "comunicação-séria-rf". Neste  caso, penso que você vai levar mais tempo do que pensou. E ainda mais quando chegar na parte do circuito, aff, já estou com pré-stress. Por gentileza mostre algum progresso verdadeiro a si mesmo e se achar que deve, vá publicando: útil pra comunidade.

 

Penso que você escolheu dar passos maior que a perna: está queimando muitas etapas (sério que fez um pisca led?). Tente um desafio menos desafiador. E não desista!

 

Permito-me me abster de ensinar beabá ok? e muito menos trocar fraldas kk brinc.!

Sucessos & progressos!

Postado

#include <12f675.h> 
# DEVICE ADC=8

#fuses INTRC_IO,NOWDT,NOPROTECT, NOMCLR ,BROWNOUT, PUT
#use delay(clock=4000000)       // 4 MHz crystal on PCB 
//#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1)    // you can use any pins for software uart... 
#use rs232(baud=9600, xmit=PIN_A4, rcv=PIN_A2, PARITY=N, BITS=8,) 

// characters tranmitted faster than the pic eats them will cause UART to hang. 

#include <stdlib.h> 

#define LED_5 PIN_A5 
#define LED_1 PIN_A1
#define ciclo_3 PIN_A3
#define TX_4 PIN_A4
#define RX_2 PIN_A2

#define fim 100

int8 periodo=0;
int8 ciclo1=0;

#int_timer1
void Timer_isr(void)
{
    /*=====================
    Teste para ciclo = 0
    =====================*/
    
    if(ciclo1 == 0)
    {
        output_low (PIN_A3);
    }
    if(ciclo1 == fim)
    {
        output_high(PIN_A3);
    }
    
    
    /*=============================
    Já que o ciclo e diferente de 0
    ===============================*/
    
    if(periodo < ciclo1)
    {
        output_high(PIN_A3);
    }
    else
    {
        output_low(PIN_A3);
    }
    if(periodo >= fim-1)
    {
        periodo=0;
    }
    periodo++;
    set_timer1(65440);   //65440
}

void setup ()
{
    SETUP_ADC_PORTS(sAN0);
    SETUP_ADC(ADC_CLOCK_DIV_8);
    
    SETUP_TIMER_1 (T1_INTERNAL|T1_DIV_BY_1);    // Configurar timer1 para clock interno/8
    enable_interrupts (INT_TIMER1);             // Habilitar Interrupções
    enable_interrupts (GLOBAL);
    set_timer1(65440);                          // Preload do timer1
    
    set_adc_channel(0);
    delay_ms(20);
    
    
  
    
    while(TRUE) 
    {
        ciclo1 = 0.4 * read_adc();
        delay_ms (50);
    }

void main (DADOS) { 
   while (TRUE) { 
      if (input(PIN_A5)){ 
         output_high(LED_5); 
         printf("a"); //sends signal a 
         delay_ms(1000);
         
       } 
       else{ 
         output_low(LED_5); 
         printf("l"); //sends signal l 
         delay_ms(200);
         
       } 
        if (input(PIN_A1)){
            output_high(LED_1);
            printf("b"); //sends singnal b
            delay_ms(1500);
        }
        else{
            output_low(LED_1);
            printf("s"); //sends signal s
            delay_ms(500);
        }    
       }
        

isadora ferraz
   } 
   
 

adicionado 8 minutos depois

isadora ferraz ai esta porém a conversão não esta funcionado

Sem títuloy.png

  • Membro VIP
Postado

Acho que você tem um longo caminho à frente (mas não desista!)

você ainda nem viu se o dado analógico está correto. Eu (eu) no seu lugar tentaria algo como:

printf("%d",ciclo1); //acho que seria esta sua "conversão"

pois conhecer isso é essencial pro teu projeto. Este estaria no seu mc TX

 

No RX estaria a funcão companheira do printf().. a scanf(). (nem lembro sua sintaxe,  tentei googlar mas desisti)

 

Mas estas são essências do c que nem uso - uso só o hw do mc -  mas teoricamente dá certo.

Sinto mas acho que não vou conseguir explicar em termos de hw do mc ok?

 

Continue tentando e vez ou outra, se achar que deve, dê uma rebobinada na fita. você tem todo o tempo do mundo

Postado

//transmit coding 

#include <18f252.h> 
#device ADC=8 
#fuses HS, NOWDT, NOLVP, NOPROTECT
#use delay(clock=4000000) 
//#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1)    // you can use any pins for software uart..
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8,Errors)
// characters tranmitted faster than the pic eats them will cause UART to hang. 

#include <stdlib.h> 
#define ADC_0 PIN_A0
#define TX_6 PIN_C6
#define RX_7 PIN_C7

void main() 

int8 fvalue;
 
 setup_adc_ports(AN0);//or setup_adc_ports(ALL_ANALOG) 
 setup_adc(ADC_CLOCK_DIV_8); 
 set_adc_channel(0); 
 delay_us(20); 
 fvalue=read_adc(); 
 putc(fvalue);
 
  while (1) { 
 fvalue=read_adc(); 
 putc(fvalue); 
 delay_ms(1000); 
}


//receive coding 

#include <18f252.h> 
#fuses HS, NOWDT, NOLVP, NOPROTECT
#use delay(clock=4000000) 
//#use rs232(baud=19200, xmit=PIN_A0, rcv=PIN_A1)    // you can use any pins for software uart..
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, BITS=8,Errors )
// characters tranmitted faster than the pic eats them will cause UART to hang.

#include <stdlib.h> 
#define LED_0 PIN_A0 
#define TX_6 PIN_C6
#define RX_7 PIN_C7
char v1;
void main() 

int8 fvalue; 
int8 v1; 
while(true) 

if(!input(pin_A0) ) 

fvalue=getc(); 
v1=(5*((int)fvalue)/255); 
printf("\ = %u",(int)v1); 



 

alguem sabe mim dizer onde estou errando

Sem títulol.png

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...