# Controlar brillo de LED con PWM en PIC16F628A



## thekako (Mar 1, 2016)

Buenas, recurro a este foro para pedir ayuda, si es que alguien sabe como hacer para encender un led pero de a poco , cambiando su brillo, intensidad, a través del tiempo y una vez encendido apagarlo lentamente de la misma manera. Sé como hacer encender y apagar led, solo que se hagan lentamente cambiando su brillo de menos a más a traves del tiempo no se como hacerlo en software Programo en C con CCS.
y tengo esto por ahora pero no me funciona:


```
#include "C:\\librerias\\16F628A.h"
#use delay(clock = 20000000)
#fuses HS, NOWDT,PUT,BROWNOUT,NOMCLR,NOLVP,PROTECT,NOCPD
#use fast_io(A) // estandar de entrada y salidas de los puertos, necesario para que funcione
#use fast_io(B)
#zero_ram
int data=0,time=0;
void main(){ 
 
set_tris_b(0b00000000);
delay_ms(50); 
setup_timer_2(T2_DIV_BY_1,254,1); 
setup_ccp1(ccp_pwm); 
 
while(1){ 
   data=data+5; 
   if(data==255){data=0;} 
   delay_ms(10+time); 
   set_pwm1_duty(data); 
  } 
}
```
 ...


----------



## ruben90 (Mar 1, 2016)

Eso se realiza utilizando PWM, verifica si el PIC contiene el módulo CCP (modo PWM) ya que será más fácil programarlo. Si no, tendrás que calcular los tiempos de encendido y apagado del Puerto, esto se realiza calculando los tiempos.
*****************************************************
Revisando el datasheet del PIC (páginas 58 y 59) si contiene el modulo.
Lo que necesitas es declarar los registros y calcular el periodo (1kHz, 2kHz,10kHz) que te funcione.
El datasheet contiene las fórmulas.

Si utilizas el CCS ahí un libro muy bueno, no me acuerdo muy bien del nombre pero en Google búscalo como "Libro CCS Proteus".
Espero haberte ayudado, Saludos.


----------



## thekako (Mar 1, 2016)

Si lo tiene, si en el codigo lo estoy utilizando y nisiquiera prende RB3, no se si me falta agregar cosas al diseño de proteus... e hize todos los calculos que necesitaba 4kHZ y obtuve este codigo nuevo:


```
#include "C:\\librerias\\16F628A.h"
#use delay(clock = 20000000)
#fuses HS, NOWDT,PUT,BROWNOUT,NOMCLR,NOLVP,PROTECT,NOCPD
#use fast_io(A) // estandar de entrada y salidas de los puertos, necesario para que funcione
#use fast_io(B)
#zero_ram

int16 data=0;
void main(){ 
 
set_tris_b(0b00000000);
setup_timer_2(T2_DIV_BY_16,78,1); //78 por formula desbordamiento timer2
setup_ccp1(ccp_pwm); // habilita el pwm
 
while(1){    
	if (data==313){
	data=0;
	}
	data=data+2; 
	set_pwm1_duty(data);
	delay_ms(25); 

} 
   
}
```

y el proteus:


----------



## ruben90 (Mar 1, 2016)

Yo utilizo mikroC, así que no puedo decirte si está bien o mal en CCS, pero como te comenté del libro es bueno, viene bien explicado, te aseguro que resuelves tus dudas.

Yo utilizo los registros del PIC, pocas veces las librerías. Primero defino los registros: PR2, T2CON y CCPR1CON.
Ya después utilizo solo el registro CCPR1L para controlar el duty cycle de la señal y me funciona de maravilla.


----------



## D@rkbytes (Mar 1, 2016)

thekako dijo:


> si es que alguien sabe cómo hacer para encender un led pero de a poco, cambiando su brillo, intensidad, a través del tiempo y una vez encendido apagarlo lentamente de la misma manera.


Yo lo hago utilizando el Timer 0 para aumentar y disminuir el ciclo activo del PWM.
Es muy sencillo hacerlo de esa forma y el código no es complicado.

Adjunto el ejemplo con simulación. (Oscilograma)
Físicamente se nota un efecto de variación de luminosidad en el LED, lento y estable que sube y baja.
Esto viene siendo como las lámparas de obstrucción en sistemas de seguridad y señalamiento.


----------



## yorsk2004 (Mar 1, 2016)

Yo también quiero hacer lo mismo pero que el ciclo de trabajo del PWM dependa de una entrada análoga. ¿Cual uC podría usar para este fin?


----------



## D@rkbytes (Mar 1, 2016)

Uno que tenga conversor análogo a digital, y puede ser con uno pequeño como el PIC12F675.


----------



## thekako (Mar 2, 2016)

D@rkbytes dijo:


> Yo lo hago utilizando el Timer 0 para aumentar y disminuir el ciclo activo del PWM.
> Es muy sencillo hacerlo de esa forma y el código no es complicado.
> 
> Adjunto el ejemplo con simulación. (Oscilograma)
> Físicamente se nota un efecto de variación de luminosidad en el LED, lento y estable que sube y baja.




Hola muchas gracias por responderme  , tengo algunas dudas, puedo probarlo colocando un led en el puerto del osciloscopio en la simulacion o no notaria los cambios de brillo?
Otra duda cuando copio tu codigo y lo intento compilar con MPLAB me tira el siguiente error sabes a que se debe? "Undefined Identifier T0_INTERNAL" intente googlearlo pero no encontre algo similar..

Desde ya muchas gracias por la ayuda 

Reedit: cambie TO_INTERNAL por RTCC_INTERNAL y pudo compilar, afecta en algo o es cosa del compilador?
Otra cosa, cual es la formula para calcular el valor del set_timer0 dado que uso un reloj de 20Mhz y en el osciloscopio se ve rara la onda, gracias!


----------



## D@rkbytes (Mar 2, 2016)

thekako dijo:


> ¿Puedo probarlo colocando un LED en el puerto del osciloscopio en la simulación o no notaría los cambios de brillo?


No se pueden ver los cambios de intensidad en el LED durante simulación con PWM.


thekako dijo:


> Cuando copio tu código y lo intento compilar con MPLAB me tira el siguiente error. ¿Sabes a que se debe? "Undefined Identifier T0_INTERNAL"
> Intenté googlearlo pero no encontré algo similar.


Eso se debe a que tu compilador ya es obsoleto y no contiene las nuevas constantes.


thekako dijo:


> Reedit: cambie TO_INTERNAL por RTCC_INTERNAL y pudo compilar, afecta en algo o es cosa del compilador?


No afecta. Esa constante es de versiones anteriores y también está disponible en la versión actual.


thekako dijo:


> ¿Cuál es la fórmula para calcular el valor del set_timer0, dado que uso un reloj de 20 Mhz. y en el osciloscopio se ve rara la onda.


La fórmula viene en la hoja de datos al igual que toda la información que requieras sobre el PIC.
En el ejemplo usé un desborde cada 30 ms. teniendo 4 MHz con el oscilador interno.

Nota que si cambias la frecuencia de oscilación, también se debe cambiar la configuración del Timer 2.
Si no haces eso también se verá afectada la frecuencia del PWM.
También existe otro detalle importante cuando se aumenta la frecuencia de reloj.
Los tiempos de desborde para los Timers disminuyen, y por consecuencia se logran frecuencias más altas para el PWM.

Con 20 MHz. El desborde máximo para el Timer 0, será de 13.1072 ms. estando el prescaler a 1:256
Así que la variación en los cambios de intensidad sobre el LED serán más rápido.

Entonces es importante que tomes eso en cuenta para elegir la frecuencia de operación del microcontrolador.


----------



## thekako (Mar 2, 2016)

Muchas gracias por la información amigo, me has aclarado un montón 

sabes que he estado probando casi todo el día y he llegado a un codigo coherente con ccs en donde la onda debiese variar subiendo y bajando el brillo del led, pero por alguna razón el PIN no está recibiendo nada por lo que no oscila nada en ella, me podrías guiar en donde se encuentra posiblemente el error que no he logrado solucionarlo aún por favor, si Revisas la imagen te darás cuenta que por RB3 no sale nada, se encuentra en azul y no en rojo :c
:


```
#include "C:\librerias\16F628A.h"
#fuses intrc_io, nocpd, noprotect, nomclr
#use delay(clock = 4M)

int variable=0;

void main(){
set_tris_b(0b00000000); 
setup_timer_2(T2_DIV_BY_16,254,1);
setup_ccp1(ccp_pwm);

while(1){
	variable=variable+5;
	if(variable=255){
		for(variable=255;variable<0;variable=variable-5){
		set_pwm1_duty(variable);
		delay_ms(20);
		}
	}
	set_pwm1_duty(variable);
	delay_ms(20);
}

}
```


----------



## D@rkbytes (Mar 2, 2016)

En lenguaje C debes igualar usando == y no un solo =
Esto es cuando comparas, cuando asignas si se usa un solo signo =

La variable "variable" no puede llegar a ser menor de 0 porque es una variable sin signo.

En C también es más fácil que escribas; variable += 5; y no: variable = variable + 5;


----------



## ruben90 (Mar 2, 2016)

prueba con esto:

```
void main() {
TRISB = 0x00;
PORTB = 0x00;
    PR2 = 0xF9; //1kHz
  T2CON = 0x05;
CCP1CON = 0x0C;
while(1) {
CCPR1L = 0x7D; //50%
}
}
```


----------



## D@rkbytes (Mar 2, 2016)

ruben90 dijo:


> prueba con esto:
> 
> ```
> void main() {
> ...


Ese programa únicamente genera una frecuencia de 1 KHz con ciclo activo fijo, y lo que se requiere es que aumente y disminuya el ciclo activo constantemente, así como lo expuse en el ejemplo que subí.

Aparte no tiene sentido incluir dentro del bucle el registro CCPR1L si siempre aplicas el mismo valor.
Y en PIC C Compiler no se usan esos registros porque tiene funciones predefinidas que lo hacen.
Por lo tanto ese código sin la declaración de registros, dará errores si se compila en PCWHD.


----------



## thekako (Mar 2, 2016)

muchas gracias por la ayuda, les informo que modifique lo que me dijeron y aún así sigue sin salida por el pin RB3, adujunto imagen para que me crean  no se a que se deberá :c

el código lo dejé así:

```
#include "C:\librerias\16F628A.h"
#fuses intrc_io, nocpd, noprotect, nomclr
#use delay(clock = 4000000)

int variable=0;

void main(){
set_tris_b(0b00000000); 
setup_timer_2(T2_DIV_BY_16,254,1);
setup_ccp1(ccp_pwm);

while(1){
	variable=variable+5;
	if(variable>=255){ //probé con == y >= y no funciona
		for(variable=255;variable<=5;variable=variable-5){
		set_pwm1_duty(variable);
		delay_ms(20);
		}
	}
	set_pwm1_duty(variable);
	delay_ms(20);
}

}
```


----------



## D@rkbytes (Mar 2, 2016)

¿Y por qué no implementas el programa del ejemplo que subí?
Hace lo que requieres. ¿No? Eso era lo que requerías en tu primer post.


----------



## thekako (Mar 2, 2016)

es que con tu código se debía de presionar un boton para que cambiara el pulso y yo necesito que siempre haga lo mismo subir de 0 a 100 y bajar de 100 a 0 infinitamente , no logre modificar tu codigo para hacer esto, por eso no lo segui ocupando jeje


----------



## D@rkbytes (Mar 2, 2016)

Creo que estás equivocado. El programa que subí hace los cambios automáticamente.
No se tiene que presionar ningún botón para que realice la variación del ciclo activo.
De hecho el único botón que tiene es el de reset, y es opcional.

Prueba el circuito físicamente y lo podrás comprobar.


----------



## thekako (Mar 3, 2016)

entonces debo probarlo fisicamente?, por que con el osciloscopio no me muestra ninguna onda si no presiono el boton 
mira adjuntare cuando no apreto nada(sin) y cuando presiono el boton(con):


----------



## D@rkbytes (Mar 3, 2016)

Algo debes estar haciendo mal. No realices modificaciones al programa ni al diseño.
El circuito empieza a correr el programa desde el inicio, tanto en simulación como físicamente.
Si puedes ver en la ventana "Watch Window" que la variable "ciclo" aumenta y disminuye, quiere decir que el programa está funcionando.

Subí dos simulaciones, una en proteus 7.10 y la otra en proteus 8.3
En ambas se muestra la forma de onda como empieza el ciclo activo desde 0 % a 100 % y luego inversamente.

Físicamente también funciona y ahí si se puede ver la actividad en el brillo del LED.

También se pueden tomar los oscilogramas físicos en tiempo real.

Ciclo activo al mínimo.


Ciclo activo a la mitad. (50 %)
​
Y ciclo activo al máximo.


Las capturas físicas son aproximadas al ciclo, porque es algo complicado atinarle. ​


----------



## yorsk2004 (Mar 4, 2016)

D@rkbytes si solo quiero un "Duty Cycle" fijo, digamos 25%, entonces me podrías asesorar con el código en C CCS.

Otra cuestión la frecuencia del PWM se puede configurar digamos a 200 Hz.

Gracias de antemano D@rkbytes.


----------



## D@rkbytes (Mar 4, 2016)

No es nada complicado calcular los valores para la frecuencia y el ciclo activo. (Ver Hoja de Datos)
Pero para generar bajas frecuencias hay que usar un oscilador más lento y la programación es diferente.
Y dependiendo de la frecuencia requerida puede existir un error y no obtenerla exactamente.
Sobre algún tema del Foro ya se ha tratado, necesitas buscar.

Adjunto un programa para encontrar los valores de forma muy sencilla.
Con este programa únicamente necesitas ingresar los parámetros necesarios y automáticamente genera el código para PIC C Compiler.


----------



## miglo (Mar 5, 2016)

D@rkbytes dijo:


> No se pueden ver los cambios de intensidad en el LED durante simulación con PWM.



D@rbytes yo he podido hacerlo, no perfecto al 100%, pero funciona por si se quiere ver.

Con un transistor 2n2222, conectando su base a la salida del pic, el colector a + y el emisor al diodo led amarillo, estè conectado con una resistencia en serie de 220Ω y a estos un condensador electrolitico de 220µf





D@rkbytes dijo:


> Creo que estás equivocado. El programa que subí hace los cambios automáticamente.
> No se tiene que presionar ningún botón para que realice la variación del ciclo activo.
> De hecho el único botón que tiene es el de reset, y es opcional.
> 
> Prueba el circuito físicamente y lo podrás comprobar.



Si lo hace por que yo lo he probado


----------



## D@rkbytes (Mar 5, 2016)

Saludos. Claro que si, sube tu simulación.
Y así es, si funciona.


----------



## miglo (Mar 5, 2016)

Bueno como no se subirlo de otra forma lo pongo asi.


----------



## david139 (May 5, 2019)

D@rkbytes dijo:


> Yo lo hago utilizando el Timer 0 para aumentar y disminuir el ciclo activo del PWM.
> Es muy sencillo hacerlo de esa forma y el código no es complicado.
> 
> Adjunto el ejemplo con simulación. (Oscilograma)
> ...


hola a todos buscando llegue a este post estoy buscando un ejemplo de pwm con un potenciometro con el pic16f628a y revise el codigo que uste compartio con el señor y me sirve pero como le hago para que suba y baje la frecuencia con un potenciometro me podrias ayudar por favor


----------



## Scooter (May 5, 2019)

PWM mantiene la frecuencia constante, lo que cambia es el reparto.


Si es eso lo que quieres, lees una entrada analógica, y ese valor lo escribes en el PWM.
Lo escribes directamente o adaptando los valores, según sea el caso.


----------



## david139 (May 5, 2019)

hola necesito un ejemplo con el pic16f628a que en el pin 17 que es el puerto RA0 este un potenciometro que me controle en el pin 12 que es el puerto RB6 una frecuencia para un inverte


Scooter dijo:


> PWM mantiene la frecuencia constante, lo que cambia es el reparto.
> 
> 
> Si es eso lo que quieres, lees una entrada analógica, y ese valor lo escribes en el PWM.
> Lo escribes directamente o adaptando los valores, según sea el caso.


tienes un ejemplo que me sirva por favor
en proteus seria algo asi


----------



## pandacba (May 5, 2019)

Porque lo quieres con un PIC? de que frecuencias se trata? lo puedes hacer con operacionales y entender lo que estas haciendo


----------



## david139 (May 5, 2019)

pandacba dijo:


> Porque lo quieres con un PIC? de que frecuencias se trata? lo puedes hacer con operacionales y entender lo que estas haciendo


bueno te cuento estoy reparando un equipo energizador y usa un pic16f628a el cual el alto voltaje lo controla un potenciometro y el puerto RB6 sale a un transistor que esta funcionando como un oscilador un sircuito inverte elevador de voltaje


----------



## Scooter (May 5, 2019)

No creo que tengas mucha dificultad en encontrar lo que buscas si le dedicas un poco de tiempo.

Si el PWM es de 8 bits y el conversor es de 12 bits, cosa común. Entonces
PWM = Lectura/4
O mejor
PWM = rotar dos bits Lectura

No aclaras si quieres modificar frecuencia como decías o en realidad quieres modificar amplitudo como he supuesto, no sé si erróneamente.

Offtopic:
Por cierto, ¿"Haci" = "así"?
(Si es eso no caben más faltas en menos letras)


----------



## david139 (May 5, 2019)

Scooter dijo:


> No creo que tengas mucha dificultad en encontrar lo que buscas si le dedicas un poco de tiempo.
> 
> Si el PWM es de 8 bits y el conversor es de 12 bits, cosa común. Entonces
> PWM = Lectura/4
> ...


pero tienes por favor por lo menos ejemplo donde me lea un potenciometro rotativo


----------



## DOSMETROS (May 5, 2019)

Por que no nos comentás bien que hace el módulo que no te funciona a ver cómo se puede reemplazar.


----------



## Scooter (May 5, 2019)

DOSMETROS dijo:


> Por que no nos comentás bien que hace el módulo que no te funciona a ver cómo se puede reemplazar.


Pues si, porque "reparar" no cuadra con reprogramar el código.


----------



## david139 (May 5, 2019)

les estoy pidiendo ejemplos es por que yo no soy programador pero tengo un amigo que sabe programar en C y el es el que me esta ayudando con el código por que yo le busco los ejemplos pero el no sabe sobre PIC por eso de los ejemplo ya me a ayudado en  casi todo pero falta esa parte del potenciometro


Scooter dijo:


> Pues si, porque "reparar" no cuadra con reprogramar el código.


bueno el equipo se daño el pic16f628a cuando lo prendo no ase nada tengo otro equipo igual le puse el pic del ese equipo al malo y funciona bien pero como todos sabemos no puedo copiar ese pic por que esta protegido entonces necesito programar  tengo un pic16f628a nuevo pero esta vació


----------



## Scooter (May 5, 2019)

Ah, eso sí que tiene todo el sentido.

Pregunta el precio de un pic programado al fabricante, si haces bien los números es bastante probable que sea mucho más barato que programarlo tu.

Cuenta el precio de tus horas, el precio de las horas en que la máquina no produce y que si programas algo mal puede que dañes el equipo.

Si no eres programador pues una de dos, aprovechas para aprender en esta ocasión, se tardan meses o años si es que se consigue alguna vez, o bien asume que te viene grande el proyecto y busca un programador. O llama al fabricante.


----------



## david139 (May 5, 2019)

Scooter dijo:


> Ah, eso sí que tiene todo el sentido.
> 
> Pregunta el precio de un pic programado al fabricante, si haces bien los números es bastante probable que sea mucho más barato que programarlo tu.
> 
> Cuenta el precio de tus horas, el precio de las horas en que la máquina no produce y que si programas algo mal puede que dañes el equipo.


si supieras que llame al distribuidor y me dijo que comprara otro equipo pero estoy en Venezuela y es super caro el equipo nuevo


----------



## DOSMETROS (May 5, 2019)

Te pregunto que hace ese módulo con el pic ? quizás se puede reemplazar por una fuentecita PWM


----------



## Scooter (May 5, 2019)

Esa es otra. He visto equipos con un microcontrolador del que se usaba solo un pin. Yo, que soy adicto, lo hubiera hecho también así con toda probabilidad, pero donde hay carencia de materiales un 555 o incluso un circuito discreto a base de transistores puede ser la solución. 

Como te ha dicho 2m detalla lo mejor posible que hace el equipo que es probable que se pueda sustituir por otra cosa.


----------



## david139 (May 5, 2019)

*B*ueno*,* es un equipo de alto voltaje para cercos electricos *,* el pic en el módulo controla una sirena que se activa si corta la linea del cerco*, *también controla el alto voltaje como dije al principio controla el oscilador del inverter de 12 voltios los eleva a 400 voltios*,* controla un trias que hace el corte para que la bobina de alta induzca y eleve el voltaje a unos 20 mil voltios *;*  pero eso ya mi amigo lo tiene listo lo que nos falta es la parte del potenciómetro que controle la señal del oscilador*.
S*i el equipo fuera analógico y le hiciera el circuito con el NE555 o el NE556 no hay problema por que yo lo he echo antes*,* la tarjeta dónde está el pic ese maneja practicamente todo*, *a ese pic le están usando todos*,* aquí es donde hago la simulación
Ésta es la tarjeta donde va el pic16f628a

Me dí cuenta que en éste pic16f628a no están usando PWM , están usando RB6/T1OSO/T1CKI  salida oscilador TIMER1  para el inverter.


----------



## ricbevi (May 5, 2019)

Para sustituir ese PIC debes hacer "ingeniería inversa", se comienza sacando el esquema eléctrico del aparato, luego si hay uno que funciona a mano, se miden y detalla y analiza todas las funciones.

Con esos datos se pasa a hacer el programa que reemplaza al original con funcionalidad similar o mejorada.

Sin todos esos datos esenciales a la hora de programar es difícil llegar a un buen resultado.

No se tiene el esquema total del aparato y no se sabe que hace el que llamas potenciómetro(no se si es el preseet de 100K que se ve en la fotografía o es otro).

Ese PIC no tiene ADC incluido por lo que para usar un preset y dosificar algo, hay que implementar métodos de lectura alternativos a la simple lectura de la caída de voltaje clásica.

Uno de ellos es medir el tiempo de carga y descarga de un capacitor conectado a la resistencia variable del preset o potenciómetro(RC) y tomar decisiones en base a ello.
Adjunto un ejemplo y simulación en Proteus y Proton Basic en cuanto al lenguaje de programación.


----------



## david139 (May 5, 2019)

ricbevi dijo:


> Para sustituir ese PIC debes hacer "ingeniería inversa", se comienza sacando el esquema eléctrico del aparato, luego si hay uno que funciona a mano, se miden y detalla y analiza todas las funciones.
> 
> Con esos datos se pasa a hacer el programa que reemplaza al original con funcionalidad similar o mejorada.
> 
> ...


hola gracias bueno ese preseet como lo llamas vamos es una resistencia variable de 100k como tu dices me varia un voltaje el cual hace que la señal que sale por el puerto RB6 del pic16f628a que me párese que es una señal cuadrada con una frecuencia de 1 mhz que la hacen con los timer de ese puerto es como si fuera la señal de un PWM


ricbevi dijo:


> Ese PIC no tiene ADC incluido por lo que para usar un preset y dosificar algo, hay que implementar métodos de lectura alternativos a la simple lectura de la caída de voltaje clásica.


como busco un ejemplo de de eso que dices orientado a C por favor


----------



## pandacba (May 5, 2019)

david139 dijo:


> les estoy pidiendo ejemplos es por que yo no soy programador pero tengo un amigo que sabe programar en C y el es el que me esta ayudando con el código por que yo le busco los ejemplos pero el no sabe sobre PIC por eso de los ejemplo ya me a ayudado en  casi todo pero falta esa parte del potenciometro
> 
> bueno el equipo se daño el pic16f628a cuando lo prendo no ase nada tengo otro equipo igual le puse el pic del ese equipo al malo y funciona bien pero como todos sabemos no puedo copiar ese pic por que esta protegido entonces necesito programar  tengo un pic16f628a nuevo pero esta vació


Lee tu mismo lo que has puesto, el micro del equipo dañado funciona en otro, el problema entonces esta en el hardware y eso es reparable, porque no nos muestras fotos del equipo, porque hasta aquí todo en el aire.
No hay un esquema no hay nada, imposible ayudar en tales condiciones. y no creo que la solución sea reprogramando el pic no tiene mucho sentido e incluso puede interferir en el funcionamiento globar, no saben de PIC's no saben electrónica, estan al horno con papas doradas


----------



## D@rkbytes (May 6, 2019)

david139 dijo:


> Hola a todos. Buscando llegué a este post.
> Estoy buscando un ejemplo de PWM con un potenciómetro con el PIC16F628A y revisé el código que usted compartió con el señor y me sirve pero, ¿cómo le hago para que suba y baje la frecuencia con un potenciómetro? ¿Me podrías ayudar, por favor?


El PIC16F628A no cuenta con ADC para poder obtener la lectura análoga de un potenciómetro.
Uno similar con ADC sería el PIC16F88, pero sus terminales cambian.
Con el 16F628A en PICBasic se puede obtener una lectura pseudo análoga de baja resolución como ya te lo mencionaron.
Obviamente nada comparable a los 10 bits del ADC


----------



## david139 (May 6, 2019)

D@rkbytes dijo:


> El PIC16F628A no cuenta con ADC para poder obtener la lectura análoga de un potenciómetro.
> Uno similar con ADC sería el PIC16F88, pero sus terminales cambian.
> Con el 16F628A en PICBasic se puede obtener una lectura pseudo análoga de baja resolución como ya te lo mencionaron.
> Obviamente nada comparable a los 10 bits del ADC


buenas espesemos de cero yace que el Pic16f628a no tienen salidas analógicas ni tienen ADC , 
pero en el circuito donde esta trabajando el pic16f628a  tiene un potenciometro o resistencia variable,
y hace una caída de voltaje o variación de voltaje, Como le hago para que el pic me lea esa caída o variación de voltaje si tienes un ejemplo en mikroc mejor por favor
la otra pregunta seria el pic16f628a tiene un puerto con esto RB6/T1OSO/T1CKI/PGC  ,
como podría sacar una señal cuadrada con una frecuencia de un 1Mhz usando  Timer1 oscillator output  que tiene ese pic tienen un ejemplo por favor si es en mikroC mejor


pandacba dijo:


> Lee tu mismo lo que has puesto, el micro del equipo dañado funciona en otro, el problema entonces esta en el hardware y eso es reparable, porque no nos muestras fotos del equipo, porque hasta aquí todo en el aire.
> No hay un esquema no hay nada, imposible ayudar en tales condiciones. y no creo que la solución sea reprogramando el pic no tiene mucho sentido e incluso puede interferir en el funcionamiento globar, no saben de PIC's no saben electrónica, estan al horno con papas doradas


la tarjeta del equipo es esa y perdona lo escribí mal el Pic del equipo "bueno" lo pongo en el equipo malo y trabaja bien el equipo  por eso digo que esta malo el pic 



hola necesito algo de esto pero con el 16f628a.
 Control de un servomotor utilizando un potenciometro, para la generación de la señal PWM no se utilizaron los módulos CCP, ya que se utilizo cualquier pin digital, para ello se utilizo el timer0 y la interrupción por desbordamiento de timer0.


----------



## ricbevi (May 6, 2019)

El 16F628A tiene salidas digitales lo que no tiene es entrada de ADC(Convertidor Analogico Digital).

Parece que no entiendes que sin circuito eléctrico como base de comienzo es imposible analizar algo para saber qué se debe hacer sin basarse en adivinación ya que las posibilidades de confección de un circuito e implementación de un software controlador son diversas.

Saca el esquema eléctrico completo del aparato, muéstralo aqui y  tal vez obtengas respuestas más precisas.


----------



## Scooter (May 6, 2019)

Como ya te han dicho, ese derivado no tiene conversor analógico a digital y por tanto no puede leer un potenciometro.
Llegados a este punto hay varias opciones:
- Que lo que parece un potenciometro, no lo sea, sea un encoder o algo así que dé pulsos digitales
-Que si que sea un potenciometro y en ese caso se lee o estima su valor a través de un circuito auxiliar
En ambos casos necesitas conocer exáctamete como es el circuito para saber que es lo que tienes que programar.

Cabe una tercera solución que es cambiar el potenciometro por dos pulsadores [+] y [-] con los que pulsando consecutivamente establezcas el valor de preset ese que buscas. Pero me imagino que lo que quieres es aprovechar el harware del que dispones sin tocar nada.

Para aprovechar lo que tienes es neceesario conocer que es lo que tienes, es decir, conocer exáctamente el esquema y como te han dicho mas arriba analizar en profundidad como funciona el que ya va para clonarlo lo mas fielmente posible.


----------



## david139 (May 6, 2019)

Scooter dijo:


> Como ya te han dicho, ese derivado no tiene conversor analógico a digital y por tanto no puede leer un potenciometro.
> Llegados a este punto hay varias opciones:
> - Que lo que parece un potenciometro, no lo sea, sea un encoder o algo así que dé pulsos digitales
> -Que si que sea un potenciometro y en ese caso se lee o estima su valor a través de un circuito auxiliar
> ...


si supieras que pensé eso de los pulsadores por que hay un modelo que los trae así 
y lo del potenciometro es para tumbar  un voltaje de 3 voltios a tierra con un condensador como dijo uno de ustedes


----------



## Gudino Roberto duberlin (May 6, 2019)

Posiblemente el PIC, utiliza el propio PWM generado por él, y la señal del potenciómetro a un comparador analógico que él mismo posee.
La señal de PWM debe pasar por un filtro RC, para luego ser comparada con la referencia.
De esa manera puede regularse la señal de PWM.


----------



## david139 (May 6, 2019)

Gudino Roberto duberlin dijo:


> Posiblemente el PIC, utiliza el propio PWM generado por él, y la señal del potenciómetro a un comparador analógico que él mismo posee.
> La señal de PWM debe pasar por un filtro RC, para luego ser comparada con la referencia.
> De esa manera puede regularse la señal de PWM.


hola puede ser pero en este caso no se esta usando el puerto que  trae el ccp están usando el pin12 que es el puerto RB6/T1OSO/T1CKI/PGC  y para mi están sacando un PWM pero usando los timer y los prescale
y el potenciometro esta conectado asi como muestra la imagen


----------



## D@rkbytes (May 6, 2019)

Es que todo se puede aún con un microcontrolador sin ADC, la cosa es saber cómo implementarlo.
Nada difícil si se tienen conocimientos en electrónica y programación.
Ejemplos hay bastantes, y en base a ellos puedes adaptar alguno a tu necesidad.


----------



## Gudino Roberto duberlin (May 6, 2019)

En la hoja de datos del 16F628A, existen dos comparadores analógicos, de los cuales uno de ellos utiliza la entrada AN0.


----------



## D@rkbytes (May 6, 2019)

Gudino Roberto duberlin dijo:


> En la hoja de datos del 16F628A, existen dos comparadores analógicos, de los cuales uno de ellos utiliza la entrada AN0.


Así es, pero es un comparador y por lo mismo no se adapta para lo requerido.
No es igual una lectura análoga de 10 bits a una comparación que únicamente nos entregará un 0 o un 1


----------



## Dr. Zoidberg (May 6, 2019)

D@rkbytes dijo:


> Así es, pero es un comparador y por lo mismo no se adapta para lo requerido.
> No es igual una lectura análoga de 10 bits a una comparación que únicamente nos entregará un 0 o un 1


Bueee....con un poco de imaginacion..tal vez sea posible variar dinamicamente por soft el umbral del comparador hasta que cambie de nivel "la salida" y de esa forma tener una aproximacion cercana a la tension en la entrada analogica 0 (no escribo AN0 por que se vé feo ).
Claro que la tension debe ser mas o menos estable mientras dure el proceso...

En fin....pensaba en voz alta...


----------



## Gudino Roberto duberlin (May 6, 2019)

D@rkbytes dijo:


> Así es, pero es un comparador y por lo mismo no se adapta para lo requerido.
> No es igual una lectura análoga de 10 bits a una comparación que únicamente nos entregará un 0 o un 1


Para que quede más claro; Activo el Módulo CCP para que funcione cómo PWM. Luego me fijo si el COMP me arroja 1 o 0.
Suponiendo la siguiente lógica, si me arroja 1, entonces reduzco paulatinamente el duty del PWM, de lo contrario lo aumento.
Claro que para lograrlo, es necesario conectar la salida del PWM con una red RC, a la entrada del módulo comparador, y la otra entrada del módulo al potenciómetro.


----------



## D@rkbytes (May 6, 2019)

Es que es lo dicho, se puede obtener PWM hasta sin microcontrolador.
La cosa es saber implementarlo para el uso requerido.
Suponiendo que fuera mi caso, programo un PIC12F683 y asunto arreglado, pero si no sé programar pues voy a estar dando tumbos buscando la forma de hacerlo.


----------



## david139 (May 7, 2019)

D@rkbytes dijo:


> Es que es lo dicho, se puede obtener PWM hasta sin microcontrolador.
> La cosa es saber implementarlo para el uso requerido.
> Suponiendo que fuera mi caso, programo un PIC12F683 y asunto arreglado, pero si no sé programar pues voy a estar dando tumbos buscando la forma de hacerlo.


bueno tienes toda la razón por que si fuera un proyecto nuevo podría sacar el PWM con un clásico 555 pero hay esta el de talle estoy tratando de reparar un enegizador de cercos eléctricos  marca Krom que tiene un Pic16f628a y que los genios de esa empresa lo programaron asi y estoy tratando de explicarles a ustedes que son los veteranos en micros para ver si me dan una ayuda por favor


Dr. Zoidberg dijo:


> Bueee....con un poco de imaginacion..tal vez sea posible variar dinamicamente por soft el umbral del comparador hasta que cambie de nivel "la salida" y de esa forma tener una aproximacion cercana a la tension en la entrada analogica 0 (no escribo AN0 por que se vé feo ).
> Claro que la tension debe ser mas o menos estable mientras dure el proceso...
> 
> En fin....pensaba en voz alta...





Gudino Roberto duberlin dijo:


> Para que quede más claro; Activo el Módulo CCP para que funcione cómo PWM. Luego me fijo si el COMP me arroja 1 o 0.
> Suponiendo la siguiente lógica, si me arroja 1, entonces reduzco paulatinamente el duty del PWM, de lo contrario lo aumento.
> Claro que para lograrlo, es necesario conectar la salida del PWM con una red RC, a la entrada del módulo comparador, y la otra entrada del módulo al potenciómetro.


esa logica que haces creo que es asi por que me puse a medir el voltaje del potenciometro que llega pin17 que es RA0/ANO  hay 2 voltios cuando giro el potenciometro hay una caída a cero quiere decir que esta recibiendo los 2 voltios que seria el alto, y cero que seria el bajo


----------



## elvi (Jun 26, 2020)

D@rkbytes dijo:


> Yo lo hago utilizando el Timer 0 para aumentar y disminuir el ciclo activo del PWM.
> Es muy sencillo hacerlo de esa forma y el código no es complicado.



Cuando quiero incluir la sentencia de WDT el PWM deja de funcionar. Lo estoy probando con un led y deja de dimerizar. Esto se debe a que estoy usando el timer 0, el mismo que usa el PWM, cierto?


----------



## D@rkbytes (Jun 26, 2020)

El Watchdog Timer produce un reset cuando desborda.
Por eso es que se debe configurar para se puedan ejecutar las rutinas, o restablecerlo antes de que lo haga.
Su uso no provocaría que el PWM deje de funcionar, lo que si lo haría sería un sleep.


elvi dijo:


> ¿Esto se debe a que estoy usando el timer 0, el mismo que usa el PWM, cierto?


El módulo CCP para el PWM usa el Timer 2, usar el Timer 0 para generar PWM es hacerlo por software.
Como el Timer 0 se puede direccionar al prescaler del Watchdog Timer, podría afectar.

Sin ver el programa es como para preguntarle a la bola de cristal y últimamente ha estado descompuesta.


----------



## Gerson strauss (Jun 27, 2020)

Señores, si es posible leer un potenciometro con un micro sin adc. En proton ide existe el comando *POT*
en donde se mide el tiempo de descarga de un condensador que varia con la resistencia del potenciometro.

Lo usan con el pin RB0, seguramente usan la interrupción para disparar el timer ...no se si funcione con otro pin.
Un ejemplo aquí de PWM y potenciometro: POT - PWM


----------



## elvi (Jun 27, 2020)

D@rkbytes dijo:


> El Watchdog Timer produce un reset cuando desborda.
> Por eso es que se debe configurar para se puedan ejecutar las rutinas, o restablecerlo antes de que lo haga.
> Su uso no provocaría que el PWM deje de funcionar, lo que si lo haría sería un sleep.
> 
> ...



Estoy usando el código de pwm que encontré en este foro por D@rkbytes con las salidas b1 y b2 conectadas a dos leds*, *utiliza el timer 2 y el timer 0 para ejecutar el PWM funciona bien hasta que quiero añadir el wdt y los leds empiezan a parpadear, entiendo que debo añadir wdt dentro del timer0 y un tiempo corto antes que se desborde. Adicionalmente uso el timer 1 para hacer retardos (Es solo didacticamente lo del timer 1). Realmente funciona el programa como quiero, pero no comprendo cual es el lugar mas optimo para colocar el wdt. Estoy programando en pic c 

Archivo .h

```
#include <16F627A.h>
#use delay(internal=4000000)
#FUSES NOBROWNOUT
#Fuses WDT
#use FIXED_IO( B_outputs=PIN_B1,PIN_B2,PIN_B3 )
```

Archivo .c

```
#include <PWM.h>

short Flagok = 0;
int16 Retardo = 1000;
int16 Ms100 = 0;
int valorms = 2;// 8;    // para 104ms de desborde
int contador = 0;


int8 ciclo = 2;
int1 flag_cambio = 0;

void EstableceTiempo(int16 tiempo);

#define ciclo_max 249
#define ciclo_min 2


#INT_TIMER0
void sdi_deborde_timer0 (void)
{
restart_wdt();

   if(!flag_cambio)                    // Si no hay cambio de ciclo...
   {  
      ciclo ++;                        // Aumentar "ciclo"
     
      if(ciclo >= ciclo_max)           // Si se supera o se alcanza "ciclo_max"...
      {
         ciclo = ciclo_max;            // Ajustar "ciclo" a "ciclo_max"
         flag_cambio = 1;              // Confirmar que se alcanzó el máximo para "ciclo"
      }
   }
   else                                // Pero Si existe cambio de ciclo...
   {
      ciclo --;                        // Diminuir "ciclo"
     
      if(ciclo <= ciclo_min)           // Si se llega al ciclo mínimo...
      {
         ciclo = ciclo_min;            // Ajustar "ciclo" a "ciclo_min"
         flag_cambio = 0;              // Confirmar que se alcanzó el mínimo para "ciclo"
      }
   }
     
   set_pwm1_duty(ciclo);               // Establecer el ciclo activo.
   set_timer0(225);                    // Recargar el Timer 0.
}

#INT_TIMER1
void  TIMER1_isr(void)
{
   contador++;
   if(contador >= valorms)
   {
      Ms100 = Ms100 + 100;              
      if(Ms100 >= Retardo)        
      {
         Flagok = 1;
         Ms100 = 0;
      }
      contador = 0;
   }
}


void main (void)
{
   setup_ccp1(CCP_PWM);                // Módulo CCP en modo PWM.
   setup_timer_2(T2_DIV_BY_4,249,1);   // Frec. = 1 KHz. Fosc = 4 MHz.
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_0(T0_INTERNAL|T0_DIV_256); // Configuración del Timer 0.
   set_timer0(225);                   
 
   setup_wdt (WDT_18MS);
 
   enable_interrupts(INT_TIMER0);      // Activar interrupción por desborde del Timer 0.
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);          // Habilitar las interrupciones.
 
   while (true)
   {
            EstableceTiempo(1000);
            while(Flagok == 0)
            {
               output_high(pin_b2);
               output_low(pin_b1);
            }
            EstableceTiempo(2000);
            while(Flagok == 0)
            {
               output_high(pin_b1);
               output_low(pin_b2);
            }
           
   
   }
}

void EstableceTiempo(int16 tiempo)
{
   Ms100 = 0;
   contador = 0;
   Retardo = tiempo;
   Flagok = 0;
}
```


----------



## D@rkbytes (Jun 27, 2020)

elvi dijo:


> Realmente funciona el programa como quiero, pero no comprendo cuál es el lugar mas óptimo para colocar el wdt.


El Watchdog Timer no tiene un lugar dentro del programa para colocarse pues es una característica del microcontrolador.
Se habilita con un simple fuse y su desborde se configura con una constante en la instrucción "setup_wdt (_mode_)"
En PIC C Compiler de CCS con tan solo usar la instrucción "restart_wdt ()" se habilitará el fuse WDT en ON automáticamente.
Si crees que tus rutinas no se completarán antes de que desborde, entonces debes resetearlo con la instrucción "restart_wdt ()"

Como seleccionaste un desborde de 18 milisegundos, "setup_wdt (WDT_18MS);" por lógica tus rutinas deben ser ejecutadas antes de ese tiempo.
Si crees que no se cumplirán en ese periodo, entonces sería conveniente aumentar el valor y resetear el Watchdog Timer cuando creas que puede desbordar.

¿Para qué quieres usar el Watchdog Timer?
¿Acaso crees que tu programa tendrá algún problema por cuelgues?
Ten en cuenta que un reset es lo último que se desea en un sistema.


elvi dijo:


> Adicionalmente uso el timer 1 para hacer retardos (Es solo didácticamente lo del timer 1).


Como recomendación, no uses retardos y mucho menos cuando uses el Watchdog Timer.


----------



## Gudino Roberto duberlin (Jun 28, 2020)

El reset del WD, lo puedes hacer en distintas partes del programa. Por ejem. En los bucles FOR, WHILE, en subrutinas extensas, etc.
Todo depende del timeout que designes al WD.
Mientras menos margen dejes, obviamente mayor cantidad de resets y de diferentes lugares deberás hacerlo.


----------



## elvi (Jun 28, 2020)

D@rkbytes dijo:


> ¿Para qué quieres usar el Watchdog Timer?
> ¿Acaso crees que tu programa tendrá algún problema por cuelgues?


Si, quiero garantizar si se cuelga, el micro salga solo del embrollo.

Logre poner el WDT en el programa de PWM cambiando el ciclo activo de pwm con el timer1 y no con el timer0. En el datasheet del micro hallé esta parte pero no comprendo su significado en los micro controladores "Una asignación de preescaler para el módulo Timer0 significa que no hay un post-escalador para el Watchdog Timer, y viceversa."


----------



## D@rkbytes (Jun 29, 2020)

elvi dijo:


> En el datasheet del micro hallé esta parte pero no comprendo su significado en los micro controladores:
> "Una asignación de preescaler para el módulo Timer0 significa que no hay un post-escalador para el Watchdog Timer, y viceversa."


Un poco extraña la traducción pero toma como prescaler a un divisor.
Cuando este es asignado al Timer 0 se podrá usar para que tenga un desborde más prolongado.
Teniendo este como factores de división: 1:1, 1:2, 1:4, 1:8, 1:16, 1:32, 1:64, 1:126 y 1:256
Por el contrario, cuando el prescaler es asignado al WDT, entonces será este el que pueda tener un desborde más prolongado.
Como este tiene un postescaler, podrá tener desbordes más prolongados.

Cuando el prescaler es asignado al WDT el Timer 0 correrá libremente desde 0 hasta 255 que es cuando desbordará pero no habrá interrupción.
Lo mismo pasará contrariamente; cuando el prescaler se asigna al Timer 0, el WDT correrá libremente y cuando desborde generará un reset.
Por lógica, al no tener prescaler asignado, el reset ocurrirá lo que tarde en desbordarse y sobre eso influye la frecuencia de reloj.
El bit que asigna el prescaler al Timer 0 o al WDT es el bit 3 del registro OPTION_REG (PSA) y los del divisor son los bits 2, 1 y 0 (PS2, PS1 y PS0)
En PIC C Compiler se usan constantes que se encuentran en el archivo .h correspondiente al PIC usado.

Cuando se asigna al Timer 0:

Cuando se asigna al WDT:


----------

