|
Gepost op maandag 12 April 2010 18:58:03 |
 |
Ik denk dat je hier beter geen interrupt gebruikt. Je komt dan namelijk als de routine is afgelopen weer op dezelfde plaats in je code terecht van waar je zat voor de interrupt.
Je kan beter zoiets toepassen:
Code |
high relais1
for teller = 0 to 1000
if ingang = 1 then
goto begin
endif
delayms 1
next
high relais 2
|
EDIT: Negeer het bovenstaande maar. Had je vraag fout begrepen. [Bericht gewijzigd door Stynus op Maandag 12 April 2010 19:13:49] |
Met vriendelijke groet, Stynus ||| www.elektronicastynus.be |
|
Gepost op maandag 12 April 2010 19:05:10 |
 |
De bedoeling was om in het hoofdprogramma de analoge ingangen in te lezen en zo nodig een fan in te schakelen (PWM gestuurd).
Het programma lijkt me toch te kloppen of heb ik ergens een fout in de code gemaakt? |
|
|
Gepost op maandag 12 April 2010 19:38:14 |
 |
u drukknoppen zijn niet ontdenderd (interrupt wordt verschillende malen aan geroepen en u schakeling toggelt)
daarom denk je dat het programma niet juist
reageert. ik ontdender altijd met een timer,
drukknop ingedrukt timer op 0 zetten,flag hoog maken
verder gaan met programma en kijken of hij na +-20 ms nog gedrukt is en dan actie ondernemen |
|
|
Gepost op maandag 12 April 2010 19:48:11 |
 |
Hetgeen je zegt zou wel eens kunnen kloppen, ik heb de scoop er eens opgehangen en het bevestigd jou theorie.
geel: uitgang pic om relais te schakelen
blauw: drukknop

Bij de eerste druk op de drukknop (blauwe puls) schakelt het relais en bij de tweede druk niet, wel toggled de uitgang van de PIC heel even, maar doet het relais niet schakelen.
Maar hoe vertaald uw oplossing zich dan in code? [Bericht gewijzigd door vdbeke op Maandag 12 April 2010 19:58:52] |
|
|
Gepost op maandag 12 April 2010 22:16:42 |
 |
Ik kreeg net een idee binnengeschoten hoe ik op een simpele manier jouw idee in praktijk kan omzetten, hieronder de code die ik heb gebruikt. Alvast bedankt voor de tip.
Ik heb het met een standaard delay opgelost hetgeen normaal niet gedaan mag worden, maar in praktijk toch goed blijkt te werken. Elke keer ik druk word het relais omgeschakeld. Het addertje staat onder de code.
Code |
'****************************************************************
'* Name : inschakelvertraging.BAS *
'* Author : vdbeke *
'* Notice : Copyright (c) 2010 vdbeke *
'* : All Rights Reserved *
'* Date : 12/04/2010 *
'* Version : 1.0 *
'* Notes : inschakelvertraging voor PA-300 *
'* : *
'****************************************************************
Device 16F876A
Config WDT_Off, PWRTE_ON, HS_OSC
ON_INTERRUPT drukknop
ALL_DIGITAL false ;er worden analoge ingangen gebruikt
XTAL 20
Symbol temp1 = PORTA.0 ;temp1 hangt aan PORTA.0
Symbol temp2 = PORTA.1 ;temp2 hangt aan PORTA.1
Symbol relais1 = PORTC.1 ;relais1 hangt aan PORTC.1
Symbol relais2 = PORTC.2 ;relais2 hangt aan PORTC.2
Symbol fan = PORTC.3 ;fan hangt aan PORTC.3
Symbol powerled = PORTC.7 ;powerled hangt aan PORTC.7
Symbol INTF = INTCON.1 ;RB0 external INTerrupt Flag
Symbol INTE = INTCON.4 ;RB0 external INTerrupt Enable
Symbol GIE = INTCON.7 ;Global Interrupt Enable
Dim toestand As Byte
Dim knop As Byte
; 76543210
PORTC = %00000000 ;PORTC zijn allemaal uitgangen
TRISC = %00000000 ;alle uitgangen van PORTC zijn 0
Clear
High powerled
toestand = 0
GoTo over_irq
drukknop:
DelayMS 20
knop = PORTB.0
If knop = 1 Then
If toestand = 0 Then
Low powerled
High relais1
DelayMS 4000
High relais2
toestand = 1
ElseIf toestand = 1 Then
Low relais1
Low relais2
High powerled
toestand = 0
EndIf
EndIf
INTF=0
Context Restore
over_irq:
GIE=0
INTE=1
GIE=1
;*****Hoofdprogramma*****
loop:
GoTo loop
;************************
End
|
Nu heb ik ??n probleem opgelost, maar een ander gecre?erd waar ik geen oplossing voor kan vinden. Relais1 moet direct inschakelen en relais2 mag pas na een paar seconden inschakelen, dit werkt perfect. Maar stel dat ik direct na het inschakelen de transfo spanningsloos wil maken dan moet ik nu wachten tot relais2 ingeschakeld is. En in een noodgeval zou dit wel eens verkeerd kunnen aflopen . [Bericht gewijzigd door vdbeke op Maandag 12 April 2010 22:36:50] |
|
|
Gepost op maandag 12 April 2010 23:02:36 |
 |
Code |
'****************************************************************
'* Name : relais schakelen *
'* Author : Gijsbrechts Danny *
'* Notice : Copyright (c) 2010 Gijsbrechts Danny *
'* : All Rights Reserved *
'* Date : 5/04/2010 *
'* Version : 1.0 *
'* Notes : Timer1 verhoogt telkens +- 1/100sec *
'* : telkenmaal timer1 = 100 = 1 seconden *
'****************************************************************
Device 16F876A
Config WDT_Off, PWRTE_ON, HS_OSC
ALL_DIGITAL false ;er worden analoge ingangen gebruikt
XTAL 20
Symbol temp1 = PORTA.0 ;temp1 hangt aan PORTA.0
Symbol temp2 = PORTA.1 ;temp2 hangt aan PORTA.1
Symbol relais1 = PORTC.1 ;relais1 hangt aan PORTC.1
Symbol relais2 = PORTC.2 ;relais2 hangt aan PORTC.2
Symbol fan = PORTC.3 ;fan hangt aan PORTC.3
Symbol powerled = PORTC.7 ;powerled hangt aan PORTC.7
Dim Seconden As Byte
Dim Key_Timer As Byte
Dim Key_Pushed As Byte
Dim Timer1 As Byte
Dim Timer2 As Byte
Dim dummy As Byte
Dim Toestand As Byte
; 76543210
PORTC = %00000000 ;PORTC zijn allemaal uitgangen
TRISC = %00000000 ;alle uitgangen van PORTC zijn 0
Toestand = 0
Clear
Symbol GIE = INTCON.7 ' Global Interrupt Enable
Symbol T0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
Symbol T0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
OPTION_REG = %10000111 ' geen pull_up , prescaler Initialisatie
TMR0 = 60 '
T0IE = 1 ' Enable TMR0 overflow interrupt
GIE = 1 ' Enable global interrupts
Clear ' clear all variables
ON_HARDWARE_Interrupt GoTo Interrupt
loop:
'************** hier u programma ************
;Key_Timer telt in stappen van +- 10ms
;Key_Pushed 0 = toets open , 1 = toets gedrukt om relais op te zetten
; 2 = toets gedrukt om relais af te zetten
; 3 = relais afgehandeld wachten tot toets gelost is
;toestand 0 = relais af
; 1 = relais 1 op
; 2 = relais1 + 2 op
If PORTB.0 = 0 Then Key_Pushed = 0
If PORTB.0 = 1 And Key_Pushed = 0 Then
Key_Timer = 0
If Toestand = 0 Then
Key_Pushed = 1 ; toets gedrukt relais zijn uit
Else
Key_Pushed = 2 ; toets gedrukt relais zijn aan
EndIf
EndIf
Select Key_Pushed
Case 1
If Key_Timer = 5 Then
High relais1
Toestand = 1
Seconden = 0
EndIf
Key_Pushed = 3
Case 2
If Key_Timer = 5 Then
Low relais1
Low relais2
Toestand = 0
EndIf
Key_Pushed = 3 ; Drukknop afgehandeld Flag op 3 voor
EndSelect
If Toestand = 1 Then ; als relais1 = aan wacht 3sec dan relais2 aan
If Seconden = 3 Then
High relais2
Toestand = 2
endif
EndIf
Toggle powerled
GoTo loop
; ****************************************************************
; ** Interrupt Handler **
; ****************************************************************
Interrupt:
Context SAVE
If T0IF = 0 Then exit_int
TMR0 = 60 ; 10ms
Inc Timer1
Inc Key_Timer
Select Timer1
Case 25 '0.25sec
Timer2 = 0
Case 50 '0,5sec
Timer2 = 1
Case 75
Timer2 = 2 '0,75sec
Case 100
Timer2 = 3 '1sec
Timer1 = 0
Inc Seconden
End Select
T0IF = 0
exit_int:
Context Restore 'Restore the registers and exit interrupt
|
probeer dit eens niet getest
ik gebruik timer0 interrupt als timer voor te ontdenderen
en relais 2 te schakelen
in het programma kijk ik of toets gedrukt is en werk met vlaggen
om toestand op te volgen kijk maar eens [Bericht gewijzigd door dannymyron op Maandag 12 April 2010 23:31:02] |
|
|
Gepost op dinsdag 13 April 2010 16:04:29 |
 |
Ik heb het getest, maar het werk niet. Daarna ben ik opzoek gegaan naar de fout. En ik denk dat ik ze gevonden heb. Bij select Key_pushed staat er bij beide cases "Key_pushed = 3", dus als er bij de volgende loop terug gekeken wordt zal ie naar case 3 willen gaan, maar deze is er niet. Dus ik denk dat daar het programma vastloopt.
Nu heb ik verschillende keren je programma proberen te ontleden, maar ik snap de werking niet.
Dan ben ik maar verder gegaan met het uitbreiden van mijn "hoofdprogramma". Deze is nu volledig af en werkt ook volledig, ik heb het meerdere malen getest en de fans schakelen bij de juiste temperatuurwaardes in op de juiste snelheden.
De code hier op het forum is weer een zooitje geworden, als je een geordend programma wil moet je me maar mailen.
Code |
'****************************************************************
'* Name : inschakelvertraging.BAS *
'* Author : vdbeke *
'* Notice : Copyright (c) 2010 vdbeke *
'* : All Rights Reserved *
'* Date : 12/04/2010 *
'* Version : 1.0 *
'* Notes : inschakelvertraging voor PA-300 en *
'* : temperatuurregeling *
'****************************************************************
; ____ +--v--+
; MCLR <1>[ ]<28>
; temp1 <2>[ ]<27>
; temp2 <3>[ P ]<26>
; <4>[ I ]<25>
; <5>[ C ]<24>
; <6>[ 1 ]<23>
; <7>[ 6 ]<22>
; GND <8>[ F ]<21> drukknop INT
; kristal <9>[ 8 ]<20> +5V
; kristal <10>[ 7 ]<19> GND
; <11>[ 6 ]<18> powerled
; relais1 <12>[ A ]<17>
; relais2 <13>[ ]<16>
; fan <14>[ ]<15>
; +-----+
Device 16F876A
Config WDT_Off, PWRTE_ON, HS_OSC
ON_Interrupt drukknop
ALL_DIGITAL false ;er worden analoge ingangen gebruikt
XTAL 20
Symbol relais1 = PORTC.1 ;relais1 hangt aan PORTC.1
Symbol relais2 = PORTC.2 ;relais2 hangt aan PORTC.2
Symbol fan = PORTC.3 ;fan hangt aan PORTC.3
Symbol powerled = PORTC.7 ;powerled hangt aan PORTC.7
Symbol INTF = INTCON.1 ;RB0 external INTerrupt Flag
Symbol INTE = INTCON.4 ;RB0 external INTerrupt Enable
Symbol GIE = INTCON.7 ;Global Interrupt Enable
Dim toestand As Bit ;toestand van relais
Dim knop As Bit ;toestand van drukknop
Dim temp1 As Float ;temperatuur van sensor 1
Dim temp2 As Float ;temperatuur van sensor 2
Dim PWMwaarde As Byte ;PWMwaarde voor fan
Dim teller As Byte ;teller voor softwarematig PWM
ADIN_RES = 10 ;Use the 10 bit result A/D
ADIN_TAD = FRC ;Use the FRC (clock source)
ADIN_STIME = 50 ;Sample time of 50 ms
; 76543210
PORTA = %00000011 ;PORTA zijn allemaal uitgangen behalve PORTA.0 & 1
PORTC = %00000000 ;PORTC zijn allemaal uitgangen
TRISC = %10000000 ;alle uitgangen van PORTC zijn 0 behalve PORTC.7
Clear
toestand = 0
GoTo over_irq
drukknop:
DelayMS 20
knop = PORTB.0
If knop = 1 Then
If toestand = 0 Then
Low powerled
High relais1
;delay????
toestand = 1
High relais2
ElseIf toestand = 1 Then
Low relais1
Low relais2
High powerled
toestand = 0
EndIf
EndIf
INTF=0
Context Restore
over_irq:
GIE=0
INTE=1
GIE=1
;**********temperatuurregeling**********
;schakelpunten...
;bij stijgende T: 35?C / 45?C / 55?C
;toerental: 60% / 80% / 100%
;schakelpunten...
;bij dalende T : 50?C / 40?C / 30?C
;toerental: 80% / 60% / 0%
loop:
temp1 = ADIn 0
temp1 = temp1 / 128 ;temp1 omzetten in ?C
temp2 = ADIn 1
temp2 = temp2 / 128 ;temp2 omzetten in ?C
If temp1 <= 30 And temp2 <= 30 Then
PWMwaarde = 0
ElseIf temp1 >= 35 Or temp2 >= 35 Then
If temp1 <= 40 And temp2 <= 40 Then
PWMwaarde = 150
ElseIf temp1 >= 45 Or temp2 >= 45 Then
If temp1 <= 50 And temp2 <= 50 Then
PWMwaarde = 200
ElseIf temp1 >= 55 Or temp2 >= 55 Then
PWMwaarde = 255
EndIf
EndIf
EndIf
'softwarematig fan PWM'en
For teller = 1 To 255 Step 1 '255 teller, telt van 1 to 255 met stappen van 1
If PWMwaarde >= teller Then
High fan
Else
Low fan
EndIf
Next
GoTo loop
;***************************************
End
|
|
|
|
Gepost op zaterdag 1 Mei 2010 16:34:21 |
 |
Ik heb me nog eens achter het programma gezet, maar het wil helaas niet echt lukken. Onderaan de code.
Als ik op de knop druk schakelt relais1 eerst in, na twee seconden schakelt relais2 in. Dit is dus precies zoals het moet!
Als ik op de knop druk en direct daarna terug druk (bv. om uit te schakelen) schakelt relais1 in en daarna schakelt het terug uit verder gebeurt er niets meer. De fan stopt ook met draaien. Het hoofdprogramma wil dus niet verder gaan, de interrupt routine blijft werken dit merk ik aan het schakelen van relais1. Als ik daarna terug op de knop druk schakelt relais1 in maar relais2 schakelt pas na lange tijd in. Als relais2 uiteindelijk dan toch ingeschakeld is gaat de fan ook terug draaien. Dus dan wordt het hoofdprogramma terug hervat.
Code |
'****************************************************************
'* Name : inschakelvertraging.BAS *
'* Author : vdbeke *
'* Notice : Copyright (c) 2010 vdbeke *
'* : All Rights Reserved *
'* Date : 12/04/2010 *
'* Version : 1.0 *
'* Notes : inschakelvertraging voor PA-300 en *
'* : temperatuurregeling *
'****************************************************************
; ____ +--v--+
; MCLR <1>[ ]<28>
; temp1 <2>[ ]<27>
; temp2 <3>[ P ]<26>
; <4>[ I ]<25>
; <5>[ C ]<24>
; <6>[ 1 ]<23>
; <7>[ 6 ]<22>
; GND <8>[ F ]<21> drukknop INT
; kristal <9>[ 8 ]<20> +5V
; kristal <10>[ 7 ]<19> GND
; <11>[ 6 ]<18> powerled
; relais1 <12>[ A ]<17>
; relais2 <13>[ ]<16>
; fan <14>[ ]<15>
; +-----+
Device 16F876A
Config WDT_Off, PWRTE_ON, HS_OSC
ON_Interrupt drukknop
ALL_DIGITAL false ;er worden analoge ingangen gebruikt
XTAL 20
Symbol relais1 = PORTC.1 ;relais1 hangt aan PORTC.1
Symbol relais2 = PORTC.2 ;relais2 hangt aan PORTC.2
Symbol fan = PORTC.3 ;fan hangt aan PORTC.3
Symbol powerled = PORTC.7 ;powerled hangt aan PORTC.7
Symbol INTF = INTCON.1 ;RB0 external INTerrupt Flag
Symbol INTE = INTCON.4 ;RB0 external INTerrupt Enable
Symbol GIE = INTCON.7 ;Global Interrupt Enable
Dim toestand As Byte ;toestand van relais
Dim knop As Bit ;toestand van drukknop
Dim temp1 As Float ;temperatuur van sensor 1
Dim temp2 As Float ;temperatuur van sensor 2
Dim PWMwaarde As Byte ;PWMwaarde voor fan
Dim teller As Byte ;teller voor softwarematig PWM
ADIN_RES = 10 ;Use the 10 bit result A/D
ADIN_TAD = FRC ;Use the FRC (clock source)
ADIN_STIME = 50 ;Sample time of 50 ms
; 76543210
PORTA = %00000011 ;PORTA zijn allemaal uitgangen behalve PORTA.0 & 1
PORTC = %00000000 ;PORTC zijn allemaal uitgangen
TRISC = %10000000 ;alle uitgangen van PORTC zijn 0 behalve PORTC.7
Clear
toestand = 0
GoTo over_irq
drukknop:
DelayMS 20 ;wachten voor ontdendering
knop = PORTB.0
If knop = 1 Then
If toestand = 0 Then
Low powerled
High relais1
toestand = 1
ElseIf toestand = 1 Or toestand = 2 Then
Low relais1
Low relais2
High powerled
toestand = 0
EndIf
EndIf
INTF = 0
Context Restore
over_irq:
GIE=0
INTE=1
GIE=1
;**********temperatuurregeling**********
;schakelpunten...
;bij stijgende T: 35?C / 45?C / 55?C
;toerental: 60% / 80% / 100%
;schakelpunten...
;bij dalende T : 50?C / 40?C / 30?C
;toerental: 80% / 60% / 0%
loop:
temp1 = ADIn 0
temp1 = temp1 / 128 ;temp1 omzetten in ?C
temp2 = ADIn 1
temp2 = temp2 / 128 ;temp2 omzetten in ?C
If temp1 <= 10 And temp2 <= 10 Then
PWMwaarde = 0
ElseIf temp1 >= 15 Or temp2 >= 35 Then
If temp1 <= 40 And temp2 <= 40 Then
PWMwaarde = 150
ElseIf temp1 >= 45 Or temp2 >= 45 Then
If temp1 <= 50 And temp2 <= 50 Then
PWMwaarde = 200
ElseIf temp1 >= 55 Or temp2 >= 55 Then
PWMwaarde = 255
EndIf
EndIf
EndIf
'softwarematig fan PWM'en
For teller = 1 To 255 Step 1 '255 teller, telt van 1 to 255 met stappen van 1
If PWMwaarde >= teller Then
High fan
Else
Low fan
EndIf
Next
If toestand = 1 Then
DelayMS 2000
High relais2
toestand = 2
EndIf
GoTo loop
;***************************************
End
|
|
|
|
Gepost op zondag 2 Mei 2010 10:04:40 |
 |
Ik denk dat ik u probleem ken u variabelen worden waarschijnlijk gewijzigd door de interrupt waardoor het kan spoken in u programma.
Quote | Because a hardware interrupt may occur at any time, It cannot be fully guaranteed that a SYSTEM variable will not be disturbed while inside the interrupt handler, therefore, the safest way to use a HARDWARE interrupt is to write the code in assembler, or to implement a SOFTWARE interrupt using the ON INTERRUPT directive. This will guarantee that no system variables are being altered. Alternatively, the assembler code may be viewed in order to ascertain whether any system variables are being used. Some of these are: -
PP0, PP0H, PP1, PP1H, PP2, PP2H, PP3, PP3H, PP4, PP4H, PP5, PP5H, PP6, PP6H, PP7, PP7H, GEN, GENH, GEN2, GEN2H, GEN3, GEN3H, GEN4, GEN4H, GPR, BPF. |
Dit probleem krijg je als je basic programmert in interrupt dan heb je
geen controle over de registers die gewijzigd worden.
In u geval is het waarschijnlijk delayms 20, wijzig dit eens in
Code |
For teller = 0 to 255
asm
nop
nop
nop
endasm
next teller
|
Een andere methode die ik altijd gebruik is de registers die kunnen
wijzigen te bewaren voor de interrupt en terug te halen na de interrupt
hiervoor gebruik ik BISVS.
Quote | Download + uitleg BISVS http://users.picbasic.org/Howto/BISVS/BISVS.htm |
Ik begrijp eigenlijk niet aan de hand van u programma opbouw waarom je
interrupt gebruikt voor de toetsen, ik zou hem eruit gooien.
Om nogeens terug tekomen op het programma dat ik heb gepost (dat niet werkt).
De bedoeling is om met een timer (die onder interrupt werkt) de status van de toest op te volgen.
vb.Keystatus = 0
toest wordt gedrukt timer = 0 en keystatus = 1
als timer = 5 (50ms) dan keystatus = 2 (toets ontdenderd)
als keystatus behandeld is in u geval de relais op of af zetten dan
wordt keystatus = 3. Keystatus wordt terug 0 als de toets is gelost.
Je kan dit uibreiden of maken zoals je wil vb.
keystatus = 0
timer = 0 :keystatus = 1 toets gedrukt
timer = 5 :keystatus = 2 toets ontdenerd
timer = 5 - 30 :keystatus = 3 toets > 50 < 300ms gedrukt (druktoets)
timer = 50 :keystatus = 4 toets .5sec gedrukt
timer = 100 :keystatus = 5 toets 1 sec gedrukt
keystatus = 6 toets behandeld
enz.
en als je nog een andere timer toevoegt dan kan je het relais na 2 sec
laten schakelen zonder delayms 2000
|
|
|
Gepost op zondag 2 Mei 2010 16:02:58 |
 |
Het asm stukje heb ik geprobeerd maar helpt niet, het geeft me exact hetzelfde probleem.
Quote | dannymyron schreef:
...
Ik begrijp eigenlijk niet aan de hand van u programma opbouw waarom je interrupt gebruikt voor de toetsen, ik zou hem eruit gooien. |
Ok? dan vraag ik aan jouw hoe jij het zou programmeren? Het is wel duidelijk dat je veel meer programmeerervaring hebt dan mij en dat ik wellicht helemaal verkeerd zit.
Mijn idee was om in het hoofdprogramma de temperatuur regeling te laten draaien en op interrupt de twee relais te laten schakelen. Zodat er onmiddellijk gereageerd wordt als ik op de drukknop druk. Verkeerde keuze blijkbaar.
Quote | dannymyron schreef:
Om nogeens terug tekomen op het programma dat ik heb gepost (dat niet werkt).
De bedoeling is om met een timer (die onder interrupt werkt) de status van de toest op te volgen.
vb.Keystatus = 0
toest wordt gedrukt timer = 0 en keystatus = 1
als timer = 5 (50ms) dan keystatus = 2 (toets ontdenderd)
als keystatus behandeld is in u geval de relais op of af zetten dan
wordt keystatus = 3. Keystatus wordt terug 0 als de toets is gelost.
Je kan dit uibreiden of maken zoals je wil vb.
keystatus = 0
timer = 0 :keystatus = 1 toets gedrukt
timer = 5 :keystatus = 2 toets ontdenerd
timer = 5 - 30 :keystatus = 3 toets > 50 < 300ms gedrukt (druktoets)
timer = 50 :keystatus = 4 toets .5sec gedrukt
timer = 100 :keystatus = 5 toets 1 sec gedrukt
keystatus = 6 toets behandeld
enz.
en als je nog een andere timer toevoegt dan kan je het relais na 2 sec
laten schakelen zonder delayms 2000
|
Om de een of ander reden snap ik het niet, ik ga het morgen nog eens proberen te bekijken!
Alvast bedankt voor je tips en hulp. |
|
|
Gepost op maandag 3 Mei 2010 22:32:33 |
 |
Probeer dit eens zou moeten werken
ik zou de fansnelheid evenredig met de temperatuur laten opgaan lijkt me toch beter
Code |
Device 16F876A
Config WDT_Off, PWRTE_ON, HS_OSC,lvp_off
ALL_DIGITAL = false ;er worden analoge ingangen gebruikt
XTAL 20
Symbol relais1 = PORTC.0 ;relais1 hangt aan PORTC.1
Symbol relais2 = PORTC.1 ;relais2 hangt aan PORTC.2
Symbol fan = PORTC.3 ;fan hangt aan PORTC.3
Symbol powerled = PORTC.7 'powerled hangt aan PORTC.7
Symbol Knop = PORTB.3
Dim Seconden As Byte
Dim Key_Timer As Byte
Dim Key_Pushed As Byte
Dim Timer1 As Byte
Dim Timer2 As Byte
Dim toestand As Byte ;toestand van relais
Dim temp1 As Float ;temperatuur van sensor 1
Dim temp2 As Float ;temperatuur van sensor 2
Dim PWMwaarde As Byte ;PWMwaarde voor fan
Dim teller As Byte ;teller voor softwarematig PWM
ADIN_RES = 10 ;Use the 10 bit result A/D
ADIN_TAD = FRC ;Use the FRC (clock source)
ADIN_STIME = 50 ;Sample time of 50 us
; 76543210
PORTA = %00000011 ;PORTA zijn allemaal uitgangen behalve PORTA.0 & 1
PORTC = %00000000 ;PORTC zijn allemaal uitgangen
TRISC = %10000000 ;alle uitgangen van PORTC zijn 0 behalve PORTC.7
Symbol GIE = INTCON.7 ' Global Interrupt Enable
Symbol T0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
Symbol T0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
OPTION_REG = %10000111 ' geen pull_up , prescaler Initialisatie
TMR0 = 60 '
T0IE = 1 ' Enable TMR0 overflow interrupt
GIE = 1 ' Enable global interrupts
Clear ' clear all variables
ON_HARDWARE_Interrupt GoTo Interrupt
;**********temperatuurregeling**********
;schakelpunten...
;bij stijgende T: 35?C / 45?C / 55?C
;toerental: 60% / 80% / 100%
;schakelpunten...
;bij dalende T : 50?C / 40?C / 30?C
;toerental: 80% / 60% / 0%
loop:
temp1 = ADIn 0
temp1 = temp1 / 128 ;temp1 omzetten in ?C
temp2 = ADIn 1
temp2 = temp2 / 128 ;temp2 omzetten in ?C
If temp1 <= 10 And temp2 <= 10 Then
PWMwaarde = 0
ElseIf temp1 >= 15 Or temp2 >= 35 Then
If temp1 <= 40 And temp2 <= 40 Then
PWMwaarde = 150
ElseIf temp1 >= 45 Or temp2 >= 45 Then
If temp1 <= 50 And temp2 <= 50 Then
PWMwaarde = 200
ElseIf temp1 >= 55 Or temp2 >= 55 Then
PWMwaarde = 255
EndIf
EndIf
EndIf
'softwarematig fan PWM'en
For teller = 1 To 255 Step 1 '255 teller, telt van 1 to 255 met stappen van 1
If PWMwaarde >= teller Then
High fan
Else
Low fan
EndIf
GoSub Check_toets
Next
GoTo loop
;********************************************************************
Check_toets:
If Knop = 0 Then Key_Pushed = 0 'toets losgelaten keypushed = 0
If Knop = 1 And Key_Pushed = 0 Then 'toets gedrukt keypushed = 1
Key_Timer = 0 'keytimer op 0 zetten
Key_Pushed = 1
EndIf
Select Key_Pushed
Case 1 'ingeval keypushed = 1
If Key_Timer > 1 Then 'kijken of 50ms verstreken ontdenderd
If toestand = 0 Then 'toestand, relais staan af
High relais1 'relais1 op zetten
High powerled
toestand = 1 'toestand wordt 1
Seconden = 0 'seconden op 0 zetten
Else 'als toestand > 0 relais1 (en 2 ?staan op)
Low relais1 'relais afzetten
Low relais2
Low powerled
toestand = 0 'toestand wordt 0
EndIf
Key_Pushed = 2 'keypushed = 2 wil zeggen is behandeld
EndIf
EndSelect
If toestand = 1 Then ; relais1 = aan
If Seconden = 2 Then 'aantal seconden vertraging inschakelen relais2
High relais2 'ja zet relais2 aan
toestand = 2 'toestand wordt 2 relais allebei aan
EndIf
EndIf
Return
; ****************************************************************
; ** Interrupt Handler **
; ****************************************************************
Interrupt:
Context SAVE
If T0IF = 0 Then exit_int
TMR0 = 60 ; 10ms
Inc Timer1
If Key_Timer <> 255 Then Inc Key_Timer
If Timer1 = 100 Then
Timer1 = 0
Inc Seconden
EndIf
T0IF = 0
exit_int:
Context Restore 'Restore the registers and exit interrupt
|
|
|
|
Gepost op donderdag 13 Mei 2010 21:43:16 |
 |
Ik heb heel de dag vrij gemaakt om de inschakelvertraging werkend te krijgen, ik dacht dat het me niet ging lukken maar met het programma van Danny is het me dan toch gelukt. Het probleem zat hem met Key_Timer, deze zorgde voor het ontdenderen. Maar om de een of ander reden wou deze niet werken. Ik heb er een paar uur aan gezeten, maar niets wou baten. Ik snap nog altijd niet wat er fout is, maar ik heb deze dan maar weggelaten en gekozen voor een simpele delay van 20ms en deze werkt naar behoren. Geen last van dender en alles werkt zoals ik het wou.
Danny heel erg bedankt voor je hulp, zonder jouw programma had ik dit zeker niet werkend gekregen.
Code |
'****************************************************************
'* Name : inschakelvertragingV3.BAS *
'* Author : vdbeke *
'* Notice : Copyright (c) 2010 vdbeke *
'* : All Rights Reserved *
'* Date : 13/05/2010 *
'* Version : 1.0 *
'* Notes : inschakelvertraging voor PA-300 en *
'* : temperatuurregeling *
'****************************************************************
; meer info: http://www.schematheek.net/index.php?p=forum/topic&t=362
; ____ +--v--+
; MCLR <1>[ ]<28>
; temp1 <2>[ ]<27>
; temp2 <3>[ P ]<26>
; <4>[ I ]<25>
; <5>[ C ]<24>
; <6>[ 1 ]<23>
; <7>[ 6 ]<22>
; GND <8>[ F ]<21> drukknop INT
; kristal <9>[ 8 ]<20> +5V
; kristal <10>[ 7 ]<19> GND
; <11>[ 6 ]<18> powerled
; relais1 <12>[ A ]<17>
; relais2 <13>[ ]<16>
; fan <14>[ ]<15>
; +-----+
Device 16F876A
Config WDT_Off, PWRTE_ON, HS_OSC
ALL_DIGITAL false ;er worden analoge ingangen gebruikt
XTAL 20
on_hardware_interrupt GoTo Interrupt
Symbol relais1 = PORTC.1 ;relais1 hangt aan PORTC.1
Symbol relais2 = PORTC.2 ;relais2 hangt aan PORTC.2
Symbol fan = PORTC.3 ;fan hangt aan PORTC.3
Symbol powerled = PORTC.7 ;powerled hangt aan PORTC.7
Symbol drukknop = PORTB.0 ;drukknop hangt aan PORTB.0
Symbol T0IF = INTCON.2 ;Timer0 Interrupt Flag
Symbol T0IE = INTCON.5 ;Timer0 Interrupt Enable
Symbol GIE = INTCON.7 ;Global Interrupt Enable
; 76543210
OPTION_REG =%10000111 ;pull-up deactiveren op PORTB, interne clock, prescaler voor TMR0, prescaler op 1:256
TMR0 = 60
; 76543210
PORTA = %00000011 ;PORTA zijn allemaal uitgangen behalve PORTA.0 & 1
PORTC = %00000000 ;PORTC zijn allemaal uitgangen
TRISC = %10000000 ;alle uitgangen van PORTC zijn 0 behalve PORTC.7
Dim timer1 As Byte
Dim seconden As Byte ;vertraging voor het inschakelen van relais2
Dim Key_Pushed As Byte ;toestand drukknop
Dim relaistoestand As Byte ;toestand van relais
Dim temp1 As Float ;temperatuur van sensor 1
Dim temp2 As Float ;temperatuur van sensor 2
Dim PWMwaarde As Byte ;PWMwaarde voor fan
Dim teller As Byte ;teller voor softwarematig PWM
ADIN_RES = 10 ;Use the 10 bit result A/D
ADIN_TAD = FRC ;Use the FRC (clock source)
ADIN_STIME = 50 ;Sample time of 50 ms
Clear ;alle variabele clearen
T0IF = 0
T0IE = 1
GIE = 1
;**********temperatuurregeling**********
;schakelpunten...
;bij stijgende T: 35?C / 45?C / 55?C
;toerental: 60% / 80% / 100%
;schakelpunten...
;bij dalende T : 50?C / 40?C / 30?C
;toerental: 80% / 60% / 0%
loop:
temp1 = ADIn 0
temp1 = temp1 / 128 ;temp1 omzetten in ?C
temp2 = ADIn 1
temp2 = temp2 / 128 ;temp2 omzetten in ?C
If temp1 <= 30 And temp2 <= 30 Then
PWMwaarde = 0
ElseIf temp1 >= 35 Or temp2 >= 35 Then
If temp1 <= 40 And temp2 <= 40 Then
PWMwaarde = 150
ElseIf temp1 >= 45 Or temp2 >= 45 Then
If temp1 <= 50 And temp2 <= 50 Then
PWMwaarde = 200
ElseIf temp1 >= 55 Or temp2 >= 55 Then
PWMwaarde = 255
EndIf
EndIf
EndIf
'softwarematig fan PWM'en
For teller = 1 To 255 Step 1 '255 teller, telt van 1 to 255 met stappen van 1
If PWMwaarde >= teller Then
High fan
Else
Low fan
EndIf
Next
;Key_Pushed:
; 0 = drukknop open
; 1 = drukknop gesloten, relais opzetten
; 2 = drukknop gesloten, relais afzetten
; 3 = relais afgehandeld
;relaistoestand:
; 0 = relais 1 + 2 uit
; 1 = relais 1 aan
; 2 = relais1 1 + 2 aan
If drukknop = 0 Then Key_Pushed = 0
If drukknop = 1 And Key_Pushed = 0 Then
DelayMS 20
If drukknop = 1 And Key_Pushed = 0 Then
If relaistoestand = 0 Then
Key_Pushed = 1 ;drukknop ingedrukt om relais1 te sluiten
Else
Key_Pushed = 2 ;drukknop ingedrukt om relais te openen
EndIf
EndIf
EndIf
Select Key_Pushed
Case 1
Low powerled
High relais1
relaistoestand = 1
seconden = 0
Key_Pushed = 3
Case 2
Low relais1
Low relais2
High powerled
relaistoestand = 0
Key_Pushed = 3
EndSelect
If relaistoestand = 1 Then
If seconden = 3 Then
High relais2
relaistoestand = 2
EndIf
EndIf
GoTo loop
Interrupt: ;interruptroutine
Context SAVE
If T0IF = 0 Then exit_Interrupt;interrupt van TMR0 of RB0?
TMR0 = 60
Inc timer1 ;ongeveer 10ms
If timer1 = 100 Then
Inc seconden
timer1 = 0
EndIf
T0IF = 0
exit_Interrupt:
Context Restore
End
|
Quote | dannymyron schreef: Probeer dit eens zou moeten werken
ik zou de fansnelheid evenredig met de temperatuur laten opgaan lijkt me toch beter
...
|
Wat is het voordeel als je deze evenredig laat toenemen? Lawaai zal het probleem niet zijn, als de fans draaien zal de muziek er waarschijnlijk toch serieus bovenuit komen. |
|
|
Gepost op dinsdag 9 Augustus 2011 21:29:19 |
 |
Ik was bezig met interrupt en kwam ik eens terug kijken in dit topic. Viel me wel een kemel van jewelste op. TRIS en PORT door elkaar gehaald. Laat dit geen voorbeeld voor anderen zijn. |
|
|
Gepost op dinsdag 9 Augustus 2011 23:40:11 |
 |
Ik heb een programmaatje geschreven om mbv interrupt op RB0 een led te toggelen. Een timer toegevoegd om de dender weg te werken. Maar het probleem is dat het niet altijd werkt .
Zie ik iets over het hoofd? timer heb ik al aangepast maar het blijft aanwezig.
Code |
'****************************************************************
'* Name : interrupt_16F877A.BAS *
'* Author : Ben Vandenberk *
'* Notice : Copyright (c) 2011 vdbeke *
'* : All Rights Reserved *
'* Date : 9/08/2011 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
DEVICE 16F877A ;We gebruiken een 16F877a type
CONFIG WDT_Off, PWRTE_Off, HS_OSC , lvp_off
;ON_INTERRUPT drukknop
ON_HARDWARE_INTERRUPT GOTO INTERRUPT
ALL_DIGITAL true
XTAL 20
SYMBOL LED_RUN = PORTB.7
SYMBOL LED_INTERRUPT = PORTB.6
SYMBOL INTF = INTCON.1 ;RB0 external INTerrupt Flag
SYMBOL INTE = INTCON.4 ;RB0 external INTerrupt Enable
SYMBOL GIE = INTCON.7 ;Global Interrupt Enable
SYMBOL T0IF = INTCON.2 ;Timer0 Interrupt Flag
SYMBOL T0IE = INTCON.5 ;Timer0 Interrupt Enable
OPTION_REG =%10000111 ;pull-up deactiveren op PORTB, interne clock, prescaler voor TMR0, prescaler op 1:256
TMR0 = 60
DIM FLAG_DENDER AS BIT
DIM timer1 AS BYTE
; 76543210
TRISB = %00000001 ;B.0 is een ingang, de overige zijn uitgangen
PORTB = %00000000
CLEAR
T0IF = 0
T0IE = 0
GIE = 1
GOTO over_irq
over_irq:
GIE=0
INTE=1
GIE=1
;*****Hoofdprogramma*****
loop:
TOGGLE LED_RUN
DELAYMS 100
GOTO loop
;************************
INTERRUPT:
;drukknop:
IF INTF = 1 AND FLAG_DENDER = 0 THEN
TOGGLE LED_INTERRUPT
FLAG_DENDER = 1
T0IE = 1
ELSEIF T0IF = 1 AND FLAG_DENDER = 1 THEN
TMR0 = 60
INC timer1 ;ongeveer 10ms
IF timer1 = 4 THEN
FLAG_DENDER = 0
timer1 = 0
T0IE = 0
ENDIF
T0IF = 0
ENDIF
INTF = 0
CONTEXT RESTORE
END
|
|
|
|
Gepost op vrijdag 26 Augustus 2011 20:00:40 |
 |
Nog maar eens een poging ondernomen om de inschakelvertraging te maken. Wonder boven wonder werkt het. Zijn er opmerking kwa structuur?
Code |
'****************************************************************
'* Name : inschakelvertragingV4.BAS *
'* Author : Ben Vandenberk *
'* Notice : Copyright (c) 2011 vdbeke *
'* : All Rights Reserved *
'* Date : 25/08/2011 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
DEVICE 16F877A ;We gebruiken een 16F877a type
CONFIG WDT_Off, PWRTE_Off, HS_OSC , lvp_off
ALL_DIGITAL true
XTAL 12.288 ;kristal van 12,288MHz
;input:
;ZCD => RB0 = INT
;drukknop (aan/ uit)
;output:
;relais K1 (over bruggingsrelais)
;relais K2 (-60V => AC PA300)
;triac (BTA41600B)
;led van drukknop
ON_INTERRUPT GOTO INTERRUPT
SYMBOL led = PORTA.0
SYMBOL drukknop = PORTB.1
SYMBOL K1 = PORTA.2
SYMBOL K2 = PORTA.3
SYMBOL triac = PORTA.1
SYMBOL INTF = INTCON.1 ;RB0 external INTerrupt Flag
SYMBOL INTE = INTCON.4 ;RB0 external INTerrupt Enable
SYMBOL GIE = INTCON.7 ;Global Interrupt Enable
SYMBOL T0IF = INTCON.2 ;Timer0 Interrupt Flag
SYMBOL T0IE = INTCON.5 ;Timer0 Interrupt Enable
DIM positief AS BIT ;toggle bit om in-/uitschakelmoment te bepalen
DIM hulp_seconden AS BYTE ;hulp variabele om mbv zcd ??n seconde te maken
DIM seconden AS BYTE ;seconden voor de softstart
DIM hulptimer AS WORD ;hulptimer TMR0
DIM Key_Pushed AS BIT
DIM softstart_procedure AS BYTE
OPTION_REG =%11000000 ;pull-up deactiveren op PORTB, interne clock, prescaler voor TMR0, prescaler op 1:2
; 76543210
TRISA = %00000000
PORTA = %00000000
TRISB = %00000011
PORTB = %00000000
CLEAR
GIE = 1
T0IF = 0
T0IE = 1
INTF = 0
INTE = 1
positief = 0
softstart_procedure = 0
;Key_Pushed:
; 0 = drukknop open
; 1 = drukknop gesloten
;softstart_procedure:
; 0 = standby
; 1 = triac triggeren op top van sinus, pulsbreedte = 3ms
; 2 = K1 + K2 sluiten + triac uit
; 4 = K1 + K2 openen op top van sinus en triac uitschakelen
WHILE 1 = 1
IF drukknop = 0 THEN Key_Pushed = 0
IF drukknop = 1 AND Key_Pushed = 0 THEN
DELAYMS 20 ;antidender
IF drukknop = 1 AND Key_Pushed = 0 THEN
Key_Pushed = 1 ;drukknop is gesloten
IF softstart_procedure = 0 THEN
hulp_seconden = 0
seconden = 0
softstart_procedure = 1
ELSE
softstart_procedure = 3
ENDIF
ENDIF
ENDIF
SELECT softstart_procedure
CASE 0 ;standby
;led drukknop laten knipperen aan 1Hz
IF hulp_seconden = 0 THEN
HIGH led
ELSEIF hulp_seconden = 50 THEN
LOW led
ENDIF
CASE 1 ;triac op top sinus triggeren (5ms na zcd)
IF hulptimer >= 48 THEN ;gate triggeren met puls van 3ms
LOW triac
ELSEIF hulptimer >= 30 THEN
HIGH triac
ENDIF
;led drukknop laten knipperen aan 5Hz
IF hulp_seconden = 0 OR hulp_seconden = 20 OR hulp_seconden = 40 OR hulp_seconden = 60 OR hulp_seconden = 80 THEN
HIGH led
ELSEIF hulp_seconden = 10 OR hulp_seconden = 30 OR hulp_seconden = 50 OR hulp_seconden = 70 OR hulp_seconden = 90 THEN
LOW led
ENDIF
IF seconden = 2 THEN softstart_procedure = 2
CASE 2 ;K1 + K2 sluiten, triac uit
HIGH K1
HIGH K2
LOW triac
CASE 3 ;op top sinus K1 + K2 openen triac uitschakelen uitschakelen
IF hulptimer >= 30 THEN
LOW K1
LOW K2
LOW triac
HIGH led
softstart_procedure = 0
ENDIF
ENDSELECT
WEND
INTERRUPT: ;interruptroutine
CONTEXT SAVE
IF INTF = 1 THEN ;RB0 => ZCD
INTF = 0
INC hulp_seconden
IF hulp_seconden = 100 THEN ;1s bereikt
INC seconden
hulp_seconden = 0
ENDIF
hulptimer = 0
ELSEIF T0IF = 1 THEN ;TMR0: 6KHZ
T0IF = 0
INC hulptimer ;hulptimer = 6 => 1ms
IF hulptimer >= 250 THEN hulptimer = 0 ;om overflow te voorkomen in het geval dat de zcd defect is
ENDIF
CONTEXT RESTORE
END
|
|
|
|
Gepost op vrijdag 26 Augustus 2011 21:29:32 |
 |
Als het werkt en je kan er aan uit, dan maakt voor mij de structuur niks uit. Heb je ergens foto's van de schakeling? |
Veel te weinig tijd voor mijn projecten of heb ik er soms te veel? |
|
Gepost op zaterdag 27 Augustus 2011 22:27:51 |
 |
Voor mij is het een leercurve, misschien zijn er dingen die beter kunnen.
Ik heb de software nu eerst geschreven na het voorval van vorige keer. De hardware moet nog gemaakt worden, maar het schema is grotendeels af (had ik nodig om de software te kunnen testen).
Er wordt een nuldoorgangsdetectie (niet met jouw schema, omdat de faseverschuiving bij kleine transfo's nogal wispelturig is) gedaan met een 6N138. Er wordt een triac gestuurd op de top van de sinus om de inschakelstroom zo klein mogelijk te houden. De stroom wordt begrensd door 4 dikke (50W) weerstanden van 10 ohm. Na 2 seconden (moet ik eventueel nog proefondervindelijk verbeteren) wordt de triac en de weerstanden overbrugd door een relais. Dit om de verliezen in de gate minimaal te houden. |
|
|
|
|
|