segunda-feira, 21 de julho de 2014

Módulo PWM do PIC16F886

As funções utilizadas no modulo pwm serão descritas abaixo:

    setup_timer_2(mode, period, postscale):

Esta função configura o timer 2 para gerar o período do pwm.

Mode(prescaler): é o divisor do clock do processador, podendo assumir os valores:
  • T2_DISABLED
  • T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16

Period(PR2):Diferente do timer0 este é o valor de contagem máximo para ocorrer o overflow do timer, assim a contagem ocorre de 0 até PR2. Sendo um valor de 8 bits, decimal de 0 a 255.

Postscale: é um número de 1 à 16 que determina quantos overflows de temporizador deve ocorrer antes de uma interrupção: (1 significa uma vez, 2 significa duas vezes, uma assim por diante).(Não utilizado no calculo do periodo do pwm).

Para tanto a equação abaixo é utilizada para calcular o período da frequência do pwm.


    setup_ccp1(CCP_PWM):

Esta função configura o pino ccp1 como saída do pwm. Ver no datasheet a qual pino se refere.

    set_pwm1_duty (value):

Escreve o valor de 10 bits para o PWM para definir o duty cycle. Para tanto a equação abaixo define o valor do duty cycle.(Value deve ser um valor long).

CÓDIGO TESTADO:

#include <16f886.h>         // identifica microcontrolador alvo


#use delay (clock=8000000) // colocar internal ao inves de clock para oscilador interno
#fuses INTRC, NOWDT, NOPROTECT, NOBROWNOUT,PUT


void main()       // função principal
  {
    setup_oscillator(OSC_8MHZ);//somente chip com oscilador OSCCON   
   
    setup_timer_2(T2_DIV_BY_16, 124, 1);//aqui é configurado o periodo do pwm
    setup_ccp1(CCP_PWM);//porta ccp1 configurada como pwm
    set_pwm1_duty(100L);//duty cycle configurado para 20%, o L após o 100 é para   
                                 //definir o valor como Long
    
  while(1)         // para repetir bloco. Laço infinito.
    {
      
    }
  }

A partir do código acima, pode ser feito o calculo do periodo do pwm do mesmo, como é mostrado abaixo:

Seguindo, pode ser calculado o duty cycle do código acima, como mostra abaixo:


Atenção para o fato de que não há nada dentro do laço while, ou seja, sua rotina principal está sendo executada livremente enquanto o trecho acima gera o sinal de pwm.

Assim a forma de onda adquirida do pino ccp1 é mostrada na figura 1 abaixo:




Saída AC Isolada

Neste post, vamos utilizar os CIs MOC3011 e BT136 com a finalidade de se obter uma saída Ac opto isolada do circuito lógico.


Conforme imagem, o circuito é composto por 3 conectores, onde em P1 é ligado ao microcontrolador, P2 aos terminais da carga e P3 na entrada de rede elétrica AC.
O circuito funcionando da seguinte maneira:
Quando há sinal em P1 o emissor de luz do moc3011 emite, assim o foto-diac conduz fazendo que tenha corrente no gate do triac e este entra em condução e alimente a carga. Como pode se verificar o circuito utiliza a própria alimentação AC para se ter a corrente do foto-diac e gate do triac, se tendo como principal limitador de corrente no gate o resistor R2. 
R3 e C1 são utilizados como snubber para o acoplador para se amenizar o efeito de dv/dt e auxiliar no disparo quando a entrada Ac estiver passando por 0V.

Datasheet para o Optoacoplador: Clique aqui.
Datasheet para o Triac: Clique Aqui.

Este circuito foi montado e testado com uma tensão de 227V e uma carga de 60W.

Conversor DA por rede R-2R

Um DAC(Digital-to-Analog Converter) é um circuito eletrônico capaz de converter uma grandeza digital (por exemplo um código binário) em uma grandeza analógica (normalmente uma tensão).
Entre os conversores DA, chamamos a atenção para a escada de rede R/2R, que provê um recurso simples para converter informação digital para uma saída analógica. Apesar de ser simples em questão de funções e design, usando resistores em uma rede de escada R/2R para uma aplicação real requer atenção para como o dispositivo é especificado. Erros de saída causados pelas tolerâncias de resistores são muitas vezes negligenciados no design. Recomendamos o uso de resistores de precisão.
Neste experimento proposto, utilizaremos apenas 3 pinos do microcontrolador para comandar um conversor DA de 8 bits. Para isso, utilizaremos o shift register 74HC595 que você encontra um datasheet neste link.
A alimentação do operacional deve ser 12V ou maior. O nível lógico alto do shift register deve ser 5V para que a saída máxima do DA seja 10V. 
Abaixo, a equação de saída do conversor proposto:

Utilizarei uma biblioteca desenvolvida para o 74HC595 que será assunto de uma outra postagem. Para este post, precisamos entender apenas a função send_out_74hc595(tamanho,dado). Com está função, conseguimos escrever até oito bits da saída do deslocador, conforme a palavra "dado".

No arquivo do final do post há a simulação do Proteus. Eu montei este mesmo circuito na protoboard e consegui erros abaixo de 2% na saída. Atenção para o fato que eu não utilizo cristal, apenas o oscilador interno do PIC, configurado no inicio do programa
   setup_oscillator(OSC_8MHZ)
Circuito:


No programa exemplo, escrevo constantemente o valor 100 no 595, que equivale a 3,9V na saída. 
Esta tensão é dada pela equação:

No link abaixo, você baixa meu código completo e a simulação no Proteus 8.1.




domingo, 20 de julho de 2014

Firmware para cubo de LED's.

Olá pessoal, voltamos a falar sobre o Cubo de LED's, mas hoje não vamos abordar aquilo que se chuta (Hardware) , mas sim aquilo que se ofende com palavras de baixo calão (Software), segue trecho de código para PIC18F242 que contaremos a seguir:

#include <18f242.h>
#include <stdio.h>
#use delay (clock=400000)
    
     int a, b, c, d;
    
     void linha( ){  
    
     b=0b00001;
     for(a=0; a<5; a++){
              d=c & b;
              if(d>0){                
                      output_high(pin_b7); //dado
                      delay_ms(1);
                      output_high(pin_b6); //clock  
                      delay_ms(1);
                      output_low(pin_b6);  //clock    
                      delay_ms(1);                 
                      }else{
              output_low(pin_b7);  //dado
              delay_ms(1);
              output_high(pin_b6); //clock
              delay_ms(1);  
              output_low(pin_b6);  //clock
              delay_ms(1);
}
              if(a==0){b=0b00010;}
              if(a==1){b=0b00100;}
              if(a==2){b=0b01000;}
              if(a==3){b=0b10000;}      
              }                                             
}

     void coluna( ){
          output_c(0b11111110);
          delay_ms(1000);
          output_c(0b11111101);
          delay_ms(1000);
          output_c(0b11111011);
          delay_ms(1000);
          output_c(0b11110111);
          delay_ms(1000);
          output_c(0b11101111);
          delay_ms(1000);
          output_a(0xff);  // desliga todo PORTA  
}
    
     void t( ){
     c=0b11111;
               linha( );
     c=0b00100;
               linha( );
     c=0b00100;
               linha( );
     c=0b00100;
               linha( );
     c=0b00100;
               linha( ); 
               coluna( );
}              
     void e( ){
     c=0b11111;
               linha( );
     c=0b00001;
               linha( );
     c=0b11111;
               linha( );
     c=0b00001;
               linha( );
     c=0b11111;
               linha( ); 
               coluna( );          
}
     void s( ){
     c=0b11111;
               linha( );
     c=0b00001;
               linha( );
     c=0b11111;
               linha( );
     c=0b10000;
               linha( );
     c=0b11111;
               linha( ); 
               coluna( );
}               
     void main( ){
        
     output_a(0x00);  // desliga todo PORTB
     output_b(0x00);  // desliga todo PORTB
     output_c(0xff);  // desliga todo PORTA
                      output_high(pin_b7); //bit erro
                      delay_ms(1);
                      output_high(pin_b6); //clock  
                      delay_ms(1);
                      output_low(pin_b6);  //clock    
                      delay_ms(1);  
     

     while(true){  
          
                      t( );
                      e( );
                      s( );
                      t( );
                      e( );

     }
}

                            
Lembro que este programa acima é apenas para teste, existem métodos para tornar o código mais "simples", mas para a nossa finalidade este serve. Vamos em partes agora, primeiramente declaramos as variáveis globais que serão usadas (Repito que este código é didático, de preferência sempre se se exclui a opção de variável global) , em seguida temos as "void's" (trechos de sub-rotina do programa principal) que executarão as seguintes funções:

void linha( ): Pega a informação contida em cada linha declarada para formar a imagem (No nosso caso letra) e transforma em uma informação serial que será jogado para nosso barramento serial/paralelo (Comentado na postagem anterior sobre o assunto).

void coluna( ): Desloca a imagem formada na primeira "face" (Também comentado na postagem anterior sobre o assunto) para as "faces" posteriores, deslocando a imagem (Área) dentro do cubo.

void "t,e,s"( ): Como o próprio nome sugere, estas "void's" geram as faces correspondentes aos caracteres T,E,S para formar a palavra "TESTE", vale ressaltar que este software não gera uma imagem tridimensional, apenas gera letra por letra e as deslocam da parte frontal para a posterior do cubo, para podermos ver o cubo trabalhando. Optei por destrinchar a "face" em linhas pare ser mais visível o conceito de construção da mesma e por ocupar menor espaço de memória, notem que apesar de estar dividido em cinco linhas cada letra na verdade a informação de saída será um único trecho de código serial. A imagem a seguir  talvez ajude a visualizar:

Notem que a sequencia de linhas forma a letra "T" que queremos gerar e em seguida chama a função "coluna" para deslocar esta letra por dentro do cubo.

void main( ): Inicializa o barramento e implementa o "loop" que escreverá a palavra "TESTE" no nosso cubo de LED's.

Voltando ao hardware, não entrei em detalhes mais relevantes porque o circuito é genérico, depende da aplicação e das dimensões que queira produzir o cubo, porem não foge do material básico, um controlador (um "PIC", por exemplo, com uma ROM de no mínimo 7KB), um conversor serial/paralelo (Aconselho que possua "Buffer") como o "STP16CP05", uma fonte 12Vdc, muitos LED's e uma estrutura mecânica.

Espero que tenham gostado, uma grande abraço.


quinta-feira, 17 de julho de 2014

Controle Remoto com Arduino

Para este projeto, utilizaremos o seguinte kit, que você encontra tanto no DX quanto no Aliexpress:

http://www.dx.com/p/ir-receiver-module-wireless-remote-control-kit-for-arduino-1-x-cr2025-135520


A pinagem do receptor você pode ver abaixo:

O hardware, como você pode ver é extremamente simples. O sensor utiliza apenas um pino para comunicar com o Arduino.

Para decodificar o sinal do controle, é necessário instalar uma biblioteca (ou então deixar o arquivo na mesma pasta que seu programa, conforme farei).
O software abaixo recebe o sinal do controle e imprime na serial o que foi recebido. Perceba que no início do programa eu defino o pino 11 como o pino onde o sinal do receptor infravermelho estará ligado.


#include "IRremote.h"  
  
int RECV_PIN = 11;  
float armazenavalor;  
  
IRrecv irrecv(RECV_PIN);  
decode_results results;  
  
void setup()  
{  
  Serial.begin(9600);  
  irrecv.enableIRIn(); // Inicializa o receptor IR  
}  
   
void loop()  
{  
  if (irrecv.decode(&results))  
  { 
    Serial.print("Valor lido : ");  
    Serial.println(results.value, HEX);  
    irrecv.resume(); //Limpa a flag para ler o próximo valor 
  } //condição true quando algum botão do controle é pressionado  
}  


Meu software, incluindo a biblioteca utilizada, se encontra no link abaixo:


terça-feira, 15 de julho de 2014

Transformar fonte de PC em fonte de Bancada

Uma fonte de bancada com uma potência razoável chega a custar mais de R$1000. Para quem é hobbista, este valor é proibitivo, porém uma fonte é necessária para quem deseja se aventurar no mundo da eletrônica.
Uma fonte de computador simples consegue fornecer mais de 20A em suas linhas de +5V e +12V, então é uma excelente opção de baixo custo para se ter na bancada.

1º Passo - Identifique os cabos:

Existem fontes com 20 e com 24 pinos em seu conector principal, abaixo está identificado cada cabo e sua tensão:

O fio branco (-5V) não está presente em todas as fontes.

2º Passo - Abra a fonte e remova o excesso de fios. Mantenha apenas uns 3 fios pretos (GND), 2 vermelhos (+5V), 2 amarelos (+12V), 2 laranjas (+3V3) e o fio azul (-12V).
Corte o fio roxo (standby) e o fio cinza, pois estes nãos serão necessários. Em algumas fontes, há também um feedback para saber se a fonte está no nível de tensão correto na saída, este fio é marrom. Normalmente, ele está ligado a saída de +3.3V, se este for o caso, deixe os dois fios ligados dentro da caixa da fonte.

3º Passo - Se sua fonte possuir chave liga/desliga, coloque em curto os fios preto e verde (PS_ON). Estes fios devem estar em curto para que a fonte funcione fora do computador. Caso não tenha chave na sua fonte, adicione uma chave nos fios verde e preto para que seja possível ligar e desligar.

4º Passo - Coloque bornes banana na sua fonte e está pronta para uso.

Se você possuir o mínimo de habilidade manual, seu resultado final será superior a esse:





Cubo de LED's

Para quem esta começando na área da eletrônica digital e quer um desafio que vai agregar conhecimento ao currículo, um protótipo bacana para fazer tanto Hardware quanto Software são os cubos de LED's. O principio é muito simples, através de uma saída serial se escreve um trecho de código binário que passará por um conversor serial/paralelo, cada saída desse conversor será um pixel de uma área plana que formará a  fatia do objeto tridimensional que queira criar o restante é magia! 
Através de um conjunto de transistores em coletor aberto acionados pelo mesmo controle que constroem o trecho de código binário se cria um conjunto de "faces", todas essas faces terão em comum o pino de saída do conversor serial/paralelo, em outras palavras o controle de acionamento do "pixel01" da primeira face controlará todos os outros "pixel01" das demais faces porem esse pixel só será ligado quando o transistor que controla a face for acionado, assim a alimentação do conjunto de faces é multiplexada, ou seja, nenhuma dessas faces, das quais o conjunto forma a região tridimensional, ligará ao mesmo tempo, elas serão acionadas alternadamente e entre o tempo de uma face apagar e a outra ligar se atualiza a informação serial, assim quando a face é acionada ela já esta com a informação certa para acionar os pixels que criarão a segunda fatia, eu sei que neste ponto já deve estar sentindo aquela farpa na sua mente, mas já esclareceremos o mistério.

A  imagem acima é o que chamamos de face, observe que a esquerda temos nosso transistor de controle para a alimentação, vale lembrar que são muitos LED's, portanto leve em consideração que passará uma galera de elétrons por ele quando a face for acionada então para conter a fumaça é interessante calcular que guerreiro (transistor) aguenta essa corrente toda. Bom, como a dimensão desta face é de 5x5 ({5 LED's por linha} X {5 linhas}) vamos imaginar que nossa imagem tridimensional é formada por 5 dessas faces e no momento que seu controle envia uma informação binária ao seu conversor serial/paralelo que coloque o LED0 (primeiro superior a esquerda, batalha naval agora ¬¬) em alta todos os LED's de mesma posição que estão nas outras faces também ficarão em alta (Se esta for a face 1, o LED0 da face 2, 3, 4 e 5 também recebem o mesmo sinal) porem eles não acionarão graças ao guerreiro a esquerda (transistor) que os mantem sem alimentação, portanto a imagem que queremos reproduzir aparecerá apenas nessa face. Quando precisamos acender a próxima face derrubamos o sinal na base do transistor de controle, atualizamos a informação da serial para que a nova imagem seja criada, e acionamos a base do transistor da face seguinte e assim por diante. O segredo fica nas mãos da frequência, o tempo que levará para as 5 faces criarem as imagens que em conjunto geram um espaço tridimensional e sua próxima atualização, por exemplo; Buumm, seu cubo de LED's gerou um cubo, volte 2 casas, brincadeira, vou mostrar nas imagens a seguir:

Faces:
Que sobrepostas geram:

Maoooeee, um monte de pontinhos, vou colocar em evidencia:

Vele lembrar que esta projeção não esta parada, é um ciclo em que a serial escreve, a face 1 liga, face1 desliga, serial escreve, face 2 liga, face dois desliga, serial escreve e assim por diante, até a quinta face aparecer, apagar e voltar a face 1 para repetir o processo, geralmente com uma frequência entre 50 e 60 Hertz, ou seja, o cubo é gerado entre 50 e 60 vezes por segundo. Isto para uma imagem parada, existe métodos de fazer animações incríveis com esta técnica, só é necessário um Hardware como mostramos aqui, uma boa base de programação e noção de espaço além de uma ponta de imaginação para gerar esses efeitos tridimensionais com cubos de LED's, não é barbada, afinal o mundo não é um morango gurizada, mas vale a pena para aumentar suas habilidades na eletrônica. E aqui já lanço o lema que nos seguira nesta página, se não pegou fogo, tá valendo. Em seguida estaremos dando algumas dicas quanto ao software, espero que tenham gostado, um grande abraço.

Segui um vídeo para mostrar o bicho funcionando, ressalto que este não é nosso, mas serve para ter uma noção ;)