Ir ao conteúdo
  • Cadastre-se

Projetos com Avr : Design, Programação em Basic e Assembly


Ir à solução Resolvido por aphawk,

Posts recomendados

EMULADOR SIMPLES DE ROTOR DE ANTENA YAESU - Parte 1

 

Estou terminando um novo controle de rotor inteligente para uso em rádio-amadorismo, e uma parte importante é a comunicação entre o rotor e o computador, então acabei tendo de estudar a maneira que ocorre essa conversa.

 

O objetivo é um rotor de antena que possa controlar de forma automática até 4 antenas com direções diferentes. Pera... afinal que doideira é essa ???

 

Em minha torre, tenho uma antena direcional principal, que é uma antena tipo log-periódica de 7 elementos, e que cobre todas as bandas entre 10 metros e 20 metros. Ou seja, atende perfeitamente as bandas de 10, 12, 15, 17 e 20 metros.

 

Mas tenho também mais duas antenas direcionais tipo dipolo : uma para atender 30m e outra para 40m.

 

O problema : empilhamento de antenas.

 

Como todas as antenas são direcionais e estão na polarização horizontal, ao colocarmos todas em um mesmo cano, um pouco acima uma das outras, ocorre uma séria interferência entre elas, podendo prejudicar totalmente o funcionamento de uma ou até de todas elas.

 

Lembro aqui que antenas direcionais tipo YAGI funcionam com "elementos parasitas" , que devem estar todos no mesmo plano e colocados nas distâncias corretas uns dos outros.  A presença de outra antena do mesmo tipo acaba fazendo que existam mais "elementos parasitas" em distâncias semelhantes, e fora do mesmo plano, e isso pode inutilizar o seu funcionamento !

 

A regra geral diz que para poder empilhar antenas em um mesmo cano, e apontando para a mesma direção, a distância entre elas deve ser no mínimo de meio comprimento de onda da maior delas. No meu caso, a distância entre elas deveria ser de "apenas 20 metros" !!!!! Como fazer isso se o cano inteiro tem apenas 6 metros ???? Oras, é impossível !

 

Então, o que fazer nesses casos ?  Simples : mudar a direção das antenas, de maneira que nenhuma esteja paralela com as outras ! E tentar diminuir ao máximo a possibilidade de qualquer tipo de cano ou metal ( leia-se Gondola ou Radiantes... ) iquem em paralelo com os elementos das antenas.

 

Como são 3 antenas, não dá para fazer a ideia mais simples, que é colocar uma a 90 graus ( totalmente perpendicular ) à outra.

 

Então escolhí colocar entre elas um angulo de 45 graus, da seguinte maneira :

 

- a antena principal aponta para a direção correta programada no rotor.

- a antena de 30m aponta para 45 graus À ESQUERDA da principal.

- a antena de 40m aponta para 45 graus À DIREITA da principal.

 

Assim a interferência entre elas fica bem minimizada, e o funcionamento de todo o conjunto é bem satisfatório.

 

A seguir continuarei com a descrição do projeto.

 

 

 

 

 

EMULADOR SIMPLES DE ROTOR DE ANTENA YAESU - Parte 2

 

Continuando... 

 

Resolvida a instalação física, vem a complicação lógica !

 

Os programas que utilizamos nos dão a informação para onde devemos apontar nossas antenas quando desejamos falar com um determinado radioamador.

 

Por exemplo, estou em São Paulo, e se quiser falar com o colega com o indicativo G7VEC tenho de apontar as antenas para 24,7 graus ( EM RELAÇÃO AO NORTE GEOGRÁFICO ).

 

Tudo bem isso ajuda bastante, mas apenas uma das minhas antenas vai estar realmente apontada para ele da maneira correta, e só ocorre caso a freqüência que eu esteja utilizando seja aquela que é atendida pela antena principal, com comprimento de onda entre 10 e 20 metros.

 

Se estiver utilizando uma frequência correspondente à antena de 30m, a direção correta deve ser 45 graus menor, ou seja, aproximadamente 335 graus.

 

E se for utilizada a antena de 40m, a direção correta será aproximadamente 70 graus !

 

A grande maioria dos bons programas para uso de radioamadores permite configurar uma porta serial para uso com o rotor YAESU, e nesse caso já apontaria o rotor direto para a direção de 24,7 graus.

 

O meu rotor não é um YAESU, e sim um CDE45 II, com controle manual. Eu vejo no programa qual a direção a apontar, e giro o meu rotor para a esquerda ou para a direita até atingir a posição desejada no marcador.

 

Este é o meu controle do rotor :

 

HyGain%20Plus%20CNw.jpg

 

Mas agora, com as três antenas, eu tenho de ficar fazendo cálculo toda hora... tenho de ver qual a frequência que estou utilizando, qual a banda correspondente, e fazer contas de cabeça para aonde devo apontar... fazer isso uma vez é simples, mas fazer isso 30,50,100 vezes por dia é um saco !

 

Então, resolví fazer um pequeno display que me mostra qual a direção devo apontar para qualquer uma das antenas que tenho no meu rotor !

 

Peguei um Arduíno Uno, e pretendo simular ao computador que meu Arduino é um rotor YAESU, assim ele recebe a direção, faz as contas para mim, e mostra no display o que preciso !

 

Claro que vou fazer o programa no Bascom....

 

A seguir, o diagrama de ligações e o programa.

 

Paulo

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

EMULADOR SIMPLES DE ROTOR DE ANTENA YAESU - Parte 3

 

Material utilizado :

 

1 display LCD comum, tipo 16x2

1 módulo I2C para display LCD

1 Arduino Uno

 

Usar um display comum LCD de 16x2 envolve bastante fios, e para evitar isto fizeram um pequeno módulo, que é soldado diretamente ao display, e assim permite que a conexão seja feita com apenas 4 fios usando o bus I2C.

 

Veja o módulo :

 

Modulo-Display.jpg

 

O esquema de ligação :

 

Circuito-Arduino-i2c-display-lcd-16x2.pn

 

Mais simples, impossível !!!!

 

Agora, um pouco da parte técnica : como é feita a conversa entre o rotor e o computador.

 

A YAESU criou um protocolo, que nada mais é que uma definição de frases e respostas que são enviadas e recebidas via padrão RS232C ( serial portanto ). Esse padrão se chama YAESU GS232 ( depois houveram acréscimos e acrescentou-se um sufixo, A e depois B ).

 

Para a minha finalidade, o que está na norma GS232 já me atende. Os comandos são enviados sempre na forma de texto, usando ASCII, o que facilita demais. O formato da comunicação é a tradicional 8N1, isto é, 8 bits, sem bit de paridade, e ao final 1 stop bit, na velocidade de 9600 Bauds.

 

A conversa envolve dois comandos básicos :  quando o computador pergunta ao rotor qual a posição que o rotor está apontando, e quando o computador envia ao rotor a nova direção para o qual ele deve apontar.

 

Para perguntar ao rotor qual a direção que o rotor está apontado, o computador envia o comando "C" seguido de um Carriage Return ( em hexadecimal  é 43 0D ) e o rotor deve responder "+0XXX" seguido de um Carriage Return e um Line Feed ( aqui, XXX representa a direção do rotor em graus, se estiver apontado para 10 graus a resposta deve ser "+0010" + Cr + Lf  ou em hexadecimal  2B 30 30 31 30 0D 0A .

 

Para ordenar ao rotor girar para alguma direção, o computador envia o comando "MXXX" seguido de um Carriage Return, onde XXX são três dígitos com a direção a apontar ( lembrando que mesmo que a direção seja de apenas dois dígitos, tem de enviar um zero na frente, por exemplo 9 graus é 009 ), assim sendo o comando "M009" fica em hexadecimal 4D 30 30 39 0D .

 

Temos de implementar apenas esses comandos em nosso programa.

 

Segue abaixo o código fonte em Bascom :

$regfile = "M328pdef.dat"
$crystal = 16000000
$hwstack = 60
$swstack = 90
$framesize = 128
Config Submode = New
Config I2cdelay = 10

' vamos carregar a library de comunicaç±ao I2C por hardware
$lib "i2c_twi.lib"                                          'hardware i2c/TWI
' e vamos definir a velocidade do bus I2C como 100 Khz
Config Twi = 100000

'agora carregamos a library feita para usar o módulo I2C de display
$lib "bl_Lcd_i2c.lib"                                       ' AN #118 library from Kent
                                                            ' with this addition
                                                            ' * lds r27,{backlight}
                                                            ' andi _temp2,&hf7
                                                            ' or _temp2,r27


' vamos usar serial por interrupcao via hardware
' com um buffer para transmissao e outro para recepcao
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 100 , Bytematch = 13
Config Serialout = Buffered , Size = 64



'---- DIM COMUNICACAO SERIAL
Dim S_serial_buffer As String * 90
Dim F_tem_dado_serial As Bit
Dim Resp$ As String * 40
Dim A$ As String * 1
Dim B$ As String * 10
Dim W_temp3 As Word
F_tem_dado_serial = 0
Dim W_pos_antena As Word
Dim W_nova_posicao As Word
Dim B_pointer_buf As Byte
Dim F_nova_posicao As Bit


'LCD-display including backlight
'0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
'1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6

'G 5 C R R E D D D D D D D D B B
'N   O S W   0 1 2 3 4 5 6 7 L L
'D V N                         S

'PCF8574
'P7 = D7
'P6 = D6
'P5 = D5
'P4 = D4
'P3 = 1 = backlight on / 0 = backlight off
'P2 = E
'P1 = RW
'P0 = RS

Const Pcf_d4 = 4
Const Pcf_d5 = 5
Const Pcf_d6 = 6
Const Pcf_d7 = 7
Const Pcf_rs = 0
Const Pcf_rw = 1
Const Pcf_e1 = 2




Dim Antena30 As Integer
Dim Antena40 As Integer
Dim Antenaresto As Integer
Dim Offset As Integer
Offset = 0
' as proximas duas variáveis sao para a biblioteca do módulo I2C do display
Dim _lcd_e As Byte
Dim Backlight As Byte

Backlight_on Alias &H08
Backlight_off Alias &H00

Backlight = Backlight_on

_lcd_e = 128

Const Pcf8574_lcd = &H4E                                    'Defines the address of the I/O expander for LCD

Config Scl = Portc.5                                        'we need to provide the SCL pin name
Config Sda = Portc.4
I2cinit
Waitms 500
cls
Cursor Off , Noblink

B_pointer_buf = 0
W_pos_antena = 123
Resp$ = ""

'----- inicio -------------------------------

W_pos_antena = 0
Enable Interrupts
F_tem_dado_serial = 0
Print "AZ=000" ; Chr(13) ; Chr(10)
Waitms 200
Clear Serialin

De_novo:
'vamos ver se temos algum dado serial a tratar
Gosub Tem_dado
If F_nova_posicao = 1 Then
'  sim, temos um comando para mudar a posicao do rotor
'  então vamos calcular as direcoes para as tres antenas
   W_nova_posicao = W_nova_posicao + Offset
   Antena30 = W_nova_posicao + 45
   Antena40 = W_nova_posicao - 45
   Antenaresto = W_nova_posicao
   If Antenaresto > 360 Then
      Antenaresto = Antenaresto - 360
   Elseif Antenaresto < 0 Then
      Antenaresto = Antenaresto + 360
   End If
   If Antena30 > 360 Then
      Antena30 = Antena30 - 360
   Elseif Antena30 < 0 Then
      Antena30 = Antena30 + 360
   End If
   If Antena40 > 360 Then
      Antena40 = Antena40 - 360
   Elseif Antena40 < 0 Then
      Antena40 = Antena40 + 360
   End If
'  agora é só mostrar no display
   Cls
   Home
   Lcd "30=" ; Antena30 ; "  40=" ; Antena40
   Lowerline
   Lcd " LOG = " ; Antenaresto
'  sinalizamos que já mostramos a posicao no display
   F_nova_posicao = 0
'  assim n±ao precisamos mais atualizar o display enquanto n±ao recebermos
'  um comando com a nova posicao.
End If
Goto De_novo



'-----------------------------------------------------------------------------
Tem_dado:
If F_tem_dado_serial = 1 Then
'     sim, temos daso a tratar vamos ver qual o comando
      F_tem_dado_serial = 0
      S_serial_buffer = Trim(s_serial_buffer)
      A$ = Mid(s_serial_buffer , 1 , 1)

      If A$ = "#" Then
'        comando ignorado
         nop

      Elseif A$ = "C" Then
'        computador quer ler a posicao do rotor
         Resp$ = "+0"
         If W_pos_antena < 10 Then
            Resp$ = Resp$ + "00"
            Resp$ = Resp$ + Str(w_pos_antena)
         Elseif W_pos_antena < 100 Then
            Resp$ = Resp$ + "0"
            Resp$ = Resp$ + Str(w_pos_antena)
         Else
            Resp$ = Resp$ + Str(w_pos_antena)
         End If
         Resp$ = Resp$ + Chr(13)
         Resp$ = Resp$ + Chr(10)
'        já montamos a resposta, basta enviar
         Print Resp$;

   Elseif A$ = "M" Then
'        computador mandou uma nova direcao ao rotor
         B$ = Mid(s_serial_buffer , 2 , 3)
         W_temp3 = Val(b$)
'        vamos ver se é diferente da posicao atual
         If W_temp3 <> W_pos_antena Then
'           sim, é diferente ...
            Set F_nova_posicao
            W_nova_posicao = W_temp3
            W_pos_antena = W_temp3
         End If
   End If
Else
End If
Return

' Rotina que trata quando recebe o caracter 0D pela serial
Serial0charmatch:

  $asm
  !PUSH R6
  !PUSH R22
  !PUSH R24
  !PUSH R25
  !PUSH R26
  !PUSH R27
  !PUSH R30
  !in R24, sreg
  !PUSH  R24
  $end Asm
' vamos ler o buffer de comunicaçao serial para uma string
  Input S_serial_buffer Noecho
' agora podemos zerar o buffer serial
  Clear Serialin
' e agora sinalizamos ao programa principal que temos dados a tratar !
  Set F_tem_dado_serial

  $asm
  !POP  R24
  !out sreg, r24
  !POP R30
  !POP R27
  !POP R26
  !POP R25
  !POP R24
  !POP R22
  !POP R6
  $end Asm
Return


 End

 

Paulo

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

  • 3 meses depois...

              ACOPLADOR DE ANTENA AUTOMÁTICO PARA RÁDIO PX

 

Após verificar vários projetos para fazer um acoplador automático multi bandas para faixa de HF ( usada por radioamadores ) , resolvi fazer um para uso em rádios PX, de baixo custo, que suporte baixa potência e funcione bem para a faixa de 26 a 28,5 Mhz.

 

Como a grande maioria de quem usa rádio PX sabe, nem sempre a estacionária de nossa antena é a ideal, em torno de 50 ohms.

 

Para resolver isso, usa-se um circuito muito simples, composto de dois capacitores variáveis e uma bobina entre eles.

 

Eu imaginei fazer o controle dos capacitores, ligando um servo ( do tipo usado em radiocontrole, de baixo custo )  em cada um, fazendo o acoplamento mecânico entre o eixo do servo e o eixo do variável. Assim, podemos girar o variável simplesmente fazendo o servo girar.

 

Precisamos medir o valor do SWR ( relação de onda estacionária ) , cujo valor ideal é 1 , sendo aceitável um valor entre 1 e 2, e perigoso quando acima de 3, podendo causar a queima do circuito transmissor do rádio.

 

Então, precisamos fazer algumas medidas, sendo que a maneira mais simples de se obter os valores é medindo a tensão direta e a tensão refletida pela antena.

 

Um circuito de medição bem antigo é conhecido por Monimatch, e é bem simples de se montar, não envolvendo ajustes complicados, nem componentes difíceis.

 

Segue abaixo uma cópia desse circuito, feita pela Heatkit :

 

image.png.855d1d04bcf1bdad452c736ca124dc0b.png

 

Reparem que nas saídas dos dois diodos temos os valores de tensão direta e refletida ( forward and reflected ), que podem ser lidas em duas portas A/D de um simples microcontrolador. Em INPUT será ligada a saída do rádio PX, e em OUTPUT será ligada a antena.

 

Sua montagem não poderia ser mais simples :

 

100_0803.png.95b9fd105422915e69e802a0b7b6b4fc.png

 

Abaixo, o circuito que permite ajustar a SWR :

 

image.png.723be6224086cfcc360151ab889f7903.png

 

A seguir continuarei com a descrição do projeto.

 

Paulo

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

ACOPLADOR DE ANTENA AUTOMÁTICO PARA RÁDIO PX - Parte 2

 

Como controlar servos tipo RC ?

 

Uma parte em que muitos encontram dificuldades é justamente na geração dos sinais de temporização para um servo.

 

Um servo utiliza controle do tipo PWM, sempre repetindo a cada 20 milissegundos.

 

Veja abaixo :

 

image.png.1a8ee903381791f272045a04c1c85e13.png

 

Para manter o servo na posição central, temos de gerar um pulso positivo de 1,5 milissegundos, e repetir esse pulso a cada 20 milissegundos.

 

Já para o servo ir à posição extrema esquerda, a largura do pulso deve ser de 1 mseg , e para a posição extrema direita deve ser de 2 mseg.

 

Um servo R/C permite movimento de 180 graus, com uma resolução de 1 grau sem nenhuma dificuldade.

 

Porém, isso significa que temos de dividir o intervalo de 1 mseg por 180,  o que significa uma resolução mínima no pulso gerado de 5,55 microsegundos !!!!!

 

Gerar essa resolução mínima por software, por exemplo criando uma interrupção do timer a cada 5,55 microsegundos só pode ser feita usando Assembly, pois mesmo para um AVR rodando a 8 Mhz tem um ciclo de instrução de 0,125 microsegundos , o que nos daria um tempo total de ciclos de máquina de apenas 5,55/0,125 = 44 ciclos de máquina.

 

Considerando que para tratar uma interrupção perdemos 5 ciclos de clock na entrada, e mais 5 ciclos de clock na saída, isso sem fazer mais nada, só sobram cerca de 34 ciclos de clock para

nosso programa, o que é muito pouco para fazermos a geração de 2 sinais PWMs , pois usamos dois servos !  Mesmo que aumente a frequência de clock para 20 Mhz, seria um desafio tentar fazer essa rotina em Assembly, e mesmo se conseguisse tomaria muito recurso de tempo do microcontrolador, e nosso programa principal teria execução muito lenta.

 

A solução é deixar o hardware do AVR fazer isso para nós !

 

O Timer1 da grande maioria dos Atmega é um Timer de 16 bits, e podemos configurar como um Counter, definindo a contagem máxima do mesmo. Quando a contagem chega ao máximo, o Counter zera e o processo começa de novo.

 

Para melhorar ainda mais para nós, existe um modo do Counter que faz exatamente o que não estamos conseguindo fazer por software :

 

Podemos definir uma determinada contagem, e quando essa contagem for atingida, a saída do Counter inverte o estado lógico !

 

Veja, definindo esse modo, quando a contagem iniciar do zero a saída vai para o nível 1; quando essa contagem atingir determinado número, a saída vai para 0, e ficará nesse nível até chegar a contagem máxima,  e nesse instante todo o processo se repete !

 

E o mais legal : esse Timer1 tem duas saídas, ( A e B ) as quais podem ter seu funcionamento com contagens diferentes !  Assim, definindo qual a contagem que queremos para cada saída, temos a geração os dois sinais de servo, de forma automática e sem perder nenhum tempo de software !

 

Esse Timer1 pode ser usado com prescaler. Uma das opções é usar prescaler de 8. Assim, com clock de 8 Mhz, e prescaler de 8, o Counter1 vai ser incrementado a cada microsegundo, o que em tese permitiria gerar uma resolução nos servos menor do que 0,2 graus !

 

Assim, lembrem que o processo todo tem de se repetir a cada 20 milissegundos, que equivale a 20.000 microsegundos. Vamos definir a contagem máxima de 20.000 para o Counter1, e já teremos o nosso sinal sendo repetido a cada 20 mseg, exatamente como deve ser feito !

 

O segredo é definir o numero da contagem aonde vai ocorrer a inversão do estado da saída. Como esse Counter1 tem 16 bits, sua contagem pode ir de 0 a 65.535 , então se definirmos que queremos essa contagem até 1500, o Counter1 vai inicialmente colocar o nivel 1 na saída desejada, e quando a contagem chegar a 1500, vai inverter o estado dessa saída, e continuar a contagem até o máximo definido, que é de 20.000 .

 

Reparem acabamos de gerar EXATAMENTE o sinal que vai mandar o servo para a posição central, que é com um pulso de nivel alto de cerca de 1,5 milissegundos ( ou 1500 microsegundos !!! ).

 

Tudo feito de maneira simples, por hardware, apenas sabendo o funcionamento do módulo Timer/Counter dos Atmegas.

 

Segue abaixo como configurar o Timer1 para fazer o que queremos, configurando diretamente os registradores do Timer1 :

 

' Definir a contagem máxima

Icr1h = High(20000)
Icr1l = Low(20000)
' Set OCRxA, OCRxB para  Servo1 e Servo2
Ocr1ah = High(1500)                                         'posição inicial qualquer servo 1 qqr valor serviria
Ocr1al = Low(1500)
Ocr1bh = High(1500)                                         'idem  servo 2
Ocr1bl = Low(1500)
' Configurar modo  FAST PWM, Mode 14, com prescale de 8, e iniciar !
Tccr1a = &B10100010                                         'COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
Tccr1b = &B00011010                                         'ICNC1 ICES1 - WGM13 WGM12 CS12 CS11 CS10
 

Prontinho !

 

Agora, basta definirmos os valores de Ocr1ah e Ocr1al para o valor em microsegundos que queremos gerar para o Servo1, e Ocr1bh e Ocr1bl para o valor em microsegundos que queremos gerar para o Servo2.

 

Lembro que embora o registrador seja de 16 bits, eles são na verdade dois registradores de 8 bits cada, então temos de sempre colocar o valor neles PRIMEIRO a parte alta que vai no registrador com final h , e logo após colocar a parte baixa que vai no registrador com final l.

 

Por exemplo, para fazer o servo 2 ir para a extrema esquerda basta fazermos :

 

Ocr1bh = High(1000)                                       
Ocr1bl = Low(1000)

 

Simples, não é ? Mas quebrou um baita dum galho kkkkkkk !

 

Neste projeto, não vamos precisar de tanta resolução assim, pois vamos mover nossos servos entre -45 e + 45 graus, num total de 30 posições diferentes apenas, então vamos usar uma resolução de apenas 3 graus.

 

Paulo

  • Curtir 3
Link para o comentário
Compartilhar em outros sites

 ACOPLADOR DE ANTENA AUTOMÁTICO PARA RÁDIO PX - Parte 3

 

Como medir a frequência ?

 

Minha ideia é montar uma tabela em Eprom e ir guardando os ajustes encontrados de maneira que quando for utilizada uma frequência próxima de uma outra que já tenha sido encontrado o ajuste, aproveitar esse ajuste e assim simplesmente recuperar os valores dos dois servos e acionar para irem direto na posição desejada.

 

Mas, para isso, preciso saber qual é a frequência que está sendo utilizada.

 

O problema : estamos falando de frequências próximas a 27 Mhz !  

 

Como fazer essa medição utilizando o nosso Atmega328 ? Pelo datasheet, mesmo utilizando um contador em modo assíncrono não conseguimos ultrapassar os 20 Mhz ( ou a frequência do clock, que em nosso caso é de 8 Mhz apenas ).

 

Neste ponto cito uma curiosidade : na família PIC16, o Timer trabalha em modo assíncrono até mais de 40 Mhz !!!!!  Para falar a verdade, é a única coisa que me dá saudades dos Pics kkkkk !

 

Como não podemos contar com o hardware interno, vamos precisar de um hardware externo. Ou seja, um divisor, que pode trabalhar a cerca de 30 Mhz sem problemas , e com uma alta impedância de entrada, para poder ser ligado diretamente à saída de RF do rádio sem causar nenhum problema.

 

Felizmente, temos esse CI, com um custo bem baixo : o 74HC4040 !

 

O 74HC4040 é um contador de 12 bits, que trabalha até 90 Mhz, e custa menos de R$ 2,00 !

 

Assim, vamos aplicar o sinal em sua entrada, claro que colocando limitadores para proteção, e vamos utilizar a sua saída Q8, que é dividida por 512.

 

Assim, uma frequência de 27.405.000 Hz , correspondente ao canal 40, vai gerar na saída uma frequência de 53.525,39 Hz, cuja parte inteira pode ser medida utilizando os outros dois Timers de 8 bits restantes no Atmega328. Na verdade, como vamos medir por apenas 1/10 de um segundo, obteremos uma contagem de 5352 Hz.

 

A seguir, mostrarei como configurar um timer como Counter externo, e o outro timer como Timer mesmo para servir de base de tempo, pois a minha ideia é contar a frequência por apenas 0,1 segundos. Para isso, vamos utilizar interrupção nos dois Timers de 8 bits para termos uma boa precisão, afinal com 8 bits podemos contar apenas até 255, e vamos precisar contar até cerca de 5700 para então multiplicar por 10 e obtermos a frequência aproximada.

 

Vejam : acabamos de descrever um Frequencímetro !

 

Na verdade, não preciso da frequência aproximada, o que preciso é apenas uma indicação da frequência para servir como índice de uma tabela contendo a posição dos dois servos. Mas digo isto pois este é o processo de se fazer um frequencímetro, e quem entender o processo pode fazer um bom frequencímetro para sua estação, apenas mudando a saída do divisor para a que é dividida por 16 ( pode ser também 32 ou 64, vai depender da resolução desejada ), assim teríamos uma precisão maior.  

 

No caso deste projeto, a ideia é a seguinte :

 

Não precisamos ajustar a estacionária cada vez que mudamos de canal, pois a variação é muito pequena. Vamos ajustar a cada intervalo de 50 Khz ( 5 canais do PX ), assim, por exemplo, se eu ajustar ela para o canal 40, e mudar para o 44, não vai ser feita nenhuma mudança, mas se mudar para o 46, sim, tem de refazer a medição e achar o novo ajuste dos capacitores, e guardar na memória EPROM para que na próxima vez apenas iremos pegar os valores da tabela na Eprom e mandar os servos irem para a posição desejada.

 

Vamos a seguir configurar o hardware dos Timers 0 e 2 , ambos de 8 bits :

 

Config Timer0 = Counter , Edge = Rising
On Ovf0 Timer_isr Nosave
Config Timer2 = Timer , Prescale = 128 , Compare_a = Disconnect , Compare_b = Disconnect , Clear_timer = 1
On Compare2a Ivtimer2 Nosave
Compare2a = 255 - 6
Enable Compare2a
Enable Ovf0
Enable Interrupts

 

O que fizemos acima ?

 

O Timer0 vai trabalhar como um contador, sendo que a contagem vai avançar a cada transição de subida do pulso de clock vindo do divisor por 512 do 74HC4040 .

E a cada vez que a contagem causar overflow de 255 para 0, ( lembre-se, é de 8 bits apenas ! ), vai gerar uma interrupção, que será tratada pela rotina Timer_isr.

Reparem o NOSAVE : ele significa que o compilador Basic não vai salvar nenhum registrador do Atmega328, deixando para mim salvar e depois repor os registradores que a minha rotina de interrupção irá alterar.

 

Já o Timer2 vai trabalhar como um timer mesmo, com prescaler de 128, não vai alterar os estados de suas saídas A a B, e de quebra quando ocorrer a interrupção de comparação da contagem com o número 6, a contagem será zerada novamente. Reparem que programamos uma interrupção por comparação de contagem, usando a parte A do Timer ( poderia ser feita com a parte B se quisesse... ), que irá chamar a rotina Ivtimer2, Igualmente com o NOSAVE.

 

A seguir, posto as rotinas de interrupção :

 


'---- INTERRUPT DO TIMER0
Timer_isr:
  $asm
  !PUSH R24
  !PUSH R26
  !PUSH R27
  !in R24, sreg
  !PUSH  R24
  $end Asm
Incr B_count1
 $asm
  !POP  R24
  !out sreg, r24
  !POP R27
  !POP R26
  !POP R24
  $end Asm
Return

'---- INTERRUPT DO TIMER2
Ivtimer2:
   $asm
  !PUSH R16
  !PUSH R23
  !PUSH R24
  !PUSH R26
  !PUSH R27
  !in R24, sreg
  !PUSH  R24
  $end asm

Incr B_count
If B_count = 25 Then
   B_temp1 = Tcnt0
   B_temp2 = B_count1
   B_count = 0
   B_count1 = 0
   Tcnt0 = 0
   F_chegou = 1
End If
 $asm
  !POP  R24
  !out sreg, r24
  !POP R27
  !POP R26
  !POP R24
  !POP R23
  !POP R16
  $end asm
Return

 

Na rotina do Timer0, a única instrução feita é a Incr B_count1, que nada mais é do que incrementar de um  o conteúdo da variável B_count1 a cada interrupção. Todas as outras instruções são em Assembly, e são apenas os famosos PUSH e POP para salvar os registradores que irão ser alterados nessa rotina de interrupção, e para repor quando a interrupção terminar.

 

Essa variável B_count1 mostra quantas vezes a contagem causou overflow, isto é, indica quantas vezes já houve uma contagem de 256 pulsos. A contagem atual está dentro do registrador TCNT0 pertencente ao hardware do Timer0. Assim, quando eu quiser saber quantos pulsos foram contados, basta multiplicar o conteúdo de B_count1 por 256 e somar a contagem em TCNT0 !   Só precisamos saber qual o instante ideal para fazermos essa conta, e esse instante é dado justamente pelo outro timer, que é o Timer2 !

 

A rotina do Timer2 é chamada a cada 4 milissegundos. Implementei nela um contador, e quando esse contador atingir 25 , significa que o tempo total passado é de 25 x 4 = 100 milissegundos, e é nesse instante que eu vou pegar a contagem do Timer0 , guardar em duas variáveis simples de 8 bits e sinalizar ao programa principal através do flag F_chegou que existe um valor a ser lido e calculado. E antes de sair da interrupção, ainda zero todas as contagens para poder medir novamente com precisão.

 

Como estamos medindo os pulsos durante 1/10 de segundo, teremos uma contagem de 1/10 da frequência real dos pulsos aplicados no Timer0, o que já basta para identificar precisamente os tais "intervalos de 50 Khz" que citei acima.

 

Para terem uma ideia, quando o rádio estiver no canal 40 teremos uma contagem medida de 5352  ( 27405000 / 512 = 53.525,39, mas por apenas 1/10 do tempo resulta em 5352 ) , e quando estiver no 41, teremos a contagem de  5354. Mas como vamos deixar um espaço de 50 Khz, o que nos interessa é a contagem para o canal 45 , que é de 5362.

 

Tá começando a clarear tudo agora !

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Olá Paulo! Tudo bem?

Tirei o domingo para dar uma nova olhada nos AVRs.

Comprei o Bascom e relendo seu tutorial, cheguei na parte que programa o led para piscar.

Copiei o programa "projeto1avr.bas", mas meu processador é o m328pdef. Então alterei a instrução que mencionava o 48 pela instrução

$regfile = "m328pdef.dat"  'Modelo do microprocessador que estamos usando

Fiz o mesmo em 

Menu > Compiler > Chip > 

Chip m328pdef.dat

Notei que no "Code Explorer" aparece "Processor MEGA88". Mesmo quando dou o Refresh, ele não muda.

Pergunto: 

1 - Quem é predominante, a instrução no editor, ou o que consta no Menu > Compiler > Chip > Chip xxxxx?

2 - Porque no "Code Explorer" o MEGA88 não muda?

Já tem mais de 2 anos que não mexo com AVR e mesmo quando usei, quase não tive oportunidade de empregá-lo em um projeto prático. Como tenho conhecimento do PIC e queremos empregar menos tempo nos projetos, acabei usando o PIC. :(

Sei que as dúvidas são elementares, mas gostaria que você me explicasse.

Grato.

[]'s

MOR_AL

Link para o comentário
Compartilhar em outros sites

3 horas atrás, MOR disse:

Olá Paulo! Tudo bem?

Tirei o domingo para dar uma nova olhada nos AVRs.

Comprei o Bascom e relendo seu tutorial, cheguei na parte que programa o led para piscar.

Copiei o programa "projeto1avr.bas", mas meu processador é o m328pdef. Então alterei a instrução que mencionava o 48 pela instrução

$regfile = "m328pdef.dat"  'Modelo do microprocessador que estamos usando

Fiz o mesmo em 

Menu > Compiler > Chip > 

Chip m328pdef.dat

Notei que no "Code Explorer" aparece "Processor MEGA88". Mesmo quando dou o Refresh, ele não muda.

Pergunto: 

1 - Quem é predominante, a instrução no editor, ou o que consta no Menu > Compiler > Chip > Chip xxxxx?

2 - Porque no "Code Explorer" o MEGA88 não muda?

Já tem mais de 2 anos que não mexo com AVR e mesmo quando usei, quase não tive oportunidade de empregá-lo em um projeto prático. Como tenho conhecimento do PIC e queremos empregar menos tempo nos projetos, acabei usando o PIC. :(

Sei que as dúvidas são elementares, mas gostaria que você me explicasse.

Grato.

[]'s

MOR_AL

 

Opa meu amigo, tudo bem ?

Quem sabe agora você "engata" de vez nos Avrs hehehe !

 

Quem é predominante é a instrução no editor. Sempre tudo no editor predomina sobre as outras configurações.

 

Isso do Menu>Compiler é algo muito antigo, e sinceramente não sei o porquê ainda não foi removido. Não me lembro de ter usado isso .... nem se preocupe mais !

 

Sobre o Code Explorer, aqui não acontece isso, testei inclusive fazendo o mesmo que você...

Sempre que mudo o tipo do microcontrolador, muda a info no Code Explorer. Deve ser um bug da versão que você está usando, tem de atualizar para as novas.

 

Em tempo : a versão atual do Bascom é a 2.0.8.1 , verifique e se a sua não for essa, tem de acessar aquela área do site do Bascom com a sua senha, onde poderá baixar a última versão, ok ? ( não adianta tentar pelo UPDATE pois não serve mais para as ultimas versões do Bascom, tem de baixar por lá mesmo, e o Update vai voltar a funcionar a partir da 2.0.8.0 ... ) .

 

Paulo

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

35 minutos atrás, aphawk disse:

Em tempo : a versão atual do Bascom é a 2.0.8.1 , verifique e se a sua não for essa, tem de acessar aquela área do site do Bascom com a sua senha, onde poderá baixar a última versão, ok ? ( não adianta tentar pelo UPDATE pois não serve mais para as ultimas versões do Bascom, tem de baixar por lá mesmo, e o Update vai voltar a funcionar a partir da 2.0.8.0 ... ) .

 

 

Paulo,

Eu comprei o Bascon-AVR há uns anos, mas não estou vendo opção de baixar sem ter que pagar mais 89 euros. Vou ter que pagar mais 89 euros para atualizar da versão 2.0.7.8 para a versão 2.0.8.1 ?

Link para o comentário
Compartilhar em outros sites

@Intrudera6 ,

 

Tem de ir na opção UPDATES , veja abaixo :

 

update.PNG.9fc2edffe6b51fa95f485c6eb61247b1.PNG

 

 

Forneça seu username e senha ( o mesmo da compra ) , e vai ver várias opções :

 

 

 

update3.PNG.3cf359547cd0af12630eb1d3fdb4d223.PNG

 

Clique em Download Lic Files ( marquei em azul ) e vai ver isto :

 

update1.thumb.PNG.a2a05b04f189bcefeb23d9b1d5daab10.PNG

 

Clique onde está marcado em azul, no Download full Bascom-AVR.

 

Vai precisar também daquele arquivo original que você recebeu quando comprou o Bascom. Veja o aviso ao final do quadro acima.

 

Antes de fazer qualquer coisa, faça um backup do seu Bascom atual, ele vai guardar tudo em um arquivo .ZIP na raiz do seu drive c: .

 

Instale a nova versão, e coloque o seu arquivo original .dll no diretório do Bascom, e pronto.

 

Mande bala !

 

Paulo

 

Link para o comentário
Compartilhar em outros sites

19 horas atrás, aphawk disse:

 

Opa meu amigo, tudo bem ?

Quem sabe agora você "engata" de vez nos Avrs hehehe !

 

Quem é predominante é a instrução no editor. Sempre tudo no editor predomina sobre as outras configurações.

E verdade, Paulo. Descobri ontem lendo o help do Bascom.

Isso do Menu>Compiler é algo muito antigo, e sinceramente não sei o porquê ainda não foi removido. Não me lembro de ter usado isso .... nem se preocupe mais !

Ok.

Sobre o Code Explorer, aqui não acontece isso, testei inclusive fazendo o mesmo que você...

Sempre que mudo o tipo do microcontrolador, muda a info no Code Explorer. Deve ser um bug da versão que você está usando, tem de atualizar para as novas.

Minha versão era (acho) 2.0.79, mas fuçando o Bascom, atualizei ontem mesmo para a versão 2.0.8.1

Em tempo : a versão atual do Bascom é a 2.0.8.1 , verifique e se a sua não for essa, tem de acessar aquela área do site do Bascom com a sua senha, onde poderá baixar a última versão, ok ? ( não adianta tentar pelo UPDATE pois não serve mais para as ultimas versões do Bascom, tem de baixar por lá mesmo, e o Update vai voltar a funcionar a partir da 2.0.8.0 ... ) .

É. Fiz isso mesmo.

Paulo

 

 

Quando você não mexe com um assunto, seu cérebro tende a dar lugar para novos. A vantagem é que basta dar um "refresh", que boa parte dele é recuperada. Mas os pequenos detalhes é que são perdidos. Estes sim, têm que ser reestudados. 

 

Em tempo:

Antes de fazer qualquer coisa, faça um backup do seu Bascom atual, ele vai guardar tudo em um arquivo .ZIP na raiz do seu drive c: .

 

Como fazer este backup? Abri o Bascom, mas não achei? Eu tenho que copiar e colar todo o diretório do Bascom e zipar os arquivos colados?

 

Instale a nova versão, e coloque o seu arquivo original .dll no diretório do Bascom, e pronto.

 

Qual desses é o arquivo que você menciona? Tem todos esses na raiz do Bascom-AVR

BASC-AVR.DLL

BASCPDF.DLL

BASPDF.DLL

bscavrl.dll

HHActiveX.dll

MFC42.DLL

MSVCRT.DLL

 

Grato, Paulo.

MOR_AL

Link para o comentário
Compartilhar em outros sites

@aphawk Ganhei uma placa núcleo L073RB em um sorteio e gostaria de dar ela para alguém auto didata e que possua interesse nos ARM pois estou meio sem tempo, já faz um tempo que estou tentar achar alguém para dar. Quero dar para um auto didata pois tem que ler bastante para usá-la, não estou muito frequente aqui no fórum (drone freestyle HAHA), se você achar alguém interessante me mande um mensagem por favor.

 

Placa: https://www.st.com/en/evaluation-tools/núcleo-l073rz.html

 

O atollic TrueSTUDIO é free e sem limitação de código então a pessoa conseguiriausar a placa numa boa =).

Link para o comentário
Compartilhar em outros sites

  • 3 meses depois...

                                     NOVO DEMO DO COMPILADOR BASCOM

 

O arquivo demo do compilador Bascom foi atualizado para uma versão bem mais moderna, embora não a atual.

Como ele possui todas as funcionalidades, embora seja limitado a gerar arquivos binários de no máximo 4K, é uma excelente opção a quem quer se iniciar nos Atmega e Attiny, que ficam mais poderosos em termos de recursos a cada dia que passa desde que a Microchip adquiriu a Atmel.

 

https://www.mcselec.com/index.php?option=com_docman&amp;task=doc_download&amp;gid=139&amp;Itemid=54

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 3 meses depois...

@xxnoxx ,

 

Se é de 8 Mhz, acredito que funcione.

 

Mas não vejo motivo para não usar um cristal, hoje em dia são muito baratos e a precisão da base de tempo é bem superior aos ressonadores.

 

Vide o problema dos Arduínos usarem ressonadores em vez de cristal, a base de tempo não é confiavel e varia bem com a temperatura.

 

Paulo

 

Link para o comentário
Compartilhar em outros sites

  • 4 meses depois...
 

Segue uma foto :

20130911_214303.jpg

 

Parabéns, @aphawk, pela iniciativa e pela realização!

 

Vou estudar o tutorial com atenção. Se não for abusar da sua boa vontade, não estou conseguindo visualizar o conjunto, uma PCB, um esquema, algo em que esses componentes - TDA8425, TEA5767, o amp e demais componentes - devem ser montados. Talvez estivesse nessa foto, que o tempo parece ter apagado.

 

E uma dúvida: pelo que entendi esse ATMEGA é algo escalável, uma plataforma multiuso como uma protoboard, será que é isso? Se for, no caso de montar esse receiver, ele ficaria com essa placa dentro do gabinete?

adicionado 1 minuto depois

Em tempo: para o amp, como tô estudando o LM3886 quem sabe esse receiver mereça mais do que um PAM, né?

Link para o comentário
Compartilhar em outros sites

@rmlazzari58 ,

 

Opa obrigado, meu amigo.

Eu montei um desses mas usei um outro circuito na saída, usei um amplificador para fones de ouvido, e a qualidade ficou fantástica.

 

Gozado que sumiram as fotos do post .... eu tenho elas guardadas no Tinypic , hoje de noite eu coloco elas com o esquema ok ?

 

A primeira versão é esta aqui :

 

PROJETO.png.6b027dd58deaf81c3ba99ac56c0a1902.png

 

vlcsnap-2019-06-06-22h18m15s777.png.c52c0fec0d37d1ff0e3c7841bbdd0a8f.png

 

A segunda versão eu incrementei com a parte de controle remoto e um belíssimo amplificador para fone de ouvidos com uma qualidade fantástica baseada em amp ops em paralelo :

 

amplificador.thumb.png.ecfc2d932b4b3604b57c395651857794.png

 

Não fiz PCB, usei uma plaquinha tipo universal, toda furada, e nela coloquei o Atmega328, o TDA e a plaquinha de FM com o TEA, e controlava tudo usando um desses pequenos controle remotos miniatura que você compra no ML e vem com o receptor infravermelho, assim evitei chaves e botões.

 

Dá também para usar um Arduíno Uno e ligar tudo nele .... enfim com os módulos que temos hoje em dia dá para implementar muita coisa nova !

 

O Atmega é um microcontrolador bem poderoso e barato, é o que tem dentro de um Arduino Uno ou Mini ou Micro.

 

O meu tutorial é a base de tudo o que tem nesse tópico, tem muitos projetinhos e muito conhecimento espalhado, até um pouco de Assembly para quem gostar.

 

Sobre o LM3886, eu ainda não brinquei com ele, mas brinquei bastante com os LM386, de 1W cada kkkkk já fiz muita coisinha com eles, e para um fone de ouvido de baixa impedância servem bem.

 

Bom proveito !

 

Paulo

Link para o comentário
Compartilhar em outros sites

  • mês depois...

Boa tarde a todos, e obrigado pelas informações postadas sobre programação.

Eu resolvi, depois dos meus quase 60 anos, aprender programação.  Comecei justamente pelo Bascom, arranho somente, nada mais além de piscar alguns LEDs. Por enquanto.

Nas andanças  pela net, me deparei com Pascal para AVR, encontrei o Mikropascal e o E-LAB AVRco.

Tenho instalado o segundo; fiquei na dúvida se o Mikropascal tem uma versão gratuita que possa ser usada.

A questão é: Vale a pena aprender  programar em Pascal os AVR's?.

A minha intenção  é de aprender a usar o Bascom, Pascal AVR e depois  aprendo o C. Nada para comércio, apenas algumas coisas úteis, e, não morrer sem aprender programação.

Agradeço a quem der  algumas informações.

Link para o comentário
Compartilhar em outros sites

@t32df ,

 

Bem vindo ao mundo dos microcontroladores !

 

Eu diria o seguinte :  dificilmente esse Pascal para Avr possui suporte para um monte de particularidades existentes na nova família dos Xmegas. E creio que terá dificuldade em encontrar soluções para eventuais problemas que você encontre.

 

Acho que você deve ir do Bascom para o C, ou para a linguagem do Arduino, vai encontrar muita gente para dividir suas experiências.

 

O Bascom é fantástico para quem conhece eletrônica suficiente para ler um datasheet de um componente e sair “conversando” com ele. E isso não é o caso da grande maioria dos programadores, que preferem usar bibliotecas existentes para isso.

 

Creio que o grande sucesso dos Arduínos se devem às milhares de bibliotecas existentes, ajuda muito a quem quer fazer alguma coisa legal mesmo sem conhecer a fundo o funcionamento.

 

Mande bala, a diversão é garantida !

 

Paulo

 

  • Curtir 1
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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!