Deteccion de cruce por cero para controlar un triac

Creo que empiezo a comprender las interrupciones, aunque me cuesta.
Te adjunto el código, y el esquema se me olvido ponerlo.

Como te decía, si pongo limitaciones proteus se me satura y el programa con la bombilla no me tira, si se las quito va.
La pena es que en mi casa todas las bombillas son de leds y no tengo ninguna de filamento, voy a ver si consigo una de filamento y te cuento.


Código:
#include <16f877A.h>
#fuses XT,NOWDT,NOBROWNOUT,NOCPD,NOLVP,NOPROTECT

#use delay(clock=4M)

#use fast_io(B)

#define TRIAC  PIN_B3
#define F_MAX  PIN_B1
#define F_MED  PIN_B2

#include <lcd.c>

  int VTO=240; 

#int_RTCC
void RTCC_isr() 
   {
 
 output_high(TRIAC);
 delay_us(10);
 output_low(TRIAC);
 disable_interrupts(INT_RTCC);
     } 
     
#int_EXT
void EXT_isr() 
   {
 set_timer0(VTO);
 enable_interrupts(INT_RTCC); 
     }
 
  void main()
     {
   set_tris_B(0x07);
   output_b(0x00);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
  
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
  
   lcd_init();
 
   lcd_gotoxy(1,1);
   lcd_putc(" Iniciando FASE ");
   lcd_gotoxy(1,2);
   printf(lcd_putc," FASE:  %3.0u",VTO);
  
   lcd_gotoxy(1,1);
   lcd_putc(" FASE  Activada ");
   
 while (true)
     {
     
  if (input(F_MAX))
          { 
       delay_ms(100);   
        VTO++;  
      lcd_gotoxy(1,2);
    printf(lcd_putc," FASE:  %3.0u",VTO);  
          }          
    
    if (input(F_MED))
          { 
       delay_ms(100);   
        VTO--;
       lcd_gotoxy(1,2);
    printf(lcd_putc," FASE:  %3.0u",VTO); 
          }
          
    if(VTO>=240)
       {
     VTO=240;
       }
       
     if(VTO<=107)
        {
       VTO=107;        
        }
        
      }
    }

Edito que me dado cuenta que el documento estaba en blanco.
No sé cómo se borra el archivo en blanco, jeje.


Bueno, pues me corrijo a mi mismo.
He vuelto a cargar el programa con las limitaciones y ahora si funciona.



OK
bueno aca te pongo el que uso en la maquina de humo DMX​
(uno esta para la bomba inductivo y el otro resistivo ., que es el calentador) tiene deteccion de temperatura tambien​
par que no te pierdas con el codigo la entrada de interupcion es PD3 (INT1)​

No se como andas econ ASM ., pero siqueres tengo tambien (es lo mismo ., pero solo dimer )​
Pero tambien al igual que el anterior ., recontra probados y sin problemas​

Papirrin no se perderá leyendo el código pero yo me he perdido por completo.
Bueno, por completo no, es una manera de decirlo, por ejemplo µ08 no sé lo que es.

Tendrías algún problema en lo básico para poder entenderlo, ponerlo en C pero para un 876 o 877 por ejemplo.

mira primero lo de la div de 64

la formula para eso es:
Temporización = (4 * (255-TMR0) * PreScaler)/Fosc

como tu frecuencia es de 50Hz el tiempo del ciclo es de 20mS, pero como gatillas a medio ciclo seria 10mS y despejando la formula seria:

TMR0=255-((tiempo*fosc)/4/64) o sea

TMR0=255-((.01*4000000)/4/64)=99

tu rango va de 99 a 255 , peroo como la onda de la frecuencia no es cudrada, el opto tarda unos microsegundos en saturar el transistor asi que puede fallar a los 99 y tendras que recorrerlo un poco como 100, 101... etc...
Ahora empiezo a entenderlo mejor después de leerlo y releerlo.
Mi falta de comprensión estaba en que yo mezclaba 2 conceptos, y son que el timer0 es de 8 bits o lo que es lo mismo de 0 a 255 y el timer1 y timer2 es de 16, en este caso por que hablamos del PIC16F877A.
Con lo que yo hacía la fórmula mal, en vez de (255-tmr0) que es el del tmr0, ponía la del timer1(65535-tmr0) con lo que no daba una a derechas.
 

Adjuntos

  • Nuevo Documento de Microsoft Word.doc
    10.5 KB · Visitas: 9
  • Nuevo Documento de Microsoft Word.doc
    36 KB · Visitas: 7
Última edición por un moderador:
Hola
Papirrin no se perdera leyendo el codigo pero yo me perdido por completo, bueno por completo no, es una manera de decirlo, por ejemplo µ08 no se lo que es, tendrias algun problema en lo basico para poder entenderlo, ponerlo en C pero para un 876 o 877 por ejemplo.
Bueno ., lamento no poder ayudarte en nada querido amigo​
Poque de programacin de PIC ., yo no se nada ., el ejemplo que subi es para ATMEGA​
Lo puse para que viera papirrin ., como se usa la interupcion externa ., del crusze por cero​
Y como se que papirrin sabe., podria adaptar las funciones al PIC ., pero la parte de electronica que subi ., sirve para el PIC tambien​
Si no tenes una lampara de filamento podes conectar una "plancha"(es resistiva)​
(y)
 
Última edición:
Ahora empiezo a entenderlo mejor despues de leerlo y releerlo, mi falta de comprension estaba en que yo mezclaba 2 conceptos y son que el timer0 es de 8 byts o lo que es lo mismo de 0 a 254 y el timer1 y timer2 es de 16, en este caso por que hablamos del pic 16f877a, con lo que yo hacia la formula mal, en vez de (255-tmr0) que es el del tmr0 ponia la del timer1(65535-tmr0) con lo que no daba una a derechas.

Asi es, los timers funcionan diferente, suponiendo el tmr2 si se utiliza el modulo CCP, se configura diferente, y creo que tambien es de 8 bits, el unico de 16 es el tmr1.

como te menciono que aunque funcionan de manera similar uno tiene funciones diferentes a las del otro y se tiene que seleccionar el que mejor se ajuste a las necesidades, me parece que seleccione el TMR0 porque es el que tiene div entre 64 y es el que en el rango de 0 a 255 da el tiempo necesario.

me falto aclarar que en un modulo sea cual sea puede, y segun la aplicacion, no es forzosamente necesario utilizar su interrupcion, y solo se puede tomar su valores de registro.

en el caso de CCS aparentemente se usan subrutinas distintas para las interrupciones pero a la hora de compilar las pone en la misma subrutina asignada por el CPU (unidad central de procesamiento) del PIC.

para saber a detalle como funciona un pic, casi es necesario tener nociones de ASM, puesto que los lenguajes de alto nivel como Basic o C ya tienen muchas algoritmos prefabricados.

y otra cosa que se me olvidaba, si vas a dejar el transformador de 12v, es conveniente que las resistencias no sean de 10K sino de 1k, puesto que las de 10K estan calculadas para 110V, y como mencione yo puse un tranformador porque no tengo las resistencias de 1W. en el esquema de locodelafonola se ve que para 220V se necesitan resistencias de 27K a 1W si se toma directamente de la red electrica.
 
Última edición:
hola
Asi es, los timers funcionan diferente, suponiendo el tmr2 si se utiliza el modulo CCP, se configura diferente, y creo que tambien es de 8 bits, el unico de 16 es el tmr1.

como te menciono que aunque funcionan de manera similar uno tiene funciones diferentes a las del otro y se tiene que seleccionar el que mejor se ajuste a las necesidades, me parece que seleccione el TMR0 porque es el que tiene div entre 64 y es el que en el rango de 0 a 255 da el tiempo necesario.

me falto aclarar que en un modulo sea cual sea puede, y segun la aplicacion, no es forzosamente necesario utilizar su interrupcion, y solo se puede tomar su valores de registro.

en el caso de CCS aparentemente se usan subrutinas distintas para las interrupciones pero a la hora de compilar las pone en la misma subrutina asignada por el CPU (unidad central de procesamiento) del PIC.

para saber a detalle como funciona un pic, casi es necesario tener nociones de ASM, puesto que los lenguajes de alto nivel como Basic o C ya tienen muchas algoritmos prefabricados.
bueno si queres ., como dije tengo en ASM ., pero lo que no entiendo es porque nesesitas cambiar el "gatillado"., del ciclo negativo ., (perdona mi ignoracia )​
Aca te subo el programa en ASM., que funciona​
Código:
;***************************************************************************/

.include "m8515def.inc"


/* ***** pin definitions */

#define LED1		PD7
#define LED2		PE0
#define	BIT9		PE2
#define OPTION		PE1
#define USA_MODE	PD4

/* ***** constants */

#define	TABLE_A		0x200
#define TABLE_B		0x400

.equ DMX_FIELD=     0x60 			/* SRAM-Beginn */
.equ DMX_CHANNELS=  8
.equ F_OSC=         8000

#define DMX_EXT

.equ BlinkPos=		0x70
.equ ShtDwnTemp=	0x71			/* Temperature to shut down */
.equ SwitchCh=		0x72			/* Mask of switched channels */


/* ***** special Flags */

#define VALID_DMX 		1 
#define VALID_ZC		2
#define SIGNAL_COMING 	3 
	
#define HOT				6
#define DATA_REFRESHED 	7 


/* ***** global register variables */

#define	tempL		R24			
#define	tempH		R25						
#define	Flags 		R16
#define DMXstate	R17			

#define	null		R2
#define	SREGbuf		R3
#define blink 		R4
#define LEDdelay 	R5				/* prescaler */

#define	status		R6				/* status bits for portc */
#define	SwitchMask  R7

#define	currentL	R18
#define	currentH	R19

#define	dimm_count	R20				/* counter */

#define	timer_startH	R8
#define	timer_startL	R9

/* ***** set time tables for firing angles */ 

.org TABLE_A	/*  50Hz */
	.dw	0x2710, 0x2472, 0x2346, 0x228F, 0x2204, 0x2190, 0x212C, 0x20D2, 0x2081, 0x2037, 0x1FF2, 0x1FB1, 0x1F74, 0x1F3A, 0x1F03, 0x1ECE 
	.dw	0x1E9B, 0x1E6B, 0x1E3C, 0x1E0E, 0x1DE2, 0x1DB8, 0x1D8E, 0x1D66, 0x1D3E, 0x1D18, 0x1CF2, 0x1CCE, 0x1CAA, 0x1C86, 0x1C64, 0x1C42 
	.dw	0x1C21, 0x1C00, 0x1BE0, 0x1BC0, 0x1BA1, 0x1B82, 0x1B64, 0x1B46, 0x1B28, 0x1B0B, 0x1AEE, 0x1AD2, 0x1AB6, 0x1A9A, 0x1A7E, 0x1A63 
	.dw	0x1A48, 0x1A2E, 0x1A13, 0x19F9, 0x19DF, 0x19C6, 0x19AC, 0x1993, 0x197A, 0x1961, 0x1949, 0x1930, 0x1918, 0x1900, 0x18E8, 0x18D1 
	.dw	0x18B9, 0x18A2, 0x188A, 0x1873, 0x185C, 0x1846, 0x182F, 0x1818, 0x1802, 0x17EB, 0x17D5, 0x17BF, 0x17A9, 0x1793, 0x177E, 0x1768 
	.dw	0x1752, 0x173D, 0x1727, 0x1712, 0x16FD, 0x16E8, 0x16D2, 0x16BD, 0x16A9, 0x1694, 0x167F, 0x166A, 0x1655, 0x1641, 0x162C, 0x1618 
	.dw	0x1603, 0x15EF, 0x15DB, 0x15C6, 0x15B2, 0x159E, 0x158A, 0x1576, 0x1562, 0x154E, 0x153A, 0x1526, 0x1512, 0x14FE, 0x14EA, 0x14D6 
	.dw	0x14C2, 0x14AE, 0x149B, 0x1487, 0x1473, 0x1460, 0x144C, 0x1438, 0x1424, 0x1411, 0x13FD, 0x13EA, 0x13D6, 0x13C2, 0x13AF, 0x139B 
	.dw	0x1388, 0x1374, 0x1360, 0x134D, 0x1339, 0x1325, 0x1312, 0x12FE, 0x12EB, 0x12D7, 0x12C3, 0x12AF, 0x129C, 0x1288, 0x1274, 0x1261 
	.dw	0x124D, 0x1239, 0x1225, 0x1211, 0x11FD, 0x11E9, 0x11D5, 0x11C1, 0x11AD, 0x1199, 0x1185, 0x1171, 0x115D, 0x1149, 0x1134, 0x1120 
	.dw	0x110C, 0x10F7, 0x10E3, 0x10CE, 0x10BA, 0x10A5, 0x1090, 0x107B, 0x1066, 0x1052, 0x103D, 0x1027, 0x1012, 0x0FFD, 0x0FE8, 0x0FD2 
	.dw	0x0FBD, 0x0FA7, 0x0F91, 0x0F7C, 0x0F66, 0x0F50, 0x0F3A, 0x0F24, 0x0F0D, 0x0EF7, 0x0EE0, 0x0EC9, 0x0EB3, 0x0E9C, 0x0E85, 0x0E6D 
	.dw	0x0E56, 0x0E3E, 0x0E27, 0x0E0F, 0x0DF7, 0x0DDF, 0x0DC6, 0x0DAE, 0x0D95, 0x0D7C, 0x0D63, 0x0D49, 0x0D30, 0x0D16, 0x0CFC, 0x0CE1 
	.dw	0x0CC7, 0x0CAC, 0x0C91, 0x0C75, 0x0C59, 0x0C3D, 0x0C21, 0x0C04, 0x0BE7, 0x0BC9, 0x0BAB, 0x0B8D, 0x0B6E, 0x0B4F, 0x0B2F, 0x0B0F 
	.dw	0x0AEE, 0x0ACD, 0x0AAB, 0x0A89, 0x0A65, 0x0A41, 0x0A1D, 0x09F7, 0x09D1, 0x09A9, 0x0981, 0x0957, 0x092D, 0x0901, 0x08D3, 0x08A4 
	.dw	0x0874, 0x0841, 0x080C, 0x07D5, 0x079B, 0x075E, 0x071D, 0x06D8, 0x068E, 0x063D, 0x05E3, 0x057F, 0x050B, 0x0480, 0x03C9, 0x029D 



.org TABLE_B	/*  60Hz */
	.dw 8333, 7402, 7224, 7086, 6970, 6870, 6781, 6701, 6627, 6559, 6495, 6436, 6379, 6325, 6274, 6225 
	.dw 6178, 6133, 6090, 6048, 6007, 5968, 5930, 5892, 5856, 5821, 5786, 5753, 5720, 5687, 5656, 5625 
	.dw 5595, 5565, 5536, 5507, 5478, 5451, 5423, 5396, 5370, 5343, 5317, 5292, 5267, 5242, 5217, 5193 
	.dw 5169, 5145, 5122, 5098, 5076, 5053, 5030, 5008, 4986, 4964, 4942, 4921, 4899, 4878, 4857, 4836 
	.dw 4816, 4795, 4775, 4755, 4735, 4715, 4695, 4676, 4656, 4637, 4617, 4598, 4579, 4560, 4541, 4523 
	.dw 4504, 4486, 4467, 4449, 4431, 4412, 4394, 4376, 4358, 4341, 4323, 4305, 4288, 4270, 4253, 4235 
	.dw 4218, 4201, 4183, 4166, 4149, 4132, 4115, 4098, 4081, 4065, 4048, 4031, 4014, 3998, 3981, 3964 
	.dw 3948, 3931, 3915, 3899, 3882, 3866, 3849, 3833, 3817, 3801, 3784, 3768, 3752, 3736, 3720, 3704 
	.dw 3688, 3672, 3655, 3639, 3623, 3607, 3591, 3575, 3559, 3543, 3527, 3511, 3496, 3480, 3464, 3448 
	.dw 3432, 3416, 3400, 3384, 3368, 3352, 3336, 3320, 3304, 3288, 3272, 3256, 3240, 3224, 3208, 3192 
	.dw 3176, 3159, 3143, 3127, 3111, 3095, 3078, 3062, 3046, 3029, 3013, 2997, 2980, 2964, 2947, 2930 
	.dw 2914, 2897, 2880, 2864, 2847, 2830, 2813, 2796, 2779, 2762, 2745, 2728, 2710, 2693, 2675, 2658 
	.dw 2640, 2623, 2605, 2587, 2569, 2551, 2533, 2515, 2496, 2478, 2459, 2441, 2422, 2403, 2384, 2365 
	.dw 2345, 2326, 2306, 2286, 2266, 2246, 2226, 2205, 2185, 2164, 2142, 2121, 2099, 2078, 2056, 2033 
	.dw 2010, 1987, 1964, 1941, 1917, 1892, 1867, 1842, 1816, 1790, 1764, 1736, 1708, 1680, 1650, 1620 
	.dw 1589, 1558, 1524, 1490, 1455, 1418, 1379, 1338, 1294, 1247, 1196, 1140, 1077, 1002, 905,  670

/* ****set interrupt-routines */

.org 0
	
	rjmp reset 				/* reset vector address */
	reti					/* External Interrupt0 Vector Address */
	rjmp zero_crossing		/* External Interrupt1 Vector Address */
	reti					/* Input Capture1 Interrupt Vector Address */
	rjmp compare			/* Output Compare1A Interrupt Vector Address */
	reti					/* Output Compare1B Interrupt Vector Address */
	rjmp zero_crossing_overflow	/* Overflow1 Interrupt Vector Address */
	rjmp LED_indicator		/* Overflow0 Interrupt Vector Address */
	reti					/* SPI Interrupt Vector Address */
	rjmp get_byte			/* UART Receive Complete Interrupt Vector Address */
	reti					/* UART Data Register Empty Interrupt Vector Address */
	reti					/* UART Transmit Complete Interrupt Vector Address */
	reti 					/* Analog Comparator Interrupt Vector Address */
	reti					/* External Interrupt2 Vector Address */
	reti					/* Output Compare0 Interrupt Vector Address */
	reti					/*  EEPROM Interrupt Vector Address */
	reti					/*  SPM complete Interrupt Vector Address */
	reti					/*  SPM complete Interrupt Vector Address */	

reset:

cli

/* ***** set stackpointer */
	ldi	tempL,low(RAMEND)
	ldi tempH,high(RAMEND)
	out	SPL,tempL
	out SPH,tempH

/* ***** WATCHDOG */
	wdr
	ldi tempL, (1<<WDE)|(1<<WDCE)
	out WDTCR, tempL
	ldi tempL, (1<<WDE)|(1<<WDCE)|(1<<WDP2)|(1<<WDP1)
	out WDTCR, tempL
	wdr

/* ***** set Ports */
/*  PortE */
	ldi tempL, 0b00000001
	out DDRE, tempL
	ser	tempL
	out PortE, tempL 					/* LED2 off, BIT9 & OPTION Pullup */

/*  PortA */
	ser tempL
	out DDRA, tempL
	out PortA, tempL 					/* high Outputs */

/*  PortB */
	ldi tempL, 0b00000000
	out	DDRB,  tempL
	ldi tempL, 0b00000011	
	out	PortB, tempL

/*  PortC */
	clr tempL
	out DDRC, tempL
	ser tempL
	out PortC, tempL  					/* Inputs with PullUp for DipSwitch */

/*  PortD */
	ldi tempL, 0b10000100
	out DDRD, tempL
	ldi tempL, 0b01111000
	out PortD, tempL 					/* DMX & Spare , LED1 off */

/* ***** get phase-time for phase zero-crossing control */
		sbis	PinD, USA_MODE
		rjmp	init_phs60

		ldi		tempH,0xD8				//50Hz
		ldi		tempL,0xF2
		rjmp 	init_phs1
  	   init_phs60:
  		ldi		tempH,0xDF				//60Hz
		ldi		tempL,0x75
   	   init_phs1:
		mov		timer_startH,tempH		/* store value */
		mov		timer_startL,tempL

/* ***** initial timer 0 */
		ldi 	tempL,0b00000101		/*  set timer0 to ck/1024 */
		out 	TCCR0,tempL			
				
/* ***** initial timer 1 */
		clr		tempL
		out		TCCR1A, tempL
		ldi 	tempL,0b00000010		/* set timer1 to clk/8 */
		out 	TCCR1B,tempL		 
				
/* ***** initial timer interrupts */
 		ldi 	tempL,0b00000000		/* enable timer0 overflow interrupt */
		sbr		tempL, (1<<TOIE0)	 
		out 	TIMSK,tempL			 
				
/* ***** set interrupt 1 for phase zero-crossing control */
		in 		tempL,MCUCR				/* interrupt by falling edge */ 
		sbr		tempL,(1<<ISC11)		 
		cbr		tempL,(1<<ISC10)		 
		out 	MCUCR,tempL			 

		in 		tempL,GIMSK				/* enable interrupt1 */
		sbr		tempL,(1<<INT1)				 
		out 	GIMSK,tempL 		 
	
		in 		tempL,GIFR				/* initial GIFR */
		sbr		tempL,(1<<INTF0)		/* clear interrupt0 flag */
		sbr		tempL,(1<<INTF1)		/* clear interrupt1 flag */
		out 	GIFR,tempL			 

/* ***** Analog Comparator */
		ldi		tempL, 0b01010010 		/* (bandgap on, ac on, irq on falling edge, irq flag cleared, irg disabled) */
		out 	ACSR,  tempL
		
/* ***** initial var */

		clr 	Flags
		clr 	Flags
		clr 	null

		ldi		tempL, 8
		sts		BlinkPos, tempL
		ldi		tempL, 25
		mov		LEDdelay, tempL

		SWITCHread:
		sbic	EECR, EEWE
		rjmp	SWITCHread
		ldi		tempL, 1
		out		EEARH, null
		out		EEARL, tempL
		sbi		EECR, EERE
		in		SwitchMask, EEDR		/* load switch mask from EE */

		sbic	PinE, OPTION			/* should store new switch pattern? */
		rjmp	initv1
		in		tempH, PinC
		cp		SwitchMask, tempH
		breq	initv_wait
		mov		SwitchMask, tempH

		SWITCHwrite:
		sbic	EECR, EEWE
		rjmp	SWITCHwrite
		out		EEARH, null
		ldi		tempL, 1
		out		EEARL, tempL
		out		EEDR, SwitchMask
		sbi		EECR, EEMWE
		sbi		EECR, EEWE

		initv_wait:
		wdr
		sbis	PinE, OPTION			/* wait till switch cleared */
		rjmp	initv_wait

	   initv1:
	    sts		SwitchCh, SwitchMask
		rcall	init_dmx
		
		cbi     PortD, LED1

/* ***** start working... */

		sei
		wdr								/* enable global interrupt */

forever:

	rjmp	forever	
		
/* ***************************************************************************
 *
 * external interrupt caused by phase-zero-crossing (idle:4.88us, BREAK:6.38us, 
 *
 *************************************************************************** */
zero_crossing:

		in		SREGbuf, SREG			/* save global status */
		push 	tempL
		push	tempH
			
		out 	TCNT1H,timer_startH		/* clear angle-timer */
		out 	TCNT1L,timer_startL		

		sbr 	Flags, (1<<VALID_ZC)	/* message for indicator */

		in		tempL,TIFR				 
		sbr		tempL,(1<<OCF1A)		/* clear compare flag */
		sbr		tempL,(1<<TOV1)			/* clear overflow-flag  */
		out	    TIFR,tempL				

  		in		tempL,TIMSK				
		sbr		tempL,(1<<OCIE1A)		/* enable timer1 compare interrupt */
		sbr		tempL,(1<<TOIE1)		/* enable timer1 overflow interrupt */
		out	    TIMSK,tempL				

		in 		tempL,GIMSK				/* disable ext-interrupt */
		cbr		tempL,(1<<INT1)		
		out 	GIMSK,tempL 			

   zero_common:	
		ser		dimm_count				/* clear counter */

		sbis	PinD, USA_MODE
		rjmp	z_common60
		ldi		ZH,((high(TABLE_A) *2)+0x01)	/* set first compare value */
		rjmp	Z_common1
	   z_common60:
	    ldi		ZH,((high(TABLE_B) *2)+0x01)	/* set first compare value */
 	   Z_common1:
		ldi		ZL,0xfe					
		lpm		tempL, Z+						/* low byte */				
		lpm		tempH, Z						/* high byte */
		add		tempL,timer_startL		/* add start-offset */
		adc		tempH,timer_startH		/* add start-offset */
		out		OCR1AH,tempH			
		out 	OCR1AL,tempL			

		pop		tempH
		pop 	tempL					/* restore global status */
		out 	SREG, SREGbuf
		reti							/* return */	

/* ***************************************************************************
 *
 * T1-overflow interrupt caused by phase-zero-crossing
 *
 *************************************************************************** */
zero_crossing_overflow:	

		in		SREGbuf, SREG			/*  save global status */
		push 	tempL
		push	tempH

		out 	TCNT1H,timer_startH		/* clear angle-timer */
		out 	TCNT1L,timer_startL		

  		in		tempL,TIMSK				 
		sbr		tempL,(1<<OCIE1A)		/* enable timer1 compare interrupt */
		cbr		tempL,(1<<TOIE1)		/* disable timer1 overflow interrupt */
		out		TIMSK,tempL				

		in 		tempL,GIFR				/* clear interrupt0 flag */
		sbr		tempL,(1<<INTF1)		 
		out 	GIFR,tempL				

		rjmp	zero_common

/* ***************************************************************************
 *
 * check next firing angle
 *
 *************************************************************************** */
compare:
		in		SREGbuf, SREG			/*  save global status */
		push 	tempL
		push	tempH

		ldi		tempL,DMX_CHANNELS
		clr		status
		ldi		ZH,high(DMX_FIELD)		/* set data-pointer */	
		ldi		ZL,low(DMX_FIELD)			

  test_stat:	
  		ld		tempH,Z+				/* get data  */
		cp		tempH, dimm_count
		ror		status
		dec		tempL					/* goto next channel */
		breq	finish					 
		rjmp	test_stat

  finish:
  		sbrs	Flags, HOT				/* if too hot -> shut down! */
		rjmp	cf_1
		clr		status 
		com		status
      cf_1:
		out 	PORTA,status
		
  get_value:
		dec		dimm_count
		breq	end_time

		sbis	PinD, USA_MODE
		rjmp	gv_60
		ldi		ZH,(high(TABLE_A) *2)	/* compare value */
		rjmp	gv_1
	   gv_60:
	    ldi		ZH,(high(TABLE_B) *2)	/* compare value 60Hz */
 	   gv_1:
		mov		ZL, dimm_count
		lsl		ZL			 
		adc		ZH,null					  
	
		lpm		tempL, Z+				/* load next timer1-compare-value */				 
		lpm		tempH, Z						 				 

		add		tempL,timer_startL		/* add start-offset */
		adc		tempH,timer_startH		 

		sbiw	tempL,0x03				/* test if next timer1-compare-value  (next angle -3) */
		in		currentL,TCNT1L			/* isn't already gone */
		in		currentH,TCNT1H
		cp		tempL,currentL
		cpc		tempH,currentH
		brge	compare_ok
		rjmp	get_value				/* else get next value */

  compare_ok:
  		adiw	tempL,0x03				/*  (next angle +3)  */
		out 	OCR1AH,tempH			/* set next timer1-compare-value */
		out		OCR1AL,tempL			 
		
		rjmp	exit_compare

  end_time:
  		in		tempL,TIMSK				/* disable timer1 compare interrupt */
		cbr		tempL,(1<<OCIE1A)		 
		out		TIMSK,tempL				 

		ldi		tempL,0xff				/* turn portA off (safe) */
		out		PORTA,tempL				

		in		tempL,TIMSK				/* check for timer-overflow-interrupt */
		sbrc	tempL,TOIE1				/* if timer1 overflow interrupt is enabled */
		rjmp	exit_compare			/*   return */

		in 		tempL,GIFR				/* clear interrupt1 flag */
		sbr		tempL,(1<<INTF1)		
		out 	GIFR,tempL				

		in 		tempL,GIMSK				/* enable external interrupt1 */
		sbr		tempL,(1<<INT1)			
		out 	GIMSK,tempL 			/* wait for next zero-crossing */

	exit_compare:
		pop		tempH
		pop		tempL
		out		SREG, SREGbuf
		reti							



/* ***************************************************************************
 *
 * manipulation of dmx data
 *
 *************************************************************************** */
 clc_dmx:
 		lsr		SwitchMask				/* should this ch be switched? */
		brcs	clc_dmx_finish			/* no */
		cpi		tempH, 127
		brsh	clc_dmx_hi
		clr		tempH					/* ch off */
		rjmp	clc_dmx_finish
	  clc_dmx_hi:
		ser		tempH					/* ch on */
	  clc_dmx_finish:
	    cpi		XL, low(DMX_FIELD +DMX_CHANNELS -1)
		brne	clc_dmx_exit
		lds		SwitchMask, SwitchCh	/* reload switch mask */
	  clc_dmx_exit:
		ret		
			
 			

/* ***************************************************************************
 *
 * LED INDICATOR 
 *
 *************************************************************************** */
LED_indicator:
		wdr								/* reset Watchdog */
		in		SREGbuf, SREG
		push	tempL

		dec	  	LEDdelay				/* clk/(256*1024*2) => 20Hz */			
		brne  	no_ind
		ldi   	tempL, 2
		mov   	LEDdelay, tempL		

working_LED:
		sbrc	Flags, DATA_REFRESHED	/* should flash? */
		rjmp	data_flash	
		sbi		PortE, LED2				/* LED off */	


Error_LED:
		lsr   	blink
		sbrc  	blink, 0				/* wenn 1st bit HI */
		rjmp  	on
		sbi   	PortD, LED1
		rjmp  	ind_tst
	 on:
	 	cbi  	PortD, LED1

     ind_tst:
	    lds		tempL, BlinkPos
		dec	  	tempL					/* ist blink durchrotiert? */
		breq	change_pat
		sts		BlinkPos, tempL
		rjmp	no_ind
	 		 	
/* wenn durchrotiert (blink = 0) */
	 change_pat:
	    ldi		tempL, 8
		sts		BlinkPos, tempL	
		clr		tempL		
		sbrs 	Flags, VALID_DMX
		ldi	 	tempL, 0b00001010
		sbrs 	Flags, SIGNAL_COMING
		ldi	 	tempL, 0b00000010
		sbrs 	Flags, VALID_ZC
		ldi  	tempL, 0b10101010

/* *** Temperature Monitoring */
	  	sbic	ACSR, ACO
		rjmp	too_hot
		cbr		Flags, (1<<HOT)			/* temp is OK */
		rjmp	tm1
	too_hot:							/* temp is too high */
		ser		tempL
		sbr		Flags, (1<<HOT)
		
   tm1: mov  	blink, tempL

		cbr		Flags, (1<<VALID_DMX)|(1<<VALID_ZC)|(1<<SIGNAL_COMING)
	no_ind:
		pop		tempL
		out		SREG, SREGbuf
		reti

    data_flash:
		cbr		Flags, (1<<DATA_REFRESHED)
	    sbis 	PortE,LED2				/* blinken green */
		rjmp 	off
		cbi		PortE,LED2
		rjmp 	Error_LED
		off:
		sbi 	PortE,LED2
		rjmp 	Error_LED



.include "lib_dmx_in.asm"

nix: rjmp nix
y otra cosa que se me olvidaba, si vas a dejar el transformador de 12v, es conveniente que las resistencias no sean de 10K sino de 1k, puesto que las de 10K estan calculadas para 110V, y como mencione yo puse un tranformador porque no tengo las resistencias de 1W. en el esquema de locodelafonola se ve que para 220V se necesitan resistencias de 27K a 1W si se toma directamente de la red electrica.
Bueno ., en realidad fijate ., el detalle del diodo a la inversa (1n4007) ya con eso no nesesita puente rectificador​
con respecto a las ressistencias de 27k x 1W ., yo le coloque de mas wataje ., porque calentaban mucho ahora tiene de 5W (no consegui de 2W)​
En cuanto al TIC 2XXX ., lo remplaze por el Q4010 TL o Q4020TL (de 10A o 20A .,respectivamente y son aislados)​
 
Última edición:
pero lo que no entiendo es porque necesitas cambiar el "gatillado"., del ciclo negativo ., (perdona mi ignoracia )
Una imagen dice mas que mil palabras:
Dibujo.JPG

Con puente rectificador en cada semiciclo genera un pulso en el cruce.

Sin puente rectificador, en el semiciclo positivo hay un flanco positivo y en el negativo hay un flanco negativo, por lo que se tiene que detectar si es flanco de subida o de bajada para saber ambos cruces por cero.

Me estoy refiriendo a que se tiene que cambiar el falling edge o el rising edge del pin de interrupción externa, o por lo menos así es en PIC, en Atmega no sé si funcione igual pero supongo que si por lo que vi en tu código.
Espero haberme explicado.
 
Última edición por un moderador:
Bueno.
Una imagen dice mas que mil palabras:
Ver el archivo adjunto 134369

Con puente rectificador en cada semiciclo genera un pulso en el cruce.

Sin puente rectificador en el semiciclo positivo hay un flanco positivo y en el negativo hay un flanco negativo, por lo que se tiene que detectar si es flanco de subida o de bajada para saber ambos cruces por cero.

Me estoy refiriendo a que se tiene que cambiar el falling edge o rising edge del pin de interrupción externa, o por lo menos así es en PIC, en Atmega no sé si funcione igual, pero supongo que si por lo que vi en tu código.
Espero haberme explicado.
Bien eso si lo entiendo. Ahora, ¿para qué necesitas diferenciar los semi ciclos?​
Porque según tengo entendido, al cruzar por cero, es el estado ideal de conmutación (encendido y apagado de la lámpara) y de este modo se evita que se queme.

O sea, el PWM de continua que acciona el diac que a su vez acciona el triac.​
Si no aprendí mal (digo, porque uno solo a veces lo interpreta erróneamente)
Trabaja unicamente cuando es detectado el cruce y en los flanco de subida o de bajada no trabaja.​
Claro que la señal de esa manera tiene mayor amplitud, y no te olvides que lo que es usado es el "PICO", y no la subida ni bajada de esa detección.

Me pasó que tuve que reformar el circuito de la bomba (maquina de humo) porque la bomba funciona con 12 VCC y yo dimerizaba el trafo que la alimenta.​
Pero al hacer eso, me quedaba sin alimentación estable en los otros circuito.​
Entonces, cambie el circuito del diac y tic por un opto-trancistor y un IRFZ​
Pero ahora dimerizo la bomba con cruce por cero.
El beneficio es, que a pesar de eso el trafo no calienta tanto al aumentar el consumo (bomba)​
También fijate el detalle de la última librería que subí, trabaja con una tabla y están definidos los dos tipos, 50Hz y 60Hz.​
 
Última edición por un moderador:
Bueno, cada aplicación es diferente y no quiere decir que no funcione el circuito que pones.
Para mi la diferencia es que no consumes más tiempo del necesario en el microcontrolador, que tampoco es una cantidad barbara, si acaso unas 10 instrucciones a lo mucho.
Pero insisto, a mi me gusta más con puente, aunque en términos generales sea casi lo mismo.

¿¿¿¿ paraque nesesitas diferenciar los semi ciclos????
Se necesita diferenciar para que se dispare el triac en cada semiciclo.
Si sólo disparas en un semiciclo es como si estuvieras rectificando a media onda, o sea, la mitad de la potencia o cómo le quieras decir.
 
Última edición por un moderador:
Termino de llegar del trabajo y veo que el tema va muy bien, yo opino como papirrin me gusta mas lo del puente, y como bien dice "vale mas una imagen que mil palabras".

Papirrin voy a usar el transformador para obtener los 12voltios, seguire tu consejo, una vez lo tenga bien definido seguramente lo haga directamente desde los 230Ac con las resistencias de mayor valor, asi me resultara mas facil para meterlo dentro de las cajas de la corriente electrica.

Locodelafonola agradecido por tu ayuda aunque como en este caso no la entienda, lo de ASM ya me lo dijo en su momento D@rkbytes pero de momento me voy defendiendo mejor con C aunque voy leyendo tambien ASM, lo que no quiero es liarme con los 2, prefiero intentar aprender mejor C y luego ASM.
 
Hola. Pon el osiloscopio a la salida de los dos circuitos, así ves

Yo tengo entendido que el puente se usa para aplicaciones sin micro, porque como vos decís, nesesitas el semiciclo negativo.​
Ahora si te fijas, lo que postee no tiene sentido, puesto que el micro te detecta estado alto no estado bajo (al menos en el programa no hay diferencia a eso)

Ahí está el detalle, por eso lo de la tabla de lectura de 50 y 60 Hz.​
Y perdona que no se explicarme bien, no soy técnico sólo mal aprendido jajajajajajajajajajajaja.​
Termino de llegar del trabajo y veo que el tema va muy bien, yo opino como papirrin me gusta mas lo del puente, y como bien dice "vale mas una imagen que mil palabras".

Papirrin voy a usar el transformador para obtener los 12voltios, seguiré tu consejo, una vez lo tenga bien definido seguramente lo haga directamente desde los 230Ac con las resistencias de mayor valor, así me resultara mas fácil para meterlo dentro de las cajas de la corriente eléctrica.

Locodelafonola agradecido por tu ayuda aunque como en este caso no la entienda, lo de ASM ya me lo dijo en su momento D@rkbytes pero de momento me voy defendiendo mejor con C aunque voy leyendo tambien ASM, lo que no quiero es liarme con los 2, prefiero intentar aprender mejor C y luego ASM.
Bueno, yo aprendí más o menos, pero es muy cierto lo que dice el maestro papirrin, hay que saber ASM.​
Aunque con atmega se usa un solo compilador para los dos lenguajes, y en C se pueden usar sentencias de ASM.​
Es medio "loco" lo que digo pero es cierto, en ASM "no doy pie con bola"
No lo entiendo, por eso uso C.​
 
Última edición por un moderador:
Yo temgo entendido que el puente se usa para aplicaciones sin micro ., porque como vos desis ., nesesitas el semiciclo negativo
Ambos circuitos lo he probado con micro y ambos funcionan.
La diferencia, reitero, es que la programación es diferente.

Ahora ya tengo desarmado el circuito porque estoy intentando una comunicación UART entre varios PIC, que por cierto me estaba sacando canas verdes, pero puedo poner la simulación de proteus de ambos métodos.
De hecho, el código que puse en el mensaje 22, lo hice para usarlo con el esquema que pusiste.

{Offtopic_On}
Por cierto y cosa aparte, si no fuera por los errores garrafales que tiene el proteus en algunas cosas, sería imposible para mi aprenderme casi de memoria los registro y los procedimientos de configuración de los pics.
Para lo que estoy haciendo del UART el proteus no lo hace como en la realidad y ya llevaba casi 6 horas intentándolo en simulación.
Lo armé en la realidad y si funciona como debe ser y en no más de 20 minutos. :LOL:
{offtopic_Off}
 
Última edición por un moderador:
Gracias.
La verdad, que aparte de la explicación y aplicación, me gusta como te tomas el tiempo para explicar el funcionamiento de las cosas.

En cuanto a lo otro, yo también lo uso. En mi caso es la USART.​
Al principio me mareo un poco, pero una vez que entendí cómo funciona, ya no tuve más problemas graves.​
 
Última edición por un moderador:
Buenas Papirrin te comento, termino de montar todo otra vez y tienes mas razon que un santo, en proteus cuando no se me atasca el programa va lento de narices, y mas aun para los que estamos haciendos nuestros pinitos, aunque como bien dices para ver como funcionan todos los componentes ayuda y de que manera.

Pues bien como te dicho lo he montado, perooooooo, con una bombilla de casquillo E27, como no encontraba de las clasicas por que por aqui se estan dejando de fabricar por no decirte que creo que ya no se fabrican, pero si he conseguido una que dentro lleva el sistema alogeno que para el caso sirve, dspues de conectarlo todo cambiar el refrigerador del triac, por que tenia uno enorme, para pruebas, esto gracias a un colega que es tecnico en televison y me pasa casi de todo lo que necesito por la cara, que no es poco, tambien hay que decir que cuando necesita que le heche un cable le ayudo en la reparacion y luego con unas cervezas todo resuelto, pues eso que con esta bombilla va de perlas el programa, lo que biene a decirme que seguramente las bombillas leds al llevar dentro su circuiteria con mas o menos componentes no reacciona igual, de hay el comentario que te hice sobre si podria ser la bombilla.

Por otro lado, aunque me digiste lo de las resistencias de 10k por 1k, al no llevar las gafas y no medir su valor puse las de 10k y funciona perfecto todo, me dado cuenta al cambiar los diodos por puentes reptificadores, cosas que pasan jejeje.

Locodelafonola ya lo miro con el osciloscopio pero como solo tengo una sonda pues no puedo disfrutar de ver las 2 señales, ya estoy mirando para comprarme la segunda sonda y asi poder ver las señales, todo esto me pasa por despistado, pierdo la cosas que da gusto.

Una pregunta Papirrin ya que no le veo explicacion, estoy haciendo pruebas y todo va bien menos cuando bajo a 100 la luz, si luego le doy a subir no se enciende ni aunque llegue a 240.

He reprogramado para que empieze en 100 y no va pero si lo pongo en 240 como pusiste tu entonces si, luego lo he modificado para que no baje de 103 y va perfecto, pero claro una bombilla en una habitacion esta apagada y cuando pulsamos se enciende, de esta manera esta encendida y hay que apagarla, es al reves, esta claro que son pruebas pero me gustaria saber el por que cuando llego a 100 ya no se enciende o por que si empiezo desde 100 tampoco se enciende. No he probado empezar desde 103.

Termino de probar desde 103 y va perfecto, pero si lo bajo ya no.
 
Última edición:
Por otro lado, aunque me digiste lo de las resistencias de 10k por 1k, al no llevar las gafas y no medir su valor puse las de 10k y funciona perfecto todo, me dado cuenta al cambiar los diodos por puentes reptificadores, cosas que pasan jejeje.
si puede funcionar, de echo yo tambien lo tengo con 10K y transformador, pero como esta pasando muy poca corriente en el diodo LED del opto puede que si habiese un bajon de luz por algo, ya no sature el fototransistor del optoy se apague el foco o sea erratico. bueno eso tambien es cuestion de gustos en diseño, lo normal para 12V seria algo aproximado a 1K.

Una pregunta Papirrin ya que no le veo explicacion, estoy haciendo pruebas y todo va bien menos cuando bajo a 100 la luz, si luego le doy a subir no se enciende ni aunque llegue a 240.

He reprogramado para que empieze en 100 y no va pero si lo pongo en 240 como pusiste tu entonces si, luego lo he modificado para que no baje de 103 y va perfecto, pero claro una bombilla en una habitacion esta apagada y cuando pulsamos se enciende, de esta manera esta encendida y hay que apagarla, es al reves, esta claro que son pruebas pero me gustaria saber el por que cuando llego a 100 ya no se enciende o por que si empiezo desde 100 tampoco se enciende. No he probado empezar desde 103.

Termino de probar desde 103 y va perfecto, pero si lo bajo ya no.

Cuando preguntes algo que estes modificando o programando en el codigo, ponlo aqui, si no no tengo idea de lo que hablas.

mira los limites se ponen mas o menos asi.

Código:
#include <16F877A.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES PUT                     //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=4000000)

#define TRIAC  PIN_B3
#define F_MAX  PIN_B1
#define F_MED  PIN_B2

int VTO=240;


#int_RTCC
void RTCC_isr() 
{

 output_high(TRIAC);
 delay_us(10);
 output_low(TRIAC);
 disable_interrupts(INT_RTCC);
}

#int_EXT
void EXT_isr() 
{
 set_timer0(VTO);
 enable_interrupts(INT_RTCC);
}



void main()
{
   
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   set_tris_B(0b111);
   
   while(true)
   {
    if (input(F_MAX))
          { 
      if(vto<=240) vto++;   
        delay_ms(10); // antirrebote si puedes usar otro metodo que no use delay mejor.
          }
          
    
    if (input(F_MED))
          {
          if(vto>=100) vto--;
           delay_ms(10); // antirrebote si puedes usar otro metodo que no use delay mejor.
          }   
   };

}

y toma en cuenta que con ese tipo de proyectos en donde se utilizan tiempos, vas contra reloj, cada instruccion que le aumentes o proceso o delay, tiene que ser perfectamente estudiado para que no afecte a las interrupciones. cada instruccion que pongas es tiempo.

por ejemplo si pones un LCD que quien sabe como este echa la libreria, puede ser que al estar ejecutando la rutina del LCD haga que el foco haga destellos erraticos. pero no es que este mal... es que el microcontrolador no tiene tiempo de hacer todo.

por eso a los microcontroladores los hacen de varias velocidades y de echo es por eso que estoy intentando hacer una comunicacion serial (UART) entre varios micros, para dejar como esclavo al micro que va a controlar el dimer y un servo, y el maestro va a controlar un LCD y otras funciones.

con respecto a las lamparas LED, no tengo idea de como esten echas, lo que si se es que no todos los focos se pueden dimmerizar como por ejemplo los ahorradores (por su circuiteria) o bueno si hay una forma de dimerizarlos pero no recuerdo como y este no es el metodo XD
 
Última edición:
esta es la simulacion de ambos circuitos con el mismo codigo que no detecta el flanco de subida y bajada y si deberia funcionar asi en la realidad mas o menos.

Dibujo.jpg

el primer oscilograma (el de arriba) corresponde al del puente rectificador, y el segundo (el de abajo) corresponde al del diodo.

la linea amarilla, corresponde a la oscilacion de la corriente alterna, la linea azul es la deteccion del cruce por cero, la linea rosa es el gatilleo, y la linea verde es el TRIAC.

como se puede observar en el del puente rectificador el triac se dispara en ambos semiciclos, y el del diodo, solo gatillea en el semiciclo negativo.

es por eso que en el del diodo se tiene que cambiar el flanco de la interrupcion externa en el microcontrolador para que gatille en ambos semiciclos, tambien puede ser que en el Atmega se pueda configurar que se desborde la interrupcion en el cambio de estado y podria funcionar, pero no se, nunca he utilizado esos microcontroladores.

de una vez pongo el codigo en Picbasic pro para quien le sirva, y es para usarse con el diagrama del puente rectificador.

Código:
Define Osc 4


OPTION_REG = %11000101 
INTCON     = %11010000 
CMCON      = %111
TRISD      = %00000000
TRISB      = %000111


VT0     Var byte

ON INTERRUPT GOTO int

PORTB.3=0

VT0=200
main:
 if PORTB.1=1 then
  if VT0<249 then VT0=VT0+1
  while PORTB.1
  wend
 endif
 if PORTB.2=1 then 
  if VT0>134 then VT0=VT0-1
  while PORTB.2
  wend
 endif 
Goto main

DISABLE 
Int:
 if INTCON.2=1 then
  INTCON.2=0
  PORTB.3=1
  pauseus 1
  PORTB.3=0
  INTCON.5=0
 endif 
 if INTCON.1 then
  INTCON.1=0
  TMR0=VT0
  INTCON.5=1
 endif
RESUME
ENABLE
 
Última edición:
Hola
esta es la simulacion de ambos circuitos con el mismo codigo que no detecta el flanco de subida y bajada y si deberia funcionar asi en la realidad mas o menos.

Ver el archivo adjunto 134414

el primer oscilograma (el de arriba) corresponde al del puente rectificador, y el segundo (el de abajo) corresponde al del diodo.

la linea amarilla, corresponde a la oscilacion de la corriente alterna, la linea azul es la deteccion del cruce por cero, la linea rosa es el gatilleo, y la linea verde es el TRIAC.

como se puede observar en el del puente rectificador el triac se dispara en ambos semiciclos, y el del diodo, solo gatillea en el semiciclo negativo.

es por eso que en el del diodo se tiene que cambiar el flanco de la interrupcion externa en el microcontrolador para que gatille en ambos semiciclos, tambien puede ser que en el Atmega se pueda configurar que se desborde la interrupcion en el cambio de estado y podria funcionar, pero no se, nunca he utilizado esos microcontroladores.

de una vez pongo el codigo en Picbasic pro para quien le sirva, y es para usarse con el diagrama del puente rectificador.

Código:
Define Osc 4


OPTION_REG = %11000101 
INTCON     = %11010000 
CMCON      = %111
TRISD      = %00000000
TRISB      = %000111


VT0     Var byte

ON INTERRUPT GOTO int

PORTB.3=0

VT0=200
main:
 if PORTB.1=1 then
  if VT0<249 then VT0=VT0+1
  while PORTB.1
  wend
 endif
 if PORTB.2=1 then 
  if VT0>134 then VT0=VT0-1
  while PORTB.2
  wend
 endif 
Goto main

DISABLE 
Int:
 if INTCON.2=1 then
  INTCON.2=0
  PORTB.3=1
  pauseus 1
  PORTB.3=0
  INTCON.5=0
 endif 
 if INTCON.1 then
  INTCON.1=0
  TMR0=VT0
  INTCON.5=1
 endif
RESUME
ENABLE
Bueno gracias a vos ., ahora veo la diferencia (yo no tengo ociloscopio ) solo el de PC​
Lo que quiero explicar es como se usan los dos codigos que subi​
El primero ., se usa en la maquina de humo ( no es comercial ., la fabrique yo )., donde maneja 4 recistencia de plancha (serie-paralelo)., y la bomba de liquido (la que use originalmente era de 220v) la actual es de 12v​
La verdad ., que lo que hace con el calefactor., es una especie de "pirometro"​
Los pirometros ., trabajan por aproximacion de temperatura programada​
Bueno el mio trabaja mas o menos asi ., con la diferencia que aparte de conectar y desconectar​
Tiene PWM (dimer)., que una vez llegada la temperatura no lo desconecta ., sino que la alimentacion es pequeña y costante​
Y porque digo esto., bueno en este caso no estan importante controlar el angulo de la face​
En el segundo ejemplo que subi ., alli si se controla eso No es importante la detecion de cruze por cero ., porque lo que en realidad se aplica a la salida ., es una tabla de ondulacion del PWM (50 o 60 HZ)​
Tal vez la solucion sea aplicarla ., pero alli ya no te podria dar idea ., de ASM no tengo practica​
 
Última edición:
No entendi mucho eso del pirometro, segun yo un pirometro solo mide altas temperaturas, pero creo que se por donde va, y lo mismo o muy parecido quiero hacer yo, a diferencia de que en lugar de programarlo en una tabla, voy ha controlar la temperatura con integrales y derivadas (PID), algo asi como se controlan los servomotores, es decir, que empiezan en lo maximo y cuando se va acercando, en este caso a la temperatura, va disminuyendo la tension (por dimmer) y por ende va calentando menos, al enfriarse empieza a subir la tension para aumentar la temperatura poco a poco y asi sucesivamente, y en teoria debe mantener una temperatura estable.

bueno esa es la idea a ver si sale.... XD
 
Última edición:
hola
No entendi mucho eso del pirometro, segun yo un pirometro solo mide altas temperaturas, pero creo que se por donde va, y lo mismo o muy parecido quiero hacer yo, a diferencia de que en lugar de programarlo en una tabla, voy ha controlar la temperatura con integrales y derivadas (PID), algo asi como se controlan los servomotores, es decir, que empiezan en lo maximo y cuando se va acercando, en este caso a la temperatura, va disminuyendo la tension (por dimmer) y por ende va calentando menos, al enfriarse empieza a subir la tension para aumentar la temperatura poco a poco y asi sucesivamente, y en teoria debe mantener una temperatura estable.

bueno esa es la idea a ver si sale.... XD
Bueno, algo así es lo que está en el primer ejemplo que puse, pero no usa tabla.​
Un pirómetro industrial, es ésto.​
pirometro-digital-p-tablero-de-automatizacion-industrial-7530-MLA5235191192_102013-F.jpg
Y sip. Maneja altas temperaturas (dependiendo del elemento sensor o termocupla)​
En mi caso, de190° a 250°, pero podría ser más.​
A eso me refería cuando te dije la diferencia de una compilación y otra, por más que una sea ASM y otra C.
También entiendo lo que querés hacer, y es usar PID (un lazo cerrado) y con los servos generar el movimiento para regular la temperatura. (¿Serán llaves de paso?)

El primer ejemplo, el set de la temperatura se leen llaves mini-dips pero bien se podría adicionar las tablas del segundo ejemplo.

La parte de electrónica de entrada y salida del primer y segundo ejemplo, son las mismas. (Es el mismo autor de las dos)​
Ojalá pudiera ayudarte más. Ahora, si necesitas que te explique algo más del código, avisa, conozco de memoria sus partes y como funciona cada una de ellas.​
Tal vez de esa manera puedas aplicarlo a los PIC.

:apreton:
 
Última edición por un moderador:
Un pirometro industrial es esto
Ah! Ok. Supongo que en esos se puede programar una temperatura y activa un relé o algo así, no? La verdad no los conocía.

generar el movimiento para regular la temperatura (¿¿¿ seran llaves de paso ??? )
No. El servo es para otra cosa.
Estoy automatizando la selladora de bolsas y en el transcurso estoy aprendiendo otras técnicas, como el UART con direccionamiento por Hardware y control de un servo con retroalimentación.

Bueno, o sea, ésto:

Hojala pudiera ayudarte mas., ahora si nesesitas que te explique algo mas del codigo ., avisa ., los conozco de memora su partes ., y como funciona cada una de ellas
Tal vez de esa manera ., puedas aplicarlo a los PIC
Primero voy a intentar lo del PID, si de plano no me funciona o no puedo, entonces si acepto tu ofrecimiento de ayuda.
Y en ASM me defiendo, no soy un experto pero si he hecho un par de proyectos, aunque casi siempre termino por hacerlos o en Basic o C.

Gracias. (y):apreton:
 
Última edición por un moderador:
Hola
aaah Ok, supongo que en esos se puede programar una temperatura y activa un rele o algo asi no? la verdad no los conocia.


no el servo es para otra cosa, estoy automatizando la selladora de bolsas XD, y en el transcurso estoy aprendiendo otras tecnicas, como el UART Direccionado por Hardware, control de un servo con retroalimentacion... bueno o sea esto:
https://www.youtube.com/watch?v=x1YEBu7-j40



primero voy a intentar lo del PID, si de plano no me funciona o no puedo, entonces si acepto tu ofrecimiento de ayuda. y ASM me defiendo, no soy un experto pero si he hecho un par de proyectos, aunque casi siempre termino por hacerlos o en basic o C...

Gracias... (y):apreton:
Bueno, ese proyecto está buenísimo. Ya entiendo que querés hacer.​
Querés automatizar la selladora y está genial la idea.​
Si precisas algo, pedilo nomás, no hay problema.​
(y) (y) (y) :apreton:
 
Última edición por un moderador:
Atrás
Arriba