PIC meerdere taken tegelijkertijd laten uitvoeren, Hoe!

Hallo Allemaal,

Ik ben met proton ide bezig een programma te schrijven voor aansturing van leds en motoren op 4 windmolens. (model 1:87)

Het volgende moet gebeuren als er op een drukknop wordt gedrukt.

De leds op de 4 molens moeten in een patroon gaan knipperen ( continu totdat de actie is voltooid )

Tegelijk met het continu knipperen van de leds worden de 4 motoren van de 4 molens met een pwm puls op snelheid gebracht stuk voor stuk ( dus eerst molen 1 begint op gang te komen tot hij op snelheid is en dan de volgende molen, enz. )

Ik heb dit zover draaiend dat alles werkt alleen de leds knipperen niet continu.

Het lijkt erop dat de tijd die de pic nodig heeft om de opdracht van de pwm uit te voeren de pauze in het ledsknipperen veroorzaakt.

Op welke manier krijg ik het voor elkaar dat de beide subroutines naast elkaar lopen i.p.v. achter elkaar aan.

met vriendelijke groeten

Adriaan

Niet, een microcontroller loopt zijn programma regel voor regel af. Je kunt het wel laten lijken dat het naast elkaar loopt, maar hij werkt altijd stap voor stap zijn programma af.

Je zou met 2 PIC's het wel ECHT naast elkaar kunnen laten lopen. Dan laat je eentje een seintje naar die andere geven dat hij moet beginnen met zijn routine.

Mvg Stefan

EDIT: post je programma eens! Misschien kunnen wij zien wat die pauze veroorzaakt en hoe je het kan wegmoffelen. En wat zonnepaneeltje hieronder zegt kan ook! (ik wist niet of je dat miscchien al gedaan hebt)

Software pwm maken m.b.v. een interrupt routine.
Dan zie je niet meer dat het in werkelijkheid niet echt tegelijk wordt gedaan.
De leds kunnen dan nog in het normale programma gestuurd worden, of evt ook interrupt based met gebruik van 1 van de timers erbij.

Je kan werken op basis van een timer interrupt.
Timer0 stel je bv. in dat die een interrupt on overflow genereert elke ms. Vervolgens kan je "taken" uitvoeren na 2ms (2interrupts) 3ms, 4ms, 5ms,... . Alleen moet je ervoor zorgen dat de code die in het interrupt service routine moet worden uitgevoerd niet meer tijd in beslag neemt dan 1ms. Mits software PWM en knipper van leds tijdsgebonden is biedt dit simplistisch multitreading systeem een goede oplossing. Een principe voorbeeld in C vindt je hieronder.

[code=C]
void YourHighPriorityISRCode()
{
if(INTCONbits.TMR0IF)
{
//timer0 opnieuw instellen voor volgende interrupt
..........

//taak 0 uitvoeren indien teller = max (5ms)
if(++task0Counter == task0CounterMax)
{
//teller terug resetten
task0Counter = 0;
//taak0 specifieke code
..........
}
//taak 1 uitvoeren indien teller = max (10ms)
if(++task1Counter == task1CounterMax)
{
//teller terug resetten
task1Counter = 0;
//taak1 specifieke code
..........
}
//taak 3 uitvoeren indien teller = max (20ms)
if(++task2Counter == task2CounterMax)
{
//teller terug resetten
task2Counter = 0;
//taak2 specifieke code
..........
}
}
}[/code]

hoi Stefanh001

Hieronder heb ik de gemaakte code geplaatst.
het probleem zal hem zitten in de gosub routines alleen weet ik nog niet hoe ik dit anders kan aanpakken.

De leds moeten immers continu hetzelfde patroon vertonen.
dus lijkt me de optie om een 2de pic te gebruiken de meest logische.
die doet dan de afhandeling van de leds.

maar ik zou zeggen schiet er eens op. (PS dit is mijn eerste programma voor een PIC )


'****************************************************************
'*  Name    : Windmolenpark.BAS                                 *
'*  Author  : Adriaan Bodewits				                    *
'*  Notice  : Copyright (c) 2011 Adriaan Bodewits				*
'*          : All Rights Reserved                               *
'*  Date    : 24-7-2011                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Device = 16F628
Config INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF
ALL_DIGITAL TRUE

;Variabelen declareren

Dim Potmeterstand As Byte                         ;   bevat de positie van de windzak
Dim servo0pos As Word                             ;   bevat de positie van servo0
Dim servo1pos As Word                             ;   bevat de positie van servo1
Dim servo2pos As Word                             ;   bevat de positie van servo2
Dim servo3pos As Word                             ;   bevat de positie van servo3
Dim servo4pos As Word                             ;   bevat de positie van servo4
Dim ledteller As Byte                             ;   maak variabele ledteller aan
Dim duty As Word                                  ;   bevat de waarde van de pwm op de uitgang
Dim a As Byte
Symbol aantalknipper        = 3                   ;   aantal knipperingen die leds maken
Symbol flitspause           = 50                  ;   pause tussen flitsen in ms
Symbol ledsuittijd          = 500                 ;   tijd dat leds tijdens knipperen uit zijn in ms
Symbol ledsaantijd          = 250                 ;   tijd dat leds tijdens knipperen aan zijn in ms
Symbol servosnelheid        = 5                   ;   snelheid van de servo ( hoger is sneller )

Symbol maxsnelheid          = 100                 ;   Maximale snelheid waarmee de molens mogen draaien
Symbol minsnelheid          = 1                   ;   Minimale snelheid waarbij de molens beginnen te draaien
Symbol cycles               = 25                  ;   aantal cycles van de PWM instructie
Symbol maxpos               = 2300                ;   Maximale uitslag van servos (180 graden)
Symbol minpos               = 700                 ;   Minimale uitslag van servos (  0 graden)
Symbol switchoff            = 0                   ;   schakelaar niet in gedrukt
Symbol switchon             = 1                   ;   schakelaar ingedrukt.

;Poortnamen

Symbol potmeter             =   PORTA.0           ;   poort waar de potmeter op aangesloten is welke de positie bepaalt voor de windzak

Symbol led0                 =   PORTA.1           ;   poort waar led1 op molen 1 is aangesloten
Symbol led1                 =   PORTA.2           ;   poort waar led1 op molen 2 is aangesloten
Symbol led2                 =   PORTA.3           ;   poort waar led1 op molen 2 is aangesloten
Symbol led3                 =   PORTA.4           ;   poort waar led1 op molen 2 is aangesloten
                                                  
Symbol molenswindrichting   =   PORTA.5           ;   poort waar druktoets 1 is aangesloten met actie molens draaien in windrichting
Symbol molensdraaien        =   PORTA.6           ;   poort waar druktoets 2 is aangesloten met actie molens starten met draaien en na 15 sec stoppen met draaien

Symbol molen1               =   PORTA.7           ;   poort waar motor van molen 1 op aangesloten is
Symbol molen2               =   PORTB.5           ;   poort waar motor van molen 2 op aangesloten is
Symbol molen3               =   PORTB.6           ;   poort waar motor van molen 3 op aangesloten is
Symbol molen4               =   PORTB.7           ;   poort waar motor van molen 4 op aangesloten is

Symbol servo0               =   PORTB.0           ;   poort waar de pulsen voor servo0 uit komen ( windzak )
Symbol servo1               =   PORTB.1           ;   poort waar de pulsen voor servo1 uit komen ( windmolen1 )
Symbol servo2               =   PORTB.2           ;   poort waar de pulsen voor servo2 uit komen ( windmolen2 )
Symbol servo3               =   PORTB.3           ;   poort waar de pulsen voor servo3 uit komen ( windmolen3 )
Symbol servo4               =   PORTB.4           ;   poort waar de pulsen voor servo4 uit komen ( windmolen4 )

;Poorten declareren

; poorten    76543210   ; 0 is uitgang , 1 is ingang
PORTA                       =   %00000000         ;   maak alle poorten laag
TRISA                       =   %01100000         ;   maak alle poorten uitgang behalve porta.5 en porta.6, hierop zijn de schakelaars aangesloten
PORTB                       =   %00000000         ;   maak alle poorten laag
TRISB                       =   %00000000         ;   maak alle poorten uitgang


Clear                                             ;   wis alle geheugen

; servos op beginstand zetten
servo0pos   =   minpos                            ;   zet servo op min positie
servo1pos   =   minpos                            ;   zet servo op min positie
servo2pos   =   minpos                            ;   zet servo op min positie
servo3pos   =   minpos                            ;   zet servo op min positie
servo4pos   =   minpos                            ;   zet servo op min positie

Servo servo0, servo0pos                           ;   schrijf servopositie naar servo0
Servo servo1, servo1pos                           ;   schrijf servopositie naar servo1
Servo servo2, servo2pos                           ;   schrijf servopositie naar servo2
Servo servo3, servo3pos                           ;   schrijf servopositie naar servo3
Servo servo4, servo4pos                           ;   schrijf servopositie naar servo4

GoTo Hoofdprogramma                               ;   spring naar hoofdprogramma

;ledskipperen                                     ; deze procedure zorgt voor een volgorde van knipperen van de leds zodat deze elke keer kan worden aangeroepen vanuit andere delen van het programma
Ledsknipperen:

    ledteller = 0
    High led0
    DelayMS flitspause
    High led1
    Low led0
    DelayMS flitspause
    High led2
    Low led1
    DelayMS flitspause
    High led3
    Low led2
    DelayMS flitspause
    Low led3
    Repeat
        DelayMS ledsuittijd
        High led0
        High led1
        High led2
        High led3
        DelayMS ledsaantijd
        Low led0
        Low led1
        Low led2
        Low led3
        ledteller = ledteller + 1 
    Until ledteller = aantalknipper
Return

; procedure molendraaien                          ; deze procedure zorgt ervoor dat de molens 1 voor 1 beginnen te draaien, ze zullen langzaam op gang komen.
molendraaien:

  For duty = minsnelheid To maxsnelheid Step 1         ; molen1 gaat steeds sneller draaien
    PWM molen1, duty, cycles
    High molen1											; molen1 gaat continu draaien
  Next
  For duty = minsnelheid To maxsnelheid Step 1          ; molen2 gaat steeds sneller draaien
    PWM molen2, duty, cycles
    High molen2											; molen2 gaat continu draaien
  Next
  For duty = minsnelheid To maxsnelheid Step 1          ; molen3 gaat steeds sneller draaien
    PWM molen3, duty, cycles
    High molen3											; molen3 gaat continu draaien
  Next
  For duty = minsnelheid To maxsnelheid Step 1          ; molen4 gaat steeds sneller draaien
    PWM molen4, duty, cycles
    High molen4											; molen4 gaat continu draaien
  Next
  Repeat 
    a = a + 1
    GoSub Ledsknipperen
  Until a = 15  
  For duty = maxsnelheid To minsnelheid Step -1   ; molen1 gaat steeds langzamer draaien 
    PWM molen1, duty, cycles
    Low molen1										; molen1 stilzetten
  Next
  For duty = maxsnelheid To minsnelheid Step -1   ; molen2 gaat steeds langzamer draaien 
    PWM molen2, duty, cycles
    Low molen2										; molen2 stilzetten
  Next
  For duty = maxsnelheid To minsnelheid Step -1   ; molen3 gaat steeds langzamer draaien 
    PWM molen3, duty, cycles
    Low molen3										; molen3 stilzetten
  Next
  For duty = maxsnelheid To minsnelheid Step -1   ; molen4 gaat steeds langzamer draaien 
    PWM molen4, duty, cycles
    Low molen4   									; molen4 stilzetten
  Next
Return

; procedure molenwindrichting                     ; deze procedure zorgt ervoor dat alle molens in windrichting worden gezet ( als windzak worden gezet )
molenwindrichting:

  For servo1pos = servo1pos To servo0pos Step servosnelheid
      Servo servo1, servo1pos
  Next
  For servo2pos = servo2pos To servo0pos Step servosnelheid
      Servo servo2, servo2pos
  Next
  For servo3pos = servo3pos To servo0pos Step servosnelheid
      Servo servo3, servo3pos
  Next
  For servo4pos = servo4pos To servo0pos Step servosnelheid
      Servo servo4, servo4pos
  Next
Return

 
;Hoofdprogramma                                   ; Dit is het hoofdprogramma.
Hoofdprogramma:


While 1 = 1
   GoSub Ledsknipperen
   servo0pos = minpos + (5 * Pot potmeter, 140)
   Servo servo0, servo0pos
   DelayMS 20
   If molensdraaien = 0 Then GoSub molendraaien
   If molenswindrichting = 1 Then  GoSub molenwindrichting
Wend 

Even een kleine nuancering op de antwoorden die zeggen dat een PIC geen zaken tegelijkertijd kan doen.
Als de led's moeten knipperen in hetzelfde ritme kan dat natuurlijk prima door deze op 1 poort aan te sluiten. Als de led's continu moeten knipperen doe je dat, zoals ook door anderen gemeld, in een timer interrupt routine. Met subroutines gaat dat nooit werken.

In het onderstaande programma worden ogenschijnlijk ook meerdere dingen uitgevoerd, is voor een RGB-lamp, maar probeer er eens inspiratie uit op te doen.

Opm: Probeer de DelayMS instructies zo kort mogelijk te houden (zie programma).

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : Roche van Ochten                                  *
'*  Notice  : Copyright (c) 2010 Roche van Ochten               *
'*          : All Rights Reserved                               *
'*  Date    : 2-6-2010                                          *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Device 16F628                ;We gebruiken een 16F628A type
Config HS_OSC, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF

XTAL = 20

'OPTIMISER_LEVEL = 3
ALL_DIGITAL TRUE
 
Declare FSR_Context_Save = OFF
 
 
Symbol PEIE   = INTCON.6                  ; Pheripheral interrupt enable
Symbol GIE    = INTCON.7                  ; Global interrupt enable
Symbol TMR0IF = INTCON.2
Symbol TMR0IE = INTCON.5
Symbol T0CS   = OPTION_REG.5
 
Symbol PWM_Output1 = PORTB.0    'Rood
Symbol PWM_Output2 = PORTB.1    'Groen
Symbol PWM_Output3 = PORTB.2    'Blauw
 
PORTB_PULLUPS = FALSE
 
;        76543210
PORTB = %00000000
TRISB = %00000000
PORTA = %00000000
TRISA = %11111111

Dim Status1 As Bit
Dim Status2 As Bit 
Dim Status3 As Bit
Dim Status4 As Bit
Dim Status5 As Bit
Dim Opgeslagen As Bit
Dim DIMMERUpDown As Bit
Dim ROODUpDown As Bit
Dim GROENUpDown As Bit
Dim BLAUWUpDown As Bit

Dim DIMMER As Byte
Dim Nummer As Byte
Dim AanUit As Byte

Dim OPSLAGCOUNTER As Word
Dim WT As Word
Dim Wacht As Word


Dim PWM_Teller As Byte                   ; PWM periode teller 0..255
Dim PWM_Waarde1 As Byte
Dim PWM_Waarde2 As Byte
Dim PWM_Waarde3 As Byte

EData 128, 128, 128, 1

 
GoTo Main



On_Hardware_Interrupt GoTo PWM_ISR
 
PWM_ISR:                                ; PWM interrupt routine
    Clear TMR0IF
    TMR0 = TMR0 + 64                    ; Herlaad timer
    If PWM_Teller == 0 Then             ; Begin van een nieuwe cycle
        If PWM_Waarde1 == 0 Then Clear PWM_Output1 : Else : Set PWM_Output1
        If PWM_Waarde2 == 0 Then Clear PWM_Output2 : Else : Set PWM_Output2
        If PWM_Waarde3 == 0 Then Clear PWM_Output3 : Else : Set PWM_Output3
    Else                                ; Kijk of de maximale "aan" tijd is bereikt
        If PWM_Teller == PWM_Waarde1 Then Clear PWM_Output1
        If PWM_Teller == PWM_Waarde2 Then Clear PWM_Output2
        If PWM_Teller == PWM_Waarde3 Then Clear PWM_Output3
    EndIf
    Inc PWM_Teller
    Context Restore 

Main:                                   ; HOOFDPROGRAMMA !!!!!
OPSLAGCOUNTER = 0
Opgeslagen = 1
PWM_Teller  = 0

AanUit = ERead 3
PWM_Waarde1 = ERead 0
PWM_Waarde2 = ERead 1
PWM_Waarde3 = ERead 2

Clear GIE
DelayMS 500
 
 
 
TMR0   = 64                             ; Voor 39 usec periode (25.6 kHz) 64 origineel
T0CS   = 0                              ; Gebruik interne klok 
TMR0IF = 0
TMR0IE = 1                              ; Timer0 interrupt enabled
If AanUit = 1 Then GIE = 1                              ; Globale interupt enabled
 
; Nu de taken voor het hoofdprogramma, bijvoorbeeld faden van led1
; van uit naar aan en tegelijkertijd led2 van aan naar uit
 

' HIERONDER HET ECHTE PROGRAMMA WAT ER UITEINDELIJK IN MOET KOMEN....

DelayMS 2000

 
While 1 = 1 

If Opgeslagen = 0 Then
    Inc OPSLAGCOUNTER
    If OPSLAGCOUNTER = $FFFE Then
        EWrite 0, [ PWM_Waarde1, PWM_Waarde2, PWM_Waarde3 ]
        OPSLAGCOUNTER = 0
        Opgeslagen = 1
    EndIf
EndIf

GoSub GETKEY
If AanUit = 0 And Nummer <> 1 Then  'Lamp is uit
    GoTo EXITSELECT
EndIf

' Lamp is aan of moet aangezet worden.
Select Nummer

    Case 1
'        Print At 2,1, "Aan/uit toets  "
        Wacht = 500
        GoSub WACHTLUS
        GoSub GETKEY
        If Nummer = 1 And AanUit = 1 Then   ' Lamp uitzetten
            EWrite 0, [PWM_Waarde1, PWM_Waarde2, PWM_Waarde3, 0]
            AanUit = 0
            GIE = 0
            PORTB = 0
            DelayMS 2000
        Else
            PWM_Teller = 0
            EWrite 3, [ 1 ]
            AanUit = 1
            GIE = 1
            Wacht = 1000
            GoSub WACHTLUS
        EndIf
                           
        
    Case 2
'        Print At 2,1, "Rood           "
        Wacht = 500
        GoSub WACHTLUS
        GoSub GETKEY
        If ROODUpDown = 0 Then
            ROODUpDown = 1
            Else ROODUpDown = 0
        EndIf
        While Nummer = 2
            If Wacht > 0 Then GoSub WACHTLUS
            If ROODUpDown = 0 Then
                Inc PWM_Waarde1             ' Dim omhoog
                Else
                Dec PWM_Waarde1             ' Dim omhoog
            EndIf
            If PWM_Waarde1 >= 250 Then ROODUpDown = 1 : Wacht = 500
            If PWM_Waarde1 <= 5 Then ROODUpDown = 0 : Wacht = 500
            GoSub GETKEY
        Wend
        Opgeslagen = 0
        OPSLAGCOUNTER = 0
                
    Case 4
'        Print At 2,1, "Groen          "
        Wacht = 500
        GoSub WACHTLUS
        GoSub GETKEY
        If GROENUpDown = 0 Then
            GROENUpDown = 1
            Else GROENUpDown = 0
        EndIf
        While Nummer = 4
            If Wacht > 0 Then GoSub WACHTLUS
            If GROENUpDown = 0 Then
                Inc PWM_Waarde2             ' Dim omhoog
                Else
                Dec PWM_Waarde2             ' Dim omhoog
            EndIf
            If PWM_Waarde2 >= 250 Then GROENUpDown = 1 : Wacht = 500
            If PWM_Waarde2 <= 5 Then GROENUpDown = 0 : Wacht = 500
            GoSub GETKEY
        Wend
        Opgeslagen = 0
        OPSLAGCOUNTER = 0
        
    Case 8
'        Print At 2,1, "Blauw          "
        Wacht = 500
        GoSub WACHTLUS
        GoSub GETKEY
        If BLAUWUpDown = 0 Then
            BLAUWUpDown = 1
            Else BLAUWUpDown = 0
        EndIf
        While Nummer = 8
            If Wacht > 0 Then GoSub WACHTLUS
            If BLAUWUpDown = 0 Then
                Inc PWM_Waarde3             ' Dim omhoog
                Else
                Dec PWM_Waarde3             ' Dim omhoog
            EndIf
            If PWM_Waarde3 >= 250 Then BLAUWUpDown = 1 : Wacht = 500
            If PWM_Waarde3 <= 5 Then BLAUWUpDown = 0 : Wacht = 500
            GoSub GETKEY
        Wend
        Opgeslagen = 0
        OPSLAGCOUNTER = 0
    
    Case 16
'        Print At 2,1, "Dimmer toets   "
        Wacht = 500
        GoSub WACHTLUS
        GoSub GETKEY
        If DIMMERUpDown = 0 Then
            DIMMERUpDown = 1
            Else DIMMERUpDown = 0
        EndIf
        While Nummer = 16
            If Wacht > 0 Then GoSub WACHTLUS
            If DIMMERUpDown = 0 Then
                Inc PWM_Waarde1             ' Dim omhoog
                Inc PWM_Waarde2
                Inc PWM_Waarde3
                Else
                Dec PWM_Waarde1             ' Dim omhoog
                Dec PWM_Waarde2
                Dec PWM_Waarde3
            EndIf
            If PWM_Waarde1 >= 250 Then DIMMERUpDown = 1 : Wacht = 500
            If PWM_Waarde2 >= 250 Then DIMMERUpDown = 1 : Wacht = 500
            If PWM_Waarde3 >= 250 Then DIMMERUpDown = 1 : Wacht = 500
            If PWM_Waarde1 <= 5 Then DIMMERUpDown = 0 : Wacht = 500
            If PWM_Waarde2 <= 5 Then DIMMERUpDown = 0 : Wacht = 500
            If PWM_Waarde3 <= 5 Then DIMMERUpDown = 0 : Wacht = 500
            GoSub GETKEY
        Wend
        Opgeslagen = 0
        OPSLAGCOUNTER = 0
            
        
    Case 17
'        Print At 2,1, "Stand opslaan  "
        Opgeslagen = 0
        OPSLAGCOUNTER = $FF00

    
    Case 14
'        Print At 2,1, "Wit Half licht "
        Wacht = 500
        GoSub WACHTLUS
        PWM_Waarde1 = 128
        PWM_Waarde2 = 128
        PWM_Waarde3 = 128
        Wacht = 1000
        GoSub WACHTLUS
        Opgeslagen = 0
        OPSLAGCOUNTER = 0
        
    
    Case Else
'        Print At 2,1, "               "
        
EndSelect

EXITSELECT:


'DelayMS 500

Wend

WACHTLUS:

For WT = 1 To Wacht
DelayMS 1
Next WT
Wacht = 0
Return

GETKEY:

Nummer = 0

    PORTB.4 = 1
    Status1 = PORTA.0
    PORTB.4 = 0
    DelayMS 5
    PORTB.4 = 1
    Status2 = PORTA.1
    PORTB.4 = 0
    DelayMS 5
    PORTB.4 = 1
    Status3 = PORTA.2
    PORTB.4 = 0
    DelayMS 5
    PORTB.4 = 1
    Status4 = PORTA.3
    PORTB.4 = 0
    DelayMS 5
    PORTB.4 = 1
    Status5 = PORTA.4
    PORTB.4 = 0
    DelayMS 5

    If Status1 = 0 Then Nummer.0 = 1
    If Status2 = 0 Then Nummer.1 = 1
    If Status3 = 0 Then Nummer.2 = 1
    If Status4 = 0 Then Nummer.3 = 1
    If Status5 = 0 Then Nummer.4 = 1
    
Return

Mvg Roche

@Hadv

Jouw methode is een goede methode! Maar al lijkt het dat er alles tegelijk gebeurt, dat is niet zo. Je interrupt-routine onderbreekt je hoofdprogramma en voert zijn ding uit, en dan gaat het hoofdprogramma weer verder met waar ie bezig was.

@carfreak

Je pauze wordt veroorzaakt door het heen en weer springen in je subroutines. Ik stel voor dat je gaat werken met een Timer, zoals veel mensen zeggen.

De werking (in het kort) van een timer is als volgt. De timer moet je initialiseren en instellen (zie datasheet PIC). Als de timer is gestart gaat ie tellen van 0 tot 255. Als ie bij 255 komt is er niks aan de hand, maar als ie dan weer +1 doet is de timer overgelopen (Overflow). Op dat moment kun je een interrupt (soort van subroutine) triggeren waarin je de status van de LEDs update. Die delays kun je dan eruit laten. (van 0 tot 255, ofwel 255 klokpulsen, is je delay).

Natuurlijk werkt niet alles tegelijk, dat is al eerder gezegd, een PIC is nu eenmaal geen parallelle processor.
Maar de taak die TS wil realiseren vereist imho ook geen parallelle processen.
Je kunt zo wel tot 8 outputs (1 poort) exact gelijk laten werken.
Gebruik timer0 op 8 bits in een interrupt routine en doe dat eventueel ook voor de PWM (zoals Roches laat zien in zijn code). Dan zul je echt met een scope moeten gaan meten om het effect te zien.
Uiteraard moet je de code in de interrupt routine zo kort mogelijk houden, en zijn delays in deze routine strikt uit den boze, maar dat was altijd al zo.
Het werken met een tweede PIC lijkt leuk, maar je krijgt geheid vertragingen. Signaal sturen van PIC1 naar PIC2, lezen van het signaal in PIC2, decoderen van het signaal en vervolgens de juiste actie uitvoeren: kost allemaal veel meer tijd dan met 1 interrupt.

Nog een advies: vermijd "HIGH" en "LOW". Volstrekt overbodig en nodeloos traag. HIGH en LOW manipuleren zowel het TRISx als het PORTx register. Als je de port.pin altijd als output gebruikt is het manipuleren van TRISx tijdverspilling. Het is alleen zinnig als je port.pin in je programma op de ene plek als input en de andere plek als output gebruikt.
Dit is de gegenereerde code voor HIGH PORTB.1


        bsf STATUS,5
        bcf TRISB,1
        bcf STATUS,5
        bsf PORTB,1

Terwijl dit volstaat als TRISB = 0


        PORTB.1 = 1

Hetgeen keurig het volgende genereert


        bsf PORTB, 1

Hallo Allemaal.

allen hartelijk dank voor de reacties en opmerkingen. ( als beginner ben je hier toch een beetje afhankelijk van )
inmiddels heb ik dan door gekregen dat de pic echt een programma afloopt en ook in die volgorde.
ik heb nu enige truuks toegepast om het probleem op te lossen.
en heb nu een werkend geheel.
Nu ben ik bezig een printlayout te tekenen en kwam toen wat vreemd uit met de pinlayout.
nu dacht ik dat ik in het programma gewoon de PORTS kon wisselen om zo het layout te kunnen vereenvoudigen.
na het omzetten van de PORTS maar even de aanpassingen gedaan op het breadboardje en dan kom je er achter dat het geheel niet meer werkt.
Mijn vraag is nu, heb ik dan puur mazzel gehad waar ik welke componenten op heb aan gesloten en dat alles toevallig goed gedaan.
Ik heb namelijk nog geen idee wat welke pinnen wel en niet kunnen.
ik ben er inmiddels achter dat RA.5 een alleen inputpin is.

ik had het op de volgende manier aangesloten:

PortA.0 potmeter met condensator ( volgens picbasic.nl )
PortA.1 uitgang naar ingang 2e pic voor ledaansturing
PortA.2 uitgang naar ingang 2e pic voor ledaansturing
PortA.3 ingang voor schakelaar ( aktieknop1 )
PortA.4 ingang voor schakelaar ( aktieknop2 )
PortA.5 ingang voor schakelaar ( aktieknop3 )
PortA.6 uitgang voor programma acktief led
PortA.7 uitgang pwm Molen1
PortB.0 uitgang servo0
PortB.1 uitgang servo1
PortB.2 uitgang servo2
PortB.3 uitgang servo3
PortB.4 uitgang servo4
PortB.5 uitgang pwm molen2
PortB.6 uitgang pwm molen3
PortB.7 uitgang pwm molen4

Om het print technisch wat eenvoudiger te krijgen heb ik het geheel gewijzigd naar het volgende :

PortA.0 potmeter met condensator ( volgens picbasic.nl )
PortA.1 ingang voor schakelaar ( aktieknop1 )
PortA.2 uitgang voor programma actief led
PortA.3 uitgang servo0
PortA.4 uitgang servo1
PortA.5 ingang voor schakelaar ( aktieknop3 )
PortA.6 uitgang pwm molen4
PortA.7 ingang voor schakelaar ( aktieknop2 )
PortB.0 uitgang servo2
PortB.1 uitgang servo3
PortB.2 uitgang servo4
PortB.3 uitgang1 naar ingang 2e pic voor ledaansturing
PortB.4 uitgang2 naar ingang 2e pic voor ledaansturing
PortB.5 uitgang pwm molen2
PortB.6 uitgang pwm molen1
PortB.7 uitgang pwm molen3

kan iemand mij uitleggen waarom het geheel nu niet meer werkt.
als ik het terugzet naar de oude situatie dan werkt het weer.

het is iets met de pinning of de configuratie maar ik heb nog geen idee wat het is.

met vriendelijke groeten

Adriaan

Misschien handig om je code te posten.
Tip: geef elke poort een naam met symbol als je dan moet veranderen moet je dat alleen boven in het programma doen en niet tig keer op verschillende plaatsen doen.

Hoi Ledfan,

ik heb de poorten al benoemd, maar heb even aangegeven wat aan welk pinnetje zit


'****************************************************************
'*  Name    : Windmolenpark.BAS                                 *
'*  Author  : Adriaan Bodewits				                    *
'*  Notice  : Copyright (c) 2011 Adriaan Bodewits				*
'*          : All Rights Reserved                               *
'*  Date    : 24-7-2011                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Device = 16F628
Config INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE

;Variabelen declareren

Dim Potmeterstand As Byte                         ;   bevat de positie van de windzak
Dim servo0pos As Word                             ;   bevat de positie van servo0
Dim servo1pos As Word                             ;   bevat de positie van servo1
Dim servo2pos As Word                             ;   bevat de positie van servo2
Dim servo3pos As Word                             ;   bevat de positie van servo3
Dim servo4pos As Word                             ;   bevat de positie van servo4
Dim servo0positie As Word                             ;   bevat de positie van servo0
Dim servo1positie As Word                             ;   bevat de positie van servo1
Dim servo2positie As Word                             ;   bevat de positie van servo2
Dim servo3positie As Word                             ;   bevat de positie van servo3
Dim servo4positie As Word                             ;   bevat de positie van servo4
Dim duty1 As Word                                 ;   bevat de waarde van de pwm op de uitgang
Dim duty2 As Word                                 ;   bevat de waarde van de pwm op de uitgang
Dim duty3 As Word                                 ;   bevat de waarde van de pwm op de uitgang
Dim duty4 As Word                                 ;   bevat de waarde van de pwm op de uitgang

servo1pos = 700
servo2pos = 700
servo3pos = 700
servo4pos = 700

Dim a As Byte
Symbol servoupsnelheid        = 2                   ;   snelheid van de servo ( hoger is sneller )
;Symbol servodownsnelheid      = 5                  ;   snelheid van de servo ( lager is sneller )


Symbol maxsnelheid          = 255                 ;   Maximale snelheid waarmee de molens mogen draaien
Symbol minsnelheid          = 1                   ;   Minimale snelheid waarbij de molens beginnen te draaien
Symbol cycles               = 10                  ;   aantal cycles van de PWM instructie
Symbol maxpos               = 2400                ;   Maximale uitslag van servos (180 graden)
Symbol minpos               = 700                 ;   Minimale uitslag van servos (  0 graden)


;Poortnamen

Symbol potmeter             =   PORTA.0           ;   poort waar de potmeter op aangesloten is welke de positie bepaalt voor de windzak

Symbol output1              =   PORTB.3           ;   poort waar uitgang naar 2e pic op input1 is aangesloten ( t.b.v. led besturing )
Symbol output2              =   PORTB.4           ;   poort waar uitgang naar 2e pic op input2 is aangesloten ( t.b.v. led besturing )

Symbol molenswindrichting   =   PORTA.1           ;   poort waar schakelaar1 is aangesloten
Symbol molensdraaien        =   PORTA.7           ;   poort waar schakelaar2 is aangesloten

Symbol molen1               =   PORTB.6           ;   poort waar motor van molen 1 op aangesloten is
Symbol molen2               =   PORTB.5           ;   poort waar motor van molen 2 op aangesloten is
Symbol molen3               =   PORTB.7           ;   poort waar motor van molen 3 op aangesloten is
Symbol molen4               =   PORTA.6           ;   poort waar motor van molen 4 op aangesloten is

Symbol servo0               =   PORTA.3           ;   poort waar de pulsen voor servo0 uit komen ( windzak )
Symbol servo1               =   PORTA.4           ;   poort waar de pulsen voor servo1 uit komen ( windmolen1 )
Symbol servo2               =   PORTB.0           ;   poort waar de pulsen voor servo2 uit komen ( windmolen2 )
Symbol servo3               =   PORTB.1           ;   poort waar de pulsen voor servo3 uit komen ( windmolen3 )
Symbol servo4               =   PORTB.2           ;   poort waar de pulsen voor servo4 uit komen ( windmolen4 )

Symbol externon             =   PORTA.5           ;   poort waar via b.v. koploper de opdracht tot starten kan worden gegeven ( via relay kortsluiten met gnd )
Symbol systeemon            =   PORTA.2           ;   poort waarop een led is aangesloten welke bij elke loopdoorgang knippert ( kijken of hij het nog doet )

;Poorten declareren

; poorten    76543210   ; 0 is uitgang , 1 is ingang
PORTA                       =   %10100010         ;   maak alle poorten laag
TRISA                       =   %00000000         ;   maak alle poorten uitgang behalve porta.3 en porta.4, hierop zijn de schakelaars aangesloten
PORTB                       =   %00000000         ;   maak alle poorten laag
TRISB                       =   %00000000         ;   maak alle poorten uitgang


Clear                                             ;   wis alle geheugen

;Hoofdprogramma                                   ; Dit is het hoofdprogramma.

output1 = 0
output2 = 0

While 1 = 1
   Toggle systeemon
   servo0pos = minpos + (7 * Pot potmeter, 148)
   Servo servo0, servo0pos
   DelayMS 20
   If molensdraaien = 0 Then GoSub molendraaien
   If molenswindrichting = 0 Then  GoSub molenwindrichting
   If externon = 0 Then GoSub externebediening
Wend 



; procedure molendraaien                          ; deze procedure zorgt ervoor dat de molens 1 voor 1 beginnen te draaien, ze zullen langzaam op gang komen.
molendraaien:

  output1 = 0
  output2 = 1
  For duty1 = minsnelheid To maxsnelheid Step 1         ; molen1 gaat steeds sneller draaien
    PWM molen1, duty1, cycles
  Next
  High molen1
  For duty2 = minsnelheid To maxsnelheid Step 1          ; molen2 gaat steeds sneller draaien
    PWM molen2, duty2, cycles
   Next
  High molen2
  For duty3 = minsnelheid To maxsnelheid Step 1          ; molen3 gaat steeds sneller draaien
    PWM molen3, duty3, cycles
  Next
  High molen3
  For duty4 = minsnelheid To maxsnelheid Step 1          ; molen4 gaat steeds sneller draaien
    PWM molen4, duty4, cycles
  Next
  High molen4
  Repeat 
    a = a + 1
    DelayMS 500
  Until a = 15  
  For duty1 = maxsnelheid To minsnelheid Step -1   ; molen1 gaat steeds langzamer draaien 
    PWM molen1, duty1, cycles
  Next
    Low molen1										; molen1 stilzetten
  For duty2 = maxsnelheid To minsnelheid Step -1   ; molen2 gaat steeds langzamer draaien 
    PWM molen2, duty2, cycles
  Next
    Low molen2										; molen2 stilzetten
  For duty3 = maxsnelheid To minsnelheid Step -1   ; molen3 gaat steeds langzamer draaien 
    PWM molen3, duty3, cycles
  Next
    Low molen3										; molen3 stilzetten
  For duty4 = maxsnelheid To minsnelheid Step -1   ; molen4 gaat steeds langzamer draaien 
    PWM molen4, duty4, cycles
  Next
    Low molen4   									; molen4 stilzetten
    output1 = 0
    output2 = 0
Return

; procedure molenwindrichting                     ; deze procedure zorgt ervoor dat alle molens in windrichting worden gezet ( als windzak worden gezet )
molenwindrichting:

  output1 = 1
  output2 = 0
  If servo0pos > servo1pos Then 
               For servo1positie = servo1pos To servo0pos Step servoupsnelheid
                   Servo servo1, servo1positie
                   DelayMS 5
               Next
               
               For servo2positie = servo2pos To servo0pos Step servoupsnelheid
                   Servo servo2, servo2positie
                   DelayMS 5
               Next
               
               For servo3positie = servo3pos To servo0pos Step servoupsnelheid
                   Servo servo3, servo3positie
                   DelayMS 5
               Next
               
               For servo4positie = servo4pos To servo0pos Step servoupsnelheid
                   Servo servo4, servo4positie
                   DelayMS 5
               Next
               servo1pos = servo1positie
               servo2pos = servo2positie
               servo3pos = servo3positie
               servo4pos = servo4positie
  Else
               For servo1positie = servo1pos To servo0pos Step -servoupsnelheid
                   Servo servo1, servo1positie
                   DelayMS 5
               Next
             
               For servo2positie = servo2pos To servo0pos Step -servoupsnelheid
                   Servo servo2, servo2positie
                   DelayMS 5
               Next
              
               For servo3positie = servo3pos To servo0pos Step -servoupsnelheid
                   Servo servo3, servo3positie
                   DelayMS 5
               Next
               
               For servo4positie = servo4pos To servo0pos Step -servoupsnelheid
                   Servo servo4, servo4positie
                   DelayMS 5
               Next
               servo1pos = servo1positie
               servo2pos = servo2positie
               servo3pos = servo3positie
               servo4pos = servo4positie
  EndIf
  output1 = 0
  output2 = 0 
Return

; externe bediening      
externebediening:

                 GoSub molenwindrichting
                 GoSub molendraaien
Return

Niet alle pinnen zijn gelijk. (Pull-ups, ST of TTL...)
RA5 bijv. is alleen input, en RA4 is een OD output...

Wat Arco al zegt: RA4 is een OpenCollector output, die werkt anders dan andere outputs.
verder...

PORTA = %10100010 ; maak alle poorten laag
TRISA = %00000000 ; maak alle poorten uitgang behalve porta.3 en porta.4, hierop zijn de schakelaars aangesloten

Je commentaar klopt niet met de instructies en de rest van het programma. Op zich trekt de assembler zich niets aan van het commentaar, maar als jij later de boel gaat aanpassen, of je code aan iemand anders geeft, is het knap lastig.
Verder is het een poort met meerdere pinnen.

[Bericht gewijzigd door hadv op (72%)]