CONTROLADOR DE SERVOS III – P/ USO COM CÂMERAS DIGITAIS – COM PIC 12F675 (REF196)

1

Dando movimento aos “olhos da segurança” de forma automática…

Continuando com os aprimoramentos do ‘controlador de servos’ para uso com suporte Pan Tilt para câmeras, foi pensado na possibilidade de fazer os movimentos horizontais de forma automática (esquerda e direita), como uma varredura no campo visual. Isto permitirá visualizar eventos em vários ângulos continuamente. Veja o novo esquema abaixo:

Conforme se observa no esquema, foi acrescentado um interruptor nomeado de ‘VARREDURA’ e um led indicador desta função. Ao ser pressionado uma vez, liga o led e começa o processo de deslocar o servo gradativamente para um lado e depois inverte o movimento até o ínicio. Isto se repetirá até o botão ‘VARREDURA’ ser pressionado novamente, quando então apagará o led e os servos irão para a posição determinada pelos potenciômetros horizontal e vertical ( potenciômetro do Joy Stick PS ou similar). Se acionamos para alterar a posição vertical, quer seja para cima ou baixo, e ao encontrar a posição desejada pressionamos o botão ‘VARREDURA’, então ficará gravado esta posição vertical e começará a varredura horizontal. Quando ocorrer um reset na alimentação este valor será perdido e a varredura será desligada.
Nos ‘defines’ do arquivo “C” pode ser alterados para dar os movimentos desejados (curso max e min) e velocidade de operação. Veja eles abaixo:

//limites de excursão dos servos horizontais e verticais
#define lim_minv 85 //determina o limite horário max. do servo vertical
#define lim_minh 65 //determina o limite horário max. do servo horizontal
#define lim_maxv 180 //determina o limite anti-horário max. do servo vertical
#define lim_maxh 180 //determina o limite anti-horário max. do servo horizontal
#define lim_initv 105 //posição pós reset do servo vertical
#define lim_inith 105 //posição pós reset do servo horizontal
#define p_total 220 //determina o periodo total (aprox.18 ms))
#define vel_inc 5 //determina a velocidade de reação dos joystick
#define vel_varr 70 //velocidade em modo varredura
#define v_estab 10 // estabiliza contra variações da leitura do AD

Tem se notado na prática, que alguns modelos tem cursos diferentes com o mesmo pulso. Cada hobista deve se certificar que os ajustes acima satisfazem corretamente para o modelo usado.
Depois de alterar, não esqueça de recompilar usando o MplabX_Ide, e usar o novo arquivo Hex gerado.
Os potenciômetros devem ser montados próximos ao pic, enquanto as saídas dos servos podem ser levadas por uma distância considerável, por meio de cabos blindado de 3 fios, até o servomotor. Use uma fonte de alimentação de 5 volts para alimentar o circuito.
Obs. Esta montagem é de natureza didática, sendo realizada apenas em placa de montagem experimentais (do tipo Protoboard), sujeito a bugs ainda não observados. Esta sendo fornecido os arquivos desta montagem, podendo ser alterados conforme a necessidade dos hobistas.
Atenção: Antes de fazer placa de circuito impresso, teste em placa de montagem experimental e veja se o circuito atende as suas necessidades.

Segue pasta com os arquivos desta montagem, compilados com MplabX (XC8 Compiler):

SERVO_CAMERA_III

Manuais:

PIC12F675
servomotor
Pan Tilt Camera

Curiosidades:

O Concorde entrou para a história da aviação
Museus — lugares interessantes para visitar
Sua Vida É Controlada Pelo Destino?
A Bíblia contém um código oculto?
Como enfrentar a ameaça terrorista
De onde vieram as instruções?
A estabilidade e a satisfação no trabalho sofrem ameaças
Em busca da sociedade perfeita
“Como nos lembramos . . . do alho!”
A doença mais temida do século 19
Cabras — a salvação dos fazendeiros no sertão
As catacumbas de Odessa — um labirinto subterrâneo

Outros assuntos:

Por que Deus permitiu o Holocausto?
Os desastres naturais são castigo de Deus?
Qual é o sentido da vida?
Por que as pessoas morrem?
Como superar o medo da morte?
O que é a alma?
Será que temos data marcada para morrer?
As experiências de quase morte são visões de outra vida?
A alma é imortal?
Quem vai para o inferno?
A mentira que tornou Deus cruel
O que é a ressurreição?
O que é a fera de sete cabeças de Apocalipse capítulo 13?
O que é a batalha do Armagedom?

Vídeos Educativos para assistir com seus filhos pequenos

Até o próximo artigo!!!

1

6 comments

  1. 0

    Olá Cláudio, bom dia!
    Tire mais uma dúvida por favor… Fiz o esquema na protoboard, funcionou bem, só que o servo só funciona de um lado no potenciômetro. Exemplo: Colocando o potenciômetro todo pra cima o servo horizontal desloca todo para a esquerda e na medida que vou voltando o potenciômetro o servo volta ao lugar normal, parecendo não ir pra direita. Esse ajuste eu faço no trecho que o Sr. deixou no artigo? Qual compilador o Sr. usa? Mais uma vez muito obrigado ! 😀

  2. 0

    olá larios queria saber se é possivel transformar esse codigo em hex,já tentei copilar mais sempre dar erro nao sei quem é o autor.Trata-se um drive de servo ou seja ele converte o pwm (1a2ms) e aciona o motor .
    é um projeto para hobista que querem como eu construir seus proprio servo motor!!

    codigo
    #include
    #fuses INTRC_IO,NOWDT,NOPUT //,NOBROWNOUT
    #use delay(clock=4000000)
    #use fast_io(a)
    #use rs232(baud=9600, xmit=PIN_A2)

    //analog implementation
    //AN0=target
    //AN1=potentiomenter

    //driver type:
    //type 0: ch0-left, ch1-right,
    //type 1: ch0-on/off, ch1-direction
    #define driver_type 0

    //output (type=0)
    #define motorL PIN_A4
    #define motorR PIN_A5

    //output (type=1)
    #define motorON PIN_A4
    #define motorDIR PIN_A5

    //PID
    #define Kp 0.2 * 16
    #define Ki 0.0 * 16
    #define Kd 0.0 * 16

    #define dead_band 1
    #define offset 30
    #define max_pwm 240
    #define max_integration 20000
    #define derivate_dead_band 10

    #byte ADRESH=0x1e
    #byte ADRESL=0x9e
    #byte ADCON0=0x1f
    #byte ANSEL=0x9f

    #define get_analog(var) #asm \
    movf ADRESL,w \
    movwf &var \
    movf ADRESH,w \
    movwf &var+1 \
    #endasm

    #define neg16(a) #asm \
    COMF a,F \
    COMF &a+1,F \
    INCF a,F \
    BTFSC 03,2 \
    INCF &a+1,F \
    #endasm

    #define txd16(dato) putc((int)dato); putc((int)(dato>>8))

    //long BARG;
    #define sgn16(i) (bit_test(i,15))
    int sign;
    int16 target,pot,e,pwm,tmp,prev_e=0,derivate,integration=0;

    void main()
    {
    int cont;

    set_tris_a(0b00001011);
    ANSEL=0b00010011; //0:nc, 001:fosc/8, 0011:DDAA

    #if driver_type==0
    output_low(motorL); output_low(motorR);
    #else
    output_low(motorON);
    #endif

    while(true) //bucle
    {
    //Get analog channels

    //TARGET
    ADCON0=0b10000001; //1: Right, 0: vref=5v, 00:NC, 00: ch=0, 1: start, 1: AD_ON
    delay_us(100);
    bit_set(ADCON0,1); //start
    while(bit_test(ADCON0,1));
    get_analog(target);

    //POTENTIOMETER
    ADCON0=0b10000101; //1: Right, 0: vref=5v, 00:NC, 01: ch=1, 1: start, 1: AD_ON
    delay_us(100);
    bit_set(ADCON0,1); //start
    while(bit_test(ADCON0,1));
    get_analog(pot);

    //** IMPLEMENTS PID *******
    pwm=0;
    e=target-pot; //error
    derivate=e-prev_e; prev_e=e; //derivate

    if((e>dead_band) || (e+dead_band>4;
    if (sign) neg16(pwm);

    //Kd
    sign=false;
    if (sgn16(derivate)) { sign=true; neg16(derivate); }
    if(derivate>derivate_dead_band)
    {
    tmp=derivate*Kd; //tmp=tmp>>4;
    if (sign) neg16(tmp);
    pwm=pwm+tmp;
    }
    }

    //Ki
    sign=false;
    if (sgn16(integration)) { sign=true; neg16(integration); }
    if (integration>max_integration) integration=max_integration; //check limits
    tmp=integration; tmp=tmp>>4;
    tmp=tmp*Ki; tmp=tmp>>4;
    if (sign) {neg16(tmp); neg16(integration) }
    pwm=pwm+tmp;

    tmp=pwm;
    if(pwm)
    {
    if(sgn16(tmp))
    {
    //negative
    #if driver_type==0
    output_high(motorL);
    #else
    output_high(motorON);
    output_high(motorDIR);
    #endif
    neg16(tmp);
    }
    else
    {
    //positive
    #if driver_type==0
    output_high(motorR);
    #else
    output_high(motorON);
    output_low(motorDIR);
    #endif
    }

    tmp+=offset;
    if(tmp>max_pwm) tmp=max_pwm;
    }

    //************************

    //implements PWM
    for(cont=0;cont<255;cont++)
    {
    delay_us(50);
    if ((int)tmp==cont)
    {
    #if driver_type==0
    output_low(motorL); output_low(motorR);
    #else
    output_low(motorON);
    #endif
    }
    }
    #if driver_type==0
    output_low(motorL); output_low(motorR);
    #else
    output_low(motorON);
    #endif

    /* //monitor
    putc('0'); txd16(POT);
    putc(0x3c); txd16(TARGET);
    putc(0x3d); txd16(PWM);
    */
    } //while(1)
    }

    endereço da imagem

    https://lh3.googleusercontent.com/XtoVKgDyEFR_Aw1Hu11MLnD02bdXUnXlstgMZ1A9ffgqJlpiJj-Y57GGVVwa-qdfxn5G=s123

    1. 0

      Olá Morais!
      Parece que está faltando o ‘include’ com o tipo de microcontrolador. Pelo esquema no link que me passou não dá para enxergar nada, nem o tipo de microcontrolador.
      Na suposição que esteja usando o 12f675, consegui compilar conforme abaixo:

      #include <12F675.h>//supondo que seja o 12f675
      //#device adc=10
      #fuses INTRC_IO,NOWDT,NOPUT //,NOBROWNOUT
      #use delay(clock=4000000)

      #use fast_io(a)
      #use rs232(baud=9600, xmit=PIN_A2)
      //analog implementation
      //AN0=target
      //AN1=potentiomenter
      //driver type:
      //type 0: ch0-left, ch1-right,
      //type 1: ch0-on/off, ch1-direction
      #define driver_type 0
      //output (type=0)
      #define motorL PIN_A4
      #define motorR PIN_A5
      //output (type=1)
      #define motorON PIN_A4
      #define motorDIR PIN_A5
      //PID
      #define Kp 0.2 * 16
      #define Ki 0.0 * 16
      #define Kd 0.0 * 16
      #define dead_band 1
      #define offset 30
      #define max_pwm 240
      #define max_integration 20000
      #define derivate_dead_band 10
      #byte ADRESH=0x1e
      #byte ADRESL=0x9e
      #byte ADCON0=0x1f
      #byte ANSEL=0x9f
      #define get_analog(var) #asm \
      movf ADRESL,w \
      movwf &var \
      movf ADRESH,w \
      movwf &var+1 \
      #endasm
      #define neg16(a) #asm \
      COMF a,F \
      COMF &a+1,F \
      INCF a,F \
      BTFSC 03,2 \
      INCF &a+1,F \
      #endasm
      #define txd16(dato) putc((int)dato); putc((int)(dato>>8))
      //long BARG;
      #define sgn16(i) (bit_test(i,15))
      int sign;
      int16 target,pot,e,pwm,tmp,prev_e=0,derivate,integration=0;
      void main()
      {
      int cont;
      set_tris_a(0b00001011);
      ANSEL=0b00010011; //0:nc, 001:fosc/8, 0011:DDAA
      #if driver_type==0
      output_low(motorL); output_low(motorR);
      #else
      output_low(motorON);
      #endif

      while(true) //bucle
      {
      //Get analog channels
      //TARGET
      ADCON0=0b10000001; //1: Right, 0: vref=5v, 00:NC, 00: ch=0, 1: start, 1: AD_ON
      delay_us(100);
      bit_set(ADCON0,1); //start
      while(bit_test(ADCON0,1));
      get_analog(target);
      //POTENTIOMETER
      ADCON0=0b10000101; //1: Right, 0: vref=5v, 00:NC, 01: ch=1, 1: start, 1: AD_ON
      delay_us(100);
      bit_set(ADCON0,1); //start
      while(bit_test(ADCON0,1));
      get_analog(pot);
      //** IMPLEMENTS PID *******
      pwm=0;
      e=target-pot; //error
      derivate=e-prev_e; prev_e=e; //derivate
      if((e>dead_band) || (e+dead_band>4));
      if (sign) neg16(pwm);
      //Kd
      sign=false;
      if (sgn16(derivate)) { sign=true; neg16(derivate); }
      if(derivate>derivate_dead_band)
      {
      tmp=derivate*Kd; //tmp=tmp>>4;
      if (sign) neg16(tmp);
      pwm=pwm+tmp;
      }
      }
      //Ki
      sign=false;
      if (sgn16(integration)) { sign=true; neg16(integration); }
      if (integration>max_integration) integration=max_integration; //check limits
      tmp=integration; tmp=tmp>>4;
      tmp=tmp*Ki; tmp=tmp>>4;
      if (sign) {neg16(tmp); neg16(integration) }
      pwm=pwm+tmp;
      tmp=pwm;
      if(pwm)
      {
      if(sgn16(tmp))
      {
      //negative
      #if driver_type==0
      output_high(motorL);
      #else
      output_high(motorON);
      output_high(motorDIR);
      #endif
      neg16(tmp);
      }
      else
      {
      //positive
      #if driver_type==0
      output_high(motorR);
      #else
      output_high(motorON);
      output_low(motorDIR);
      #endif
      }
      tmp+=offset;
      if(tmp>max_pwm) tmp=max_pwm;
      }
      //************************
      //implements PWM
      for(cont=0;cont<255;cont++)
      {
      delay_us(50);
      if ((int)tmp==cont)
      {
      #if driver_type==0
      output_low(motorL); output_low(motorR);
      #else
      output_low(motorON);
      #endif
      }
      }
      #if driver_type==0
      output_low(motorL); output_low(motorR);
      #else
      output_low(motorON);
      #endif
      /* //monitor
      putc('0'); txd16(POT);
      putc(0x3c); txd16(TARGET);
      putc(0x3d); txd16(PWM);
      */
      } //while(1)

      //}

      gerando o seguinte hex:

      :1000000000308A0004280000FF238316900000308F
      :100010008A000A2884011F3083051F08BF399F000A
      :1000200083161F08F0390F389F00073083129F0096
      :100030000515B001B101B401B5010B3065001330F5
      :1000400083169F0083120512851281309F00213094
      :10005000A000A00B29289F149F182C2883161E0887
      :100060008312A6001E08A70085309F002130A00043
      :10007000A00B38289F149F183B2883161E08831254
      :10008000A8001E08A900AD01AC0128082602AA009C
      :100090002708AB002908031C290FAB0230082A02ED
      :1000A000B2002B08B3003108031C310FB3022B0838
      :1000B000B1002A08B000AB08031D70282A08013CD3
      :1000C000031C702801302A07B7002B08B80003185A
      :1000D000B80AB808031D70283708043C031C7028B0
      :1000E000A50803197828AC09AD09AC0A0319AD0AB3
      :1000F000A501B31F82280130A500B209B309B20AD5
      :100100000319B30AB308031D892832080A3C0318EF
      :100110009928AF01AE01A50803199328AE09AF09CC
      :10012000AE0A0319AF0A2E08AC070318AD0A2F0850
      :10013000AD072528A501B51FA4280130A500B409E5
      :10014000B509B40A0319B50A35084D3C0318B3289C
      :10015000FF3A031DAF283408203C0318B3284E3063
      :10016000B5002030B4003508AF003408AE00AF0C45
      :10017000AE0CAF0CAE0CAF0CAE0CAF0CAE0C0F3027
      :10018000AF05AF01AE01AF0CAE0CAF0CAE0CAF0CB7
      :10019000AE0CAF0CAE0CAF05A5080319D928AE09FB
      :1001A000AF09AE0A0319AF0AB409B509B40A0319B5
      :1001B000B50A2E08AC070318AD0A2F08AD072D08A5
      :1001C000AF002C08AE002C082D040319FF28AF1F28
      :1001D000F0280516AE09AF09AE0A0319AF0AF128D7
      :1001E00085161E30AE070318AF0AAF08031DFC28A2
      :1001F0002E08F03C0318FF28AF01F030AE00B60126
      :10020000360F032910291030A000A00B052900008B
      :1002100036082E02031D0E2905128512B60A002982
      :06022000051285126300C7
      :02400E00F43983
      :00000001FF
      ;PIC12F675

      Mas como não sei o esquema, nem tenho certeza do pic usado, não posso afirmar que vá funcionar. Fica por sua conta e risco.

      Cláudio

  3. 0

    bom dia larios e um prazer muito grande de conhecer jente nova tenho 48 anos trabalho no ramos de eletronica departamento de radio frequencia e eletronica analogica e muito bom ver teus projetos microcomtrolado fusiona muito bem um abraço wesley

Comments are closed.