17 de jul. de 2012

Relógio LCD com números grandes

Durante o desenvolvimento do projeto de um robô de sumô para a disciplina de projeto integrado II do curso de Engenharia de Controle e Automação, me deparei com a necessidade de mostrar informações numa tela de LCD caractere de 20X4, porém uma grande limitação destes displays facilmente encontrados a venda no comércio é o tamanho efetivo do caractere.

Pensando nisto busquei um artigo que havia me deparado na internet, em que o programador utilizava mais de um caractere para a construção dos dígitos a serem exibidos. O artigo em questão pode ser visto aqui.

Utilizando a técnica descrita anteriormente, aqui mesmo neste blog  foram criados alguns caracteres especiais que formam os dez algarismos utilizados para a criação deste relógio que apresento hoje a vocês.

Caracteres Especiais

A junção de quatro destes caracteres especiais formam um numeral decimal que ocupa o lugar de seis caracteres do display com exceção dos dois últimos caracteres que formam os pontos para divisão dos dígitos do relógio.

Para a base de tempo utilizamos o RTC PCF8583 contido na placa PK2Lab, que nos retorna de forma serial as informações referentes a hora, minutos e segundos e ainda gera um sinal de clock de 1Hz  para a atualização dos dados no display a cada segundo.

O microcontrolador escolhido para este exemplo é o PIC18F4520, por ser o microcontrolador escolhido pela Microchip como substituto natural ao PIC16F877 sendo a pinagem totalmente compatível com os microcontroladores da linha 16F, portanto os pinos de comunicação I2C também seguem esta regra, consequentemente a placa tem que estar com os jumpers na posição 16F e não na posição 18F como usual.

1

Os pinos de enables dos leds devem estar dasabilitados para não influenciarem na comunicação serial I2C.

O programa foi desenvolvido utilizando a ferramenta MikroC PRO e foi baseado no código exemplo do RTC que acompanha a placa, apenas foram feitas algumas modificações para a inserção do código que gera os caracteres maiores no LCD.

Para este projeto foi utilizado o oscilador interno de 8MHz do microcontrolador, é importante observar que por default o microcontrolador opera com uma frequência de 1MHz e é necessário que sejam setados dois bits do registrador OSCCON para configurar a frequência de 8MHz.

OSCCON.B5 = 1;            // Ajusta oscilador interno para 8MHz
OSCCON.B4 = 1;            // Ajusta oscilador interno para 8MHz

Foram criadas algumas funções para conversão e exibição dos números no LCD.

void Caracter_Especial()         

Cria os caracteres especiais na CGRAM do display LCD

void Converte_Numeros(char numero,char lin, char col)

Efetua a conversão dos numeros do RTC para os digitos grandes

void Display_Time()

Mostra os digitos na tela do display LCD

void ZERO(char linha, char coluna)

Prepara os caracteres especias para exibição dos digitos grandes

void PONTOS(char linha, char coluna)

Prepara os caracteres especiais para exibição dos pontos


O resultado pode ser visto abaixo:

DSC00926

 

 

Código do projeto

19 de jun. de 2012

Conversor Digital Analógico R2R

 

Conversores Digitais

Durante muito tempo fiquei intrigado com a eletrônica no que diz respeito a conversão de grandezas entre o mundo real e o mundo digital. No mundo real, as grandezas podem ser analisadas de forma contínua, já no mundo digital, onde temos a representação de grandezas em formado binário (temos apenas bits que podem valer 0 ou 1) estas grandezas devem ser discretizadas, ou seja, tanto o tempo (amostragem) quanto a amplitude (quantização) devem ser analisados.

O processo de amostragem do sinal consiste em obter instantâneamente o valor do sinal a ser processado em intervalos regulares, sendo que a frequência destes intervalos definem a taxa de amostragem do conversor.

Para que a resposta de um conversor digital possa ser substâncialmente eficiente em relação a entrada (conversor AD) ou a saída (conversor DA), se faz necessário que se respeite o teorema de Nyquist, que diz que a frequência de amostragem deve ser de pelo menos duas vezes maior que a maior frequência a ser amostrada. Um exemplo prático da aplicação desta teoria pode ser observada em aparelhos reprodutores de CD em que normalmente se informa a taxa de seu conversor interno que é de 44100Hz, ou seja mais de 2 vezes a maior frequência audível ao ser humano que está na faixa dos 20000Hz.

Harry Nyquist (1889–1976)

Harry Nyquist (1889–1976)


Conversor DA R2R

Neste projeto vamos efetuar a implementação de um conversor Digital Analógico utilizando um método muito eficiente de conversão que utiliza apenas dois valores de resistores, facilitando a construção e calibração do mesmo. Este conversor pode ser montado em um protoboard resistor por resistor ou comprado em um único package já contendo todos os resistores devidamente ajustados, este componente é conhecido como rede R2R. (R2R network)

Bourns-4610X-R2R-103LF

A placa PK2Lab, possui conectores de expansão que possibilitam a conexão de placas externas, como por exemplo a placa fornecida pela Mikroelektronica que consiste um em conversor DA R2R completo que pode fornecer uma corrente máxima de 20mA em sua saída.

Placa

Nesta placa podemos observar a utilização de resistores de dois valores distintos, sendo 47K e 100K representando respectivamente R e 2R conforme o esquema abaixo:

Esquema

Pode-se observar ainda a utilização de um amplificador do tipo Rail-to-Rail da Microchip operando como buffer de saída, está etapa pode ser obtida à partir de um simples amplificador operacional.

buffer

A vantagem de se utilizar amplificadores do tipo Rail-to-Rail, é o fato de a saída do sinal poder trabalhar praticamente no limite dos níveis de alimentação do operacional, isto é muito bem vindo quando trabalhamos com tensões de 3V por exemplo.

Até aqui temos o nosso hardware do conversor DA implementado, e para demonstrar o funcionamento do mesmo na prática, vamos gerar uma forma de onde senoidal podendo servir de base para um gerador de funções digital.

Para tanto, vamos utilizar uma tabela no microcontrolador que conterá os valores a serem aplicados na rede R2R do conversor DA para obtenção da senoide.

Esta tabela pode ser gerada contendo todos os pontos que formam a senoide completa de 0 a 2 pi de forma direta ponto a ponto, como mostrado no programa picseno1, ou utilizando a função de cosseno para gerar metade da senoide, sendo a outra metade é obtida através do espelhamento da primeira que será apresentada implementado no programa picsen2.

 

coseno

Função Cosseno

seno

Função Seno obtida da junção da função cosseno direta e espelhada

 

A função cosseno que será usada para criar a tabela pode ser implementada no MikroC PRO utilizando uma função interna do compilador.

cosE3 (ângulo em graus)

Esta função retorna o valor do cosseno do ângulo passado como parâmetro multiplicado por 1000 e arredondado para um valor inteiro aproximado. Exemplo: cosE3(45) resulta em 707 que corresponde a 0.707 valor do cosseno de 45°.

Para definir a frequência de saída do gerador, podemos utilizar a fórmula abaixo que leva em consideração a quantidade de pontos de amostra e a frequência desejada para definirmos o tempo de delay para a amostragem do sinal.

Valor_Delay = 1/(frequência * 360)

Como utilizamos 360 pontos para criar a nossa forma de onda, obtivemos um resultado muito bom, mesmo sem a utilização de filtro passa baixa na saída.

Fotos do projeto:

foto (2)

foto (1)

 

 


Programa picsen1.c

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

                      JL Audio Manutenção Eletrônica

Data: Junho 2012
Autor: Jean Carlos
Projeto: Gerador Senoidal
Microprocessador: PIC18F4550
Clock do processador: 48MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual:
Descrição:

          Gerador de sinal senoidal utilizando tabela de referencia


*******************************************************************************/
// Inicializações do programa

// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

//******************************************************************************
// Variáveis Globais

char amostra;
char tabela_Seno[] =
{127, 130, 133, 136, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173,
176, 179, 182, 185, 187, 190, 193, 195, 198, 201, 203, 206, 208, 211, 213, 215,
217, 220, 222, 224, 226, 228, 230, 232, 233, 235, 237, 238, 240, 241, 242, 244,
245, 246, 247, 248, 249, 250, 251, 252, 252, 253, 253, 254, 254, 254, 254, 255,
255, 254, 254, 254, 254, 253, 253, 252, 252, 251, 250, 250, 249, 248, 247, 246,
244, 243, 242, 240, 239, 237, 236, 234, 232, 231, 229, 227, 225, 223, 221, 219,
216, 214, 212, 209, 207, 204, 202, 199, 197, 194, 191, 189, 186, 183, 180, 177,
175, 172, 169, 166, 163, 160, 157, 154, 150, 147, 144, 141, 138, 135, 132, 129,
125, 122, 119, 116, 113, 110, 107, 104, 100, 97, 94, 91,88, 85, 82, 79, 77, 74,
71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 42, 40, 38, 35, 33, 31, 29, 27, 25,
23, 22, 20, 18, 17, 15, 14, 12, 11, 10, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 16, 17,
19, 21, 22, 24, 26, 28, 30, 32, 34, 37, 39, 41, 43, 46, 48, 51, 53, 56, 59, 61,
64, 67, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96,99,102, 105, 108, 111, 114, 118,
121, 124, 127 };

//******************************************************************************
//Rotina Principal


void main()
{
TRISA     = 0b00000000;
PORTA   = 0b00000000;
TRISB     = 0b00000000;
PORTB   = 0b00000000;
TRISC     = 0b00000000;
PORTC   = 0b00000000;
TRISD     = 0b00000000;
PORTD   = 0b00000000;
TRISE     = 0b00000000;
PORTE   = 0b00000000;
ADCON1 = 0X0F;                                           // Entradas digitais.

Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"Gerador Senoidal");

while(1)
{
  for(amostra = 0; amostra <= 256; amostra++)
     {
     PORTD = Tabela_Seno[amostra];
     delay_us(65);                                       // Delay = 1/(Freq*256)
     }                                                   // Para 60Hz --> 1/(60*256) = 65us
}
}


Programa picsen2.c

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

                      JL Audio Manutenção Eletrônica

Data: Junho 2012
Autor: Jean Carlos
Projeto: Gerador Senoidal 60Hz
Microprocessador: PIC18F4550
Clock do processador: 48MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual:
Descrição:

          Este circuito gera uma senoide de 60Hz com 180 Amostras


*******************************************************************************/
// Inicializações do programa

// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

//******************************************************************************
// Variáveis Globais

char sample;
char array[181];

//******************************************************************************
//Rotina Principal


void main() {
TRISA     = 0b00000000;
PORTA   = 0b00000000;
TRISB     = 0b00000000;
PORTB   = 0b00000000;
TRISC     = 0b00000000;
PORTC   = 0b00000000;
TRISD     = 0b00000000;
PORTD   = 0b00000000;
TRISE     = 0b00000000;
PORTE   = 0b00000000;
ADCON1 = 0X0F;                                                           // Entradas digitais.

Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"Gerador Senoidal");
Delay_ms(1000);
 
  for (sample = 0; sample <= 180; sample++)                   // 181 amostras de 0 a pi
  {                                                                                
    array[sample] = (255l * (1000 + cosE3(sample)))/2000;

  }

  while(1)
  {
    for (sample = 0; sample <= 180; sample++)                 // Amostras de 0 a pi
    {

      PORTD = array[sample];                                          // Delay = 1/(Freq*360)
      Delay_us(46);                                                          // Para 60Hz 46.29us

    }
        
    for (sample = 179; sample > 0; sample—)                    // Amostras de pi a 2pi
    {
      PORTD = array[sample];
      Delay_us(46);
    }
  }
}

29 de abr. de 2012

Teclado Matricial

 

Dentre as várias maneiras de interagirmos com o hardware em uma IHM (Interface Homem Máquina) uma das formas mais comuns é através do pressionamento de chaves e botoeiras para que o programa possa então executar uma tarefa específica.

Hoje vamos interfacear um teclado matricial, como o encontrado em telefones celulares e calculadoras, onde temos várias chaves conectadas ao microcontrolador de maneira eficiente a fim de não despediçarmos pinos do hardware.

foto

Para efetuar a conexão de uma tecla ao microcontrolador, podemos citar a maneira mais simples que utiliza apenas uma tecla e um resistor de Pull-up ou Pull-down conforme o nível de tensão que desejarmos quando ocorrer o pressionamento da tecla.

Chave HI-LO_1

Porém nesta configuração precisamos um pino para cada tecla conectada ao microcontrolador, o que caracteriza o desperdício de hardware, porém isto pode ser resolvido  com  implementação de uma simples matriz, onde conseguimos maximizar a utilização dos pinos de forma eficiente.

No esquema abaixo podemos observar a utilização das linhas e colunas que formam a matriz.

 

Capturar

 

O número máximo de chaves para esta implementação pode ser obtida através da equação abaixo:

                 N°teclas = Colunas x Linhas

O funcionamento do teclado matricial consiste em energizar apenas uma única linha por vez e efetuar a leitura das colunas para verificar o pressionamento de alguma das teclas, quando detectado um nível alto em alguma das colunas durante o rastreamento se torna possível a identificação da tecla pressionada. Para que não haja erros de leituras durante este processo, se faz necessário o uso de resistores de pull-down para garantir um nível baixo nas colunas que não estão sendo ativas pelo pressionamento de tecla.

Função para escaneamento de teclado

Para efetuar a leitura do teclado matricial, vamos criar uma função que retornará o valor da tecla pressionada em hexadecimal ou o valor 0xFF caso nenhuma tecla tenha sido pressionada.No nosso exemplo utilizaremos um teclado matricial de [4x3] que foi adquirido através do site www.goodluckbuy.com.

Assim que a função é chamada, colocamos um nivel alto na primeira linha e efetuamos a leitura das quatro colunas, caso alguma coluna responda nivel alto, retornamos da função com o valor correspondente a matrizagem, vejamos como fica o código:


#define Coluna_1  PORTD.B0
#define Coluna_2  PORTD.B1
#define Coluna_3  PORTD.B2

#define Linha_1    PORTD.B6
#define Linha_2    PORTD.B5
#define Linha_3    PORTD.B4
#define Linha_4    PORTD.B3

char Le_Teclado()         // Função que efetua a leitura do teclado matricial
{
Coluna_1 = 1;
Coluna_2 = 0;
Coluna_3 = 0;
Delay_ms(1);
if(Linha_1) return 1;
if(Linha_2) return 4;
if(Linha_3) return 7;
if(Linha_4) return 10;
 
Coluna_1 = 0;
Coluna_2 = 1;
Coluna_3 = 0;
Delay_ms(1);
if(Linha_1) return 2;
if(Linha_2) return 5;
if(Linha_3) return 8;
if(Linha_4) return 0;
 
Coluna_1 = 0;
Coluna_2 = 0;
Coluna_3 = 1;
Delay_ms(1);
if(Linha_1) return 3;
if(Linha_2) return 6;
if(Linha_3) return 9;
if(Linha_4) return 11;
 
return 255;
}


Este código  mostra como efetuar uma leitura “simples” do teclado matricial, porém dependendo do hardware utilizado pode apresentar problemas de estabilidade efetuando leituras falsas ou deixando de apresentar um pressionamento.

MikroC PRO

O compilador MikroC PRO, possui internamente uma biblioteca própria para uso com teclados matriciais e que torna o processo de escaneamento uma tarefa simples. Podem ser utilizadas as configurações [4x1] , [4x2] , [4x3] ou [4x4].

Keypad_Init()

Efetua a inicialização do teclado matricial, esta função requer que seja declarado anteriormente uma variável chamada keypadPort que define o PORT onde será conectado o nosso hardware do teclado.

char keypadPort at PORTD;  

Keypad_Key_Press()

Efetua a leitura de uma tecla pressionada, retornando o valor da tecla (1 –16) ou 0 caso nenhuma tecla seja pressionada.

Keypad_Key_Click()

Efetua a leitura de uma tecla pressionada, retornando o valor da tecla (1 –16) ou 0 caso nenhuma tecla seja pressionada, porém é uma função com propriedades de bloqueio, ou seja, quando chamada, aguarda o pressionamento da tecla, bloqueando o processo do programa durante a espera do pressionamento da tecla.

Notem que esta biblioteca do MikroC PRO, embora nos ajude a interfacear o teclado não retorna o valor direto das teclas e sim a posição dela na matriz.

Vejamos como ficou o nosso código completo utilizando o compilador MikroC PRO.

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

                            JL Audio – www.esquemas .org

Data: 04/2012
Autor: Jean Carlos
Projeto: Teclado Matricial
Microprocessador: PIC18F4550
Clock do processador: 48MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual: 1.0
Descrição:
                 Implementação de leitura de teclado matricial na
                 placa PK2Lab, através de biblioteca do MikroC PRO.

*******************************************************************************/
// Inicialização do teclado no PORTD

char keypadPort at PORTD;

// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

//******************************************************************************
// Variáveis Globais

char tecla, tecla_antiga = 0;

//******************************************************************************
// Rotinas Auxiliares

//******************************************************************************
//Rotina Principal

void main()
{
TRISA     = 0b00000000;
PORTA    = 0b00000000;
TRISB     = 0b00000000;
PORTB    = 0b00000000;
TRISC     = 0b00000000;
PORTC    = 0b00000000;
PORTD    = 0b00000000;
TRISE     = 0b00000000;
PORTE    = 0b00000000;
ADCON1  = 0X0F;          // Entradas digitais.


Keypad_Init();          // Inicializa o Teclado Matricial

Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,2,"Tecla Press:");
Delay_ms(100);

while(1)
{

tecla = Keypad_Key_Press();      // Efetua leitura do teclado
 
if(tecla != 0)
{
  switch (tecla)                          // Efetua conversão para impressão
      {
      case  1: tecla = 49; break; // 1
      case  2: tecla = 50; break; // 2
      case  3: tecla = 51; break; // 3
      case  4: tecla = 65; break; // A
      case  5: tecla = 52; break; // 4
      case  6: tecla = 53; break; // 5
      case  7: tecla = 54; break; // 6
      case  8: tecla = 66; break; // B
      case  9: tecla = 55; break; // 7
      case 10: tecla = 56; break; // 8
      case 11: tecla = 57; break; // 9
      case 12: tecla = 67; break; // C
      case 13: tecla = 42; break; // *
      case 14: tecla = 48; break; // 0
      case 15: tecla = 35; break; // #
      case 16: tecla = 68; break; // D
      }
  if(tecla != tecla_antiga)       // Atualiza a ultima tecla pressionada
    {
    tecla_antiga = tecla;
    }
  Lcd_Chr(2,15,tecla);            // Imprime a tecla pressionada no LCD
}
}//while(1)
}//main


Abaixo o vídeo do projeto funcionando!

Bom projetos a todos e até a próxima!

1 de abr. de 2012

Sensor Ultra-Sônico


Sensores de ultra som são componentes muito úteis no desenvolvimento de projetos microcontrolados por serem fáceis de implementar e ter uma resposta linear diretamente proporcional a distância em que se encontra de um determinado objeto.
Veremos agora como funciona o sensor de ultrasom DYP-ME007 que pode  ser adquirido diretamente da China através do site www.goodluckbuy.com

Sensor ultra1

O Sensor de ultrasom pode detectar objetos a distâncias que variam entre 2 e 350cm de distância com uma precisão de 3mm, sendo que o modelo testado retornou uma precisão de 2mm.
A detecção de distância é feita através do disparo de um pulso de nível alto com duração de 10us no pino de Trigger do sensor, assim que ele detectar este sinal, emite uma sequencia de 8 pulsos na frequência de 40KHz, frequência esta que define o termo Ultra-sônico utilizado na nomenclatura. Após este som emitido “Bater” em algum objeto, retorna e é capturado pelo microfone do sensor para processamento das informações.

Sensor

A distância “D” corresponde a real distância do objeto, como o sensor recebe a informação de distância de emissão e recepção, obtêm duas vezes a distância real, como a velocidade do som no ar a temperatura média de 25°C é de 340m/s, facilmente se obtém a relação de distância em milímetros através da equação:
Distância = Velocidade * Tempo
2 * Distância = 340 * Tempo
Distância = 170 * Tempo
 
Todos estes cálculos são efetuados diretamente pelo sensor DYP-ME007 que ao final entrega no pino Echo um pulso ativo correspondente a distância real do objeto como mostra a figura abaixo:
 
Temporização
 
Para se transformar o tempo (us) retornado pelo sensor  em distância(mm), basta dividir valor do tempo por 58.
Este valor é obtido da seguinte relação:
Um metro corresponte a um pulso de aproximadamente 5764us, transformando em cm temos 57,64cm que arredondamos para 58 para facilitar os cálculos no microcontrolador.

Teste de funcionamento.

Este sensor possui quatro pinos de conexão sendo:
VCC – Alimentação de 5V (Consumo médio de 20ma)
GND – Alimentação GND
Trigger- Pino para disparo de leitura (10ms)
Echo – Pino de retorno de informações referente a distância medida
Out – Este pino NÃO deverá ser conectado

Podemos detectar a largura de pulso do sensor de várias maneiras, porém a maneira mais elegante de se fazer isto com microcontroladores PIC, é utilizando o módulo CCP na função CAPTURE.
Para isto temos que conhecer um pouco mais sobre este módulo interno do microcontrolador.
O módulo CCP utiliza os Timers internos do microcontrolador como base de tempo, neste caso específico do modo CCP que é o CAPTURE, é utilizado o TIMER1 incrementando a cada us.
Desta forma quando o módulo CCP detecta a borda alta correspondente ao pino ECHO do sensor, ativa a contagem do TIMER,(incrementeado a cada us) e muda a configuração da borda de sensibilidade para baixa, aguardando assim o término do pulso referente a distância, com isto conseguimos saber qual o período do pulso entrege pelo sensor em já em us.
Após esta informação ser processada temos que alterar novamente a borda de sensibilidade para alta afin de estarmos prontos para uma nova informação proveniente so sensor.
Através do uso deste módulo, trabalhamos apenas com interrupções liberando o microcontrolador para outras tarefas tornando o programa mais eficiente.


Abaixo segue o programa exemplo da placa PK2Lab para uso com estes sensores.
/******************************************************************************
                      JL Audio Manutenção Eletrônica
Data: 01/2012
Autor: Jean Carlos
Projeto: Sensor de distância DYP-ME007
Microprocessador: PIC18F4550
Clock do processador: 8MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual:
Descrição:

          Este projeto demonstra o uso do sensor de distancia DYP-DM007
          Com a placa PK2Lab, o valor referente a distância entre o
          objeto e o sensor é exibido no display LCD.

          Trigger -> RC0
          Echo    -> RC2 -> Entrada do módulo CCP1

          O resultado da captura é salvo em CCPR1H e CCPR1L
          Para efetuar este projeto, iremos configurar o TMR1 como contador
          sincrono,para ser incrementado pela fonte de clock externo que é
          o cristal de 8MHz conectado a placa PK2Lab(Sem PLL).

          8MHz -> (Fosc/4)2MHz -> Prescaler 2:1 -> 1MHz (1uS)
          Para calcular a distancia em centimetros, usamos a formula abaixo:


*******************************************************************************/
// Configuração do LCD da placa PK2Lab V.1.1

sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;


//******************************************************************************
// Definições e  Variáveis Globais

#define Trigger RC0_bit
char txt[4];                  // Usado para conversão de dados em string
char Tempo_H, Tempo_L, Distancia_cm;
unsigned int Periodo;         // Variável que armazena o período do Pulso ECHO

//******************************************************************************
// Funções Auxiliares

void interrupt()
{
if(CCP1IF_bit && CCP1CON.B0)  // Captura por CCP1 e borda configurada como subida...
{
  CCP1IF_bit  = 0;            // Limpa a flag para nova captura
  CCP1IE_bit  = 0;            // Desabilita interrupção por periféricos(CCP1)
  CCP1CON     = 4;          // Configura a borda de captura para DESCIDA. (ESTE EVENTO CAUSARIA INTERRUPÇÃO ERRÔNEA)
  CCP1IE_bit  = 1;            // Habilita interrupção por periféricos(CCP1)
  TMR1H       = 0;             // Zera registradores do TMR1 para contagem de tempo
  TMR1L       = 0;
  TMR1ON_bit  = 1;          // Habilita contagem de tempo.
}

else if(CCP1IF_bit)
      {
       CCP1IF_bit  = 0;        // Limpa a flag para nova captura
       TMR1ON_bit  = 0;      // Desabilita contagem de tempo.
       CCP1IE_bit  = 0;        // Desabilita interrupção por periféricos(CCP1)
       CCP1CON     = 5;      // Configura a borda de captura para SUBIDA. (ESTE EVENTO CAUSARIA INTERRUPÇÃO ERRÔNEA)
       CCP1IE_bit  = 1;       // Habilita interrupção por periféricos(CCP1)
       Tempo_H     = CCPR1H;  // Carrega valores de tempo capturado(Neste caso em us)
       Tempo_L     = CCPR1L;
      }

}
Pulso()                       // Gera o Pulso de trigger para o sensor ultra som.
{
Trigger = 1;
Delay_us(10);
Trigger = 0;
}

//******************************************************************************
//Rotina Principal

void main()
{
TRISC  = 0b00000100;         // Entrada CCP1
PORTC  = 0b00000000;
INTCON = 0b11000000;         // Liga interruptores GIE e PEIE
TMR1IE_bit = 0;              // Desabilita interrpções de TMR1
CCP1IE_Bit = 1;              // Habilita interrupções por CAPTURA(CCP1)
CCP1CON    = 5;              // Configura módulo CCP1 para CAPTURA e borda de SUBIDA.

T1CKPS1_bit = 0;             // Prescaller TMR1 2:1
T1CKPS0_bit = 1;
TMR1CS_bit  = 0;             // Clock selecionado -> OSC/4
TMR1ON_bit  = 0;             // Timer -> 1 = Habilita contagem

Lcd_Init();
Lcd_Cmd(_Lcd_Cursor_Off);
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,1,"***  PK2Lab  ***");
Lcd_Out(2,1,"Distancia:    cm");
Delay_ms(100);

while(1)
{
Pulso();                                 // Dispara leitura de distância.
Delay_ms(100);                     // Intervalo entre leituras.
Periodo = (Tempo_H<<8)+ Tempo_L;   // Obtenção do período relativo ao ECHO
Distancia_cm = Periodo/58;    // Conversão da distância informada para cm

                  //------------------------------------------------------------------------------------//
                  // Um Pulso de 58us corresponde a uma distância de 1cm  //
                  //------------------------------------------------------------------------------------//


// Distância MINIMA 3cm e MAXIMA 3m

if((Distancia_cm < 3)||Distancia_cm >300) Lcd_Out(2,12,"---");
else
    {
    byteToStr(Distancia_cm, txt);   // Converte texto para impressão
    Lcd_Out(2,12,txt);                   // Imprime valores no display
    }
}
}

9 de mar. de 2012

Utilizando outras famílias de microcontroladores Microchip na placa PK2Lab!!!


Hoje vou demonstrar a vocês como utilizar outros microcontroladores da empresa Microchip na placa PK2Lab. A Microchip comercializa uma ampla gama de microcontroladores distribuídos em várias famílias, sendo elas:

PIC10 / PIC12 / PIC16 / PIC18 / PIC24 / DsPIC30 / DsPIC33
 
Todas estas famílias de microcontroladores são suportados pelo gravador contido na placa PK2Lab, bastando apenas interligar os pinos do gravador ao dispositivo de destino.
Para este exemplo irei utilizar um microcontrolador da família PIC12 que dispõe de conversor AD, 5 pinos de I/O e um pino de entrada (GP3) e oscilador interno de 4MHz, que é o PIC12F675.

PIC12F675

Para efetuar a conexão do microcontrolador à placa vamos utilizar alguns cabos de conexão facilmente encontrados a venda nas lojas de componentes eletrônicos e sites como o Mercado Livre  e um Proto-Board que é uma placa para desenvolvimento de projetos que consiste de uma matriz de contatos elétricos.

Placa2

Os pinos da placa PK2Lab responsáveis pela gravação de microcontroladores externos à placa estão identificados como ICSP, que é a abreviação de  In Circuit Serial Programmer. Estes pinos são conectados aos pinos responsáveis pela gravação no dispositivo a ser programado.

ICSP

O esquema elétrico do projeto é mostrado abaixo e consiste basicamente de 4 componentes, sendo uma chave, um LED, um buzzer e o microcontrolador.
Esquema

Todos os componentes, exceto o microcontrolador estão disponíveis na placa PK2Lab e vamos utiliza-lós de maneira bem simples através dos pinos de expansão.

DSC00846

Os conectores contam com a nomenclatura dos pinos referentes ao soquete do microcontrolador ON-BOARD, ou seja, para a utilização correta destes periféricos internos através dos ports de expansão, temos que efetuar uma breve análise no esquema da placa PK2Lab.

Led

Vamos utilizar o led referente ao PORTC pino 0, portanto este led pode ser acessado através do barramento de expansão PORTC B0. Os outros pinos podem ser verificados no esquema elétrico da placa e associados aos respectivos PORT’s.
Como dito anteriormente, todos os pinos estão disponíveis através dos PORT’s de expansão, com exceção de três pinos do PORTE, porém estes três pinos podem ser acessados através do conector ZIF sem maiores dificuldades.

OBS. APENAS UM MICROCONTROLADOR PODE SER UTILIZADO POR VEZ, OU SEJA, AO EFETUAR A CONEXÃO DE DISPOSITIVO EXTERNO, RETIRAR TODO E QUALQUER MICROCONTROLADOR DO SOQUETE ZIF DA PLACA!

Vejamos o resultado do projeto!!!

Placa1

Abaixo segue o código do projeto.

/******************************************************************************
                      JL Audio Manutenção Eletrônica
Data: 03/2012
Autor: Jean Carlos
Projeto: Pisca Led com Chave e Buzzer
Microprocessador: PIC12F675
Clock do processador: 4MHz
Estação de desenvolvimento: PK2Lab V 1.1
Compilador: MikroC PRO V 4.60.0.0
Versão atual: 1.0
Descrição:

          Este projeto visa demonstrar o funcionamento da placa PK2Lab
          com outros microcontroladores da família Microchip, para isto
          vamos utilizar um Proto Board e alguns cabos para conexão
          entre o microcontrolador e a placa.


*******************************************************************************/
// Inicializações do programa

#define LED      GPIO.B5     // Define o LED conectado ao pino 2 (GP5)
#define CHAVE GPIO.B4     // Define a chave conectada ao pino 3 (GP4)

//******************************************************************************
// Variáveis Globais

unsigned int Tempo;             // Variável utilizada para temporização entre piscadas
//******************************************************************************
// Rotinas Auxiliares

//******************************************************************************
//Rotina Principal

void main()
{
TRISIO   = 0b00010000;    // Configura as entradas e saídas
GPIO     = 0b00000000;    // Inicia os pinos todos desligados
ANSEL  = 0b00000000;    // Entradas digitais.


while(1)
{
if(CHAVE)                      // Se a chave for pressionada...
   {
    Tempo = Tempo + 100;             // Incrementa o tempo em 100ms
    if(Tempo > 1000) Tempo = 100; // Limita o tempo máximo

   }
LED = ~LED;                 // Inverte o estado do LED o complementando
                                               
Vdelay_ms(Tempo);                 // gera atraso entre piscadas
}//while(1)
}//main

************************************************************************************************
Grande abraço a todos e bons projetos!!!

20 de jan. de 2012

Curso de Microcontroladores PIC em linguagem "C"


Lançamento!!!


Hoje venho apresentar a vocês o meu mais recente trabalho, uma idéia que se concretizou depois de muito tempo de dedicação e persistência.Trata se do curso de microcontroladores PIC em linguagem "C" baseado totalmente na placa PK2Lab e no compilador MikroC PRO!!!




A proposta inicial deste trabalho era criar um pequeno guia sobre a linguagem C para que as pessoas que adquiriram a placa PK2Lab pudessem rapidamente se familiarizar com os comandos da linguagem, porém, com o uso do compilador MikroC PRO, o resultado ficou melhor do que esperado, resultando em uma apostila muito completa que trata desde o princípio básico de programação incluíndo os laços de repetição e controle de fluxo até o uso de interrupções de Timers e comunicação serial entre microcontrolador e PC. 

São ao todo 13 exemplos de programas comentados linha a linha, o que torna o processo de aprendizagem simples e eficiente, muitos deles implementados em mais de uma maneira para que seja possível a observação das várias formas de escrever o mesmo código.

O conteúdo do curso foi exaustivamente estudado para proporcionar um aprendizado rápido de muitos dos periféricos da placa PK2Lab, incluindo muitas imagens e fórmulas para cálculo de registradores referentes aos Timers e modulo de PWM.

Todos os registradores relacionados as interrupções estão bit a bit comentados em português, facilitando ao máximo o entendimento e configuração deste processo.

Foi inserido um tópico relacionado a criação de novos projetos, sendo efetuado um passo a passo para esclarecer a principal dúvida dos que iniciam o uso do compilador MikroC PRO, que é a etapa de configuração dos Fuse Bits do dispositivo, neste processo é feita a configuração do microcontrolador PIC18F4550 para operar em modo PLL de 48MHz.

Bom pessoal, este curso acompanha a placa PK2Lab, portanto ao adquirir a placa automaticamente receberão uma cópia do mesmo sem custo adicional, aos que tenham interesse em adquirir apenas o curso, podem o fazer através do site www.esquemas.org

A placa PK2Lab a partir de agora será disponibilizada apenas em uma única versão completa com todos os periféricos prontos para uso, e pode ser obtida através do link abaixo.





Bom por hoje é isto, em breve mais novidades e postagems sempre com um conteúdo diferente envolvendo esta fantástica área da eletrônica chamada MICROCONTROLADORES.


16 de jan. de 2012

Caracteres especiais no LCD


Olá galera, ano novo, férias, nada melhor que começar 2012 com um post bacana para dar uma alegrada... E em breve novidades sobre o curso da PK2Lab em C... Aguardem!!!

Hoje vamos conhecer um pouco mais sobre os displays LCDs e aprender a criar nossos próprios caracteres customizados.

Bom, mais qual é a utilidade disto???

Imaginem o quão interessante seria mostrar o valor de uma grandeza, como o valor de tensão correspondente a um sensor, ou mesmo o tempo restante de um processo, em uma escala de barras customizada no display LCD. Para isto podemos utilizar vários caracteres disponíveis na tabela de caracteres do próprio controlador do LCD que contém muitos simbolos interessantes, porém, quando realmente a criatividade aflora, vimos que esta tabela não resolve muita coisa e ai é que entra a criação de caracteres na CGRAM do display.

O Controlador HD44780, possui internamente uma área destinada a criação de 8 caracteres especiais, estes caracteres situam se a partir do endereço 0 da CGRAM e são formados por um conjunto de 8 bytes cada, dispostos a formar a imagem apresentada no LCD.

O compilador MikroC PRO, possui uma ferramenta muito útil para a criação destes caracteres e está localizada na aba Tools -> Lcd Custon Caracter.


 



Vamos utilizar esta ferramenta para criar duas setas laterais que formarão o cursor de ajuste de um sistema de som em que as funções serão ajustadas pelo teclado e os valores poderão ser visualizados em uma barra no LCD.

Para começar a criar nosso caractere, basta clicar nos pontos em que desejamos que o display acenda, até formar a imagem pretendida, assim que terminar, devemos clicar em generate code para que o software gere a função que é responsável pela criação e envio dos dados para a CGRAM do controlador.

Esta ferramenta pode gerar códigos em C, Pascal e Basic, para tanto basta selecionar a linguagem antes de clicar em generate code.

Depois de gerado, o código deve ser inserido como uma função qualquer dentro do programa que ira utilizá-la. Normalmente neste ponto eu altero um pouco este procedimento para facilitar a escrita do código, porém, nada impede de utilizar a função criada pela ferramenta de forma direta.


//**********************************************************************************************************
// Rotinas Auxiliares

const char character1[] = {24,28,30,30,30,28,24,0};  // Seta Esquerda
const char character2[] = {3,7,15,15,15,7,3,0};         // Seta Dir eita

void Caracter_Especial()       // Função que cria os caracteres especiais na CGRAM.    
{
  char i;
    Lcd_Cmd(64);                  // Entra em modo de criação de caracter e...         
    for (i = 0; i<=7; i++) Lcd_Chr_CP(character1[i]);  // Envia os bytes que formam o...
    for (i = 0; i<=7; i++) Lcd_Chr_CP(character2[i]);  // caracter um a um sequencialmente.
}


Para apresentação dos caracteres apenas posicione o cursor do display onde o caracter deverá aparecer e use a função Lcd_Chr_CP(ENDEREÇO DA CGRAM).


Exemplo:

while(1)
{
 Caracter_Especial();         // Chama a função que cria os caracteres na CGRAM.
 Lcd_Out(2,1,"---");
 Lcd_Chr_CP(1);                // Insere seta para esquerda. (Endereço 0 da CGRAM)
 Lcd_Chr_CP(0);               
// Insere seta para direita.    (Endereço 1 da CGRAM)
 Lcd_Out(2,6,"-----------");
 ....

}//while(1)


Veja como fica o resultado:

 
Bom, esta é apenas uma das situações onde os caracteres especiais podem ser utilizados, com o tempo vocês verão como é importante este recurso.

Por falar nisto... alguém já viu um LCD que escreve palavras com acentuação como no bom e velho português??? fica a idéia !!!

Grande abraço a todos...

 EM BREVE...

Curso de microcontroladores PIC em linguagem C !!!