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
hadv
Just find out what you like and let it kill you
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.
Roches
Domoticz en ESP8266, goede combo!!!
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).
hadv
Just find out what you like and let it kill you
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
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Niet alle pinnen zijn gelijk. (Pull-ups, ST of TTL...)
RA5 bijv. is alleen input, en RA4 is een OD output...
hadv
Just find out what you like and let it kill you
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%)]