lunes, 5 de marzo de 2012

control de servomotor por grados

Este es un ejemplo de un sencillo programa para controlar un servomotor por medio de la computadora. controlando a diferentes grados



//Control de motor servo hobbico
//#include <16F877.h>
#include <16F870.h>
#use delay(clock=10000000)
#fuses HS,NOWDT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#define out_SERVO PIN_C1
#include <stdio.h>
#include <stdlib.h>
void main()
{
  char ch;        //character variable
  char ch_p='0';  //character para indicar posicion
  int enable_SERVO; //variable de habilitación - apagado - default
  enable_SERVO = 0;  //apagado - default
  output_bit(out_SERVO,0);
  while(1)
  {
    if(kbhit())
    { //only get the character if one has been received
      ch = getchar(); //wait for and get serial character
      switch(ch)
      {
        case 'a': // arrancar motor
                  enable_SERVO=1;
                  break;
        case 'p': // parar motor
                  enable_SERVO=0;
                  break;
        default: // cambio de posicion
                  ch_p = ch;
                  break;
       }
    }
    if(enable_SERVO==1) //si esta habilitado el SERVO
    {
      output_bit(out_SERVO,1);
      switch(ch_p)
      {
        case '0': // posicion 0
                  delay_us(1000); 
                  break;
        case '1': // posicion 1
                  delay_us(1100); 
                  break;
        case '2': // posicion 2
                  delay_us(1200); 
                  break;
        case '3': // posicion 3
                  delay_us(1300); 
                  break;
        case '4': // posicion 4
                  delay_us(1400); 
                  break;
        case '5': // posicion 5
                  delay_us(1500); 
                  break;
        case '6': // posicion 6
                  delay_us(1600); 
                  break;
        case '7': // posicion 7
                  delay_us(1700);
                  break;
        case '8': // posicion 8
                  delay_us(1800);
                  break;
        case '9': // posicion 9
                  delay_us(1900);
                  break;
        case 'A': // posicion 10
                  delay_us(2000);
                  break;
       }
      output_bit(out_SERVO,0);
      delay_us(18000);//time - a variable 0-255 or a constant 0-65535
      }
  }
}

lunes, 10 de octubre de 2011

Fuente de alimentacion de 5V

Fuente de alimentacion de 5V



Modulo adaptador rs232


Modulo adaptador rs232
Todos hemos visto que las computadoras tienen puertos de comunicación, que inclusive ocupamos muchas veces sin siquiera saber cómo trabajan, tal es el caso del puerto serie, al cual en la antigüedad de las computadoras le conectábamos el ratón, o un fax MODEM externo, o inclusive una impresora.

Convertidor de analogico a digita

Convertidor de analogico a digital esta configuración produce una señal cuya tensióndepende del número de pulsos aplicadosa la entrada. Podemos obtener niveles escalonados de 0 a 7, en función de los pulsos de entrada.



lunes, 3 de octubre de 2011

Multimetro digital de 0 a 5v

Es un circuito que mide la tensión de 0 a 5v por medio de un microcontrolador 16f876 y la muestra en una LCD en este ejemplo estoy utilizando un potencimetro para demostrar que funciona y ademas muestra el convertidor de analógico a digital.



#include <16F876.h>
#device adc=10

#FUSES XT,NOWDT
#FUSES
#use delay(clock=4000000)
#include <LCD.C>

void main() {
   int16 q;
   float p;

   setup_adc_ports(AN0);                                   //Canal 0 analógico
   setup_adc(ADC_CLOCK_INTERNAL);    //Fuente de reloj RC

   lcd_init();
   
   for (;;) {
      set_adc_channel(0);           //Habilitación canal0
      delay_us(20);
      q = read_adc();                  //Lectura canal0
      p = 5.0 * q / 1024.0;           //Conversión a tensión 

      printf(lcd_putc, "\fADC = %4ld", q);
      printf(lcd_putc, "\nVoltage = %01.2fV", p);

      delay_ms(100);
      }

Barómetro y altímetro

Mediante el uso de el sensor mpx4115 y el microcontrolador 16f876 recuerden que también funciona con el 16f870 la altitud y la presión y el promedio de la temperatura en la que se encuentra en algún cierto punto de la tierra. recuerde que este circuito funciona solamente con este tipo de sensor. al final de la pagina tienen el link para descargar el circuito y el programa.



#include <16F876.h>
#device adc=10
#FUSES XT,NOWDT
#FUSES
#use delay(clock=4000000)
#include <math.h>
#include <LCD.C>
#BYTE TRISA = 0x85
#BYTE PORTA = 0x05

void main() {
   int16 q;
   float tv,tr,temp,y,tf,error;                          //Variables ecuaciones
   float p,presion,pres_atm,pres_psi,alt;       //Variables cálculo presión y altura
   int cnt=0;
   bit_set (TRISA , 2);
   setup_adc_ports(RA0_RA1_RA3_ANALOG);  //RA0 y RA1 analógica, RA2 digital
   setup_adc(ADC_CLOCK_INTERNAL);
   lcd_init();
   
   for (;;) {
      set_adc_channel(0);                       //Lectura presión en voltios
      delay_us(20);
      q = read_adc();
      p = 5.0 * q / 1024.0;
      presion= (0.475+p)/0.045;           //Lectura presión en Kpa

      set_adc_channel(1);                     //Lectura temperatura
      delay_us(20);
      q = read_adc();
      tv = 5.0 * q / 1024.0;
      tr = tv * 10000.0 / (5.0 - tv);
      y = log(tr/20000.0);
      y = (1.0/298.15) + (y *(1.0/4050.0));
      temp=1.0/y;
      temp = temp -273.15;
         if (temp>=0 && temp<=85) TF=1.0;
         else TF=3.0;
      ERROR = TF * 1.5;                   //Cálculo del error de presión con la temperatura
                                                            //el error puede ser ± pero aquí usamos - o + 
      presion=presion-ERROR;              //Presión en Kpa 
      pres_atm = presion * 0.0098692;   //Presión en Atm
      pres_psi = presion * 0.1450377;    //Presión en Psi
      alt = -7990.652789*log(presion/101.304);   //Altura 
     if (BIT_TEST(PORTA,2)==0) cnt++;    //Calcular número veces pulsa botón
     if (cnt>=4) cnt=0;           
      Switch (cnt) {                       //Según número veces pulsa botón se elige menú
        case 0:
        lcd_gotoxy(1,1);
        printf(lcd_putc, "\P= %5.2f Kpa   ", PRESION);
        printf(lcd_putc,"\nT = %04.2f C", temp);
        break;
        case 1:
        lcd_gotoxy(1,1);
        printf(lcd_putc, "\P= %4.2f atm   ", PRES_atm);
        printf(lcd_putc,"\nT = %04.2f C", temp);
        break;
        case 2:
        lcd_gotoxy(1,1);
        printf(lcd_putc, "\P= %3.2f psi   ", PRES_psi);
        printf(lcd_putc,"\nT = %04.2f C", temp);
        break;
        case 3:
        lcd_gotoxy(1,1);
        printf(lcd_putc, "\Alt= %7.2f m   ", alt);
        printf(lcd_putc,"\nT = %04.2f C", temp);
        break;
         }
     delay_ms(100);
      }}



domingo, 2 de octubre de 2011

control de velocidad de motor cc

Es un circuito mediante un teclado se puede controlar la velocidad del motor tiene 10 velocidades distintas en las cueles pude girar le dejo el circuito y el programa para descargarlo



#include <16f876.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#USE DELAY (CLOCK=4000000)
#INCLUDE <MI_kbd.C>
#include <MI_lcd.c>
#USE STANDARD_IO (a)
int16 counter=0;

//*************** INT TIMER1*********************
#int_TIMER1
void TIMER1_isr(void) {
counter=get_timer0();         //Lectura contador TMR0
counter=counter*2*120;     //Conversión a rpm
  printf(lcd_putc,"%6lu rpm",counter);
  lcd_gotoxy(1,1);
set_timer0(0);                      //Reinicia cuenta
set_timer1(3036);                // Recarga a 0.5s
 }
//**********************************************
VOID MAIN()
{        
   CHAR K,kant='0';
   char PWMH=0,PWML=0;
   lcd_init();
   kbd_init();
   PORT_B_PULLUPS(TRUE);
 
   setup_timer_0(rtcc_ext_l_to_h|RTCC_DIV_2);   //Configuración TMR0
     setup_timer_1(T1_internal|T1_DIV_BY_8);     //Configuración TMR1
   set_timer0(0);                               //Borrado contador
   set_timer1(3036);                         //Carga a 0.5s
   enable_interrupts(int_timer1);
   enable_interrupts(global);           //Habilitación interrupciones
 
WHILE (1) {
      k=kbd_getc();
      if (k=='\0') k=kant;
      if ((k=='*') || (k=='#')) k='0';
      kant=k;
       k=k-48;
       PWMH=k*28;
       PWML=255-PWMH;
      for(PWMH;PWMH>0;PWMH--){
       OUTPUT_HIGH(PIN_A0);}
      for(PWML;PWML>0;PWML--){
      OUTPUT_LOW(PIN_A0);}
  }}