PIC 16F628a - Led laten knipperen tijdens ander proces

Beste mede elektronica forummers,

Ik ben bezig om een TomTom in mijn auto in te bouwen. Ik heb van de sloop een oud dashbord beeldscherm gekocht, oude scherm en elektronica eruit gehaald en de TomTom erin gebouwd. Ik heb zelf een printje gebouwd met een PIC erop.

Ik heb twee inlezingen: Een knop op het dashbord en het contact. Wanneer het contact aan is en de knop wordt ingedrukt gaat de TomTom omhoog. Wanneer je weer de knop indrukt of het contact uit zet gaat de TomTom weer naar beneden.
Met behulp van een paar relais stuur ik het motortje aan en schakel ik de spanning op de TomTom.

Voor het resultaat zie:
http://youtu.be/v7TKPHE5Z9A

Ook zit er op de knop in het dashbord een ledje. Dit ledje brandt wanneer de TomTom omhoog staat en gaat uit wanneer de TomTom weer in het dashbord is gezakt.

Nou is mijn vraag of het mogelijk is om het ledje te laten knipperen tijdens het omhoog gaan, tijdens een timerpauze of naar beneden gaan.

Tijdens het omhoog of naar beneden gaan bewaak ik de stroom door een spanningsval te meten over een weerstandje. Wanneer het schermpje dan in zijn eindstand is wordt de spanningsval over de weerstand groter. Dit meet ik met een comparator en deze stuurt dit door naar de PIC. De PIC schakelt vervolgens het relaitje af.

Dat betekent dat het knipperen en het meten van de stroom tegelijkertijd moeten gebeuren.

Multitasking is niet mogelijk, ook PWM met b.v. een frequentie van 0,5Hz wil ook niet.

Misschien is het helemaal niet mogelijk maar ik ben benieuwd naar jullie ideeën en reacties.

Bijgevoegd mijn code voor de PIC. (ik schrijf in JAL)


-- -----------------------------------------------------------------------------
-- Title: Aansturen van een TomTom in een Volvo RTI scherm
-- Author: Albert Nieuwenhuis
--
-- Notes:
--  - File creation date/time: 21 Oct 2012.
--
-- -----------------------------------------------------------------------------
include 16f628a                    -- target PICmicro

-- configuration memory settings (fuses)
pragma target clock 4_000_000      -- oscillator frequency
pragma target OSC  INTOSC_NOCLKOUT -- Internal oscillator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  disabled        -- no Low Voltage Programming

enable_digital_io()                -- disable analog I/O (if any)

-- Configureren van input en outputpinnen
pin_A0_direction =  output
pin_A1_direction =  output
pin_A2_direction =  input
pin_A3_direction =  input
pin_A4_direction =  input
pin_A6_direction =  output
pin_A7_direction =  output

-- Definiëren van input en outputpinnen
alias   powerrelais     is pin_A0
alias   omhoogrelais    is pin_A1
alias   led             is pin_A6
alias   omlaagrelais    is pin_A7

var volatile bit knop       is pin_A2
var volatile bit comparator is pin_A3
var volatile bit contact    is pin_A3

-- Definiëren van variabelen
var byte timer
var bit stand
var bit toestemming

-- Beginstanden van variabelen definiëren
omhoogrelais = off
omlaagrelais = off
powerrelais = off
led = off
timer = 0
stand = 0
toestemming = 0



-- Het programma
--------------------------------------------------------------------------------

procedure omhoog (bit in out stand, bit in out toestemming) is
          led = on
          omhoogrelais = on
          repeat
                if comparator == high then
                   _usec_delay(100000)
                   timer = timer + 1
                else
                   timer = 60
               end if
          until timer == 60
          omhoogrelais = off
          powerrelais = on
          stand = 1
          timer = 0
          toestemming = 0
          _usec_delay(15000000)
end procedure

procedure omlaag (bit in out stand, bit in out toestemming) is
          led = off
          powerrelais = off
          _usec_delay(15000000)
          omlaagrelais = on
          repeat
                if comparator == high then
                   _usec_delay(100000)
                   timer = timer + 1
                else
                   timer = 60
               end if
         until timer == 60
         omlaagrelais = off
         stand = 0
         timer = 0
         toestemming = 0
         _usec_delay(5000000)
end procedure

procedure knoptimer (bit out toestemming) is
          repeat
                if knop == high & timer < 5 then
                    timer = timer + 1
                    _usec_delay(100000)
                elsif knop == high & timer == 5 then
                    timer = timer + 1
                    toestemming = 1
                else
                    toestemming = 0
                    timer = 6
                end if
          until timer == 6
          timer = 0
end procedure


forever loop
if knop == high then knoptimer (toestemming)
elsif knop == high & contact == high & stand == 0 & toestemming == 1 then omhoog (stand, toestemming)
elsif knop == high & contact == high & stand == 1 & toestemming == 1 then omlaag (stand, toestemming)
elsif contact == low & stand == 1 then omlaag (stand, toestemming)
end if
end loop
--------------------------------------------------------------------------------

Kan je niet gewoon een timer starten en met een overflow interrupt het ledje laten knipperen?

En dan met een boolean om het knipperen aan/uit te zetten.

Software matig kan je ook een timer opbouwen maar alleen bekend hiermee op de AVR/Arduino; http://www.arduino.cc/playground/Code/SimpleTimer

Geen antwoord op je vraag helaas. Maar wel leuk project. Heb ook zoiets in een oude RTI lift gebouwd. Werkt 100x beter dat de originele RTI!

Ik weet niet hoe je dat doet in jal, maar kan je dat niet on_interrupt doen. Dan draaid er een timer op de achtergrond die je aanroept als je hem nodig hebt om je led te laten knipperen.

Misschien staat hier iets.
http://www.circuitsonline.net/forum/view/62113/1/jal

in jal kan je meerdere Tasks maken

Maar Hoe ? dat weet ik niet .. ik heb het in de boek van bert van dam gelezen maar me er nog niet mee beziggehouden

ik dacht :

task1
blablabla
suspend
blablabla
suspend
blabla
end task1

task2
blabla
knipperled
suspend
end task2

foreverloop
suspend
.

en dan moest je in de compiler ergens ingeven dat er 3 taken zijn.

De suspend moet je zetten waar het proces eventueel mag worden onderbroken

Het lijkt mij geen probleem om een ledje te laten knipperen. Bijv 0.5 sec aan en 1 sec uit. Maak hiervoor een loop met een LED_aan en eentje met LED_uit. Plaats in beide Loops je stroommeting of andere zaken die af wilt vangen. Ik zie dat je nu ook al Delays gebruikt, deze tijd kun je ook gebruiken om wat anders te doen. We noemen dit een State Machine.

Ik zou ook een interrupt gebruiken. Die zijn hier ideaal voor.
Zoals AgentP al aangaf.

In je main start je een timer. Elke keer bij een overflow schiet ie in je interrupt routine waar je je Led-aan-uit afhandeld. Als ie daarmee klaar is, gaat ie weer verder met waar ie mee bezig was.
Simpeler kan bijna niet.

Je kan natuurlijk ook een knipperledje kopen.
En wanneer jij dat wil, zet je met een poortje spanning op dat ledje.
Dan hoef je maar op 2 momenten een commandootje te geven.

Beste allemaal,

Alvast bedankt voor jullie opmerkingen. Ik denk dat ik eerst even wat met een interrupt of een state ga proberen. Een hardware knipperend ledje zal alleen niet gaan omdat ik hem ook constant wil laten branden.

Het proces is namelijk als volgt:

TomTom is beneden = led uit
TomTom gaat omhoog = led knipper
TomTom is omhoog = led constant
Timer die loopt voordat TomTom naar beneden gaat = led knipper
TomTom gaat naar beneden = led knipper
TomTom is beneden = led uit

Het zal eerst even uitzoeken zijn maar zodra ik wat heb laat ik het weten.

Nogmaals bedankt voor jullie tips.

Ga vanuit je omhoog routine met en gosub naar een label bv "knipperled"
iedere keer als je in dit label komt verhoog je een teller.
Als de teller een bepaalde waarde heeft bereikt dan draai je de status van de poort om, hoog wordt laag en laag wordt hoog.
en reset je de teller. Heb je de waarde nog niet bereikt dan kom je direkt terug in het programma gedeelte waar je vandaan komt.
De waarde van de teller bepaald de snelheid van je knipperen.

Hoi allemaal,

Ik ben eerst begonnen met het maken van een simpel programma om de interrupts maar eens onder de knie te krijgen. Even op een breadbordje een schakeling gebouwd en een relaitje (via transistor) aan een uitgang van de PIC. (dit omdat ik even geen los ledje in huis heb) :-)

Hieronder volgt de code van het programma:


-- -----------------------------------------------------------------------------
-- Title: Testen van een interrupt
-- Author: Albert Nieuwenhuis
--
-- Notes:
--  - File creation date/time: 7 nov 2012.
--
-- -----------------------------------------------------------------------------
include 16f628a                    -- target PICmicro

-- configuration memory settings (fuses)
pragma target clock 4_000_000      -- oscillator frequency
pragma target OSC  INTOSC_NOCLKOUT -- Internal oscillator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  disabled        -- no Low Voltage Programming

enable_digital_io()                -- disable analog I/O (if any)

-- Configureren van input en outputpinnen
pin_A0_direction =  output
pin_B0_direction =  input

-- Definiëren van input en outputpinnen
alias   relais     is pin_A0
var volatile bit inlees       is pin_B0

-- Beginstanden van variabelen definiëren
relais = off

-- Initialize the interrupt control register
-- GIE:  0 = global interrupts enabled
-- PEIE: 0 = Peripheral interrupts disabled
-- T0IE: 0 = TMR0 Overflow interrupt disabled
-- INTE: 0 = RB0/INT external interrupt disabled
-- RBIE: 0 = RB Port Change interrupt enabled
-- T0IF: 0 = clear TMR0 Overflow interupt flag
-- INTF: 0 = clear RB0/INT external interrupt flag
-- RBIF: 0 = clear RB Port Change interrupt flag
intcon = 0b_1110_0000





-- Het programma
--------------------------------------------------------------------------------


procedure aanuit is
          relais = high
          _usec_delay(1000000)
          relais = low
          _usec_delay(1000000)
end procedure

procedure interrupt is
          pragma interrupt
          for 2 loop
              relais = high
              _usec_delay(500000)
              relais = low
              _usec_delay(500000)
          end loop
         intcon_intf = 0
end procedure


forever loop
        aanuit()
end loop

Nou gaat mijn relais aan en uit om de seconde. Het idee is dat als ik de interrupt pin hoog maak dat het relais om de halve seconde gaat knipperen. Echter gebeurt dat al na een seconde of 5 zonder dat ik de interrupt poot hoog maak en hij blijft de interrupt houden, hij komt zeg maar niet meer uit de interrupt procedure.

Heeft iemand misschien een idee waar het mis gaat?
Ik hoor het graag.

[edit]

Ik heb in de code de "for" loop verkeerd geprogrammeerd. Ik heb het verbeterd naar "for 2 using lus loop" en een nieuwe variabele lus aangemaakt. Maar helaas, geen oplossing. Nog steeds na een seconde of 5 komt de interrupt in werking zonder reden.
[/edit]

Misschien een stomme vraag, maar je laat de pin niet toevallig zweven als je niets wilt? Zo ja, ff een pull down toevoegen.

Timo

Sorry,

Was ik vergeten te vermelden. Ik heb de interrupt poort met een 10k aan de min vast zitten.

Zo doet je interrupt dus niets, als je een interrupt gebruikt heb je geen delay nodig. Als je delay gebruikt wacht je hele programma tot dat de delay afgelopen is, en dat wil je niet.

Ik heb wel een voorbeeld voor je, maar dat is in picbasic.

Beste Lambiek,

Een voorbeeld is altijd welkom. Ook al is ie in een andere taal. Proberen is het altijd waard.
Dus als je 'm voor mij hebt, graag... :D

Hier heb je het voorbeeld.


Device 16F877                          ; processor type

Xtal 10                                ; Crystal 10 Mhz

On_Interrupt TIMER_0                   ; Interrupt timer_0

Config HS_OSC,_                        ; Cristal groter dan 4MHz
       WDT_OFF,_                       ; Watchdog Timer Enable uit
       PWRTE_ON,_                      ; Power-up Timer Enable aan
       BODEN_OFF,_                     ; Brown-out Reset Enable uit
       LVP_OFF,_                       ; Low Voltage Programming uit
       CPD_OFF,_                       ; Memory Code Protection uit
       WRTE_ON,_                       ; Program Memory Write Enable aan
       DEBUG_OFF,_                     ; In-Circuit Debugger Mode uit
       CP_OFF                          ; Code Protection uit
       
All_Digital true                       ; Alle poorten digitaal

Declare LCD_RSPin PORTD.2              ; reset display poort D.2
Declare LCD_ENPin PORTD.3              ; enable display poort D.3
Declare LCD_DTPin PORTD.4              ; data display poort D.4 t/m D.7
 
Symbol T0IF = INTCON.2                 ; TIMER0 interrupt vlag
Symbol T0IE = INTCON.5                 ; TIMER0 interrupt enabel
Symbol GIE  = INTCON.7                 ; Enable interrupt
        
Symbol PS0  = OPTION_REG.0             ; Instelling prescaler
Symbol PS1  = OPTION_REG.1             ; Instelling prescaler
Symbol PS2  = OPTION_REG.2             ; Instelling prescaler
Symbol PSA  = OPTION_REG.3             ; Instelling oscillator
Symbol T0SE = OPTION_REG.4             ; Instelling puls H/L - L/H
Symbol T0CS = OPTION_REG.5             ; Instelling clock intern of extern

Symbol Q1 = PORTA.0                    ; Poort_A.0 als uitgang
Symbol Q2 = PORTA.1                    ; Poort_A.1 als uitgang
Symbol Q3 = PORTA.2                    ; Poort_A.2 als uitgang
Symbol Q4 = PORTA.3                    ; Poort_A.3 als uitgang
Symbol Q5 = PORTC.0                    ; Poort_C.0 als uitgang

Dim puls As Bit                        ; Timer_0 puls
                                                          
Dim TMR_1  As Word                     ; Timer1
Dim TMR_2  As Word                     ; Timer2
Dim TMR_3  As Word                     ; Timer3
Dim TMR_4  As Word                     ; Timer4
Dim TMR_5  As Word                     ; Timer5
     
Dim VAL_TIMER As  Word                 ; Variabele waarde timer
Dim LIMITE_TIMER As Word               ; Variabele limite

Clear
    
DelayMS 1000                           ; wacht 1 seconden

Cls                                    ; wis display

;------------------------------------------------------------------------------
; Poort instellingen
;------------------------------------------------------------------------------
                                                                           
            ;543210                    ; Hulpregel poort_A
    PORTA = %000000                    ; Maak poort_A laag
    TRISA = %000000                    ; Poort_A I/O
    
            ;543210                    ; Hulpregel poort_B
    PORTB = %000000                    ; Maak poort_b laag
    TRISB = %000000                    ; Poort_B I/O
    
            ;76543210                  ; Hulpregel poort_C
    PORTC = %00000000                  ; Maak poort_C laag
    TRISC = %00000000                  ; Poort_C I/O
    
            ;76543210                  ; Hulpregel poort_D
    PORTD = %00000000                  ; Maak poort_D laag
    TRISD = %00000000                  ; Poort_D I/O
    
            ;210                       ; Hulpregel poort_E
    PORTE = %000                       ; Maak poort_c laag
    TRISE = %000                       ; Poort_E I/O
    
;------------------------------------------------------------------------------
; Reset - timers, uitgangen, enz, enz 
;------------------------------------------------------------------------------

    TMR_1 = 0                          ; Reset timer_1
    TMR_2 = 0                          ; Reset timer_2
    TMR_3 = 0                          ; Reset timer_3
    TMR_4 = 0                          ; Reset timer_4
    TMR_5 = 0                          ; Reset timer_5
    Q1 = 0                             ; Reset uitgang_1
    Q2 = 0                             ; Reset uitgang_2
    Q3 = 0                             ; Reset uitgang_3
    Q4 = 0                             ; Reset uitgang_4
    Q5 = 0                             ; Reset uitgang_5
                                                                     
GoTo instelling                        ; Ga naar instelling
              
; -----------------------------------------------------------------------------
; INTERRUPT ROUTINE                    ; Plaats eerst de interrupt routine
; -----------------------------------------------------------------------------

TIMER_0:                            

    Inc VAL_TIMER                      ; Increment waarde timer
    T0IF = 0                           ; Wis interrupt flag
    Context Restore                    ; Herstel registers en stap uit interrupt
    
instelling:                            ; Instelling register
    GIE  = 0                           ; Zet interrupt uit
    PS0  = 0                           ; Prescaler bit_0
    PS1  = 0                           ; Prescaler bit_1
    PS2  = 1                           ; Prescaler bit_2
    PSA  = 0                           ; Prescaler toegewezen aan TIMER0
    T0SE = 0                           ; Trigger van laag naar hoog
    T0CS = 0                           ; Trigger door interne clock
    TMR0 = 0                           ; Reset TIMER0
    T0IE = 1                           ; TIMER0 Interrupt enabel aan
    GIE  = 1                           ; Zet Interrupt aan
                               
    LIMITE_TIMER = 3                   ; INT(2500000 /(256*32)) = 305/100 = 3
    VAL_TIMER = 0                      ; Variabele waarde timer is 0
    
;------------------------------------------------------------------------------
; Hier het programma.
;------------------------------------------------------------------------------
                                                             
MAIN:                                  ; Hoofd programma    
    While 1 = 1                        ; Als 1 is 1                                    
    If VAL_TIMER > LIMITE_TIMER Then   ; Als V_T groter dan 3 dan
     VAL_TIMER = 0                     ; Reset V_T - V_T is 0                     
     puls = 1                          ; Puls is 1
    EndIf                              ; Einde als
      
; testje - 0.100 sec - H/L
    
    If puls = 1 Then
     If Q1 = 0 Then
      Q1 = 1
       Else Q1 = 0
     EndIf
    EndIf
                                       
; testje - 0.10 sec - H/L
    
    If puls = 1 Then
     TMR_1 = TMR_1 + 1
    EndIf
    
    If TMR_1 > 5 Then
      If Q2 = 0 Then
       Q2 = 1
       Else Q2 = 0
      EndIf
     TMR_1 = 0
    EndIf
                              
; testje - 1 sec - H/L
    
    If puls = 1 Then
     TMR_2 = TMR_2 + 1
    EndIf
    
    If TMR_2 > 50 Then
      If Q3 = 0 Then
       Q3 = 1
       Else Q3 = 0
      EndIf
     TMR_2 = 0
    EndIf
    
; testje - 10 sec - H/L
    
    If puls = 1 Then
     TMR_3 = TMR_3 + 1
    EndIf
    
    If TMR_3 > 500 Then
     Q4 = 1
    EndIf
    
    If TMR_3 > 1000 Then
     Q4 = 0
       TMR_3 = 0
    EndIf
    
; testje - 20 sec uit 1 sec aan    
    
    If puls = 1 Then
     TMR_4 = TMR_4 + 1
    EndIf
    
    If TMR_4 > 2000 Then
     Q5 = 1
    EndIf
    
    If TMR_4 > 2050 Then
     Q5 = 0
       TMR_4 = 0
    EndIf
    
; testje - print opdracht
    
    Print At 1,1,"TMR_1 ",Dec TMR_1,"  "
    Print At 2,1,"TMR_2 ",Dec TMR_2,"  "
    Print At 3,1,"TMR_3 ",Dec TMR_3,"  " 
    Print At 4,1,"TMR_4 ",Dec TMR_4,"  " 
    
    If Q3 = 1 Then
     Print At 2,12,"AAN"
    EndIf
    If Q3 = 0 Then
     Print At 2,12,"UIT"
    EndIf
    
    If Q4 = 1 Then
     Print At 3,12,"AAN" 
    EndIf
    If Q4 = 0 Then
     Print At 3,12,"UIT"
    EndIf
    
    If Q5 = 1 Then
     Print At 4,12,"AAN" 
    EndIf
    If Q5 = 0 Then
     Print At 4,12,"UIT"
    EndIf
      
    puls = 0                           ; Puls is 0
            
    Wend                               ; Terug naar begin
    
End                                    ; Einde programma

Kijk maar of je er iets mee kan.

Hoi Lambiek,

Dank je wel voor je code.

Heb zelf ook even lopen spelen met een interrupt. Het 5 seconden probleem lijkt in 'm voeding te zitten. Als ik de voeding inschakel door middel van de schakelaar op de voeding stopt het relais na een aantal seconden met knipperen. Als ik dan vervolgens even het voedingsdraadje naar m'n breadbord los haal en weer aansluit doet alles het weer en blijft het werken. :-)

Als ik nu de interrupt pin hoog maak voert de PIC ook netjes de interrupt procedure uit. Dus dat werkt ook. :D

Alleen mijn volgende vraag is als volgt. Als ik de interrupt pin hoog maak moet ik hem vervolgens eerst weer laag maken en dan weer hoog maken voordat hij de interrupt weer opnieuw wil uitvoeren.

Hoort dit? Of is dit ook een instelling dat ik gewoon de pin hoog kan houden? Of is een interrupt een eenmalig signaal wat eerst weer laag gemaakt moet worden om opnieuw te werken?

Mijn code is als volgt:


-- -----------------------------------------------------------------------------
-- Title: Testen van een interrupt
-- Author: Albert Nieuwenhuis
--
-- Notes:
--  - File creation date/time: 7 nov 2012.
--
-- -----------------------------------------------------------------------------
include 16f628a                    -- target PICmicro

-- configuration memory settings (fuses)
pragma target clock 4_000_000      -- oscillator frequency
pragma target OSC  INTOSC_NOCLKOUT -- Internal oscillator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  disabled        -- no Low Voltage Programming

enable_digital_io()                -- disable analog I/O (if any)

-- Configureren van input en outputpinnen
pin_A0_direction =  output
pin_B0_direction =  input

-- Definiëren van input en outputpinnen
alias   relais     is pin_A0
var volatile bit inlees       is pin_B0

-- Beginstanden van variabelen definiëren
relais = off

-- Initialize the interrupt control register
-- GIE:  1 = global interrupts enabled
-- PEIE: 0 = Peripheral interrupts disabled
-- T0IE: 1 = TMR0 Overflow interrupt disabled
-- INTE: 1 = RB0/INT external interrupt disabled
-- RBIE: 0 = RB Port Change interrupt enabled
-- T0IF: 0 = clear TMR0 Overflow interupt flag
-- INTF: 0 = clear RB0/INT external interrupt flag
-- RBIF: 0 = clear RB Port Change interrupt flag
intcon = 0b_1011_0000





-- Het programma
--------------------------------------------------------------------------------
procedure isr is
          pragma interrupt
          relais = 1
          intcon_intf = 0
end procedure

forever loop
          relais = 1
          _usec_delay(1000000)
          relais = 0
          _usec_delay(1000000)
end loop

Ik hoor graag van jullie en alvast bedankt voor het meedenken.

Nog weer een update...

Ik heb met het bovenstaand programmaatje mijn interrupt half werkend. Dat wil zeggen dat ik nog steeds het probleem heb dat ie na ongeveer 5 seconden op de interrupt blijft hangen. Ik dacht eerst dat het aan mijn voeding lag maar ook als ik alleen even de PIC spanningsloos maak gebeurt het ook.

Als ik de PIC even spanningsloos maak (1 sec.) blijft ie daarna gewoon werken.

Kan het zijn dat naast mijn pootje een soort van timer interrupt nog stiekem meeloopt en na een seconde of 5 ook een interrupt geeft?

Ik hoor het graag.

albertje

De code kan ik niet helemaal ontcijferen echter zover ik nu kan beoordelen:

Je springt naar een interrupt routine maar controleert niet welke interrupt er is ( bv RB0 ), dit dus eerst testen welke interrupt is op getreden. En dan nog belangrijker: in de IR routine wordt het relais gezet, maar in je normale programma heb je 50% kans dat het relais weer direct uitgezet wordt. Dus wordt het voor jouw niet duidelijk als het relais door de IR routine gebruikt wordt of door je loop.

Je gebruikt je interrupt verkeerd, kijk eens goed naar mijn voorbeeld daar komt geen delay in voor. En dat moet ook niet als je een interrupt gebruikt, een interrupt draaid op de achtergrond en heeft geen invloed op de rest van je programma. (mits je het goed opsteld)

Jij zit nog steeds met die delay, en dat klopt niet. Als je een delay in je programma hebt staan, dan wacht je hele programma daar tot dat je delay afgelopen is.

Het is jammer maar ik weet helaas niet hoe je dat in jall moet doen, maar het kan nooit veel anders zijn dan in picbasic.

Als je in het programma wat je het eerst gepost hebt.
De led elke keer inverteert in de repeat lus van omhoog en omlaag. dan knippert hij elke seconde. eventueel de delay en tellers aanpassen om hem sneller te laten knipperen. Of zie ik dat verkeerd

Dank je wel allemaal voor jullie antwoorden.

@Winjohan,
JE hebt inderdaad gelijk, ik vraag niet uit welke interrupt gedaan moet worden. Ik zou er iets bij kunnen zetten van: "if INTF == 1 then ...... end if. Ga ik zo even proberen. Misschien dat dat ook wel mijn rare probleem van die willekeurige interrupt na 5 seconden tegenhoudt.

@Lambiek,
Ik heb ook geen delay in de interrupt procedure staan. Die delays staan alleen in mijn normale programma. Dat zorgt ervoor dat het relais om de seconde aan en uit knippert.
Wanneer dan de PIC merkt dat pinnetje RB0 hoog wordt dan moet het relais gewoon aan blijven. En dat probeer ik met een interrupt voor elkaar te krijgen.

@Jodokussen,
Tijdens het knipperen moet de PIC ook in de gaten houden of een ander inputje hoog wordt. En een PIC kan geen multitasken dus moet één van de twee met een interrupt opgelost worden. En nu probeer ik eerst een simpele interrupt onder de knie te krijgen.

En een PIC kan geen multitasken dus moet één van de twee met een interrupt opgelost worden.

Een interrupt is een vorm van multitasking... ;)
En als je wilt kun je ook altijd een RTOS draaien op een pic. (Liefst op een 18F of hoger, een 16F heeft niet genoeg geheugen daarvoor)

:D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D :D

Ik heb 'm te pakken. :-)
Ik heb van het werk een paar ledjes geleend en ik heb iedere mogelijke interrupt een ledje gegeven. Op die manier kon ik achterhalen wie de boosdoener was die na ongeveer 5 seconden een interrupt genereerde.

Groen ledje voor timer 0 en rood voor het externe pootje RB0.
En waarempel, na seconde of 5 ging het groene ledje aan. Het probleem zat dus in timer 0.
Even kort in de datasheet kijken en daar staat dat met een bitje in het optieregister de timer 0 kijkt naar een vallende flank op pootje RA4.
Die hangt bij mij los dus even met een 10k aan min gelegd...

En het probleem is weg. :D

Maar waarom die timer 0 uberhaupt reageerde was de volgende fout van mij:


-- Initialize the interrupt control register
-- GIE:  1 = global interrupts enabled
-- PEIE: 0 = Peripheral interrupts disabled
-- T0IE: 1 = TMR0 Overflow interrupt disabled
-- INTE: 1 = RB0/INT external interrupt disabled
-- RBIE: 0 = RB Port Change interrupt enabled
-- T0IF: 0 = clear TMR0 Overflow interupt flag
-- INTF: 0 = clear RB0/INT external interrupt flag
-- RBIF: 0 = clear RB Port Change interrupt flag
intcon = 0b_1011_0000

Bovenstaand verhaal had ik uit een van de voorbeelden geplukt van de linkjes die gegeven waren in eerdere posts. alleen heb het bitje T0IE verkeerd geïnterpreteerd. Ik dacht bij bitje = 1 dat ie disabled was maar dat is bij bitje = 0. Na goed lezen van de datasheet staat het er ook gewoon... (deep shame).

Maargoed, de interrupt test is geslaagd. Nu maar eens verder aan het programma waar ik mee begon.

Iedereen bedankt voor het lezen, meedenken en antwoorden.
Zodra ik weer nieuws heb meld ik het.

leuk project, ziet er goed uit!
interrupt is leerzaam, maar ik denk dat het ook makkelijk zonde kan..

waarom geen functie als:

byte lampSwitch

function wachtEnKnippper byte delay
loop 100
_u_sec.....(delay / 100) j
if lampSwitch == 100
; switch uitgang
uitgang = !uitgang
lampSwitch = 0
end if
lampAan++
end loop
end function

ik typ dit bericht op mijn mobiel, dus de code klopt vaart niet, maar het gay om het idee.

@Jodokussen,
Tijdens het knipperen moet de PIC ook in de gaten houden of een ander inputje hoog wordt. En een PIC kan geen multitasken dus moet één van de twee met een interrupt opgelost worden. En nu probeer ik eerst een simpele interrupt onder de knie te krijgen.

Je wilt toch tijdens het omhoog en omlaag gaan het ledje laten knipperen dan kan je dat toch in die repeat lus doen waar je naar de comparator kijkt ?
dan wordt elke seconde de led aansturing geinverteerd
als je sneller wilt knipperen maak je de delay wat korter en die 60 een beetje hoger

procedure omhoog (bit in out stand, bit in out toestemming) is
led = on
omhoogrelais = on
repeat
if comparator == high then
_usec_delay(100000)
timer = timer + 1

LED = NOT LED (of ziets)

else
timer = 60
end if
until timer == 60
omhoogrelais = off
powerrelais = on
stand = 1
timer = 0
toestemming = 0
_usec_delay(15000000)
end procedure