Autor Tema: Problemas para controlar led RGB con PWM y ahora también ADC [Solucionado]  (Leído 8443 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Problemas para controlar led RGB con PWM
« Respuesta #15 en: 29 de Enero de 2013, 19:54:30 »
pwm0, pwm1 y pwm2 son las variables que controlan la potencia o duty de cada pin PWM.
pwm0, pwm1 y pwm2 son variables de tipo Byte, por lo que solo pueden contener valores comprendidos entre 0 y 255
Call _pwm_rb(pwm0, pwm1, pwm2) actualiza los tres PWM al mismo tiempo, porque si se realizara una funcion para
controlar o actualizar cada pwm por separado no funcionaria bien, los colores harian parpadeos extraños.

Código: [Seleccionar]
'***********************************************************
'Codigo original de dogflu66 (no es el codigo original)
'Tres PWM por software
'No entiendo donde tengo que variar el duty?
'Pic16F628A
'***********************************************************
'Configuración de fuses y reloj
Define CONF_WORD = 0x3f50  '0x2f50
Define CLOCK_FREQUENCY = 4
'Configuración de módulos
AllDigital  'Los pin analogicos/digitales trabajaran como digitales
TRISA = 0  'Puerto A configurado como salidas, execto RA5 que solo trabaja como entrada
TRISB = 0  'Puero B configurado como salidas
PORTB = 0  'Puerto B puesto a cero todos sus pin
'Rutina principal
main:
Dim cont As Byte  'word  'Contador incremento potencia de los PWMs
Dim pwm0 As Byte  'Potencia PWM 0
Dim pwm1 As Byte  'Potencia PWM 1
Dim pwm2 As Byte  'Potencia PWM 2
Dim x As Bit  'Variable auxiliar
pwm0 = 0  'Potencia inicial 0 PWM0
pwm1 = 0  'Potencia inicial 0 PWM1
pwm2 = 0  'Potencia inicial 0 PWM2
x = 0

While x = 0  'Bucle principal

Call _pwm_rb(pwm0, pwm1, pwm2)  'Controla y actualiza los PWMs
pwm0 = cont
pwm1 = cont
pwm1 = cont
cont = cont + 1
'If cont > 900 Then cont = 0

Wend

End                                               
'Funcion para practicas con control de potencia con 3 PWM (software)
'Para control con positivo comun
'Pin utilizado RB0 a RB2 del puerto B
'Frecuencia aproximada 230Hz a 8Mhz de CLK.
'Tres valores de entrada mediante _pwm0 a _pwm2
'Con valores comprendidos entre 0 a 255 pasos de potencia
Proc _pwm_rb(_pwm0 As Byte, _pwm1 As Byte, _pwm2 As Byte)
Const periodo = 255  'Periodo de la señal
Dim ctrl As Byte  'Lleva el tiempo transcurrido del periodo
If _pwm0 > 0 Then RB0 = 0  'Pin a OFF
If _pwm1 > 0 Then RB1 = 0  'Pin a OFF
If _pwm2 > 0 Then RB2 = 0  'Pin a OFF
ctrl = 0  'Comienza ciclo
While ctrl < periodo  'Mientras no se complete el periodo
If ctrl >= _pwm0 Then RB0 = 1  'Pin a ON
If ctrl >= _pwm1 Then RB1 = 1  'Pin a ON
If ctrl >= _pwm2 Then RB2 = 1  'Pin a ON
ctrl = ctrl + 1  'Tiempo transcurrido del periodo
Wend
End Proc
« Última modificación: 29 de Enero de 2013, 21:30:14 por dogflu66 »
Saludos desde Granada, España.

Desconectado Bregy

  • PIC12
  • **
  • Mensajes: 51
Re: Problemas para controlar led RGB con PWM
« Respuesta #16 en: 29 de Enero de 2013, 23:21:32 »
Amigo dogflu:
- Esa variable "x" que declaras no tiene mas funcion que hacer que el bucle funcione?

Esta linea que es lo que hace?
- Proc _pwm_rb(_pwm0 As Byte, _pwm1 As Byte, _pwm2 As Byte)

Por lo poco que se para hacer PWM por soft tienes que invocar a el timer0 y no veo donde lo invoques... si me equivoco dime entonces como se invoca...

Gracias amigo dogflu. :-/ :-/

Desconectado RockLee_89

  • PIC16
  • ***
  • Mensajes: 140
Re: Problemas para controlar led RGB con PWM
« Respuesta #17 en: 30 de Enero de 2013, 00:29:33 »
hola amigo Bregy en este ejemplo no uso ningun taimer
y en caso que quieras activar un taimer tienes que ir al registro itcon del pic el cual se encuentra en el datashet del pic

las funciones proc y function
hay no te puedo ayudar mucho ya aque apenas unos dias se que existen y mas o menos para que se pueden utilizar el amigo dogflu66 me explico el funcionamiento de las 2 pero aun no las leo como se debe para entenderlo

pero hablando buerdamente la instruccion proc funciona basicamente como si fuera una subrutina pero esta se llama mediante la instruccion cal y esta sirve para realizar alguna accion como el encendido o apgado de las salidas pwm

si quieres leer lo que me explico el amigo dogflu66  se encuentra en el ejemplo donde pedi ayuda es sobre multiplexacion de displey de 7 segmentos si quieres leerlo para ver si lo entiendes mejor que yo  :mrgreen: :mrgreen: :mrgreen:

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Problemas para controlar led RGB con PWM
« Respuesta #18 en: 30 de Enero de 2013, 05:47:56 »
Amigo dogflu:
- Esa variable "x" que declaras no tiene mas funcion que hacer que el bucle funcione?

Esta linea que es lo que hace?
- Proc _pwm_rb(_pwm0 As Byte, _pwm1 As Byte, _pwm2 As Byte)

Por lo poco que se para hacer PWM por soft tienes que invocar a el timer0 y no veo donde lo invoques... si me equivoco dime entonces como se invoca...

Gracias amigo dogflu. :-/ :-/


La variable x es para que el bucle funcione.

***************************************
'------------------------------------------------------
Proc _pwm_rb(_pwm0 as Byte, _pwm1 as Byte, _pwm2 as Byte)

... cuerpo de la función

End Proc 'Terminación de la función
'-------------------------------------------------------

Todo eso es equivalente a la siguiente subrutina:
'----------------------------------
Dim _pwm0 as Byte
Dim _pwm1 as Byte
Dim _pwm2 as Byte

_pwm_rb:

.... cuerpo de la subrutina

Return 'Terminación de la subrutina
'----------------------------------

Vamos por pasos:

¿Qué es mejor; el freno de tambor o los frenos de disco?
¿Qué es mejor, la frenada normal o con abs?

Lo mejor para ilustrar los casos anteriores no es buscar la diferencia, si no la igualdad, y es que en todos los casos frenas. Solo cuando buscas una frenada más corta es cuando se verifican las diferencias entre unos métodos y otros.

Pues lo mismo pasa con las interrupciones, si la rutina principal de tu programa no demanda controlar la función de los pwm por interrupciones, mejor sigues sin usar las interrupciones hasta que tengas la necesidad. Las interrupciones por si solas son complicadas así que te recomiendo que no te metas a mayores hasta tener claro el código actual. Más adelante tendrás tiempo de mejorar el código con interrupciones y con comunicación entre pic, ya tendrás tiempo de correr.

Hace más de 30 años que no se usa el comando goto en la programación del lenguaje Basic, fue sustituido por las subrutinas, concretando; por el gosub/return, y el siguiente paso son las funciones que sustituyen a las subrutinas.
« Última modificación: 30 de Enero de 2013, 06:34:47 por dogflu66 »
Saludos desde Granada, España.

Desconectado Bregy

  • PIC12
  • **
  • Mensajes: 51
Re: Problemas para controlar led RGB con PWM
« Respuesta #19 en: 30 de Enero de 2013, 13:28:37 »
Hola de nuevo y gracias por toda la ayuda tengo una duda...

El codigo fue tomado de uno de los tutoriales de dogflu y lo intente modificar para un 16f877a...

Código: [Seleccionar]
Define CONF_WORD = 0x2f10
Define CLOCK_FREQUENCY = 4
'********************************** PIC Entrenadora BASIC (PicEBasic)******************************
'NOMBRE: 16F88_Pic_EBasic_Ejemplo_27
'MICRO: PIC16f877a
'FECHA/AUTOR: 08/07 - By COS
'Version: 1.0
'Estudio del modulo ADC
'xD Se lo robe a Dogflu66 y lo intente pasar a 16f887A
'*****************************************************************************************************
'Define SIMULATION_WAITMS_VALUE = 1  'suprime los tiempos de espera Waitms, solo para el simulador
'******************************************************************************************************
'_____Variables
Dim contenedor As Word  'contendra el valor de la entrada del ADC
'_____ASIGNACION DE I/O y valores de inicio de las salidas, configracion ADC

ADCON0 = %11000001
ADCON1 = %00001110

CMCON = 0x07  'comparador a off
TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'puerto B como salidas
TRISA.0 = 1  'como entrada (RA0, adc)
TRISC = 0

'_____Main Programa
WaitMs 25
main:
ADCON0.GO = 1  'A/D conversion en progreso
While ADCON0.GO = 1  'pausa hasta terminar la conversion
Wend
contenedor.HB = ADRESH  'asignacion de valores, tiene la conversion a 8Bit
contenedor.LB = ADRESL  'asignacion de valores
'adc_4 y adc_4.LB no tendran valores utilies, solo el byte alto de adc_4

If contenedor.HB > 150 Then
PORTC.1 = 1
WaitMs 500
PORTC.1 = 0
Endif

Goto main
End                                 

No quiero que me den todo un nuevo codigo solo que me aclaren unas dudas como que entre que valores me va a arrojar el adc por que pongo 500 no me deja pongo 2000 tampoco me deja y mientras escribia esto me di cuenta de que creo que es por que la variable contenedor esta declarada como byte, pero igual solo diganme que esta mal...

El programa solo hace que cuando la lectura supere tal valor se encienda un led...

Les estoy muy agradecido por ayudarme mucho cada dia aprendo mas gracias a ustedes. :) :) :) :)
« Última modificación: 30 de Enero de 2013, 13:34:35 por Bregy »

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Problemas para controlar led RGB con PWM
« Respuesta #20 en: 30 de Enero de 2013, 20:03:26 »
Define CONF_WORD = 0x3f71
Define CLOCK_FREQUENCY = 4
'********************************** PIC Entrenadora BASIC (PicEBasic)******************************
'NOMBRE: 16F88_Pic_EBasic_Ejemplo_27
'MICRO: PIC16f877a
'FECHA/AUTOR: 08/07 - By COS
'Version: 1.0
'Estudio del modulo ADC
'xD Se lo robe a Dogflu66 y lo intente pasar a 16f887A
'*****************************************************************************************************
'Define SIMULATION_WAITMS_VALUE = 1  'suprime los tiempos de espera Waitms, solo para el simulador
'******************************************************************************************************
'_____Variables
Dim contenedor As Word  'contendra el valor de la entrada del ADC
'_____ASIGNACION DE I/O y valores de inicio de las salidas, configracion ADC
'ADCON1 = %00000111  'Puerto A como digital
'ADCON1 = %11000000  'Salida lectura 10Bit, F/64, Todo el puerto A analogico, Vdd, Vss
ADCON1 = %01000000  'Salida lectura 8Bit, F/64, todo el puerto A analogico, Vdd, Vss
ADCON0 = %10000001  'F/64, Modulo On, lectura en canal AN0 (Pin 2)

CMCON = 0x07  'comparador a off
TRISA = 0x00  'Puerto A como salidas
TRISB = 0x00  'puerto B como salidas
TRISC = 0  'Puerto C como salidas
TRISA.0 = 1  'como entrada (RA0, adc)

'_____Main Programa
WaitMs 20  'Espera que el modulo ADC se configure
main:
   ADCON0.GO = 1  'A/D conversion en progreso
   While ADCON0.GO = 1  'pausa hasta terminar la conversion
   Wend
   contenedor.HB = ADRESH  'asignacion de valores, tiene la conversion a 8Bit
   contenedor.LB = ADRESL  'asignacion de valores
   'adc_4 y adc_4.LB no tendran valores utilies, solo el byte alto de adc_4
   
   If contenedor.HB > 150 Then
      PORTC.1 = 1
      WaitMs 500
      PORTC.1 = 0
   Endif
   
Goto main
End


Corregido; en teoría tendría que funcionar en la realidad, no tengo para probarlo fisicamente.
Para trabajar con el simulador con el ADC estando la salida de su lectura configurada a 8bit tienes que realizar la siguiente conversión:
(150x1023)/255 = 602 puntos del potenciómetro del simulador. If contenedor.HB > 150 esto son aproximadamente 602 puntos en el simulador porque las escalas no son las mismas.
El simulador tendría que tener la posibilidad de cambiar la escala de la resolución de entrada y poder ponerla a 8bit, pero no tiene la opción.
Pero ten en cuenta que solo pasa en el simulador.
« Última modificación: 30 de Enero de 2013, 20:11:10 por dogflu66 »
Saludos desde Granada, España.

Desconectado Bregy

  • PIC12
  • **
  • Mensajes: 51
Re: Problemas para controlar led RGB con PWM
« Respuesta #21 en: 30 de Enero de 2013, 23:26:46 »
Dogflu entonces mi código para 16f877a estaba bien por que lo acabo de probar y si funciona... :-/ :-/ :-/
Gracias por ayudarme...

Haber dime si esta bien mi razonamiento para convertir señales de micrófono a ADC:

Primero tendría que amplificar el micrófono hasta el voltaje de referencia osea 5v, verdad?
Luego tengo que hacer el programa como enantes y listo ya esta listo para ser usado en aplicaciones?

Si obvie un paso hasmelo saber...

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Problemas para controlar led RGB con PWM y ahora también ADC
« Respuesta #22 en: 31 de Enero de 2013, 09:38:10 »
En teoria sí.

Si tienes algun problema pegunta en el foro tecnico a ver si alguien ha trabajado con acondicionador de señal de microfono a pic.
« Última modificación: 31 de Enero de 2013, 19:31:55 por dogflu66 »
Saludos desde Granada, España.

Desconectado Bregy

  • PIC12
  • **
  • Mensajes: 51
Re: Problemas para controlar led RGB con PWM y ahora también ADC
« Respuesta #23 en: 01 de Febrero de 2013, 02:08:40 »
Amigos como puedo reducir este codigo?:
Código: [Seleccionar]
'===============================================================
'Codigo de ADC aplicado al pic 16f877a
'No tengo placa entrenadora solo mi proteus y mi protoboard
'No es codigo robado de nadie xD, por fin!
'===============================================================

'Defino parametros del microcontrolador
Define CONF_WORD = 0x3f71
Define CLOCK_FREQUENCY = 4

'Configuro puertos
TRISA = 0
TRISB = 0
TRISC = 0
TRISD = 0
ADCON1 = 0x0e

'Declaro una variable an0
Dim an0 As Word

'Programa:
'Analisa el valor del ADC
'Si cumple la condicion enciende un led
loop:
Adcin 0, an0
If an0 > 50 Then
RB0 = 1
Else
RB0 = 0
Endif
If an0 > 100 Then
RB1 = 1
Else
RB1 = 0
Endif
If an0 > 150 Then
RB2 = 1
Else
RB2 = 0
Endif
If an0 > 200 Then
RB3 = 1
Else
RB3 = 0
Endif
Goto loop
End                                               

Desconectado RockLee_89

  • PIC16
  • ***
  • Mensajes: 140
Re: Problemas para controlar led RGB con PWM y ahora también ADC
« Respuesta #24 en: 01 de Febrero de 2013, 10:22:10 »
hola Bregy y cual es el motivo para reducir este codigo
saludos

Desconectado Bregy

  • PIC12
  • **
  • Mensajes: 51
Re: Problemas para controlar led RGB con PWM y ahora también ADC
« Respuesta #25 en: 01 de Febrero de 2013, 11:59:27 »
Hola Ernestoes que yo creo que se puede recucir aun mas :D y si no es posible esta bien.


 

anything