Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
Evertton Laddaga

Controlando motor de passo com potenciometro

Recommended Posts

Sabe programar?

Tem conhecimento em microcontroladores?

Você quer o projeto pronto ou já tem alguma ideia....

Falou

Compartilhar este post


Link para o post
Compartilhar em outros sites
 

Bom, é um projeto interessante.

Veja que com o motor segue o giro do potenciômetro.

Vamos supor o seguinte cenário:

+5V

|

|

|-----AN0

|

|

0V

Temos duas divisões, 2,5V para cima e 2,5V para baixo.

Em um primeiro momento, pensei o seguinte:

No código, ficamos lendo o canal AD o tempo todo. Se a leitura atual for maior que a anterior, o motor gira no sentido do relógio.

Se a leitura atual for menor que a anterior, o motor gira para no sentido anti-relógio.

Como é um motor de passo, podemos dimensionar o tamanho do giro no código com a quantidade de passos.

Eu criaria dois vetores de 4 posições com os valores dos passos. Em um motor de passo de 5 fios, sendo 1 fio o VCC, me resta 4 fios de passos.

Um vetor seria o sentido do giro do relógio e o outro vetor seria no sentido anti-relógio.

Cada vez q eu ler o canal AD e verificar uma variação na leitura para mais ou para menos, chamaria uma rotina para "dar 1 passo" ou "2 passos" ou "quantos passos eu quiser".

Seria algo mais ou menos do tipo.

Falou

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
 

Na forma que você falou de verificar o valor anterior, então sempre eu teria que ficar armazenando esses valores para ter uma referencia de verificação, certo?; vamos supor q eu esteja com meu potenciômetro em repouso em 2,5V(seria o valor armazenado para verificação), logo eu movimento ele para 3V(valor a ser comparado), como seria a lógica pra comparar o meus 2,5V com o 3V e logo em seguida descartar esse 2,5 e começar a ter a referencia de comparação em 3V?

EU imagino algo assim, mas não consegui programar essa lógica... Faria algo parecido com isso: Quando houver uma variação de tensão no potenciômetro a variável de verificação se manteria com seu ultimo valor(2,5V), no entanto a variável a ser comparada sempre iria variar junto com a tensão no potenciômetro(3V), logo eu teria 2 valores distintos e faria a comparação como você disse... Terminada a comparação a variável de verificação iria receber o valor atual do potenciômetro(3V) e iniciaria o ciclo novamente... claro q isso em escalas de milissegundos.

você acha que assim poderia funcionar, alguma ideia de como eu poderia programar em cima dessa lógica?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou no estágio. Mais tarde posto um exemplo para você poder estudar.

Vou postar circuito, simulação e código.

Falou

Compartilhar este post


Link para o post
Compartilhar em outros sites
 

Bom fiz um exemplo aqui.

Sério que me deu mais trabalho que podia imaginar. Demorei um bocado. Não foi tão simples como imaginei.

Bom, na simulação está funcionando.

O código ficou meio bagunçado. Pois eu testava de uma forma, depois de outra......

Circuito:

Motor_de_Passo_com_potenciometro.png

Código:

Tenta compreender ele. Caso tenha dúvidas, vou tirando. Veja que essa forma não é a única que pode ser feita. Para falar a verdade não gostei muito. Mas funciona.

#include <16F877A.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection

#use delay(clock=4000000)

#include <LCD.C>

#define frame_time 75 //Velocidade do motor

int8 i = 3, i_1 = 0,j;
int16 ad_antigo, ad_atual;
int8 y;
int8 inicio = 1;
signed int16 distancia;

char sentido_motor[4]=
{
0b0001, //PASSO1
0b0010, //PASSO2
0b0100, //PASSO3
0b1000, //PASSO4
};

void main ()
{
lcd_init();
delay_ms (100);

SETUP_ADC_PORTS(AN0);
SETUP_ADC(ADC_CLOCK_DIV_8);

set_adc_channel(0);
delay_us (20);

while(true)
{
ad_atual = read_adc();

if (inicio)
{
ad_antigo = ad_atual;
inicio = 0;
}

distancia = ad_atual - ad_antigo;
printf(lcd_putc,"\fnow:%lu d:%ld\nold:%lu",ad_atual,distancia, ad_antigo);

if (distancia != 0)
{
if (distancia > 0)
{
y = 0.195 * distancia;
for (j=0;j<y;j++)
{
output_b(sentido_motor[i_1]);
i_1++;
if (i_1 > 3)
{
i_1 = 0;
}
delay_ms(frame_time);
}
}
else if (distancia < 0)
{
y = 0.195 * distancia * -1;
for (j=0;j<y;j++)
{
output_b(sentido_motor[i]);
i--;
if (i == 255)
{
i = 3;
}
delay_ms(frame_time);
}
}
}

ad_antigo = ad_atual;
delay_ms (200);
}
}

Falou

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu criaria dois vetores de 4 posições com os valores dos passos.

Falou

Matheus,

Caramba, voltei uns 30 anos lendo esse post .... VETOR , na minha época, era uma entidade demonstrativa de força, diferente de MATRIZ, que é uma entidade dimensional.

Não sabia que esse termo se aplica à programação de hoje em dia !

Tá vendo só , ficar velho é uma M.... !!!!! :D

P.S. - Quanto à sua solução, eu fiz quase a mesma coisa que voce.... funcionou, mas também achei que podia funcionar melhor, e eu incluí um sistema de "aceleração do STEP" não linear ( ficou numa tabela ) em função da diferença da tensão medida em relação aos 2.5 volts.

Ficou um pouco mais "redondo" o movimento do step motor.

Um abração, Matheus !

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites
 

aphawk mostra a sua programação aqui para nós...

Pow Matheus ficou muito bom, era bem isso q eu tava pensando mesmo, eu não consegui entender a parte da distancia... teria como você da uma explicadinha?

Compartilhar este post


Link para o post
Compartilhar em outros sites
Matheus,

Caramba, voltei uns 30 anos lendo esse post .... VETOR , na minha época, era uma entidade demonstrativa de força, diferente de MATRIZ, que é uma entidade dimensional.

uhauhauhauha pois é, quando comecei a estudar programação na faculdade, os dois professores começaram pelo Pascal e sempre diziam vetor isso, vetor aquilo.

Eu sempre associei também com força. Lá da física. Custei associar com matriz.

Mas aí lendo aqui e ali cheguei ao seguinte: "Vetores nada mais são que matrizes unidimensionais."

Vem assim é um monte de apostila que li.

Sua ideia é interessante com relação à aceleração. Pois percebi que se o potenciômetro tem um giro rápido, pode demorar para chegar até o ponto desejado.

eu não consegui entender a parte da distancia... teria como você da uma explicadinha?

Então, você deve saber que o canal AD no modo 10 bits vai de 0 a 1023. Certo?

Considerei um motor de passo de 1.8º por passo, ou seja, o mesmo precisa dar 200 passos para dar uma volta completa.

Como escolhi criar 1 vetor de 4 posições (cada posição 1 passo), pois o motor tem 4 bobinas, percebi que o meu programa teria q chamar a rotina de "passos" umas 50 vezes para dar 1 giro completo.

Ora, 50 x4 = 200. Sendo esse o número necessário para dar 1 volta.

Dessa forma, montei uma equação que relaciona o valor do AD com a quantidade de passos necessários (num total de 50, variávei J no código).

Veja como fiz a equação:

grafico_excel.png

Fui no excel e o mesmo traçou o gráfico com a equação.

Imagine que seu potenciômetro está em fim de curso e o canal AD lê 0. OK.

Aí você gira o potenciometro até uns 60% do giro dele. O AD vai lá e lê 700.

Ora, meu AD inicial era 0, agora é 700. Então minha diferença é de 700.

Indo até o gráfico, vemos que se olharmos o eixo X, vamos ver que o número 700 se encontra mais ou menos relacionado como número 30 no eixo Y.

Conclui-se que o motor terá que girar 30 * 4 = 120 vezes para chegar no lugar onde queremos.

Sendo o número 30 repassado a nossa variável J e o número 4 é o nosso vetor de 4 posições.

Isso funciona se fosse ao contrário também.

Veja que não montei o circuito. Tenho uns 8 motores de passo aqui e posso ver isso depois. Apesar que meu tempo está meio corrido.

Falou

Editado por MatheusLPS
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Evertton,

Meu código está em Bascom em um projeto de controladora para 8 motores, vou separar ele e postarei aqui.

A ideia é simples, olha o jeito que o Matheus explicou o conceito de "distância", repare que é uma função linear, isto é, se a distância é de 1 volt, os steps são , por exemplo, 30 steps por minuto; se a distância aumentar para 2 volts, os steps seriam 60 por minuto, certo ?

Repare que isso é uma função LINEAR. O que eu fiz foi assim :

Se o potenciometro estiver em um dos extremos, os steps feitos serão o máximo que o meu motor aguenta. Imagine que o meu motor trabalha com o máximo de 500 steps por minuto.

Então temos uma função linear do tipo :

Se o potenciometro estiver a meio caminho, isto é , na metade entre um dos extemos e a posição central, o resultado é que serão aplicados 250 steps por minuto, certo ? Pois é uma função linear !

Criei uma tabela de correspondencia entre esses resultados que são obtidos pela função linear, e coloquei um valor que segue uma funçao tipo X ao quadrado. Usei uma tabela exatamente para poder ajustar os valores na mão para ficar mais natural.

Veja se entendeu o conceito !

Paulo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então matheus eu não entendi essa parte do programa      (y = 0.195 * distancia;)    nao entendi o porque de 0.195.

 

Estou fazendo um projeto similar a esse, so que estou utilizando o PIC18F4550

 

olha a programação que fiz ate o momento

 

 

 

#include<P18F4550.h> // Inclui Informações do microcontrolador.

#include<delays.h>   // Adiciona a biblioteca de funções de atraso.
#include<adc.h>      // Adiciona a biblioteca de funções para o módulo conversor A/D.
 
// Fosc = 20MHz
// Tciclo = 4/Fosc = 0,4us
#pragma config FOSC = HS            // Fosc = 20MHz -> Tcy=200ns
#pragma config CPUDIV = OSC1_PLL2   // PLL desligado
 
#pragma config WDT = OFF       // Desabilita o Watchdog Timer (WDT).
#pragma config PWRT = ON       // Habilita o Power-up Timer (PWRT).
#pragma config BOR = ON        // Brown-out Reset (BOR) habilitado somente no hardware.
#pragma config BORV = 1        // tensão do BOR é 4,33V.
#pragma config LVP = OFF       // Desabilita o Low Voltage Program.
#pragma config DEBUG = ON               // habilita debug
#pragma config PLLDIV = 5               // PLL para 20MHz
 
 
 
// Definições de hardware
#define BOBINA_A PORTDbits.RD0      // Define outro nome para a estrutura.
#define BOBINA_B PORTDbits.RD1      // Define outro nome para a estrutura.
#define BOBINA_Ab PORTDbits.RD2    // Define outro nome para a estrutura.
#define BOBINA_Bb PORTDbits.RD3    // Define outro nome para a estrutura.
 
#define MOTOR PORTD                 // Define o nome da estrutura do PORTD para MOTOR             
 
 
unsigned char buffer[16];
 
void main(void)
{
unsigned int resultado_conv;
int i = 0;
 
// Tabela de dgitos do MOTOR
char table[] = {0b00000011, // Passo 1
                       0b00000110, // Passo 2
                       0b00001100, // Passo 3
                       0b00001001  // Passo 4
};
 
OpenADC(ADC_FOSC_16              // Seleção da fonte de clock para a conversão A/D. Fosc = 20Mhz. Tad = 16/20MHz = 0,8us.
         &ADC_RIGHT_JUST              // Resultado justificado para a direita.
         &ADC_4_TAD,                       // Configuração do tempo de aquisição automático. (4*tad = 3,2us)
         ADC_CH0                              // Seleciona o canal 0 (AN0)
         &ADC_INT_OFF                     // Interrupção desabilitada.
         &ADC_VREFPLUS_VDD       // Vref+ = Vcc
         &ADC_VREFMINUS_VSS,     // Vref- = Vss
         ADC_1ANA);                          // Habilita somente o canal AN0.
         
 SetChanADC (ADC_CH0);     // Seleciona o canal 0 (AN0).
 Delay10TCYx(5);           // Delay de 50 ciclos de máquina.
 
 
 
 
 
// *** Inicialização
 
 TRISAbits.TRISA0 = 1;     // Configura o pino AN0 como entrada
 TRISDbits.TRISD0 = 0;     // Configura o pino RD0 como saída.
 TRISDbits.TRISD1 = 0;     // Configura o pino RD1 como saída.
 TRISDbits.TRISD2 = 0;     // Configura o pino RD2 como saída.
 TRISDbits.TRISD3 = 0;     // Configura o pino RD3 como saída.
 
 
 while(1)  // Looping infinito
 {
 ConvertADC();   // Inicia a conversão.
 while(BusyADC());   // Aguarda o fim da conversão.
 resultado_conv = ReadADC();   // Armazena o resultado da conversão.
 
// Vcc = 5 Volts.
// Vref+ = Vcc e Vref- = Vss.
// V_1bit = 4,887585mV
// resultado_conv = 511 --> V_sinal_analógico = 2,5 Volts.
 
MOTOR = table
 
 if(resultado_conv==511)
{
  
PORTD = 0;
 
}
 
 if(resultado_conv>511)
{
    i--; 
    if(i<0b00000011){
    i=0b00001001;
}
    
}
 
 else if(resultado_conv<511)
{
   i++;
   if(i>0b00001001){
   i=0b00000011;
}
}
 
 }
}    
 
 
acho que esta errado a parte do MOTOR = table; para baixo

Compartilhar este post


Link para o post
Compartilhar em outros sites

@KainanXD

O 0.195 seria a quantidade de passos necessária para alcançar a posição requerida. Explico:

Veja a imagem do Excel logo acima onde relaciono a leitura do AD com a quantidade de chamadas necessárias para 1 giro completo. Assim, pela imagem do Excel, no eixo X temos o AD variando de 0 a 1023. E o You variando de 0 a 50. Bom, imagina que seu potenciômetro está na posição 0V, seu AD lê zero. Agora, você gira o potenciômetro todo para um lado e seu AD vai ler o valor máximo. Isso quer dizer q seu motor deverá dar uma volta completa. Certo?

Nesse exemplo eu considerei um motor com 4 bobinas a serem controladas e considerei que cada passo do motor gira ele em 1.8*. Com isso, precisamos dar 200 passos para dar uma volta (200×1.8 = 360). Mas eu disse q nosso motor tem 4 bobinas e vou controlar individualmente. Nesse caso,ativo uma bobina por vez em sequência. Meu motor não precisa de 200 steps para dar 1 volta? Mas cada loop é composto por 4 bobinas. Ou seja. Se eu chamar meu loop das 4 bobinas 50 vezes dou uma volta completa.

Mas nem sempre vou precisar dar uma volta completa. Imagina que eu queira apenas meia volta pois meu potenciômetro saiu do zero e foi para metade. Nesse caso faço uma regra de três para saber quantos step preciso para chegar nessa posição. Como é tudo linear, para não ter q fazer regra de três o tempo todo eu relacionei o AD com a quantidade máxima de chamadas (50) ao meu loop de 4 bobinas.

Ora, eu preciso ativar as bobinas 4 x Y. Sendo Y a relação entre AD e 50.

Nesse caso minha função linear entre AD e 50 deu Y = 0.048x.

Aí eu já sabia que a quantidade total de steps deveria ser multiplicada por 4. Assim sendo:

Total de passos = (0.048x) × 4 = 0.192x

Sendo x a "distância" a ser percorrida.

Por isso no código eu sempre pego o AD atual e subtrai o do AD antigo. Com isso sei a distância entre a posição do potenciômetro de agora e a anterior.

Veja que esse é apenas um exemplo.

O código que usei está longe do ideal. Isso é apenas um exercício didático. Vejo melhorias a serem feitas para alguma aplicação prática. Como filtragem do sinal do potenciômetro. Talvez uma histerese. Adicionar aceleração ao motor de acordo com a distância. Ou até mesmo mudar completamente o código e aplicar um controlador PID.

Observe que nesse exemplo, considerei que o motor sempre dará os passos. Na prática pode ser que ele patine ou dê passo a mais. Nesse exemplo você não tem certeza de onde o motor está. Teria que adicionar um controle de posição real do motor. Seja por encoder ou outro tipo de feedback.

Falou

  • Curtir 3

Compartilhar este post


Link para o post
Compartilhar em outros sites

@circuit

Obrigado pelo elogio.

@KainanXD

Desculpe não analisar seu código. Estou sem PC até hoje. Analisar código pelo smartphone é tenso. Mesmo o meu tendo uma tela fullhd de 5.7".

Esse tipo de coisa necessito do compilador e do simulador para testar. E sem falar que você nem usou as tags para postar código. Veja (code) seu código aqui (/code). Substituindo os parênteses por colchetes. Normalmente ignoro códigos sem tags pois ficam ilegíveis.

Falou

Editado por MatheusLPS
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito boa a explicação @MatheusLPS, muito obrigado mesmo, esta de parabéns...

 

Não sou muito bom em programação estou tendo que me virar pra poder entregar o meu TCC funcionando em novembro kkkk, é que faço curso técnico então eles não aprofunda muito em microcontrolador, só o básico mesmo, então estou tendo que aprender na raça mesmo, pesquisando em livros e tal.

 

Mas meu projeto é isso ai mesmo, igual do vídeo, ai depois que eu conseguir fazer essa parte vou ter que adicionar um encoder pra ler a posição do motor. 

 

Agora que você explico eu consegui compreender melhor, só que vou usar o PIC18F4550 e na sua programação que você fez você usou o PIC16F877A, então tem alguns detalhes na minha programação que tem que ser ajustada, por exemplo no PIC18F4550 ele nao aceita o comando OUTPUT_B e nem esse delay_ms(frame_time); mais esses sao detalhes que vou ir verificando

 

output_b (sentido_motor[i_1]);
delay_ms(frame_time);

 

mais de uma olhada na minha programação que eu fiz ate o momento esta logo acima, Obrigado!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se você pegar o código que postei e trocar o 16F877A pelo 18F4550, tem q funcionar com o mínimo de ajuste. Os pinos são compatíveis. 

 

Se tiver q ajustar vai ser no AD.

 

O seu código tem um monte de configurações desnecessárias. Você está usando o compilador CCS? Qual versão? 

 

Falou

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá li e re-li este tópico, achei extremamente importante em vista que neste ano de 2015 me encontro em novembro, (fiz este breve comentario pois o rapaz tinha que entregar o tcc em novembro, no caso, mesma coisa que eu, que coincidência) e tenho que entregar esta parte funcionando do motor de passo. Gostaria de saber como ficou a programação utilizando o PIC18F4550, por gentileza gostaria que comentassem aqui ou me mandassem essa programação pelo e-mail: ofabioh@gmail.com.
Muito obrigado por disponibilizarem este conhecimento, esta sendo de bom uso! Continuem assim!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá primo...não vou te ajudar mas te ajudar a ajudar quem quem vai te ajudar

 

to com preguiça de ler tudo. Melhor voce reestruturar sua dúvida e antecipo que é interessante falar algo de si, seus sucessos e tal. Desenhos, esquemas, fotos e tal são interessantes. Agencia, conta e senha do banco também ... por mp por gentileza (brinc.. não tente nada por mp)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá primo...não vou te ajudar mas te ajudar a ajudar quem quem vai te ajudar

 

to com preguiça de ler tudo. Melhor voce reestruturar sua dúvida e antecipo que é interessante falar algo de si, seus sucessos e tal. Desenhos, esquemas, fotos e tal são interessantes. Agencia, conta e senha do banco também ... por mp por gentileza (brinc.. não tente nada por mp)

Me chamo Fabio, estou cursando técnico em eletrônica, estou no ultimo modulo do tecnico. Restruturando a duvida, estou programando em C, estou numa etapa que tenho uma SAPZ (se chama Situação de Aprendizagem).

Vou manda a programação:

/*
 * File:   sapzmodel.c
 * Author: Usuario-Note
 *
 * Created on 2 de Outubro de 2015, 08:55
 */
 
//.....BIBLIOTECAS PADRÕES............//
#include <stdio.h>
#include <stdlib.h>
#include <pic18f4550.h>
#include "R.h"
#include "lcd4bit.h"
#define _XTAL_FREQ 2000000
 
void __espera_ms(unsigned int t)
{
    unsigned int x=0;
    for(x=0;x<t;x++)
        __delay_ms(1);
}
 
/*
 *
 */
 
 
//.......FUNÇÃO SELO...........//
bit selo=0; //selo do display
bit selo1=0;//selo do pwm
bit selo2;//selo motor de passo
bit BUZZER;//BOTÃO DE SELEÇÃO DO SPEED//
 
 
void main()
{
    TRISB0=1;//SW1
    TRISB1=1;//SW2
    TRISB2=1;//SW3
    TRISC0=0;//BUZZER
 
    int cont=0; //display
    int cont1=0; //pwm
    int cont2=0; //motor passo
    int SW1=0;  //VARIAVEL PARA SW1
    int SW2=0;  //VARIAVEL PARA SW2
    int SW3=0;  //VARIAVEL PARA SW3
    char buffer[17];//variavel de letras
 
    //Variáveis e seus tipos
    float celsius;      //Variável que salva o valor de temperatura em celsius.
    float fahrenheit;   //Variável que salva o valor de temperatrura em fahrenheit.
    float motion;       //Variável que salva o valor de
    float speed;        //Variável que salva o valor de
    int sp;             //Variável que salva o valor de
    int sw1=0;          //Variável que salva o valor de
    float celsiusp;     //Variável que salva o valor obtido na conversão A/D.
    char buffer[17];    //Variável que salva os dados do display.
    float pwm;            //Variável que salva os dados do PWM
 
    //Display
        init_lcd(_XTAL_FREQ);//Liga LCD
        cursor_off();/*Desliga Cursor*/
        clear_lcd();//Limpa LCD
 
        //Parametrização do TMR2 - Utilizado como base de tempo no PWM//
 
   TRISBbits.RB0=1; //Botão que Muda a tela do display
    TRISBbits.RB1=1; //Botão que Liga ou desliga o pwm
    TRISCbits.RC2=0; //Pino do RC2/CCP1(PWM) como saída
    TRISCbits.RC0=0; //buzzer
 
    //Parametrização do TMR2 - Utilizado como base de tempo no PWM
    T2CONbits.TMR2ON=1; //Liga o TMR2
    T2CONbits.T2CKPS=2; //Prescaler do TMR2 em 1:16
                TMR2=0; //Zera a contagem do TMR2;
 
    //Parametrização do conversor A/D
    ADCON2bits.ADCS=0b101; //Configura a frequencia usada, pode usar o numero decimal, para 20 hz usar "101"-.
    ADCON1bits.PCFG=12; //define entadas como analógico e ou digital
    ADCON0bits.ADON=1; //liga o conversor analógico
 
    //..........INICIO DO PROGRAMA.............//
 
    sprintf(buffer,"DATALOGGER");//printa a informação
    lprintf_lin_col(buffer,1,4);//declara a informação
    sprintf(buffer, "SENAI");//printa a informação
    lprintf_lin_col(buffer,2,6);//declara a informação
    tempo_ms(2000);//delay de 2 segundos
 
    clear_lcd;//limpa LCD
    sprintf (buffer,"TEMPERATURE");
    lprintf_lin_col(buffer,1,4);
    sprintf(buffer,"METER");
    lprintf_lin_col(buffer,2,6);
    tempo_ms(3000);
    clear_lcd();
    cursor_off;
 
 
     while(1)
     {
         if(RB0 &&!selo)  //FUNÇÃO SELO
        {
            clear_lcd();  //LIMPA DISPLAY
            SW1++;  //INCREMENTA VARIAVEL
            selo=1;
        }
         if(!RB0 && selo)  //FUNÇÃO SELO
 
        selo=0;  //DEFINE 0 EM SELO
 
 
 
 
        if(SW1==4)  //FUNÇÃO PARA RESETAR CICLO DO DISPLAY LCD
 
        SW1=0;
 
             if(SW1==0)
        {
   ADCON2bits.ADFM=1; //Bits justificado a direita
   ADCON0bits.CHS=0; //Seleciona o canal 0 para ser convertido
 
   __delay_us(40);     //Espera o capacitor carregar os dados
 
   ADCON0bits.GO=1;    //Para a conversão e salvamento dos dados
   while(ADCON0bits.nDONE); //inicia a leitura dos dados
   celsiusp=(ADRESH<<8)+ADRESL; //salva os dados numa variável
   ADCON0bits.GO=0;    //Para a conversão e salvamento dos dados
 
   celsius=celsiusp*150/1023; //converte o valor obtido pelo conversor em célcius
 
 
    sprintf (buffer,"CELSIUS");
    lprintf_lin_col(buffer,1,4);
    sprintf(buffer, "VALUE:  %.2f    ",celsius);
    lprintf_lin_col(buffer,2,6);
 
        }
 
        if(SW1==1)
        {
    ADCON2bits.ADFM=1; //Bits justificado a direita
    ADCON0bits.CHS=0; //Seleciona o canal 0 para ser convertido
 
    __delay_us(40);     //Espera o capacitor carregar os dados
 
    ADCON0bits.GO=1;    //Para a conversão e salvamento dos dados
    while(ADCON0bits.nDONE); //inicia a leitura dos dados
    celsiusp=(ADRESH<<8)+ADRESL; //salva os dados numa variável
    ADCON0bits.GO=0;    //Para a conversão e salvamento dos dados
 
    celsius=celsiusp*150/1023; //converte o valor obtido pelo conversor em célcius
 
    fahrenheit=celsius/5*9+32; //converte o valor de celsius para fahrenheit.
 
    sprintf (buffer,"FAHRENHEIT");
    lprintf_lin_col(buffer,1,4);
    sprintf(buffer, "VALUE:  %.2f  ",fahrenheit);
    lprintf_lin_col(buffer,2,6);
        }
    if(SW1==2)
        {
         if(SW2==1)
         {
    speed=pwm*100/1023;
 
    sprintf(buffer, "SPEED");
    lprintf_lin_col(buffer, 1,6);
    sprintf(buffer, "VALUE: %.0f%% ",speed);
    lprintf_lin_col(buffer, 2,1);
 
        }
           if(SW2==0)
           {
    sprintf(buffer, "SPEED");
    lprintf_lin_col(buffer, 1,6);
    sprintf(buffer, "VALUE:  OFF",speed);
    lprintf_lin_col(buffer, 2,1);
 
            }
     }
       if(SW1==3)
        {
    sprintf (buffer,"MOTION");
    lprintf_lin_col(buffer,1,4);
    sprintf(buffer, "VALUE:%.1f SP:%.1f",motion ,sp);
    lprintf_lin_col(buffer,2,6);
 
        }
    //................
 
    if(RB1 &&!selo1)  //FUNÇÃO SELO
        {
            SW2++;  //INCREMENTA VARIAVEL
            selo1=1;
        }
         if(!RB1 && selo1)  //FUNÇÃO SELO
        {
 
            selo1=0;  //DEFINE 0 EM SELO
 
 
        //AÇÕES SE ESTIVER LIGADO O PWM
 
          if(SW2==1)
              {
 
        ADCON2bits.ADFM=0; //Bits justificado a direita
        ADCON0bits.CHS=1; //Seleciona o canal 0 para ser convertido
 
        __delay_us(40);  //Espera o capacitor carregar os dados
 
        ADCON0bits.GO=1;    //Para a conversão e salvamento dos dados
        while(ADCON0bits.nDONE); //inicia a leitura dos dados
        pwm=(ADRESH<<2)+(ADRESL>>6); //salva os dados numa variável
        ADCON0bits.GO=0;    //Para a conversão e salvamento dos dados
 
                         //Parametrização do PWM
        CCP1CONbits.CCP1M=0b1111; //Liga o PWM
        PR2=155; //Utilizado na parametrização do período do PWM
 
                         //controla a frequencia do pwm
        CCPR1L=ADRESH;      //Período ativo do duty cycle
        CCP1CONbits.DC1B0=(ADRESL>>6);
        CCP1CONbits.DC1B1=ADRESL>>7;
 
        if(RB1==0)
            {
         RE0=1;
         tempo_ms(2000);
         RE0=0;
         
     }
 
        if(SW2==0)
 
        {
             CCP1CONbits.CCP1M=0; //Desliga o PWM no CCP1
                pwm=0;
 
        if(RB1==1)
        {
 
         RE0=1;
         tempo_ms(2000);
         RE0=0;
         tempo_ms(2000);
         RE0=1;
         tempo_ms(2000);
         RE0=0;
         tempo_ms(2000);
         RE1=0;
        }}}}}}
 
 
Também vou mandar a imagem
 
ejdel0.jpg

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário






Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×