PDA

View Full Version : Fan regulator - Any advise



Now-Started
- 27th August 2009, 11:22
Hello Everyone
This is my first post here and hope to get some help from someone. I recently bought PICBasic Pro and tried few programs and now I feel it is time to jump into something more useful and exciting.
I want to make a fan regulator using two rf modules and my PIC12f629. I found the following code on the net posted by someone, I can understand some of it but need some help to understand it completely:

DEVICE 12F629
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, BODEN_OFF, CP_OFF, MCLRE_OFF
;XTAL 4
ALL_DIGITAL = TRUE
; 76543210
TRISIO = %00011100 ;1-input, 0-output
PORTB_PULLUPS OFF
CMCON = 7 ;comparator off
;************************************************* ******************************
;pull-up initialization
;OPTION_REG.7 = 0 ;enable pull-ups
;WPU.4 = 1 ;pull-up on GPIO.4 pin
OPTION_REG = %11010101 ;presc 1:64 ,External Interrupt Edge to rising edge

;I/O symbols
SYMBOL Triac_out = GPIO.0 ;pin for fiering triac
SYMBOL IR_Receiver = GPIO.3 ;pin for receiving ir-data from ir-module
SYMBOL Zero_cross = GPIO.2 ;pin for detecting zero-cross point
SYMBOL Dim_UP_Button = GPIO.4
SYMBOL Dim_DOWN_Button = GPIO.5

;interrupt symbols
SYMBOL GIE = INTCON.7 ; Global Interrupt Enable 1 = enable, 0 = disable
SYMBOL T0IE = INTCON.5 ;TMR0 Overflow Interrupt Enable bit
SYMBOL INTE = INTCON.4 ;GP2/INT External Interrupt Enable 1 = enable, 0 = disable
SYMBOL T0IF = INTCON.2 ;TMR0 Overflow Interrupt Flag bit
SYMBOL INTF = INTCON.1 ;External Interrupt Flage 1 = external interrupt occurred (must be cleared in software)


DIM Load_Value AS WORD
DIM I AS BYTE

;Clear interrupt sources flages and enable them
T0IF = 0 ;Clear TMR0 overflaw interrupt flag
INTF = 0 ;Clear External Interrupt Flag
;T0IE = 1 ;Enable TMR0 overflaw interrupt
;INTE = 1 ;Enable External Interrupt
;GIE = 1 ;Enable Global interrupt ( 0 disable)


Load_Value = 155

ON_INTERRUPT Interrupt_Detect

GOTO MAIN

Interrupt_Detect:
IF INTF = 1 THEN
TMR0 = Load_Value
T0IE = 1
INTF = 0 ;Clear INT Flag (be ready for the next)
ENDIF

IF T0IF = 1 THEN
ASM
Bsf GPIO,0
Nop
Nop
Nop
Nop
Nop
Nop
Nop
Nop
Nop
Nop
Bcf GPIO,0
ENDASM
T0IF = 0
ENDIF
CONTEXT RESTORE


MAIN:

GIE = 0 ' Turn off global interrupts
While GIE = 1:GIE = 0:Wend ' Make sure they are off

;T0IE = 1 ' Enable TMR0 overflow interrupt
INTE = 1
GIE = 1 ' Enable global interrupts

IF Dim_UP_Button = 1 THEN GOSUB DIM_UP
IF Dim_DOWN_Button = 1 THEN GOSUB DIM_DOWN

GOTO Main


DIM_UP:
Load_Value = Load_Value + 8
IF Load_Value >= 155 THEN Load_Value = 155
FOR I = 0 TO 5000 : DELAYUS 100 : NEXT
RETURN


DIM_DOWN:
Load_Value = Load_Value - 8
IF Load_Value <= 67 THEN Load_Value = 67
FOR I = 0 TO 5000 : DELAYUS 100 : NEXT
RETURN
-----------------------------------------------------
Just to put some light on the above program, I want to add that this code was written in some proton (to me it looks very similar to PBP). It is meant to be an IR operated unit ( I will try RF modules).

I just need some help on understanding timers & their role in above program along with the role of Load_Value as I dont understand the following as well in the code:

" Load_Value = Load_Value - 8
IF Load_Value <= 67 THEN Load_Value = 67" & also

"Load_Value = Load_Value + 8
IF Load_Value >= 155 THEN Load_Value = 155"

Many Thanks

Jerson
- 27th August 2009, 14:19
Hey Now-started

First of all, this code is very similar to what you can use in PBPro.

Now to your specific queries.
what the code is supposed to do is

1. Get triggered by the external interrupt pin on a mains zero crossing
2. When this happens, the TMR0 timer is loaded with the delay time to fire the triac. Think of this as a phase lag triggering like the triac dimmer you use in your lamps.
3. The 67 and 155 are limiting values for the delay time, so when you increase the value it should not increase beyond 155 and when you decrease it should not go below 67. If these conditions are not met, you will have weird behaviour on the triac dimmer
4. The load_value is the delay time I talk of here. The +/-8 is the step for the dimmer value

I hope my explanation will turn on more light bulbs for you :)
Hope you can put a name on your alias Now_started ;)

Acetronics2
- 27th August 2009, 15:20
Hi, Jerson

Talking about lamps ...

I don't know if this circuit can work with LITTLE fans motors ... ( synchronous motors or computer fans ... between others ... )

Alain

Now-Started
- 27th August 2009, 16:41
1. Get triggered by the external interrupt pin on a mains zero crossing
2. When this happens, the TMR0 timer is loaded with the delay time to fire the triac. Think of this as a phase lag triggering like the triac dimmer you use in your lamps.
3. The 67 and 155 are limiting values for the delay time, so when you increase the value it should not increase beyond 155 and when you decrease it should not go below 67. If these conditions are not met, you will have weird behaviour on the triac dimmer
4. The load_value is the delay time I talk of here. The +/-8 is the step for the dimmer value

Thanks Jason, my name is Damien. Your explanation has showed me light at the end of a looong tunnel. Few questions have risen again:

1) Does this code wait for any command to start the light/fan or as soon as the circuit is connected it fires the triac?
2) What is "Nop, Nop..." & why it is repeated many times?

Thanks again (Getting there)

Jerson
- 27th August 2009, 18:54
Hi Damien

The code starts right away. It uses the DIM_UP and DIM_DOWN buttons to change the dimming value.
the NOP commands are repeated as a means of attaining a small delay time between the GPIO.0 on and GPIO.0 off commands. Meaning, make a tiny pulse to fire the triac.

A tiny warning, the PBPro compiler doesn't support the CONTEXT RESTORE command. You should also read up on Darrel Taylor's instant interrupts to get this working smoothly under PBPro. The interrupts supported by PBPro are too primitive to achieve anything time critical.

Alain, I think the circuit should be good for a ceiling fan too. The triac rating should help to decide that.

Now-Started
- 27th August 2009, 19:50
[QUOTE=Jerson;77773]
A tiny warning, the PBPro compiler doesn't support the CONTEXT RESTORE command. You should also read up on Darrel Taylor's instant interrupts to get this working smoothly under PBPro. The interrupts supported by PBPro are too primitive to achieve anything time critical.
[QUOTE]

Thanks Jerson (sorry to call you Jason before), where can I read about Darrel Taylor's instant interrupts? & can you advise me of what will be the replacement code for CONTEXT RESTORE (what does it do?))

Thanks

P.S: I know that it may be too much to ask, but can someone please make important corrections to this code according to PBPro, I think I will be able to adjust the rest according to my need (atleast I hope)

Acetronics2
- 27th August 2009, 20:03
Hi,

Looking at this interrupt stubb ... it seems translating it into pure ASM interrupt is fairly easy ... as all commands have their straight asm equivalent !!!

BTW ... I do not see DT Interrupts fitting into a '629 ...

Alain

Now-Started
- 28th August 2009, 05:32
BTW ... I do not see DT Interrupts fitting into a '629 ...

I have 12F635 as well, if that helps :)

Jerson
- 28th August 2009, 08:58
Am I missing something? I looked up microchip site for 16F629 ... nothing. Is it a 639 and a 635 you talk about?

As to whether DT instant interrupts fits in a 628 or equivalent, I'm not sure, but I've used assembly language interrupts on a 628. It's very easy once you know.

Acetronics2
- 28th August 2009, 10:53
Hi, Jerson

You should have a strong coffee ...




DEVICE 12F629
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, BODEN_OFF, CP_OFF, MCLRE_OFF
...
...


lol ...

For DT interrupts ... the problem is the RAM size, not the Program size ...

So, a 12Fxxx with enough RAM ( 12F683 i.e. ) is Ok

It won't fit into a 16F84 nor ...

Alain

Jerson
- 28th August 2009, 13:02
Hi Alain - I really needed coffee. Too much stress I guess. I mistook it for a 16F device!!! haha

OTOH 64 bytes RAM should be good enough to do asm interrupts no?

This is what I did with the 16F628 interrupts.


' define the interrupt handler
define INTHAND _IntHandler
' These variables are used to save the machine state on interrupt
wsave var byte $20 SYSTEM ' location for W if in bank0
wsave1 var byte $A0 SYSTEM ' location for W if in bank1
wsave2 var byte $120 SYSTEM ' location for W if in bank2
ssave var byte BANK0 SYSTEM ' location for STATUS register
psave var byte BANK0 SYSTEM ' location for PCLATH register
fsave var byte BANK0 SYSTEM ' location for FSR register

IntHandler:
asm
movwf wsave ; Save the W register
swapf STATUS, W
clrf STATUS ; Point to bank 0
movwf ssave ; Save the STATUS register
movf PCLATH, W ; Save PCLATH
movwf psave
movlw ((INTHAND) >> 8) ; Set PCLATH for jump
movwf PCLATH

btfss INTCON, INTF ; branch if PULSEIN arrived
goto EndInt

; your code goes here

; restore the machine context
EndInt
movf fsave,w ;restore the FSR
movwf FSR
movf psave,w ;restore PCH
movwf PCLATH
swapf ssave, W ;restore STATUS
movwf STATUS
swapf wsave, F
swapf wsave, W ;restore W
retfie
endasm

I have not checked the datasheet for the banks used in the 12F629, but the wsave registers may need to change accordingly. Otherwise, the context save and restore takes just 4 bytes of RAM !!!!

That also answers Damien as to the code needed for the CONTEXT RESTORE of proton

:)