Curso de programación de PIC en PICBasic Pro

Que tal muchachos
estoy retomando lo del driver para servomotor con encoder en encuadratura
estoy trabajando con el pic 18f4431 que tiene su propio modulo QEI
gracias al ejemplo de autotronico he podido hacer algunos ejercicios con este pic
el problema que tengo ahorita es manejar las variables coma flotante (decimales)
para los parametros PID. alguien a manejado variables de tipo coma flotante en PBP? algun ejemplo?
Saludos arturouc
Adjunto las librerias necesarias para trabajar con punto flotante en PBP
mas el ejemplo de MELABS (microEngineering Labs, Inc.) que no pude compilar. :rolleyes:
Mas referencias sobre este tema se encuentran en estos enlaces. Enlace1 Enlace2 Enlace3
Ok. Espero te puedan servir.
 

Adjuntos

  • PBP Floating Point.rar
    290.4 KB · Visitas: 196
Bien, pues ya pude compilar el ejemplo FP.bas
La cosa fue mas sencilla de lo que me esperaba, y todos los errores que me aparecian,
se debian a la falta de una definición. Esta-> Define __16F84 1
Esta definición si esta declarada en el ejemplo FP.bas
Y en los enlaces que indique arriba el ejemplo no incluye esa definición en el programa.
Así que abri el ejemplo FP.bas con MicroCode Studio, le di a compilar normalmente con F9
y el programa se compilo perfectamente y sin usar MPASM :)
El ejemplo es para un 16F84 no probe con otros de gama mas alta.

Ok. Ahora separe solo los archivos necesarios para usar punto flotante en PBP
Estos archivos de deben copiar dentro de la carpeta de instalación de PBP Compiler.
Tambien hice el ejemplo de la simulación en Proteus para ver el resultado.
Adjunto los archivos del ejemplo y las librerias que se requieren solamente para PBP

PD. En el archivo adjunto PBP FP Library vienen otros 3 ejemplos mas para el 16F877
4FUNC32.BAS, 4FUNCTN.BAS y AB-CD.BAS

Como dijo arturouc esperamos mas ejemplos con estas librerias...
Suerte y hasta luego. :apreton:
 

Adjuntos

  • PBP Ejemplo FP Compilado.rar
    10.9 KB · Visitas: 200
  • PBP FP Library.rar
    73.3 KB · Visitas: 155
Última edición:
gracias Darkbytes por los ejemplos
este es el vídeo de simulación en proteus

este es el codigo:
Código:
   define OSC 20
    DEFINE LCD_DREG PORTD   
    DEFINE LCD_DBIT 4      
    DEFINE LCD_BITS 4      
    DEFINE LCD_RSREG PORTE  
    DEFINE LCD_RSBIT 0      
    DEFINE LCD_EREG PORTE   
    DEFINE LCD_EBIT 1       
    DEFINE LCD_LINES 2      
    DEFINE LCD_COMMANDUS 2000   
    DEFINE LCD_DATAUS 50    
    DEFINE ADC_BITS 8       
    DEFINE ADC_CLOCK 3      
    DEFINE ADC_SAMPLEUS 50  
    DEFINE CCP2_REG PORTC   
    DEFINE CCP2_BIT 1       
                                          
'------------Variables-------------

    mot_pwr  var    word  
    Upos     var    word
    vel      var    word      
    pot_val  var    byte        
    posicion var    word  
    posH     var    byte
    posL     var    byte
    posHtem  var    byte   
    FreMot  var     word
    a       var     word
    b       var     word
    c       var     word
    rt      var     word
    eT      var     word
    iT      var     word
    dT      var     word
    yT      var     word
    uT      var     word
    iT0     var     word
    eT0     var     word
    vmax    var     word
    vmin    var     word   
    	 
'----------Initialization----------
    
    CCP1CON = %00111111         
    ANSEL0 = %00000001          
    ANSEL1 = %00000000            
    TRISA = %00011111          
    LATA  = %00000000           
    TRISB = %00000000           
    TRISC = %00010000          
    QEICON = %10001000          
    PORTC.0 = 1                 
    PORTC.1 = 0                  
    LCDOUT $FE, $80, "  Iniciando... "   
    LCDOUT $FE, $C0, " parametros... "
    'pause 500  
    fremot = 15000                  'frecuencia para el hpwm
    PORTC.0 = 0                 
    PORTC.3 = 0                           
    upos=1                                                         
    posicion= 0                 'variable posicion real       
    POSCNTH = 0                 
    POSCNTL = 0         
    vmin= 125                   'pwm minimo para el motor
    vmax= 255                   'pwm maximo para el motor
    it0= 0                      'variable para calulo de termino derivarivo
    et0= 0                      'variable para calculo del error
    a=2                         'parametro proporcional
    b=1/2                       'parametro integral
    c=1/20                      'parametro derivativo
             
lop:                                                                                           
    gosub CalPos                'ir a calcular la posicion actual
    
     gosub campos               'ir a ver si cambio la posicion
     gosub calvel               'calcular PWM para el motor
    IF mot_pwr > posicion then  'si set point es mayor que posicion actual                         
        HPWM 1, vel, fremot     'sale PWM por CCP1
        HPWM 2, 0, fremot       'por CCP2 no sale nada
    else                        'en caso contrario posicion actual > set point
        HPWM 2, vel, fremot     'no sale nada por CCP1  
        HPWM 1, 0, fremot       'sale pwm por CCP2
    endif                             
    gosub lcd                   'muestra informacion en LCD
    GOTO lop                      
    end  
    
lcd:                            'sub que muestra en lcd

    LCDOUT $FE, $80, "SP= ",dec4 mot_pwr," ", dec4 vel   
                               
    LCDOUT $FE, $C0, "posicion = ",DEC5 POSIcION
                               
    return    
CalPos:                        'sub para calcular posicion
    posH = POSCNTH
    posL = POSCNTL
    POShTEM = POSCNTH
    IF posh - poshtem = 0 then goto Listo
    posH = POSCNTH
    posL = POSCNTL    
Listo:    
    POSIcION = 256*posh + posL 'se convierte en 16 bit la pos
    yT=posicion
    RETURN  
campos:                        'sub para cambiar de posicion
    ADCIN 0, pot_val   
    rT=pot_val * 8
    'if pot_val <200 then  vel=200
                 
    mot_pwr = rT 'POT_VAL '11*pot_val/16 + 77
    'mot_pwr = mot_pwr '* 2
    return         
calvel:                  'CALCULO DEL PWM CON PID
    eT = abs (rT - yT)   'calculo del error
    iT = b*eT + iT0      'calculo de valor integral (magnitud del error)
    dT = c * (eT - eT0)  'calculo del valor derivativo (tiempo de respuesta)
    uT = iT + a * eT + dT 'valor del PID
    if uT> vmax then      'si la salida del PID es mayor que el valor de PWM
        uT = vmax          'que puedo mandar asignale el valor 255
    else
        if uT< vmin then uT=vmin  'PWM minimo que quiero enviar
    endif
    vel=uT                'velocidad del motor en PWM
        
    return

falta incluir variables en punto flotante...
este driver es con el objetivo de mover un robot paralelo
que ya les había mostrado aqui, pero ahora es de aluminio
luego les subo un vídeo...
 

Adjuntos

  • servodriver 18f4431_8feb2012.rar
    45.3 KB · Visitas: 105
  • servo driver en proteus.rar
    19.3 KB · Visitas: 102
Última edición:
D@rio

Disculpa mi demora, pero estuve ocupado con temas laborales. Desconozco sobre que esquema circuital de conexiones estas trabajando, por eso se desconoce como esta seteado el ITG-3205. De lo que he leido la Datasheet, he interpretado lo siguiente:

1) Registro 67
- Se debe definir la fuente del Clock de Entrada en el PowerUp con CKL-SEL.
- Se deben habilitar los "Gyro's" a usar alguno/todos en nuestra aplicación con STBY_XG y/ó STBY_YG y/ó STBY_ZG. Para conocer bien el funcionamiento yo habilitaria uno solo.

2) Registro 22
- Se debe definir el fondo de escala FS_SEL dado que el Reset Inicial en el PowerUp lo pone a 00h y es necesario ajustarlo a 03h !!!.
- El DLPF_CFG ajusta la configuración del filtro digital y esta relacionado con el SMPLRT_DIV del Registro 21 y entre ambos determinan la tasa de refresco en las mediciones de los Gyro's.

3) Registro 21
- Se debe ajustar el SMPLRT_DIV que esta relacionado con el DLPF_CFG del Registro 22.

4) Registro 23
- Cargar "0" en los bit's 1 y 3.
- Poner a "1" el INT_ANYRD_2CLEAR para que se pueda leer cualquier Registro.
- El bit RAW_RDY_EN habilita al RAW_DATA_RDY del Registro 26 para que indique la disponibilidad de datos nuevos en los Registros 27 ÷ 32 de los Gyro's y de esa forma la aplicación se entera de todas las actualizaciones de posición de todos los Gyro's. Aunque se pueden leer en cualquier momento los Registros 27 ÷ 32 no podras saber si hubo algun cambio desde la lectura anterior.



Hay muchos más Registros, algunos de solo Lectura y otros de Lectura y/ó Escritura que en definitiva se usan dependiendo de la aplicación/circuito que se le de a este "Sensor/Detector de 3D". Hay otros que de seguro no les di importancia y son tanto o más importantes que los que cite.

Dado que es muy tedioso saber en que condiciones esta conectado, supongo que tendra algun µControlador el control que tienes y que desconocemos que programa tiene dicho µControlador, por lo tanto no podemos saber como realiza el seteo inicial.

Podria ser interesante ya que tu has realizado un circuito para pruebas y programado algo especifico en PBP; cambiar el programa para leer de una sola vez el estado de todos los Registros, en formato Hexadecimal y poder anotarlos en algun lado/posición de Memoria de tu circuito de pruebas.


El tema de los registros de los Gyro's/Temperatura y el Doble Byte con Complemento a 2 solo me centre en "http://es.wikipedia.org/wiki/Complemento_a_dos" y si bien muestra un ejemplo con 4 bit's se traslada de forma comprensible a los 16 bit's que nos entregan los Gyro's con su parte H y L.


Hasta aca llegue y creo que aun queda mucho por investigar, pero es necesario comenzar a hacer alguna prueba para que empieze a darnos respuestas el ITG y saber si analizamos en el sentido correcto o no. Disculpa lo largo del presente y quedo a tu disposición.



Saludos, JuanKa.-
 
hola juanka.
gracias por el tiempo que dedicaste a tratar de ayudarme, estoy muy agradecido. (y) te cuento que estuve haciendo algunas pruebas de lectura del gyro en la pc utilizando el serial comunicator del microcode. configurando el FS_SEL a 03h, pude leer la parte baja del eje X y este es el que me da la medida que necesito para lograr lo que estoy intentando hacer. el eje X en su parte baja, me da una lectura inicial de 150, lo que equivale a un pulso de salida de 1.5ms con lo que el servo se mantiene en una posision central si el gyro no se mueve. si todo estuviese bien, al mover el gyro hacia la izquierda, el servo se moveria hacia la izquierda, si yo moviese el gyro a la derecha, el servo se muoveria a la derecha. el unico problema en esto ahora, es que esa lectura, es erratica, por lo que el servo se mueve como loco para todos lados si yo lo muevo, incluso si yo lo dejo quieto, en la pantalla del serial comunicator se ve una variacion desde 150 a 165. sospecho que todavia deberia configurar algun registro que seguramente tiene que ver con eso. seguire investigando y sigo escuchando :D seguimos en contacto, saludosss y gracias de nuevo.
edit: aca te dejo el codigo que escribi para lograr lo que te conte.
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
 define I2C_SCLOUT 1
 trisa=%000000
 trisb=%00000000
 porta=%000000
 portb=%00000000
SDA VAR PORTB.1
 SCL VAR PORTB.2 
 
a1 var byte
a2 var byte
x var byte
clear

leer:
i2cwrite sda,scl,%11010000,22,["03h"]
I2CREAD sda,scl,%11010000,29,[a1]  
I2CREAD sda,scl,%11010000,30,[a2] 
pulsout portb.3,a2
pause 10
goto leer
 
Última edición:
Hola a todos, he estado buscando a lo largo de este post como hacer una cosa pero aún no lo he conseguido.

Lo que trato de hacer es muy simple:

Tengo 4 leds y un pulsador. Los leds están ejecutando una rutina, al pulsar el pulsador pasan a otra, al pulsar de nuevo vuelven a cambiar...

Solo consigo hacer un cambio de rutina, pero de ahí no salgo...
 
Hola a todos, he estado buscando a lo largo de este post como hacer una cosa pero aún no lo he conseguido.

Lo que trato de hacer es muy simple:

Tengo 4 leds y un pulsador. Los leds están ejecutando una rutina, al pulsar el pulsador pasan a otra, al pulsar de nuevo vuelven a cambiar...

Solo consigo hacer un cambio de rutina, pero de ahí no salgo...

Voy a buscarlo creo que lo tengo por ahi:unsure:
 
Última edición:
Hola amigo Yiroshi. Lo que has posteado es para manejar 4 interrupciones distintas y yo quiero manejar varias rutinas a través de una sola interrupción (ademas está en assembler y la verdad es que no lo manejo)

Gracias!
 
Buenas noches amigos, soy nuevo en la programación de PIC´s, alguien me puede decir como utilizar un GLCD en PBP? como hacer las librerias, alguien tiene algún programa ejemplo? gracias
Saludos. Aqui hay algunos ejemplos para un GLCD NOKIA
Y Aqui dejo otros más son en PICBASIC pero para Proton.
Adjunto el programa GLCD Font Creator (Gratuito) para MikroBasic mas unas librerias.

En este enlace hay un código para PBP usando un PIC16F877 con un GLCD KS0108
Suerte y hasta luego.
 

Adjuntos

  • GLCD Proton 001.rar
    29.9 KB · Visitas: 85
  • GLCD Proton 003.rar
    1.3 MB · Visitas: 94
  • glcd_font_creator_v120.zip
    1.9 MB · Visitas: 110
  • xglcd_lib_v100.zip
    233 KB · Visitas: 88
hola que tal,

tengo algo de tiempo enseñandome a programar con este programa, se "supone" que se lo basico pero el maestro nos dejo una practica muy sencilla y no supe como hacerla por lo que recurro a ustedes.

1.- utilizando la pic 16f877, que todo lo que entre en el puerto d salga por el puerto b, digamos que si pongo en alto d0 el puerto b0 se ponga en alto, o si meto varios en el puerto d esas mismas señales salgan por el puerto b

2.- seria basicamente lo mismo que en el primero pero solo se utilizaria el pueto b (4 puerto como entrada y cuatro como salida). digamos que si pongo en alto b0 se ponga en alto b4, y si pongo en alto b1 se ponga en alto b5. y asi susesivamente.


trate de hacerlo con condicionantes pero se hacen muchas condicionantes y quisiera saber si alguien sabe como hacer esto de una manera sencilla.

de antemano gracias y estare pendiente de sus respuestas.
 
1.- utilizando la pic 16f877, que todo lo que entre en el puerto d salga por el puerto b, digamos que si pongo en alto d0 el puerto b0 se ponga en alto, o si meto varios en el puerto d esas mismas señales salgan por el puerto b
Trisb=0
Trisd=255
main:
portb=portd
goto main

2.- seria basicamente lo mismo que en el primero pero solo se utilizaria el pueto b (4 puerto como entrada y cuatro como salida). digamos que si pongo en alto b0 se ponga en alto b4, y si pongo en alto b1 se ponga en alto b5. y asi susesivamente.

Trisb=%1111
Main:
portb.4=portb.0
portb.5=portb.1
portb.6=portb.2
portb.7=portb.3
Goto main

y asi deberia funcionar (no he echo la prueba:D)
 
Última edición:
:unsure:

Oigan... alguien me puede confirmar o rechazar mi teoria de que con el pic 16f628A no se puede utilizar el RA5/MCLR/vpp como puerto Digital IO y ademas usar el Oscilador interno...

o lo que es lo mismo no es valido si pongo
@ DEVICE INTRC_OSC
@ DEVICE MCLR_OFF
porque se deshabilita el oscilador interno...

y se deberia poner...
@ DEVICE INTRC_OSC
@ DEVICE MCLR_On
ademas de utilizar una resistencia de 4k7 de RA5/MCLR/vpp a vdd...

Cierto o Falso?
 
Última edición:
:unsure:

Oigan... alguien me puede confirmar o rechazar mi teoria de que con el pic 16f628A no se puede utilizar el RA5/MCLR/vpp como puerto Digital IO y ademas usar el Oscilador interno...

o lo que es lo mismo no es valido si pongo
@ DEVICE INTRC_OSC
@ DEVICE MCLR_OFF
porque se deshabilita el oscilador interno...

y se deberia poner...
@ DEVICE INTRC_OSC
@ DEVICE MCLR_On
ademas de utilizar una resistencia de 4k7 de RA5/MCLR/vpp a vdd...

Cierto o Falso?

Saludos lubeck.
Haber si entendi, lo de usar RA5 como IO pues ya se sabe que solo es Input.
Ahora, yo he usado
@ DEVICE INTRC_OSC,MCLR_OFF
; ó
@ DEVICE INTRC_OSC_NOCLKOUT,MCLR_OFF
Para usar RA5 como entrada, y el oscilador interno siempre ha funcionado.
Lo unico que pasa es que no existe la función de RESET

Por cierto, sobre el segundo código que escribiste arriba para el amigo alejandrozama
dejame decirte que si funciona, lo probe sobre protoboard.

;************************************************************************
Una cosa rara que estoy notando en este momento y que nunca se me habia ocurrido comprobar es.
La palabra de configuración INTRC_OSC se refiere a que el oscilador interno tendra salida de clock por RA6.
y la palabra de configuración INTRC_OSC_NOCLKOUT que el oscilador interno no tendra salida de clock.
Porque se libera el pin RA6 para ser usado como IO

En la hoja de datos dice esto:

INTRC is now called INTOSC.
Timer1 Oscillator is now designed for 32.768 kHz operation. In the PIC16F627/628,
the Timer1 oscillator was designed to run up to 200 kHz.


Note 1: INTOSC with RA6 = I/O or RC with RA6 = I/O.
2: INTOSC with RA6 = CLKOUT or RC with RA6 = CLKOUT.


Bien pues, configure el oscilador interno de las dos formas y nada que tengo salida de clock por RA6 :confused:
En cambio si lo configuro con oscilador a Xtal (Use uno de 4Mhz) Si que tengo salida de clock (Obvio)
Use osciloscopio y frecuencimetro para esta prueba.
Lo raro es que configurando el PIC para oscilador interno no obtuve salida de clock.
Y configure RA6 como salida.
 
Última edición:
Hola Dark....

Haber si entendi, lo de usar RA5 como IO pues ya se sabe que solo es Input.
:oops: tienes razon me resbale... RA5 es solo input

La palabra de configuración INTRC_OSC se refiere a que el oscilador interno tendra salida de clock por RA6.
y la palabra de configuración INTRC_OSC_NOCLKOUT que el oscilador interno no tendra salida de clock.

segun el archivo inc de pbp estos dos son lo mismo...
INTRC_OSC_CLKOUT equ 3FEC0011h ; XX XXXX XXX1 XX01
INTOSC_OSC_CLKOUT equ 3FEC0011h ; XX XXXX XXX1 XX01

y estos tres son lo mismo....
INTRC_OSC_NOCLKOUT equ 3FEC0010h ; XX XXXX XXX1 XX00
INTOSC_OSC_NOCLKOUT equ 3FEC0010h ; XX XXXX XXX1 XX00
INTRC_OSC equ 3FEC0010h ; XX XXXX XXX1 XX00

el valor 3FEC0011h clkout tiene salida por ra6
y el valor 3FEC0010h noclkout no tiene salida....

(dato solo como reafirmacion.)

Timer1 Oscillator is now designed for 32.768 kHz operation. In the PIC16F627/628,
the Timer1 oscillator was designed to run up to 200 kHz.
yo estoy intentando usar el timer1 como entrada de oscilador con el cristal de 32.768...

pero se me queda pasmado el pic, lo tengo con un lcd y no aparece nada... solo se ve la primer linea con los cuadritos negros y la segunda linea nada (tengo un lcd de 16x2)

anexo simulacion que si funciona pero en la realidad no.... por si alguien tiene chance de analizarlo, seguramente es algo tonto que estoy pasando por alto... (probe con tres pics y dos lcd que supuestamente funcionan y lo mismo, revice 800mil veces las conexiones en el proto) :D

Bien pues, configure el oscilador interno de las dos formas y nada que tengo salida de clock por RA6
En cambio si lo configuro con oscilador a Xtal (Use uno de 4Mhz) Si que tengo salida de clock (Obvio)
Use osciloscopio y frecuencimetro para esta prueba.
Lo raro es que configurando el PIC para oscilador interno no obtuve salida de clock.
Y configure RA6 como salida.

entonces deduzco que en lo que basaba mi teoria del mcrl y el oscilador no se refiere al oscilador en si, sino a que se deshabilita el reloj del ra6 no?

segun el datashit...

Dibujo.JPG
 

Adjuntos

  • Futbolitos.rar
    21.1 KB · Visitas: 88
Última edición:
Atrás
Arriba