Curso de programación de PIC en PICBasic Pro

Que tal amigos...

Les dejo un circuito regulador de voltaje variable con un LM317, simulado en proteus, para los que les agrade esta bueno...


Por otra parte pido de sus apoyos para agregarle a este circuito un LCD que me indique el voltaje presente en mi regulador de voltaje...

pueden modificar el circuito y dejar el programa para el LCD

o algun circuito que me recomienden en proteus que traiga este LCD que me indique los volts presentes....

Saludos///
 

Adjuntos

  • FuenteReguladaLM3XX.zip
    123.9 KB · Visitas: 104
hola amigos, he conseguido este programa de un libro de basic de una sht11 con un pic 18f2250, pero no comprendo unas pocas cosas de el y me gustaria saber si podriais ayudarme a comprenderlas. el programa funciona bien pero como dije no entiende esas cositas.lo pongo y os comento mis dudas
Código:
1 DEFINE OSC 8
2 DEFINE LCD_DREG PORTB   
3 DEFINE LCD_DBIT 4   
4 DEFINE LCD_RSREG PORTB
5 DEFINE LCD_RSBIT 0      
6 DEFINE LCD_EREG PORTB   
 7 DEFINE LCD_EBIT 1   
 8 CONTROL VAR BYTE             
 9 ISI1    VAR BYTE      
 10 ISI2    VAR BYTE      
 11 U1      VAR BYTE        
 12 U2      VAR BYTE
 13 H0      VAR HAM.BYTE0
 14 H1      VAR HAM.BYTE1
 15 HAM     VAR WORD
 16 RAI    var word
 17 ISI     VAR WORD
 18 P1      VAR WORD
 19 P2      VAR WORD
20 P3      VAR WORD            
 21 W       VAR WORD
 22 DTA     VAR PORTC.4
 23 CLK     VAR PORTC.5    
 24 ISARET  VAR BIT  
 25 HATA    var BIT
 26 PORTC=0
 27 PORTB=0
 28 TRISC=0
 29 TRISB=0
 30 INICIO:
     31   CONTROL=%00000101
       32 HAM=0
      33 GOSUB CONTROL_PULSO
   34     GOSUB DATO_HUMEDAD
      35  GOSUB HUMEDAD      
      36  PAUSE 50
       37 CONTROL=%00000011
       38 HAM=0
       39 RAI=HAM  
      40  GOSUB CONTROL_PULSO
        41 Gosub DATO_TEMPERATURA
     42   GOSUB TEMPERATURA          
43 HUMEDAD:    
   44     LCDOut $FE,2
    45    LCDOut "    HUME = ",DEC U1 , "," , DEC1 U2," % "
   46   RETURN           
 47 TEMPERATURA:    
     48   LCDOut $FE,$C0  
   49     if ISARET=1 THEN  
      50    LCDOut "    TEMP =-",DEC ISI1 , "," , DEC1 ISI," C "
       51   RETURN  
       52 endIF  
     53   LCDOut "    TEMP = ",DEC ISI1 , "," , DEC1 ISI2," C "
     54   RETURN          
55 EMPEZAR:
   56     OUTPUT DTA
      57  OUTPUT CLK
    58    HIGH DTA
   59     LOW CLK
   60     PAUSE 1
   61     HIGH CLK
      62  LOW DTA
     63   PAUSE 1
    64    LOW CLK
     65   PAUSE 1
     66   HIGH CLK
     67   PAUSE 1
     68   HIGH DTA
   69     LOW CLK
     70   RETURN
71 RESET:  
   72     OUTPUT DTA
     73   OUTPUT CLK
     74   high DTA=1
     75   FOR W=0 TO 9
   76     HIGH CLK
    77    pause 1
     78   LOW CLK
      79  Next W
      80  Return
81 CONTROL_PULSO:
   81     GOSUB EMPEZAR
      83  SHIFTOUT DTA,CLK,1,[CONTROL]
    84    INPUT DTA
    85    PULSOUT CLK,10
    86    HATA=0
   87     FOR W=0 to 65500
      88     IF DTA=0 then SALIR
    89    NEXT W
     90   HATA=1        
 91 SALIR:  
     92   SHIFTIN DTA,CLK,0,[H1]
    93    OUTPUT DTA
      94  LOW DTA
      95  PULSOUT CLK,10
     96   INPUT DTA
    97    SHIFTIN DTA,CLK,0,[H0]
       98  PULSOUT CLK,10
      99  RETURN
100 DATO_TEMPERATURA:
     101   if ham<4200 then
       102   ISARET=1
       103   ISI1=(4200-HAM)/100
      104    ISI2=((4200-ham)//100)/10
     105     goto EXCESO
      106  endif
    107    ISI1=(HAM-3850)/100
    108    ISI2=((HAM-3850)//100)/10
109 EXCESO:
     110   if HAM>16384 then
       111   ISI1=0
    112      ISI2=0
   113     endif  
    114    RETURN          
115 DATO_HUMEDAD:
    116    p1=(28542-(54722**ham+ham))**ham-80    
   117     P2=655+(HAM*5)+(HAM**15917)         
   118     P3=(P2**2480)-(P2**2730)+P1  
   119     U1=p3/10
    120    U2=p3//10
 121       IF ham>3710 THEN
  122        u1=0
   123       U2=0
   124     ENDIF  
   125     return

1. en la linea 13,14, pone var ham.byte0, hambyte1, que significa esto?
2. en la linea 87 que funcion tiene este for?
3. cuando llega a la subrutina dato humedad y dato temperatura, no entiendo de donde toma valor el ham y porque se mueve de valor.
gracias por su atencion, saludos
 
Última edición por un moderador:
amigo...
te puedo colaborar en algo
tenes que revisar todas las variables.
vos sabes que var significa convertir o darle nombre a una variable de tamaño bite byte o word eso quiere decir por ejemplo que

rodrigo var word

es darle a word un nombre lo que es lo mismo darle un valor al nombre rodrigo un peso word.
me comprendes. entonces segun tus dudas el nombrar una funcion en la que se hace una operacion se toma en cuenta que esa variable es la que se opera es como decir 1+2 = 3

si al principio yo llamo a 1 como him, a 2 como her y a 3 como man diria entonces





siendo constantes

him con 1
her con 2
man con 3

inicio

him + her = man

el simplemente cojio una variable de nombre ho y le dio otro nombre de peso byte en el cual el peso del byte sea 0 o 1. fijate que el coloca ham.byte0, lo mismo mas abajo pero con un peso 1 y luego da valor a ham como word. eso con el fin de que los bytes sean solo 1nos o ceros.

el ejercicio indica que en un momento determinado el programa tiene que leer solo 0 o unos en una salida.

el for en tu siguiente pregunta indica que

la variable que el nombro como W que es de peso word, va ir en asenso hasta llegar a esa sifra osea
hasta 65500

es decir. 0.1.2.3...65500 en decimal. has la convercion decimal a binaria y te daras cuenta de que se trata.

si ham es un peso word osea que vale 65500, l ejercicio indica que hay que hacer una operacion lo cual se le cede a otra variable.

ejemplo

ham var word
p1 var word

inicio

p1 = ham + 48 '' quiere decir que p1 toma un valor de 65548
 
Última edición:
Hola de nuevo por aca me llegaron unos componentes nuevos que pedi, unos servos, DS1307, 24C16, LM315, entre otros ya ire haciendo pruebas con cada uno en fisico e ire comentando al respecto, ahora estoy con los servo motores son modelo SG-5010 de tower pro, y tengo una duda sobre que decisión tomar al respecto del programa a realizar ya hice varias pruebas con el comando PULSOUT, una con pulsadores externos y otra con un joystick tipo PS2 con ADC. Con el adc utilice un PIC16F877A ya que con el 16F628A no logre ver bien si tenia ADC y como configurarlo. Con el 16F877A y el adc logre mover el servomotor y posicionarlo en 0° grados con un pulsout de 150, ahora cuando lo mando a +180° o -180° con pulsout 255 o 50 tiende a seguir moverse pero por el tope interno que trae no se mueve pero si se siente que vibra, ahora lo coloque a 45 y 250 y se le quito, luego queria mejorar la velocidad ya que estaba muy lenta logre subir un poco la velocidad pero ahora me da un problema al posicionarlo se queda temblando.

Vi que con el comando PWM también se puede hacer pero como no es un PWM real no se si alguien lo ha realizado y si no da problemas y si hay otra manera de que sea rápido y seguro mover el motor, no digo que sea super rápido pero si lo suficientemente aceptable como para mover un brazo robot...saludosss
 
Última edición:
hola gente, yo por aqui de nuevo. bueno, les cuento como voy con el wiimotion jejeje... un fracazo total en mi esfuerzo, he estado todos estos dias tratando de leer primero el wiimotion directamente y despues el itg3205 y con eso estoy ahora. bueno, aqui les dejo el codigo para leer el itg que estoy intentando hacer funcionar ahora para ver si me dan una manito y me dicen de paso si esta bien asi como lo estoy haciendo. el codigo lo que hace, es leer el eje x y segun la lectura, mueve un servo que es lo unico que tengo para ver la señal externamente jeje... bueno, aca lo dejo. saludos y espero puedan ayudarme...

Código:
@ DEVICE MCLR_OFF, WDT_OFF, LVP_OFF, BOD_OFF, PWRT_ON, PROTECT_OFF
 DEFINE   OSC   4              ' Para trabajar con un cristal de 4MHz
 DEFINE I2C_HOLD 1
 trisa=%000000
 trisb=%00000000
 porta=%000000
 portb=%00000000
SDA VAR PORTB.1
 SCL VAR PORTB.2 
 
a1 var byte
a2 var byte
a3 var byte
a4 var byte
a5 var byte
a6 var byte
med1 var byte

leer:
I2CREAD sda,scl,%1101000,$29,[a1]
I2CREAD sda,scl,%1101000,$30,[a2]  
PAUSE 10
med1=a1+a2
pulsout portb.0,med1
pause10
goto leer
 
Última edición:
Hola D@rio.
Haber, un detalle que note en esta parte del código.
leer:
I2CREAD sda,scl,%1101000,$29,[a1]
I2CREAD sda,scl,%1101000,$30,[a2]
PAUSE 10
; ¿Cuanto pesa cada valor que ingresa a a1 y a a2? que son del tipo BYTE
med1=a1+a2 ; Lo pregunto porque al sumarlas puede ser que no quepan dentro de med1
pulsout portb.0,a2 ; ¿Que haces con med1? que también es del tipo BYTE
pause10
goto leer
 
Hola Darkbytes y D@rio en unas paginas a tras comente al respecto de los bit de cada parametro son de 16bits con un complemento a dos lo cual no se que significa, he visto que con el DS1307 se utiliza para mostrar los datos en la lcd un HEX2 pero a que se refiere y si tiene algo que ver?

Me imagino que A1 = GYRO_XOUT_L ; y ; A2 = GYRO_XOUT_H
que según el datasheet ambos suman 16bits con el complemento a 2
 
Hola Darkbytes y D@rio en unas paginas a tras comente al respecto de los bit de cada parametro son de 16bits con un complemento a dos lo cual no se que significa, he visto que con el DS1307 se utiliza para mostrar los datos en la lcd un HEX2 pero a que se refiere y si tiene algo que ver?

Me imagino que A1 = GYRO_XOUT_L ; y ; A2 = GYRO_XOUT_H
que según el datasheet ambos suman 16bits con el complemento a 2
Ok. Saludos.
Si, yo por eso le pregunte a D@rio sobre el peso de cada dato ingresado a A1 y A2
ya que una variable BYTE es de 8 BITS y al hacer A1+A2 el resultado será de 16 BITS
y no se podrá guardar dentro de la variable med1 por ser del tipo BYTE
Si esta bien declarar las variables como BYTE para leer la EEPROM porque es un BYTE
el que se leerá, como valor máximo se tendrá, FF o 255 en decimal que es el valor
de una localidad virgen en caso de una EEPROM. Si A1=255 se suma con A2=255 el resultado será 510
y excede la capacidad de med1. Por lo tanto med1 debe ser del tipo WORD
 
hola darkbytes, hola reyvilla.
bueno, lo que dicen es muy cierto y la verdad no lo habia tenido en cuenta jeje... les cuento que acabo de probar el programa cambiando la variable med1 del tipo byte por una variable word y sigue sin funcionar... les cuento que al encender el circuito, el servomotor se va al minimo, osea como si le estuviese llegando una señal de 0,5ms, me da la impresion de que el numero que le esta llegando es 0, osea que la variable no aumenta su numero.
pd: (el servo se mueve segun el numero de la variable med1)
saludosss
 
En la variable med1 justamente yo veo el problema, fíjate que lo mejor seria visualizar el valor de la variable para poder trabajarla, si no tienes una lcd puedes grabar el valor en la eeprom del pic y luego verla al leer el pic con el mismo programador y de esa manera ya tendrías una idea de los valores ya que si los valores están por debajo de 50 o por encima de 255 no te va a funcionar para mover el servo en este caso pareciera ser mayor siempre ya que son 16bit por eje, prueba grabando en la eeprom del pic como te indico es facil y no tienes que cambiar nada en el circuito solo agregar en el codigo (write 00,med1) y listo lo lees y ya tendrás el primer valor de referencia...saludoss

PD: Otra cosa que me acabo de dar cuenta es que las direcciones que tu colocas como

a1 = $29 y a2 = $30 estas serian a1 = $1D Y a2 = $1E ya que si colocas 29 y 30 serian en decimal pero como le colocas el símbolo $ lo transformas a hexadecimal y esa seria otra direccion de memoria...saludosss
 
Última edición:
D@rio, mira este ejemplo que adjunto, lo use para otro que transmite el valor del ADC vía serial.
Como el valor entregado por la lectura máxima del ADC es de 1024 (En realidad me entregaba 1023)
y ese valor no lo podía enviar vía serial, lo dividí entre 4 y en el receptor lo multiplicaba.
Aún no se como enviar valores WORD vía serial, Tengo una idea usando tres variables.
Una del tipo WORD y dos del tipo BYTE, usando el nombre de tus variables seria:
med1 VAR WORD
a1 VAR BYTE
a2 VAR BYTE
; Y luego hacer
ADCIN ,0,med1
a1=med1.HighByte
a2=med1.LowByte
luego enviar a1, después a2 y en el receptor sumarlas en otra variable WORD
No lo he hecho, pero puede funcionar. (Luego lo probare) :)
El ejemplo que realicé se encuentra por acá
Hasta luego y suerte

PD: Otra cosa que me acabo de dar cuenta es que las direcciones que tu colocas como

a1 = $29 y a2 = $30 estas serian a1 = $1D Y a2 = $1E ya que si colocas 29 y 30 serian en decimal pero como le colocas el símbolo $ lo transformas a hexadecimal y esa seria otra direccion de memoria...saludosss
Si. Ese es un detalle muy importante ;)
 

Adjuntos

  • 12F675 SERVO_POT.rar
    9.6 KB · Visitas: 112
Última edición:
Darkbytes, vi tu circuito y el código pero por ningún lado veo lo que indicas del envió serial de una variable tipo word y el problema lo tienes en el envió o a la hora de recibirlo?

PD: El standar para la trasmisión seria rs-232 en el envio de datos de 5,6, 7 u 8 bits a la ves, los que tienes que hacer en un tipo de tabla para enviar y recibir información de tal manera que al enviarla tenga una señalizacion especifica y al recibirla según la señalizacion puedas armar los datos sin ningún problema, puedes enviar un paquete de informacion con una señalizacion pero sera enviada de 8 bits a la vez por lo cual que al recibirla según la señalizacion debes ir ordenandola que seria lo mismo reconstitulirla para poder leer el dato completo, bueno eso si se tratase de varios valores y varias constantes cualquier cosa me avisas
 
Última edición:
Darkbytes, vi tu circuito y el código pero por ningún lado veo lo que indicas del envió serial de una variable tipo word y el problema lo tienes en el envió o a la hora de recibirlo?

PD: El standar para la trasmisión seria rs-232 en el envio de datos de 5,6, 7 u 8 bits a la ves, los que tienes que hacer en un tipo de tabla para enviar y recibir información de tal manera que al enviarla tenga una señalizacion especifica y al recibirla según la señalizacion puedas armar los datos sin ningún problema, puedes enviar un paquete de informacion con una señalizacion pero sera enviada de 8 bits a la vez por lo cual que al recibirla según la señalizacion debes ir ordenandola que seria lo mismo reconstitulirla para poder leer el dato completo, bueno eso si se tratase de varios valores y varias constantes cualquier cosa me avisas
Ok. Gracias reyvilla.
En ese ejemplo que subi no es donde hago el envio del ADC via serial sino en el del link
que puse mas abajo, ese ejemplo es el que use para el ejemplo final.

D@rio, mira este ejemplo que adjunto, lo use para otro que transmite el valor del ADC vía serial.

El ejemplo que realicé se encuentra por acá
Y Upps!! necesitaria ver algún ejemplo porque no entendi. :D
Gracias.
 
Última edición:
Hola muy buenas estoy de nuevo por acá realice un sistema de control para un brazo con servomotores el sistema lo hice con un control tipo ps2 con los dos joystick con un pot de 10k y 4 ADC del pic 16f877a, funciona muy bien algo lento cuando se controla con los joystick, pero logre agregar una sistema de grabado de posiciones del brazo, de tal manera que puedo hacer una secuencia completa y al ejecutarla se hace de manera rápida ya que el pic no pierde tiempo en leer los adc si no que en base a los datos guardados en la eeprom que seria como las coordenadas activa los motores de manera muy rápida. Ahora mi codigo para guardar los datos me funciona perfecto pero quisiera poder depurarlo un poco mas pensaba utilizar la sentencia for...next y un loockup o algo asi pero no me termina de dar.

El problema es el siguiente:
Pretendo guardar los ángulos de los servomotores en posiciones de memoria eeprom del pic.
para lograrlo me aprovecho de la variable donde trabajo los angulos de los motores en mi caso llamada MPOS1 de tipo word que va de 55 a 250.
Como son 6 datos a guardar continuamente se debe incrementar a la par la direccion de memoria lo cual quiere decir que si MPOS1 se guardo por primera ves en la direccion de memoria $00 y son 6 datos, el siguiente dato para esa variable debe ser guardado en la direccion de memoria $06 y asi con todos los demas no se si se entiende pero dejo el codigo que uso para lograrlo y ver si me echan una mano a mejorarlo.

Código para grabar los ángulos actuales de los 6 servomotores.

GRABANDO:

WRITE ADDRM1,MPOS1 'GRABA EN LA EEPROM EL VALOR DE MPOS1 EN LA DIRECCION ADDRM1
WRITE ADDRM2,MPOS2 'GRABA EN LA EEPROM EL VALOR DE MPOS2 EN LA DIRECCION ADDRM2
WRITE ADDRM3,MPOS3 'GRABA EN LA EEPROM EL VALOR DE MPOS3 EN LA DIRECCION ADDRM3
WRITE ADDRM4,MPOS4 'GRABA EN LA EEPROM EL VALOR DE MPOS4 EN LA DIRECCION ADDRM4
WRITE ADDRM5,MPOS5 'GRABA EN LA EEPROM EL VALOR DE MPOS5 EN LA DIRECCION ADDRM5
PAUSE 10

ADDRM1 = ADDRM1 + 5 'INCREMENTA ADDRM1 DE 5 EN 5 PARA DIRECCION DE MEMORIA
ADDRM2 = ADDRM2 + 5 'INCREMENTA ADDRM2 DE 5 EN 5 PARA DIRECCION DE MEMORIA
ADDRM3 = ADDRM3 + 5 'INCREMENTA ADDRM3 DE 5 EN 5 PARA DIRECCION DE MEMORIA
ADDRM4 = ADDRM4 + 5 'INCREMENTA ADDRM4 DE 5 EN 5 PARA DIRECCION DE MEMORIA
ADDRM5 = ADDRM5 + 5 'INCREMENTA ADDRM5 DE 5 EN 5 PARA DIRECCION DE MEMORIA

RETURN 'Retorna


*****************************************************
Cada vez que se va esta subrutina incrementa la dirección de memoria de 5 en 5 para lograr que al grabar nuevamente no se monten los datos uno sobre otro.

Así como esta funciona pero creo que con un next se puede mejorar...saludoss:)
 
Atrás
Arriba