archive-nl.com » NL » P » PICBASIC.NL

Total: 182

Choose link from "Titles, links and description words view":

Or switch to "Titles and links view".
  • Alfabetische index van www.picbasic.nl
    met bus en PIC s ICSP In Circuit Serial Programming ICSP PIC programmer In circuit programmeren tips Infrarood afstandsbediende 230V lichtdimmer Instellen BumbleBee Instellen PIC programmer met Proton PIC Basic Instellen Proton PIC Basic Instellen XWisp Instellen XWisp2 Ionosfeer DCF77 Kiesschijf genereert DTMF tonen DIL versie Kiesschijf genereert DTMF tonen SMD versie Klapraam automatiseren Kwikschakelaar Laatste toevoegingen op deze website Lampicon schemerlamp LCD HD44780 LCD HD44780 A00 ASCII overzicht Lichtdimmer 230V met aanraakbediening Lichtdimmer 230V met draadloze IR bediening Luxaflex automatiseren MFV Töne aus Impulsen generieren Modulerende kamerthermostaat Motor overbelast detector Motoren RB35 Nieuw op deze website Nieuws over Microchip PIC controllers Nummermelder Ombouwen CD speler naar DVD recorder Ombouwen CD speler naar HDD DVD recorder Overbelastingsdetectie RB35 motor Parallax Basic Stamp Pelgrim CBU vervangingsprint met origineel display Pelgrim CBU vervangingsprint met LC display Philips DVDR900 Philips HDD900 Philips ProntoNeo PIC Basic Afbreken lange programmaregels Anticontactdender Array s Berekeningen door de compiler Bit manipulatie Bouwjaar PIC aflezen Cijfers na de komma met een BYTE of WORD variabele Commando beschrijvingen Compiler berekeningen Componentenlijst voor de PIC programmeercursus Configuratiebits instellen Contactdender onderdrukken Cursus Cursus componenten pakket bestellen DAC simpele Digitaal Analoog Converter Daglicht meten met een LDR Debugger voor Proton PIC Basic programma s Decimale punt weergeven op een display Display HD44780 aansluiten Display HD44780 aansturen Display HD44780 op andere poorten van PIC aansluiten EEPROM geheugen Eigen karakters voor display maken False en True Formatteren van een tabel in de EEPROM Fuses instellen Geluiden met PWM HD44780 A00 ASCII overzicht HD44780 display aansluiten HD44780 display aansturen HD44780 op andere poorten van de PIC aansluiten Hoe doet de functie POT zijn meting In stukken breken lange programmaregels Instructie beschrijvingen Instellen editor options Instellen gebruikers keywords syntax highlight sleutelwoorden Instellen kleuren van syntax Interne oscillatorsnelheid instellen op 48kHz of 4MHz Interrupt On Change IOC Kristal Lange programmaregels in stukken breken Lichtmeting met een LDR LCD aansturen LDR uitlezen zonder ADC Meerdere toetsen op één ingangspoort Modulus berekenen Motoren aansturen ook met PWM Nesten Neutraalstand voor servomotoren NTC uitlezen zonder ADC Operator beschrijvingen Overzicht commando s en instructie s Overzicht cursuscomponenten Overzicht operatoren Potmeter neutraalstand voor servomotor Potmeter uitlezen zonder ADC Programma s opsplitsen met INCLUDE Programmeer cursus PWM regeling Register CONFIG van 16F628A beschrijving Register INTCON van 16F628A beschrijving Register IOC van 12F675 beschrijving Register OSCCAL interne oscillator kalibreren Register PCON van 16F628A beschrijving Resonator Restwaarde van een deling berekenen Schaal bepalen voor POT instructie Servomotoren aansturen Temperatuur meten met een NTC Tijdweergave op display True en False Underscore Up to date brengen van PIC Basic Vragen stellen over PIC Basic doe je op het forum Waarde van Schaal bepalen voor POT instructie Wachtwoord in SERIN SEROUT Willekeurige getallen PIC file stuffer PICflash2 koppelen aan Proton IDE PICkit2 herprogrammeren PICkit2 koppelen aan Proton IDE PICkit2 Wisp adapterkabel PIC nieuws PIC programmeer cursus zie PIC Basic PIC programmer zie Galva Wisp PIC programmeren zie PIC Basic Poster automatisch verplaatsen Printplaten etsen uitleg met meer dan 150 foto s Printplaten zelf maken Aanmaken etsmiddel fijnetskristal Aanmaken

    Original URL path: http://www.picbasic.nl/zoeken.htm (2016-02-17)
    Open archived version from archive

  • PIC programmeren met PIC Basic (10)
    dus maximaal 65535 geven De tijd dat de LED aan is kan nu maximaal 65535 250 262mSec zijn De tijd dat de LED uit is kan hier maximaal 65535 50 1310mSec zijn Verderop staat een voorbeeld dat mooier knippert en waarbij ook de minimale tijd is in te stellen Om de acht LED s op PORTB allemaal willekeurig te laten knipperen geef je het bijna willekeurige RANDOM getal aan het register PORTB DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal 76543210 TRISB 00000000 Alle PORTB poorten zijn uitgangen Hoofdprogramma WHILE 1 1 Oneindige lus PORTB RANDOM Maak de acht PORTB uitgangen willekeurig hoog of laag DELAYMS 500 Knipperen om de halve seconde WEND Terug naar WHILE Als je de acht LED s van PORTB in dezelfde volgorde als de poorten hebt opgesteld dus LED volgorde B 0 B 1 B 2 B 7 dan zie je dat RANDOM gewoon een kwestie is van de bits doorschuiven en dat er alleen bij de LED van PORTB 0 willekeurig een 0 of een 1 wordt toegevoegd Meer hierover bij het volgende voorbeeld Met behulp van een HD44780 display kunnen we deze bitverschuiving ook laten zien DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal DELAYMS 500 LCD stabilisering Hoofdprogramma WHILE 1 1 Oneindige lus CLS Display steeds wissen PRINT BIN16 RANDOM Plaats de willekeurige BINaire waarde op het display DELAYMS 1000 Elke seconde een ander getal WEND Terug naar WHILE Het programma loopt zoals gebruikelijk weer in een oneindige lus zodat steeds een nieuw getal op het display kan komen Door PRINT wordt de bin aire random waarde getoond in 16 cijfers vanwege keyword sleutelwoord BIN16 Degene die goed oplet ziet dat het willekeurige toch niet zo willekeurig is dan eerst gedacht Het opwekken gebeurt doordat PIC Basic alle 16 bitjes een plaats naar links schuift bitwise shift left en er rechts willekeurig een 0 of 1 aan toevoegt Daarom heet de functie ook pseudo bijna niet echt random Je kunt er niet de getallen voor de landelijke staatsloterij mee bepalen een slim iemand zou getallen kunnen voorspellen Maar er kan wel wat aan gedaan worden zoals verderop te zien zal zijn SEED De syntaxis SEED Waarde Met de instructie SEED kun je de functie RANDOM een startwaarde geven Waarde mag een constante variabele of een berekening zijn met een waarde van 1 65535 Als we Waarde door een andere willekeurige waarde laten bepalen krijgen we een meer willekeurig getal met RANDOM Die willekeurige waarde kunnen we krijgen van bijvoorbeeld een NTC of LDR lichtgevoelige weerstand omdat deze componenten meestal verschillende waarden geven na iedere meting Maar picbasic nl heeft een andere manier gevonden om met behulp van SEED een willekeurige startwaarde voor RANDOM te verkrijgen Het onderstaand programma laat zien dat de opgegeven waarde aan de instructie SEED de startwaarde van RANDOM is DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Display wissen SEED 65535 65535 1111111111111111 alle 16 bits 1 WHILE 1 1 Oneindige lus PRINT AT 1 1 BIN16 RANDOM Plaats de willekeurige BINaire waarde op het display DELAYMS 1000 Elke seconde een ander getal WEND Terug naar WHILE Nu zie je dat als je de PIC opstart dat de RANDOM functie begint met 1111111111111111 en daarna naar links schuift terwijl er rechts steeds willekeurig een 0 of een 1 wordt bijgevoegd Steeds als je de PIC weer opstart zie je dat dezelfde volgorde van nullen en enen weer langskomen verderop gaan we daar wat aan doen Hoe kunnen we de randomizer toevalsgenerator nu schudden met behulp van SEED Wel door het volgende te doen DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Variabelen declareren WORD DIM x AS WORD In WORD variabele x komen de willekeurige getallen BYTE DIM Teller AS BYTE Teller voor FOR NEXT lus CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Display wissen WHILE 1 1 Oneindige lus FOR Teller 1 TO 11 Toevalsgenerator 11x schudden SEED x 2221 Verhoog x met 2221 wat een nieuwe startwaarde oplevert x RANDOM Geef willekeurige waarde aan variabele x NEXT PRINT AT 1 1 BIN16 x Plaats de BINaire waarde van x op regel 1 van het display PRINT AT 2 1 DEC x Plaats de DECimale waarde van x op regel 2 van het display DELAYMS 1000 Elke seconde een ander getal WEND Terug naar WHILE Dit programma trekt willekeurige getallen uit 1 65535 Het is al behoorlijk willekeurig er is geen volgorde meer te bekennen in de binaire en dus ook decimale weergave Eerst trekken we een aantal maal een willekeurig getal 11 met behulp van de FOR NEXT lus in dit voorbeeld Bij elk getrokken willekeurig getal in variabele x wordt een extra waarde opgeteld priemgetal 2221 in dit voorbeeld en weer teruggegeven door middel van SEED Hierdoor zal de RANDOM generator een nieuw willekeurig getal trekken dat gebaseerd is op het vorige willekeurige getal 2221 Na 11 is er niets meer over van de oude vorige waarde die x bij het binnengaan van de FOR NEXT lus had de randomizer is als het ware goed door elkaar geschud Het getal 2221 is maar een voorbeeld het mooist is een groot priem getal maar elk getal werkt De getallen zijn nu onderling wel behoorlijk willekeurig maar steeds wanneer je de PIC opnieuw opstart door reset of spanningsonderbreking komen weer dezelfde willekeurige getallen in dezelfde volgorde opdraven Om bij een toepassing waarbij geen mens aan te pas komt bij iedere opstart van de PIC tóch steeds een andere startwaarde te krijgen kunnen we het volgende doen DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Variabele declareren WORD DIM x AS WORD In WORD variabele x komen de willekeurige getallen x x EREAD 0 x voor CLEAR x is dus nog niet gewist willekeurig EWRITE 0 x Schrijf het willekeurige getal in x naar EEPROM adres 0 en 1 CLEAR Nu pas alle RAM geheugen wissen x EREAD 0 Lees EEPROM adres 0 en 1 x is een WORD variabele weer uit DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Wis displayscherm SEED x In x staat een willekeurig getal gekregen via EEPROM uit x PRINT DEC RANDOM Plaats willekeurige getal op het display END Let op deze END is nu belangrijk Elke PIC start op met alle duizenden RAM geheugencellen op een willekeurige waarde 0 of 1 Dit is ook de reden dat je bovenin een programma altijd CLEAR moet plaatsen waardoor alle bits van het hele RAM geheugen op 0 worden gezet zodat je altijd met een leeg schoon geheugen begint Maar nu kunnen we van die willekeur mooi gebruik maken Overigens is ook hier de willekeur weer beperkt omdat vaak niet altijd dezelfde bits 0 of 1 worden Door ergens bovenin het programma maar in ieder geval nog vóór CLEAR de willekeurige waarde die WORD variabele x heeft bij het opstarten van de PIC op te slaan in de EEPROM op adres 0 én 1 in dit geval want x is een WORD variabele samen met de waarde die nog van de vorige keer op EEPROM adres 0 staat krijg je een behoorlijk willekeurig getal Pas daarna ga je het geheugen wissen met CLEAR CLEAR wist alleen het gehele RAM geheugen niet het EEPROM geheugen het willekeurige getal blijft dus behouden in EEPROM Meteen na het wissen van het RAM kun je de EEPROM weer uitlezen waarin nu dus nog steeds het willekeurige getal staat en geven deze waarde terug aan variabele x In x hebben we nu dus een redelijk willekeurig getal om met SEED een startwaarde voor RANDOM in te stellen Hierdoor start de toevalsgenerator verderop in het programma met een willekeurige waarde waardoor de getallen die daarna allemaal getrokken worden ook weer anders zullen zijn Het volgende voorbeeld laat heel snel willekeurige getallen zien maar als er een getal onder de 1000 getrokken wordt dan laat het display dit 1 seconde zien Het programma zal elke keer als je de PIC hebt opgestart weer met geheel nieuwe getallen en volgorde komen DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Variabele declareren WORD DIM x AS WORD In WORD variabele x komen de willekeurige getallen BYTE DIM Teller AS BYTE Teller voor FOR NEXT lus x x EREAD 0 x voor CLEAR x is dus nog niet gewist willekeurig EWRITE 0 x Schrijf het willekeurige getal in x naar EEPROM adres 0 en 1 CLEAR Nu pas alle RAM geheugen wissen x EREAD 0 Lees EEPROM adres 0 en 1 x is een WORD variabele weer uit DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Display wissen WHILE 1 1 Oneindige lus FOR Teller 1 TO 11 Toevalsgenerator 11x schudden SEED x 2221 Verhoog x met 2221 wat een nieuwe startwaarde oplevert x RANDOM Geef willekeurige waarde aan variabele x NEXT PRINT AT 1 1 BIN16 x Plaats de BINaire waarde van x op regel 1 van het display PRINT AT 2 1 DEC x Plaats de DECimale waarde van x op regel 2 van het display IF x 1000 THEN DELAYMS 1000 Wacht een seconde als het getal kleiner dan 1000 is WEND Terug naar WHILE Het programma plaatst op displayregel 1 de binaire 16 bits waarde van x en doet dat in de decimale notatie op displayregel 2 Er zijn nog meer willekeurige factoren te vinden die je kunt gebruiken om een willekeurige opstartwaarde te krijgen De mens natuurlijk maar ook door bijvoorbeeld met een LDR de lichtsterkte van het moment dat de PIC opstart te meten met POT of RCIN zie cursus deel 5 en de waarde die dit oplevert aan SEED aan te bieden of te verwerken bijvoorbeeld optellen of vermenigvuldigen met x Of gebruik een NTC weerstand En als je een PIC hebt met een ADC aan boord kun je een analoge zwevende spanning van een loshangend pootje van de PIC meten en de waarde die dat oplevert als willekeurige opstartwaarde voor SEED gebruiken PIC type 16F628 A heeft helaas geen ADC aan boord Maar al deze methoden hebben het nadeel dat ze een ingangspin van de PIC gebruiken terwijl bovenstaande SEED voorbeelden intern een willekeurig getal oplevert dat meestal willekeurig genoeg is voor een project Voorbeelden Hoe nu een getal trekken uit 0 20 De functie RANDOM geeft immers een getal uit 1 65535 Er zal dus een berekening aan vooraf moeten gaan Het volgende voorbeeld laat zien hoe dat gaat DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Variabele declareren WORD DIM x AS WORD Met WORD variabele x gaan we de randomizer schudden BYTE DIM RND AS BYTE In RND komt steeds een willekeurig getal te staan DIM Teller AS BYTE Teller voor de FOR NEXT lus x x EREAD 0 x voor CLEAR x is dus nog niet gewist willekeurig EWRITE 0 x Schrijf het willekeurige getal in x naar EEPROM adres 0 en 1 CLEAR Wis nu pas alle RAM geheugen x EREAD 0 Lees EEPROM adres 0 en 1 x is een WORD variabele weer uit DELAYMS 500 LCD stabilisering GOTO Hoofdprogramma Spring over de subroutine Subroutine Load RND FOR Teller 1 TO 11 Toevalsgenerator 11x schudden SEED x 2221 Verhoog x met 2221 wat een nieuwe startwaarde oplevert x RANDOM Geef willekeurige waarde aan variabele x NEXT RND x 65535 21 Waarde 0 t m 20 dat zijn 21 verschillende waarden IF RND 20 THEN Load RND Af en toe kan RND 21 worden dan nog een keer schudden RETURN Hoofdprogramma CLS Display wissen WHILE 1 1 Oneindige lus GOSUB Load RND Ga een nieuwe willekeurige waarde aan RND geven PRINT AT 1 1 RND Plaats de decimale waarde van RND op het display DELAYMS 1000 Laat om de seconde een getal zien WEND Terug naar WHILE De variabele die het willekeurige getal bevat hebben we hier de naam RND r a nd om gegeven Het schudden van de randomizer toevalsgenerator en het trekken van een willekeurig getal in RND is hier in een subroutine geplaatst waardoor het overzichtelijker blijft Om RND een nieuwe willekeurige waarde te geven hoef je nu alleen maar de regel GOSUB Load RND te plaatsen Je moet er wel op letten dat je geen andere dingen met variabele x gaat doen Het is namelijk van belang dat x alleen wordt gebruikt voor het schudden van de randomizer Steeds als je dan weer gaat schudden wordt het gebaseerd op de waarde die nog van de vorige keer in x zit Nog even dit het is belangrijk dat je subroutines boven het hoofdprogramma plaatst en niet onderaan Dit in tegenstelling tot de vroegere homecomputers zie cursus deel 6 De regel RND x 65535 21 levert meestal een getal op van 0 20 in RND Meestal want heel af en toe kan de uitkomst 21 zijn terwijl we een getal uit 0 20 willen hebben Als dit gebeurt wordt de trekking opnieuw gedaan Formule De PIC kijkt alleen naar de cijfers vóór de komma Dus een getal als 99 97 is voor de PIC gewoon 99 waard Getallen met cijfers achter de komma is mogelijk door de variabele te declareren als FLOAT dit neemt echter veel geheugenruimte in van de PIC gebruik FLOAT dus niet als het even kan De functie RANDOM levert dus een willekeurig getal van 1 65535 in bovenstaande programma wordt die waarde aan de variabele met de naam x gegeven Daarna volgt de berekening RND x 65535 21 waarna de uitkomst in variabele RND staat Om te kijken wat er kan gebeuren nemen we eerst de laagst mogelijk waarde die in x kan zitten dat is dus 1 De berekening is dan 1 65535 21 Berekeningen die tussen haakjes staan worden het eerst uitgerekend In deze berekening is dat dus 65535 21 met als uitkomst 3120 7143 Maar de PIC laat de cijfers na de komma weg dus is de uitkomst 3120 Dan volgt nog de berekening 1 3120 met als uitkomst 0 0003 De PIC laat de cijfers na de komma weer weg dus de uitkomst is 0 Ook als RANDOM aan x een waarde levert van 2 t m 3119 zal de uitkomst 0 zijn Levert RANDOM een waarde van 3120 t m 6239 dan is de uitkomst een 1 Bij 6240 t m 9359 is de uitkomst een 2 enzovoort We nemen nu de hoogst mogelijke waarde die in x kan zitten dat is dus 65535 De berekening is dan 65535 65535 21 Eerst de berekening 65535 21 waarvan de uitkomst dus 3120 is Daarna 65535 3120 21 0048 De PIC ziet dit als 21 terwijl we een getal vroegen uit 0 20 Die 21 kun je zien als een restwaarde een deling komt immers vaak nooit op hele getallen uit Maar hoe dan ook je moet er wél voor zorgen dat RND nooit de restwaarde kan bevatten als het van de subroutine terugkomt Nu is dat eenvoudig te doen door na de berekening te schrijven IF RND 20 THEN Load RND waardoor opnieuw een getal wordt getrokken Ook als x hier van RANDOM een getal krijgt van 65520 t m 65535 zal de uitkomst 21 zijn en wordt de trekking opnieuw gedaan Zoals je ziet is een deel van de berekening steeds hetzelfde ongeacht het getrokken getal Hierboven is dat 65535 21 Waarom zou je de PIC dat laten berekenen Dat kost allemaal geheugen en tijd terwijl de uitkomst altijd 3120 is een constante waarde Daarom kun je dit gedeelte beter door de compiler oftewel je PC laptop laten berekenen juist omdat het een constante waarde is In de volgende voorbeelden gebeurt dat dan ook de uitkomst plaatsen we dan met SYMBOL in de constante met de naam DeelFactor SYMBOL DeelFactor 65535 HoogsteGetal 1 LaagsteGetal In de hierna volgende voorbeelden kun je de hoogste en laagste getallen invullen bij de constanten HoogsteGetal en LaagsteGetal Het programma trekt dan willekeurige waarden die lopen van het opgegeven hoogste en laagste getal Waarom achter HoogsteGetal 1 in de formule In de formule wordt LaagsteGetal van HoogsteGetal afgehaald maar dan kom je er altijd één tekort Een paar voorbeelden HoogsteGetal LaagsteGetal 5 0 6 1 200 100 200 101 5 5 100 99 Maar moet 6 zijn want 6 verschillende mogelijkheden Maar moet 6 zijn want 6 verschillende mogelijkheden Maar moet 101 zijn want 101 verschillende mogelijkheden Maar moet 100 zijn want 100 verschillende mogelijkheden Als een getal moet worden getrokken uit 0 5 dan kunnen dat 6 verschillende waarden zijn geen 5 Hoe nu een getal gooien voor bijvoorbeeld een dobbelsteen 1 6 De 0 mag nu namelijk ook niet getrokken worden Dat is vrij simpel trek een getal uit 0 en 5 en tel er bij de uitkomst 1 bij met bijvoorbeeld INC RND Als er nu een 0 wordt getrokken dan wordt deze dus 1 Als er nu een 1 wordt getrokken dan wordt deze dus 2 Als er nu een 5 wordt getrokken dan wordt deze dus 6 In onderstaand voorbeeld is overigens nog geen veiligheid ingebouwd die de trekking opnieuw doet als het getal hoger dan 6 blijkt te zijn Heel af en toe kan er hier dus nog een 7 tussendoor glippen Het voorbeeld laat het zien DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Algemene constanten SYMBOL HoogsteGetal 6 Bepaalt de maximale waarde die getrokken kan worden SYMBOL LaagsteGetal 1 Bepaalt de minimale waarde die getrokken kan worden Compiler berekeningen SYMBOL DeelFactor 65535 HoogsteGetal 1 LaagsteGetal DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Display wissen WHILE 1 1 Oneindige lus PRINT AT 1 1 DEC RANDOM DeelFactor LaagsteGetal DELAYMS 1000 Laat om de seconde een ander getal zien WEND Terug naar WHILE En getallen uit 100 t m 200 Hetzelfde verhaal Trek eerst een getal uit 0 t m 100 En dan net als het bovenste voorbeeld alleen dan geen 1 maar 100 erbij optellen Door de constanten LaagsteGetal en HoogsteGetal blijft het overzichtelijk en is het makkelijk te wijzigen in andere waarden Nu is bovenstaand voorbeeldje een uitgeklede versie om je het gebruik van LaagsteGetal en HoogsteGetal te laten zien echt mooi willekeurig zijn de getallen niet omdat de schudroutine hier niet in zit Hè hè vanaf nu beginnen we ergens te komen in onderstaand voorbeeld zit alles wat we tot nu toe besproken hebben Het programma trekt een getal dat ligt tussen LaagsteGetal en HoogsteGetal Wordt het getal heel af en toe hoger dan HoogsteGetal dan wordt de trekking opnieuw gedaan De getallen zijn behoorlijk willekeurig omdat hier de boel weer flink geschud wordt En ook de voorziening die er voor zorgt dat er weer met nieuwe getallen wordt begonnen als de PIC uitgeschakeld is geweest met behulp van de interne EEPROM is aanwezig Bovendien kun je bij de constanten LaagsteGetal en HoogsteGetal zelf waarden naar wens invullen DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Algemene constanten SYMBOL HoogsteGetal 6 Bepaalt de maximale waarde die getrokken kan worden SYMBOL LaagsteGetal 1 Bepaalt de minimale waarde die getrokken kan worden Compiler berekeningen SYMBOL DeelFactor 65535 HoogsteGetal 1 LaagsteGetal Bereken waarde voor deling Variabele declareren WORD DIM x AS WORD Met WORD variabele x gaan we de randomizer schudden BYTE DIM RND AS BYTE In RND komt steeds een willekeurig getal DIM Teller AS BYTE Teller voor de FOR NEXT lus x x EREAD 0 x voor CLEAR x is dus nog niet gewist willekeurig EWRITE 0 x Schrijf het willekeurige getal in x naar EEPROM adres 0 en 1 CLEAR Wis nu pas alle RAM geheugen x EREAD 0 Lees EEPROM adres 0 en 1 x is een WORD variabele weer uit DELAYMS 500 LCD stabilisering GOTO Hoofdprogramma Spring over de subroutine s Subroutine Load RND FOR Teller 1 TO 11 Toevalsgenerator 11x schudden SEED x 2221 Verhoog x met 2221 wat een nieuwe startwaarde oplevert x RANDOM Geef willekeurige waarde aan variabele x NEXT RND x Deelfactor RND RND LaagsteGetal Verhogen met laagste getal IF RND HoogsteGetal THEN Load RND Af en toe kan RND hoger worden dan nog een keer RETURN Hoofdprogramma CLS Display wissen WHILE 1 1 Oneindige lus GOSUB Load RND Laad RND met een nieuwe willekeurige waarde PRINT AT 1 1 RND Plaats de decimale waarde van RND op het display DELAYMS 1000 Laat om de seconde een getal zien WEND Terug naar WHILE Soms lijkt het dat een getal langer dan anders blijft staan De oorzaak is simpel er is dan hetzelfde getal getrokken als het vorige Nu even controleren of het wel eerlijk verloopt Het nu volgende programma trekt weer heel snel getallen uit 0 t m 5 Hierbij wordt op het display afgebeeld hoe vaak ieder getal wordt getrokken Als één van de getallen 250 maal is getrokken stopt het programma Op die manier is te bekijken of de PIC wel eerlijk en willekeurig de getallen trekt Wanneer steeds of heel vaak hetzelfde getal als eerste de 250 bereikt of als er een getal ver achter blijft bij de rest dan zit er iets niet goed in het programma DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Algemene constanten SYMBOL HoogsteGetal 5 Bepaalt de maximale waarde die getrokken kan worden SYMBOL LaagsteGetal 0 Bepaalt de minimale waarde die getrokken kan worden Compiler berekeningen SYMBOL DeelFactor 65535 HoogsteGetal 1 LaagsteGetal Bereken delingswaarde Variabele declareren BYTE ARRAY DIM Getal 6 AS BYTE Array bestaande uit 6 elementen WORD DIM x AS WORD Met WORD variabele x gaan we de randomizer schudden BYTE DIM RND AS BYTE In RND komt steeds een willekeurig getal DIM Teller AS BYTE Teller voor de FOR NEXT lus x x EREAD 0 x voor CLEAR x is dus nog niet gewist willekeurig EWRITE 0 x Schrijf het willekeurige getal in x naar EEPROM adres 0 en 1 CLEAR Wis alle RAM geheugen x EREAD 0 Lees EEPROM adres 0 en 1 x is een WORD variabele weer uit DELAYMS 500 LCD stabilisering GOTO Hoofdprogramma Spring over de subroutine s Subroutine Load RND FOR Teller 1 TO 11 Toevalsgenerator 11x schudden SEED x 2221 Verhoog x met 2221 wat een nieuwe startwaarde oplevert x RANDOM Geef willekeurige waarde aan variabele x NEXT RND x Deelfactor LaagsteGetal Bereken waarde tussen Laagste en HoogsteGetal IF RND HoogsteGetal THEN Load RND Af en toe kan RND hoger worden dan nog een keer RETURN Hoofdprogramma CLS Display wissen REPEAT Herhaal GOSUB Load RND Laad RND met een nieuwe willekeurige waarde INC Getal RND Verhoog de teller van het getrokken getal 0 5 met 1 PRINT AT 1 1 Getal 0 Geef op display weer hoe vaak er een 0 is getrokken PRINT AT 1 6 Getal 1 Geef op display weer hoe vaak er een 1 is getrokken PRINT AT 1 11 Getal 2 Geef op display weer hoe vaak er een 2 is getrokken PRINT AT 2 1 Getal 3 Geef op display weer hoe vaak er een 3 is getrokken PRINT AT 2 6 Getal 4 Geef op display weer hoe vaak er een 4 is getrokken PRINT AT 2 11 Getal 5 Geef op display weer hoe vaak er een 5 is getrokken UNTIL Getal RND 250 Totdat een zojuist getrokken getal 250 maal is getrokken END Belangrijk dat deze END er nu staat Dit doen we met behulp van een array met 6 elementen met de naam Getal zie cursus deel 6 In de subroutine Load RND wordt een willekeurig getal uit 0 t m 5 getrokken en aan de variabele RND gegeven Twee regels van het vorige voorbeeld RND x DeelFactor en RND RND LaagsteGetal zijn hier samengevoegd tot één regel RND x DeelFactor LaagsteGetal In de regel INC Getal RND wordt de waarde van de arrayvariabele die net getrokken is met 1 verhoogt Dus stel dat het zojuist getrokken getal dat steeds in de variabele RND staat een 4 is dan wordt arrayvariabele Getal 4 met 1 verhoogt In Getal 4 komt dus te staan hoe vaak er een 4 wordt getrokken Zo staat straks in Getal 0 hoe vaak er een 0 is getrokken in Getal 1 hoe vaak er een 1 is getrokken enz Bij PRINT AT wordt de actuele waarde van elke arrayvariabele op het display gezet Op displayregel 1 staat hoe vaak achtereenvolgens de getallen 0 1 en 2 zijn getrokken en op displayregel 2 hoe vaak 3 4 en 5 zijn getrokken 243 218 250 241 233 241 De REPEAT UNTIL lus voert de lus net zolang uit totdat één van de getallen de 250 heeft bereikt Steeds als er een getal is getrokken wordt bij UNTIL Getal RND bekeken of het zojuist getrokken getal de 250 heeft bereikt In bovenstaand displayvoorbeeld is Getal 0 243 maal getrokken Getal 1 is 218 maal getrokken enz Omdat Getal 2 als eerste de 250 heeft gehaald wordt de lus beëindigt en wordt verder gegaan met de eerstvolgende instructie Die eerstvolgende instructie is END waardoor het PIC programma beëindigt wordt de PIC gaat in low power mode Denk eraan dat het nu belangrijk is dat END ook wordt geplaatst omdat het programma uit de REPEAT UNTIL lus springt zodra één van de getallen 250 maal is getrokken of gegooid of hoe je het ook noemt Je kunt het testprogramma steeds opnieuw starten door de spanning even van de PIC te halen je zult dan ook zien dat steeds een ander willekeurig getal als eerste de 250 bereikt Rad van fortuin 2 Kon je in de vorige versie van Rad van fortuin nog inschatten bij welke LED je de toets in moest drukken om even later een andere LED als winnaar uit de bus te laten komen dat zal bij het volgende voorbeeld niet zo makkelijk meer gaan omdat door RANDOM de remsnelheid steeds een beetje anders is De ene keer zal het rad wat sneller afremmen dan een andere keer waardoor niet meer in te schatten is bij welke LED je Toets in moet drukken DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL FALSE 0 Niet waar SYMBOL HOOG 1 Hoog signaal SYMBOL LAAG 0 Laag signaal SYMBOL TRUE 1 Waar Algemene constanten SYMBOL RadSnelheid 50 mSec Bepaalt de snelheid van het rad lager getal sneller Poortnamen SYMBOL Toets PORTA 1 Met deze pulstoets start en stop je het rad van fortuin Variabelen declareren WORD DIM Tijd AS WORD Wachttijd die steeds langer wordt als Toets is ingedrukt BYTE DIM Poort AS BYTE Bevat 1 2 4 8 16 32 64 of 128 afhankelijk welke poort hoog is DIM RND AS BYTE Bevat de uitkomst van de berekening met RANDOM DIM Teller AS BYTE Teller voor de FOR NEXT lus BIT DIM Stoppen AS BIT Als dit bit 1 is dan gaat het rad afremmen om te stoppen 76543210 PORTB 00000000 Eerst alle PORTB uitgang registers uit laag maken TRISB 00000000 Alle PORTB poorten zijn uitgangen CLEAR Wis alle RAM geheugen Hoofdprogramma SEED 2221 Geef random generator een startwaarde WHILE 1 1 Oneindige hoofd lus Stoppen FALSE Reset BIT variabele Stoppen FALSE voor nieuwe ronde Tijd RadSnelheid Het rad weer op de opgegeven hoge snelheid instellen RND RANDOM 3276 Trek een getal uit 0 en 19 WHILE 1 1 Oneindige lus totdat Tijd boven ingestelde waarde komt FOR Teller 1 TO 8 We hebben acht LED s tellen dus van 1 t m 8 Poort Poort 2 1 2 4 8 16 32 64 128 steeds 1 LED verder IF Poort 0 THEN Poort 1 Als laatste poort is geweest dan weer met eerste verder PORTB Poort Laat de LED branden die in Poort is aangegeven IF Toets LAAG THEN Stoppen TRUE Er moet gestopt worden als toets is ingedrukt IF Stoppen TRUE THEN Tijd Tijd Tijd 10 RND Bij stop tijd steeds langer IF Tijd 1000 THEN WinnaarBekend Als tijd overschrijdt dan naar WinnaarBekend DELAYMS Tijd Wachttijd is variabel wordt langer als op toets is gedrukt NEXT WEND Terug naar binnenste WHILE 1 1 WinnaarBekend WHILE Toets HOOG Laat winnaar LED knipperen totdat op Toets wordt gedrukt PORTB Poort Laat de LED branden die winnaar is DELAYMS 150 Tijd dat LED aan is PORTB 0 LED s uit DELAYMS 70 Tijd dat LED uit is WEND Terug naar binnenste WHILE de WHILE Toets HOOG WHILE Toets LAAG WEND Wacht eerst tot de toets weer is losgelaten WEND Terug naar buitenste WHILE 1 1 Door een willekeurig getal te trekken met RANDOM en dit bij de afremtijd op te tellen zal het rad de ene keer iets sneller afremmen dan een andere keer waardoor je niet meer in kunt schatten bij welke LED je de toets in moet drukken om een andere LED als winnaar uit de bus te laten komen Het verschil is maar miniem tussen het afremmen maar net voldoende om het vooraf voorspellen onmogelijk te maken Het programma is verder precies hetzelfde als het eerste Rad van fortuin voorbeeld Schemerlamp met willekeurig knipperende 12V lampjes Het schemerlampproject van deze site maakt ook gebruik van de functie RANDOM om af en toe eens maximaal één lampje uit te zetten voor de gein Meestal branden alle lampjes gewoon Het programma werkt simpel Door RANDOM wordt een getal gekozen uit 1 25 Als het getrokken getal een 1 is dan zal lampje 1 uitgezet worden is het getal een 2 dan wordt lampje 2 uitgezet enzovoort tot aan getal 6 voor lampje 6 Elk ander getal dat getrokken wordt 7 25 zal geen lampje uitzetten waardoor alle lampjes blijven branden Daarna wacht het programma een aantal minuten en zet dan alle lampjes weer aan als er een lampje uit was zal die dus weer aan gaan Hierna wacht het programma weer een aantal minuten waardoor het zeker is dat alle lampjes even aan zijn Door dit alles krijg je het effect dat er maar af en toe een lampje een paar minuten uit is De voorziening met de EEPROM is hier ook toegepast zodat steeds als je de lamp inschakelt het weer een verrassing is welk lampje er als eerste uit zal gaan Zowel het Basicprogramma als het HEX bestand is te downloaden bij het artikel van de Lampi c on schemerlamp Meer info zelfbouw staande schemerlamp De Lampi c on Onthouden welke getallen zijn geweest De ingebouwde MP3 speler van het aloude Napster op de PC heeft een random functie die je kunt aanvinken maar het programma Napster onthoud niet welke muzieknummers al zijn geweest Zo kan het gebeuren dat uit een lijst met bijvoorbeeld 20 verschillende muzieknummers eerst Madonna wordt afgespeeld daarna Queen en daarop weer hetzelfde nummer van Madonna Een CD speler met een shuffle toets speelt van een CD de tracks in willekeurige volgorde in random order Als de CD speler goed is ontworpen dan onthoud het welke tracks er zijn geweest om te voorkomen dat na een aantal nummers hetzelfde nummer opnieuw wordt afgespeeld Om lotto of bingo getallen te trekken betekent het dat een eenmaal getrokken getal daarna niet nog een keer getrokken mag worden De PIC moet de getallen die zijn getrokken dus onthouden Steeds als RANDOM dan een getal trekt moet eerst worden bekeken of dit getal al eerder is getrokken en als dat het geval is dan zal nog een keer een getal met RANDOM moeten worden getrokken net zolang totdat een getal wordt getrokken dat nog niet geweest is Hiervoor moeten we gebruikmaken van een paar PIC Basic instructies die dit mogelijk maken Lotto Bingo Het onderstaand voorbeeld trekt elk getal van 1 t m 8 maar één keer DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL HOOG 1 Hoog signaal SYMBOL LAAG 0 Laag signaal Algemene constanten SYMBOL HoogsteGetal 7 BYTE Bepaalt de maximale waarde die getrokken kan worden SYMBOL LaagsteGetal 0 BYTE Bepaalt de minimale waarde die getrokken kan worden Compiler berekeningen SYMBOL DeelFactor 65535 HoogsteGetal 1 LaagsteGetal Bereken de deelfactor Poortnamen SYMBOL Toets PORTA 1 Deze pulstoets laat een willekeurig getal op het display zien Variabelen declareren WORD DIM x AS WORD Met WORD variabele x wordt de randomizer geschud BYTE DIM ReedsGeweest AS BYTE Bevat de 8 bits die bijhouden welke getallen al zijn geweest DIM RND AS BYTE Bevat een willekeurig getal 0 7 DIM Teller AS BYTE Teller voor de FOR NEXT lus BIT DIM ID1 AS BIT bIt Dummy 1 Hulpbitje x x EREAD 0 x voor CLEAR x is dus nog niet gewist willekeurig EWRITE 0 x Schrijf het willekeurige getal in x naar EEPROM adres 0 en 1 CLEAR Nu pas het RAM geheugen wissen x EREAD 0 Lees EEPROM adres 0 en 1 x is een WORD variabele weer uit DELAYMS 500 LCD stabilisering GOTO Hoofdprogramma Spring over de subroutine s Subroutine Load RND FOR Teller 1 TO 11 Toevalsgenerator 11x schudden SEED x 2221 Verhoog x met 2221 wat een nieuwe startwaarde oplevert x RANDOM Geef willekeurige waarde aan variabele x NEXT RND x Deelfactor LaagsteGetal Bereken waarde tussen Laagste en HoogsteGetal IF RND HoogsteGetal THEN Load RND Af en toe kan RND hoger worden dan nog een keer RETURN Hoofdprogramma CLS Display wissen PRINT Druk op de toets Plaats eerste bericht op het display WHILE 1 1 Oneindige lus WHILE Toets HOOG WEND Wacht op een toetsindruk DELAYMS 10 Contactontdendering bij indrukken van de toets CLS Wis display tevens tijd tegen contactdender toets 10mSec REPEAT Herhaal onderstaande lus GOSUB Load RND Geef een willekeurig getal 0 7 aan RND ID1 GETBIT ReedsGeweest RND Geef een 0 of een 1 aan dummy variabele ID1 UNTIL ID1 0 Is ID1 niet 0 dan opnieuw getal trekken herhaal lus SETBIT ReedsGeweest RND Maak bit van getrokken getal 1 PRINT AT 1 1 DEC RND 1 Plaats decimale waarde van RND 1 0 7 wordt dan 1 8 IF ReedsGeweest 11111111 THEN Zijn alle getallen geweest alle bits aan dan PRINT AT 2 1 Allen getrokken Plaats tekst op display regel 2 DELAYMS 4000 Wacht 4 seconden en dan PRINT AT 1 1 Druk toets voor Plaats tekst op display regel 1 PRINT AT 2 1 nog een ronde Plaats tekst op display regel 2 CLEAR ReedsGeweest Zet alle bits weer op 0 00000000 ENDIF WHILE Toets LAAG WEND Wacht totdat de toets wordt losgelaten DELAYMS 20 Contactontdendering bij loslaten van de toets WEND Terug naar WHILE Onthouden van getallen die al geweest zijn doen we door bitjes van een extra variabele op 1 te zetten Omdat we maar van acht getallen hoeven te onthouden welke al eens zijn getrokken kunnen deze waarden onthouden worden in een BYTE 8 bits variabele die we hier ReedsGeweest al geweest noemen Het idee is zo BYTE variabele ReedsGeweest is 0 oftewel binair 00000000 alle acht bitjes op 0 We laten RANDOM een getal trekken die na terugrekenen een getal oplevert van 0 t m 7 laten we hier zeggen dat het eerste getrokken getal een 5 is Dan gaan we eerst kijken of bit 5 van ReedsGeweest een 0 is zo ja dan zetten we bit 5 van ReedsGeweest op 1 en plaatsen we

    Original URL path: http://www.picbasic.nl/beginners10.htm (2016-02-17)
    Open archived version from archive

  • Foto's UV belichtingsbakken van andere hobbyisten
    zijn vaak op rommelmarkten en in kringloopwinkels te vinden Lees meer hierover op het forum van CircuitsOnline Foto ZX6RR Foto s Stynus Foto s Thyrof 8 8 Foto s Fantomaz 8 8 Foto s Rikkepic Foto Willem Afwijkend is de belichtingsbak met ultra violet LED s Deze is behandeld in Elektor Elektuur van september 2006 UV LED belichtingsbak Meer hierover op CircuitsOnline 8 8 Foto Frits Kieftenbelt Meer info over

    Original URL path: http://www.picbasic.nl/etsen_belichtingsbakken.htm (2016-02-17)
    Open archived version from archive

  • PIC programmeren met PIC Basic (9)
    weer met 17 verder gaan Een WORD constante een getal groter dan 255 en kleiner dan 65536 past natuurlijk niet in één EEPROM adres en wordt daarom verdeeld over twee adressen 2 bytes En een DWORD en FLOAT over vier adressen 4 bytes Dit gebeurt met LSB first Least Significant Byte eerst EDATA 1000 zal verdeeld worden over twee adressen In de EEPROM komt dit als 232 3 Hoezo 232 en 3 Wel de 3 op EEPROM adres 1 is de MSB waarde van 1000 3 256 768 De LSB is de restwaarde van het getal 1000 en staat op EEPROM adres 0 1000 768 232 Stel je schrijft ergens bovenin onderin middenin maakt niet uit waar in je programma EDATA 7 FF 256 11000011 ABC Om te laten zien hoe dit in het EEPROM geheugen komt pakken we de hokjes er weer even bij 0 00000111 1 11111111 2 00000000 3 00000001 4 11000011 5 01000001 6 01000010 7 01000011 EDATA begint dus altijd vanaf adres 0 De eerste waarde is 7 binair 00000111 en wordt dus naar adres 0 geschreven Op adres 1 komt het hexadecimale getal FF oftewel binair 11111111 decimaal 255 Hexadecimale waarden zijn in PIC Basic herkenbaar doordat ze beginnen met het dollarteken Dan volgt een waarde die groter is dan één byte namelijk 256 Deze is dus groter dan 255 en past niet op één adres Daarom wordt een WORD waarde over twee adressen verdeelt LSB first De waarde 256 wordt binair geschreven als 00000001 00000000 LSB first betekent dat de meest rechtse byte de LSB van een getal eerst naar het geheugen wordt geschreven en daarna het MSB de linkse byte MSB is in het voorbeeld 00000001 Hierdoor komt op adres 2 het LSB Least Significant Byte en op adres 3 het MSB Most Significant Byte Op adres 4 komt 11000011 oftewel 195 En op de adressen 5 6 en 7 komen achtereenvolgens de ASCII codes van A B en C 65 66 en 67 Als je het keyword EDATA op meerdere plaatsen in je programma plaatst telt de compiler gewoon verder met de adressen Dus het vorige voorbeeld EDATA 7 FF 256 11000011 ABC kan ook als volgt worden geschreven EDATA 7 FF EDATA 256 11000011 EDATA ABC De eerste EDATA die de compiler in het programma tegenkomt begint dus op adres 0 maar de volgende EDATA begint in dit geval niet opnieuw op adres 0 maar telt verder waar de vorige EDATA is opgehouden In bovenstaand voorbeeld plaatst de eerste EDATA de waarde 7 op adres 0 en de waarde 255 hexadecimaal FF op adres 1 De tweede EDATA schrijft de opgegeven waarden niet opnieuw naar adres 0 maar gaat nu verder op adres 2 ook als EDATA op een andere plek verderop in het programma staat geschreven En de derde EDATA gaat weer verder vanaf het eerstvolgende adres waar de tweede EDATA is opgehouden Meer info over EDATA Voorbeelden Pincode slot variant 1 Onderstaand programma is een codeslot Deze werkt met een display en een toetsenbordje met twaalf toetsen 0 t m 9 en op één poort met RCIN zie cursus deel 5 Vanwege de 50 regels limiet van de LITE versie van PIC Basic demo versie kunnen in dit voorbeeld maar 5 toetsen worden gebruikt 1 t m 5 Bij de volledige PIC Basic versie kunnen alle twaalf toetsen gebruikt worden SELECT CASE uitbreiden Vergeet de 220E 220Ω weerstand niet De EEPROM wordt hier gebruikt om te onthouden hoe vaak een foute code cijfercombinatie is ingetoetst Als er drie keer een verkeerde code is ingetoetst blokkeert de PIC en is dan nooit meer aan de praat te krijgen de PIC zal dan dus opnieuw met de PIC programmer moeten worden geprogrammeerd Het display geeft dan alleen maar PIC geblokkeerd aan verder doet de PIC niets meer ook niet als de spanning er even van af is gehaald DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Variabelen declareren WORD DIM ToetsCode AS WORD Hierin komt de door de gebruiker getoetste code in te staan DIM Weerstand AS WORD WORD Bevat de door RCIN gemeten toetsen weerstandswaarde BYTE DIM Cijfer AS BYTE Bevat de ingedrukte cijfertoets na meting met RCIN en SELECT DIM BD1 AS BYTE Byte Dummy 1 EDATA 0 Bij het programmeren van de PIC EEPROM adres 0 op 0 zetten Pincode programma CLS Display wissen bij opstart WHILE 1 1 CLEAR ToetsCode Begin met een frisse toetscode ToetsCode op 0 zetten dus IF EREAD 0 3 THEN Als aantal pogingen op EEPROM adres 0 3x of meer is dan PRINT AT 1 1 PIC geblokkeerd Tekst plaatsen dat PIC geblokkeerd is END Beeindig programma blokkeer PIC PIC gaat niet verder ENDIF FOR BD1 1 TO 4 Code intoetsen bestaande uit 4 cijfers WHILE PORTA 1 1 WEND Wacht steeds op een toetsindruk HIGH PORTA 1 Condensator ontladen op de toetsen poort PORTA 1 DELAYMS 1 Even wachten zodat condensator helemaal leeg is Weerstand RCIN PORTA 1 HIGH Geef RC oplaadtijd aan WORD variabele Weerstand SELECT Weerstand We gaan de variabele met de naam Weerstand testen CASE 31 Cijfer 1 Is Weerstand kleiner dan 31 dan is het toets 1 anders CASE 94 Cijfer 2 Is Weerstand kleiner dan 94 dan is het toets 2 anders CASE 159 Cijfer 3 enz CASE 228 Cijfer 4 CASE 300 Cijfer 5 END SELECT IF ToetsCode 0 THEN CLS Display alleen wissen bij eerste toetsindruk PRINT Plaats een op het display i p v het cijfer ToetsCode ToetsCode 10 Cijfer Schuif digits 1 plaats naar links en Cijfer erbij WHILE PORTA 1 0 WEND Wacht tot toets wordt losgelaten NEXT DELAYMS 700 Nog even laten zien IF ToetsCode 2553 THEN Als ingetoetste code gelijk is aan vereiste code dan IF EREAD 0 0 THEN EWRITE 0 0 Is EEPROM adres 0 niet 0 dan 0 maken teller op 0 PRINT AT 1 1 Code OK END Normaal kan hier naar de rest van een programma worden gegaan ELSE anders is er dus een foute code ingetoetst BD1 1 EREAD 0 Tellerstand van EEPROM adres 0 verhogen en in dummy zetten EWRITE 0 BD1 Daarna waarde van dummy BD1 weer wegschrijven naar EEPROM PRINT AT 1 1 Code onjuist IF BD1 3 THEN PRINT AT 2 1 Nog DEC 3 BD1 pogingen ENDIF WEND Er mag dus maar drie keer achter elkaar een foute code worden ingetoetst Het programma slaat steeds het aantal keer dat een foute code is ingedrukt op in de EEPROM Als je dit met het normale RAM geheugen zou bijhouden dan zou je na twee keer een foute code de spanning eraf kunnen halen en dan de PIC opnieuw kunnen starten waardoor de teller die het aantal foutief ingetoetste codes bijhoudt weer op 0 staat Als je het met de EEPROM bijhoudt kan de gebruiker de spanning er wel even af halen maar de PIC blijft onthouden hoe vaak er fout is ingedrukt Nadat de goede code is ingetoetst wordt de foute code teller op EEPROM adres 0 natuurlijk wel weer op 0 gezet De PIC houdt dus met zijn EEPROM bij hoe vaak er een foute code is ingetoetst Als dit getal groter of gelijk is aan drie dan wordt de PIC geblokkeerd door het programma steeds meteen te beëindigen met END Omdat een lege gewiste EEPROM op al zijn adressen 255 11111111 heeft staan wordt adres 0 het enige EEPROM adres dat in bovenstaand programma wordt gebruikt op 0 gezet tijdens PIC programmeren met EDATA 0 In de WHILE WEND lus wordt WORD variabele ToetsCode op 0 gezet met CLEAR ToetsCode Daarna wordt bekeken wat de waarde op EEPROM adres 0 is EEPROM adres 0 houdt in dit programma bij hoe vaak er een foute code is ingetoetst IF EREAD 0 3 THEN Als aantal pogingen op EEPROM adres 0 3x of meer is dan PRINT PIC geblokkeerd Tekst plaatsen dat PIC geblokkeerd is END Beeindig programma ENDIF Als dat getal 3 of groter is dan is er dus 3 keer achter elkaar een foute code ingetoetst en wordt de PIC geblokkeerd met END Ook al zal de gebruiker de spanning er af halen na het opnieuw starten van de PIC zal er alleen PIC geblokkeerd op het display verschijnen verder doet de PIC niets meer De PIC zal dus met een PIC programmer opnieuw moeten worden geprogrammeerd Als de PIC niet geblokkeerd is wordt er in de FOR NEXT lus een cijfercombinatie ingetoetst De FOR NEXT lus voert zijn lus 4 keer uit omdat het codenummer uit 4 cijfers bestaat Zodoende kunnen 4 cijfers worden ingetoetst De ingetoetste code wordt opgeslagen in de WORD variabele ToetsCode Het programma laat de cijfers niet zien maar plaatst er asterisks sterretjes voor in de plaats Na het intoetsen wordt de ingetoetste code vergeleken met de vaste code hier als voorbeeld 2553 IF ToetsCode 2553 THEN Als ingetoetste code gelijk is aan vereiste code dan IF EREAD 0 0 THEN EWRITE 0 0 Is EEPROM adres 0 niet 0 dan 0 maken PRINT AT 1 1 Code OK END Normaal kan hier naar de rest van een programma worden gegaan Als de ingetoetste code die in de variabele ToetsCode staat gelijk is aan 2553 de vereiste pincode dan is de goede code ingetoetst Er wordt dan bekeken of de teller op EEPROM adres 0 groter is dan 0 voor het geval er eerst 1 of 2 keer een foute code is ingetoetst en als dat zo is dan wordt de teller op EEPROM adres 0 weer op 0 gezet met EWRITE 0 0 Daarna wordt op het display Code OK gezet en zal het programma in dit voorbeeld tenminste beëindigen In een volledig programma kun je vanaf hier naar het begin van de rest van je programma springen waardoor dat hoofdprogramma pas start als eerst de juiste pincode is ingetoetst Anders de teller op EEPROM adres 0 is dus kleiner dan 3 maar de toetscode is niet juist ELSE anders is er dus een foute code ingetoetst BD1 1 EREAD 0 Tellerstand van EEPROM adres 0 verhogen en in dummy zetten EWRITE 0 BD1 Daarna waarde van dummy BD1 weer wegschrijven naar EEPROM PRINT AT 1 1 Code onjuist IF BD1 3 THEN PRINT AT 2 1 Nog DEC 3 BD1 poging en ENDIF Eerst wordt EEPROM adres 0 uitgelezen met 1 verhoogt en de uitkomst in dummyvariabele BD1 geplaatst In de regel daarna wordt de verhoogde waarde van BD1 weer naar EEPROM adres 0 weggeschreven Het móet wel via een dummy want EWRITE 0 1 EREAD 0 kan niet Als voorbeeld is hier de EREAD opdracht rechtstreeks in de EWRITE opdracht geplaatst dit kan dus niet het moet via een dummy variabele Je krijgt hier van de compiler niet altijd een foutmelding maar het verwachte resultaat blijft uit Daarna wordt er nog Code onjuist op het display gezet en wordt op de tweede regel afgebeeld hoeveel pogingen er nog kunnen worden gedaan Dit wordt bereikt door de waarde die nog steeds in dummyvariabele BD1 staat van de 3 pogingen af te halen oftewel 3 BD1 Alles tezamen zorgt ervoor dat alleen als er een foute code is ingetoetst er naar EEPROM wordt geschreven Als meteen bij de eerste poging de goede code wordt ingetoetst wat meestal zo zal zijn wordt er dus nooit iets naar de EEPROM geschreven wat de EEPROM ten goede komt Pincode slot variant 2 Onderstaand voorbeeld is een ander soort codeslot zonder display Het voordeel van deze is dat je de pincode eventueel kunt wijzigen en opslaan in de EEPROM nadat je eerst de goede oude pincode hebt ingetoetst Bovendien kun je als daar behoefte aan is de code uitbreiden tot wel meer dan 100 cijfers de constante AantalDig aanpassen en bij EDATA de defaultcode opgeven bij het vorige pincode slot programma kan de pincode maximaal 4 cijfers lang zijn Vergeet niet de 10k pull up weerstand Hier worden acht toetsen aangesloten op PORTB 0 t m PORTB 7 Vier toetsen moeten in een bepaalde volgorde worden ingetoetst om uitgang PORTA 2 hoog te maken Als er drie keer een verkeerde code is ingetoetst gaat de rode LED branden blokkeert de PIC en is dan net als het vorige voorbeeld nooit meer aan de praat te krijgen de PIC zal dan dus opnieuw met de PIC programmer moeten worden geprogrammeerd De PIC houdt met zijn EEPROM bij wat de pincode is en hoe vaak er een foute pincode is ingedrukt Als dit getal groter is dan drie dan wordt de PIC geblokkeerd door het programma steeds meteen te beëindigen met END Als de goede cijfercombinatie is ingetoetst dan is de pincode eventueel te wijzigen in een andere pincode en wordt deze automatisch opgeslagen in de EEPROM met EWRITE Om met deze 8 PORTB ingangen een 10 cijferig toetsenbordje te kunnen bedienen kun je toets 9 en 10 parallel aansluiten op een andere toets die ook niet bij de juiste code hoort Denk ook aan de losse pull up weerstand van 10k aan PORTA 1 Het heeft weinig nut om PORT A PULLUPS ON in het programma te schrijven de PIC16F628A heeft nu eenmaal geen ingebouwde pull up weerstanden op PORTA alleen maar op PORTB DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF DATA CP ON ALL DIGITAL TRUE Alle ingangen digitaal Algemene constanten SYMBOL AantalDig 4 Het aantal cijfers digits waaruit een code bestaat EEPROM adresnamen SYMBOL EE FouteCode 0 Op EEPROM adres 0 wordt het aantal foute codes bijgehouden Poortnamen SYMBOL LED Groen PORTA 2 Groene LED brandt als de goede code is ingedrukt SYMBOL LED Rood PORTA 3 Rode LED brandt bij foute code of als de PIC geblokkeerd is Variabelen declareren ARRAY DIM ToetsCode AantalDig 1 AS BYTE Array variabele declareren met aantal cijfers per code BYTE DIM Toets AS BYTE Toetsnummer teller van FOR NEXT lussen DIM BD1 AS BYTE Byte Dummy 1 76543210 Default pincode is PORTB 7 B 0 B 7 B 5 EDATA 0 Teller foute code ingetoetst op 0 10000000 Eerste toetsindruk is S8 128 PORTB 7 00000001 Tweede toetsindruk is S1 1 PORTB 0 10000000 Derde toetsindruk is S8 128 PORTB 7 00100000 Vierde toetsindruk is S6 32 PORTB 5 76543210 PORTA 00000000 Alle PORTA poorten laag TRISA 11110011 PORTA 2 en A 3 zijn uitgangen voor de LED s PORTB PULLUPS ON On chip pull up weerstanden actief voor de toetsen DELAYMS 300 Stabilisering signalen GOTO PincodeInvoer Spring over de subroutine SUBROUTINES CodeIntoetsen FOR Toets 1 TO AantalDig Code intoetsen WHILE PORTB 255 WEND Wacht op een toetsindruk op 1 van de PORTB poorten DELAYMS 5 Tegen contactdender bij indrukken van een toets ToetsCode Toets PORTB Sla ingetoetste code geinverteerd op in arrayvariabele LED Rood 0 Rode LED uitzetten mocht die branden door een foute code WHILE PORTB 255 WEND Wacht tot toets wordt losgelaten DELAYMS 5 Tegen contactdender bij loslaten van de toets NEXT RETURN PincodeInvoer IF EREAD EE FouteCode 3 THEN Meer dan 3x fout ingetoetst is de PIC geblokkeerd LED Rood 1 Zet rode LED aan PIC geblokkeerd END Eindig uitvoering van het programma ENDIF GOSUB CodeIntoetsen Spring naar de subroutine voor code intoetsen Controleren en vergelijken van de ingetoetste cijfers met code in EEPROM FOR Toets 1 TO AantalDig Controleer cijfer voor cijfer IF ToetsCode Toets EREAD Toets THEN Als er een foute code is ingedrukt dan BD1 1 EREAD EE FouteCode FouteCode teller EEPROM verhogen en even in dummy zetten EWRITE EE FouteCode BD1 Dummy BD1 met verhoogde teller in EEPROM schrijven LED Rood 1 Rode LED aanzetten ten teken foute code ingetoetst BREAK Verlaat FOR NEXT lus voortijdig ENDIF NEXT IF Toets AantalDig THEN Als vorige FOR NEXT geheel is doorlopen dan is code goed LED Groen 1 Groene LED aanzetten IF EREAD EE FouteCode 0 THEN EWRITE EE FouteCode 0 EEPROM teller weer op 0 zetten IF PORTA 1 0 THEN Als PORTA 1 laag is dan is een nieuwe code in te voeren GOSUB CodeIntoetsen Typ nieuwe code in FOR Toets 1 TO AantalDig Alle cijfers van de nieuwe code schrijven in EEPROM EWRITE Toets ToetsCode Toets de nieuwe toetscode in EEPROM opslaan NEXT ENDIF END Normaal kan hier naar de rest van een programma worden gegaan ENDIF GOTO PincodeInvoer Je kunt met een PIC programmer niet alleen naar het EEPROM schrijven maar deze ook uitlezen Een slimme gebruiker zou op die manier toch nog achter de in de EEPROM opgeslagen pincode kunnen komen door de PIC EEPROM via de PIC programmer terug te lezen in de PC laptop en zo op het beeldscherm de pincode kunnen achterhalen Door achter CONFIG de fuse setting DATA CP ON te zetten kan een PIC programmer niet meer in het EEPROM geheugen van de PIC kijken DATA CP ON DATA C ode P rotect ON Code beveiliging van EEPROM ingeschakeld Bericht voor degenen met een Wisp628 of Galva Wisp programmer Wegens een fout in BumbleBee V3 00 is deze fuse niet met BumbleBee te programmeren wél met XWisp en XWisp2 Heb je XWisp en XWisp2 niet geinstalleerd dan kun je DATA CP ON uit de CONFIG verwijderen De pincode in de EEPROM is dan echter wel door anderen met een PIC programmer te achterhalen Meer info over XWisp2 bij het Galva Wisp PIC programmer artikel Om uitgang PORTA 2 hoog te krijgen groene LED gaat branden moet na elkaar PORTB 7 B 0 B 7 en B 5 laag worden gemaakt Deze volgorde is de default volgorde de eigenlijke pincode dus en wordt met behulp van EDATA in de EEPROM geprogrammeerd Foute pincode teller Eerste pincode cijfer Tweede pincode cijfer Derde pincode cijfer Vierde pincode cijfer opgeslagen op EEPROM adres 0 default 0 opgeslagen op EEPROM adres 1 default 128 opgeslagen op EEPROM adres 2 default 1 opgeslagen op EEPROM adres 3 default 128 opgeslagen op EEPROM adres 4 default 32 PORTB 7 PORTB 0 PORTB 7 PORTB 5 Als deze of andere PORTB poorten in een andere volgorde laag worden gemaakt zal nadat 4 keer een PORTB poort laag is gemaakt de rode LED gaan branden ten teken dat een foute code is ingetoetst Ook hier kun je dus maximaal 3 keer een foute 4 cijferig getal intoetsen want als de vierde poging ook fout is blokkeert de PIC forever De enige mogelijkheid om de PIC dan weer aan de praat te krijgen is hem opnieuw programmeren Als de juiste volgorde wordt ingetoetst B 7 B 0 B 7 B 5 dan gaat de groene LED branden en wordt EEPROM adres 0 die het aantal fout ingetoetste codes telt weer op 0 gezet als dit adres een grotere waarde bevat dan 0 IF Toets AantalDig THEN Als vorige FOR NEXT geheel is doorlopen dan is code goed Groene LED 1 Groene LED aanzetten IF EREAD EE FouteCode 0 THEN EWRITE EE FouteCode 0 EEPROM teller weer op 0 zetten Is PORTA 1 laag S9 ingedrukt houden op het moment dat het laatste cijfer van de pincode wordt ingetoetst dan is de pincode van de PIC te wijzigen Er is dan een nieuwe 4 cijferig pincode in te toetsen op de poorten B 0 t m B 7 die daarna opgeslagen wordt in de EEPROM Denk er aan dat PORTA 1 al laag moet zijn vóórdat het laatste cijfer van de juiste oude pincode is ingetoetst Is het laatste cijfer ingetoetst dan mag ook S9 op PORTA 1 weer los worden gelaten en kan meteen met het intoetsen van de nieuwe code worden begonnen IF PORTA 1 0 THEN Als PORTA 1 laag is dan is een nieuwe code in te voeren GOSUB CodeIntoetsen Typ nieuwe code in FOR Toets 1 TO AantalDig Alle cijfers van de nieuwe code schrijven in EEPROM EWRITE Toets ToetsCode Toets de nieuwe toetscode in EEPROM opslaan NEXT ENDIF END Normaal kan hier naar de rest van een programma worden gegaan Als PORTA 1 laag is wordt eerst met GOSUB naar een stukje programma gesprongen die de invoer van een 4 cijferig pincode regelt Dat is dezelfde subroutine waarmee de oude pincode is ingetoetst Hiermee wordt dus ook de nieuwe gewijzigde pincode ingetoetst Als het programma weer terugkomt uit de subroutine CodeIntoetsen staat de nieuwe ingetoetste pincode in de array ToetsCode De FOR NEXT lus die daarna komt slaat de nieuwe pincode cijfer voor cijfer op in de EEPROM op de EEPROM adressen 1 t m 4 Pincode slot variant 3 Het volgende programma is een variant van het vorige codeslot programma Hier worden ook acht toetsen aangesloten op PORTB 0 t m PORTB 7 Vier toetsen moeten in een bepaalde volgorde worden ingetoetst om PORTA 2 hoog te maken Als er meer dan drie keer een foute pincode is ingetoetst blokkeert de PIC minimaal 1 uur en pas daarna kan er weer een pincode worden ingetoetst De PIC houdt met zijn EEPROM bij wat de pincode is en hoe vaak er een foute pincode is ingedrukt Als dit getal groter is dan drie dan wordt de PIC niet voor eeuwig geblokkeerd maar geblokkeerd voor 1 uur door het programma een uur te laten wachten Wordt in die wachttijd de spanning uitgeschakeld en even later weer ingeschakeld dan moet er opnieuw weer een heel uur worden gewacht Na meer dan drie keer een foute pincode moet de PIC dus verplicht minimaal 1 uur lang voedingsspanning hebben zonder onderbrekingen Als het uur voorbij is krijgt de gebruiker maar 1 poging om het nog eens te proberen Is de pincode dan weer fout dan moet opnieuw minimaal een uur worden gewacht Is de pincode nu goed dan kan bij een volgende keer wel weer drie maal een foute poging worden gedaan voordat de PIC weer voor een uur blokkeert Vanwege de 50 regel limiet in PIC Basic LITE is het met onderstaand programma niet mogelijk om de pincode te wijzigen Mensen die de volledige PIC Basic versie hebben kunnen het vorige en het onderstaande programma combineren tot een groter programma dat dan zowel de uur wachten optie heeft alsook de mogelijkheid tot wijzigen van de pincode DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Algemene constanten SYMBOL AantalDig 4 Het aantal cijfers digits waaruit een code bestaat EEPROM adresnamen SYMBOL EE FouteCode 0 Op EEPROM adres 0 wordt het aantal foute codes bijgehouden Poortnamen SYMBOL LED Groen PORTA 2 Groene LED brandt als de goede code is ingedrukt SYMBOL LED Rood PORTA 3 Rode LED brandt bij foute code of als de PIC geblokkeerd is Variabelen declareren ARRAY DIM ToetsCode AantalDig 1 AS BYTE Array variabele declareren met aantal cijfers per code BYTE DIM Toets AS BYTE Toetsnummer teller van FOR NEXT lussen DIM BD1 AS BYTE Byte Dummy 1 76543210 Default pincode is PORTB 7 B 0 B 7 B 5 EDATA 0 Teller foute code ingetoetst op 0 10000000 Eerste toetsindruk is S8 128 PORTB 7 00000001 Tweede toetsindruk is S1 1 PORTB 0 10000000 Derde toetsindruk is S8 128 PORTB 7 00100000 Vierde toetsindruk is S6 32 PORTB 5 76543210 PORTA 00000000 Alle PORTA poorten laag TRISA 11110011 PORTA 2 en A 3 zijn uitgangen voor de LED s PORTB PULLUPS ON On chip pull up weerstanden actief voor de toetsen CLEAR Wis alle RAM geheugen DELAYMS 300 Stabilisering signalen Pincode programma WHILE 1 1 IF EREAD EE FouteCode 3 THEN Meer dan 3x fout ingetoetst is de PIC geblokkeerd LED Rood 1 Zet rode LED aan PIC geblokkeerd FOR BD1 1 TO 60 Een uur wachten door 60 maal 1 minuut te wachten DELAYMS 60000 60 000 mSec 1 minuut NEXT Uur is voorbij EWRITE EE FouteCode 3 EEPROM nu niet op 0 maar op 3 zo is maar 1 poging mogelijk LED Rood 0 Rode LED weer uitzetten ENDIF FOR Toets 1 TO AantalDig Code intoetsen WHILE PORTB 255 WEND Wacht op een toetsindruk op 1 van de PORTB poorten DELAYMS 5 Tegen contactdender bij indrukken van een toets ToetsCode Toets PORTB Sla ingetoetste code geinverteerd op in arrayvariabele LED Rood 0 Rode LED uitzetten mocht die branden door een foute code WHILE PORTB 255 WEND Wacht tot toets wordt losgelaten DELAYMS 5 Tegen contactdender bij loslaten van de toets NEXT Controleren en vergelijken van de ingetoetste cijfers met code in EEPROM FOR Toets 1 TO AantalDig Controleer cijfer voor cijfer IF ToetsCode Toets EREAD Toets THEN Als er een foute code is ingedrukt dan BD1 1 EREAD EE FouteCode FouteCode teller EEPROM verhogen en even in dummy zetten EWRITE EE FouteCode BD1 Dummy BD1 met verhoogde teller in EEPROM schrijven LED Rood 1 Rode LED aanzetten ten teken foute code ingetoetst BREAK Verlaat FOR NEXT lus voortijdig ENDIF NEXT IF Toets AantalDig THEN Als vorige FOR NEXT geheel is doorlopen dan is code goed LED Groen 1 Groene LED aanzetten IF EREAD EE FouteCode 0 THEN EWRITE EE FouteCode 0 EEPROM teller weer op 0 zetten GOTO HoofdProgramma Spring naar de rest van het programma ENDIF WEND HoofdProgramma Hier kan het hoofdprogramma worden geschreven Deze zal pas worden uitgevoerd als de pincode goed is ingevoerd END Als voorbeeld is ook hier de default pincode in de EEPROM PORTB 7 B 0 B 7 B 5 DATA CP ON zelf bij CONFIG plaatsen als je daar behoefte aan hebt Als je het programma wilt testen ga je natuurlijk niet steeds een uur wachten Om te testen wijzig je de tijd door DELAYMS 60000 te veranderen in DELAYMS 600 Zodoende duurt de blokkade nog maar 60 600 36000 mSec oftewel 36 seconden Is je programma helemaal goed getest en werkt het zoals je wilt dan natuurlijk niet vergeten om de tijd weer langer te maken Het voorbeeld van de digitaal naar analoog omzetter van cursus deel 7 is hier uitgebreid met de interne EEPROM Startte het voorbeeld in deel 7 steeds op met de spanning op 0V in onderstaand voorbeeld start de spanning op met de spanning die het had toen de PIC werd uitgeschakeld door de spanning steeds op te slaan in de EEPROM Het schema van cursus deel 7 blijft ongewijzigd DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL HOOG 1 Hoog signaal SYMBOL LAAG 0 Laag signaal Algemene constanten SYMBOL WijzigSpeed 10 Snelheid van wijzigen van PWM bij hoger en lager toetsen EEPROM adresnamen SYMBOL EE Spanning 0 Adres 0 van de EEPROM bevat de spanning Poortnamen SYMBOL PWM Signaal PORTA 6 Op deze poort komt het PWM signaal SYMBOL ToetsHoger PORTB 0 Toets om spanning te verhogen SYMBOL ToetsLager PORTB 1 Toets om spanning te verlagen Variabele declareren DIM Spanning AS BYTE Deze variabele bevat de spanning als PWM duty waarde EDATA 0 Na het PIC programmeren spanning op 0V 76543210 PORTA 00000000 Maak alle poorten van PORTA laag TRISA 10111111 PORTA 6 is uitgang voor het PWM signaal PORTB PULLUPS ON Pull up activeren voor de toetsen CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Wis display Spanning EREAD EE Spanning Lees spanning in van vorige keer om mee op te starten WHILE 1 1 Oneindige lus Als op ToetsHoger wordt gedrukt en spanning is nog niet maximaal dan deze verhogen IF ToetsHoger LAAG AND Spanning 250 THEN INC Spanning Als op ToetsLager wordt gedrukt en spanning is nog niet nul dan deze verlagen IF ToetsLager LAAG AND Spanning 0 THEN DEC Spanning Reken PWM waarde om naar spanning en plaats dit op het display PRINT AT 1 1 DEC2 Spanning 25 DEC2 Spanning 4 Volt Stuur naar poort PWM Signaal de grootte Spanning als een PWM signaal PWM PWM Signaal Spanning WijzigSpeed IF ToetsLager HOOG AND ToetsHoger HOOG THEN Beide toetsen losgelaten dan IF Spanning EREAD EE Spanning THEN EWRITE EE Spanning Spanning ENDIF WEND EDATA 0 zorgt ervoor dat de schakeling opstart met 0V Dit geldt dus alleen voor de allereerste keer direct nadat de PIC geprogrammeerd is De keren daarna start de PIC op met de spanning die het had toen de schakeling werd uitgeschakeld In het hoofdprogramma wordt vóór de oneindige lus de variabele Spanning eerst weer op de waarde gebracht die het had toen de PIC werd uitgeschakeld door Spanning EREAD EE Spanning De naam EE Spanning heeft bij SYMBOL de waarde 0 gekregen dus eigenlijk staat hier Spanning EREAD 0 Onderin het programma wordt de spanning alleen in de EEPROM opgeslagen als de insteltoetsen ToetsLager en ToetsHoger niet bedient zijn anders zou elk verhoging of verlaging stapje in de EEPROM worden opgeslagen wat de levensduur van de EEPROM verkort Nu wordt het pas opgeslagen als de spanning goed is ingesteld en de toetsen zijn losgelaten Bovendien wordt er alleen naar EEPROM geschreven als de waarden verschillen IF Spanning EREAD EE Spanning Er staat immers Als Spanning kleiner of groter is dan de waarde in de EEPROM dan EWRITE EE Spanning Spanning de nieuwe spanningsinstelling in de variabele Spanning opslaan op EEPROM adres EE Spanning In dit voorbeeld wordt alleen adres 0 gebruikt maar als in een groter programma veel EEPROM adressen voor diverse instellingen en waarden worden gebruikt is het overzicht snel verloren als je directe adressering gebruikt Bij SYMBOL wordt daarom opgegeven dat de waarde van de spanning ligt opgeslagen op EEPROM adres 0 met de naam EE Spanning Verder in het programma plaatsen we dan niet meer direct het adres achter de instructies EREAD en EWRITE maar geven we de naam EE Spanning op Hierdoor is het meteen duidelijk dat we het EEPROM adres hebben dat de spanning bevat Om aan te geven dat de naam een EEPROM adres is begin ik de naam met EE Overigens is EE Spanning gewoon een naam Het had dus ook EREAD Adres Spanning of EREAD PietJanHein kunnen zijn Ik heb er een gewoonte van gemaakt om namen van EEPROM adressen altijd te beginnen met EE PietJanHein werkt dus maar aan EE PietJanHein kan ik zien dat het een EEPROM adres betreft In een groter programma is IF EREAD 0 250 AND EREAD 22 1 THEN EWRITE 5 0 niet echt duidelijk omdat niet meteen te zien is wat de EEPROM adressen 0 22 en 5 precies bevatten Door de adressen eerst namen te geven is het een stuk duidelijker en het kost geen geheugenruimte extra in de PIC Als je namelijk gaat compileren dan plaatst de compiler de PC laptop dus eerst alle adreswaarden weer voor de namen in de plaats Onderstaand programmadeel doet dus precies hetzelfde als bovenste programmadeel maar neemt toch niet meer geheugen in van de PIC EEPROM adresnamen SYMBOL EE Spanning 0 EEPROM adres 0 bevat de spanningswaarde SYMBOL EE Stroom 5 EEPROM adres 5 bevat de stroombegrenzingswaarde SYMBOL EE Gebruiker 22 EEPROM adres 22 bevat gebruikersinstellingen IF EREAD EE Spanning 250 AND EREAD EE Gebruiker 1 THEN EWRITE EE Stroom 0 De overeenkomst tussen EDATA en EWRITE is dat ze allebei waarden naar de interne EEPROM toe schrijven EDATA doet dat echter maar één keer en dat is alleen tijdens het programmeren van de PIC zelf De waarden achter EDATA worden dan ook door de PIC programmer in de EEPROM geschreven en niet door de PIC EWRITE schrijft naar het EEPROM als de PIC zijn programma uitvoert De waarden van EWRITE worden door de PIC zelf in zijn EEPROM geschreven Je kunt niet aan het begin van een programma EWRITE gebruiken om de EEPROM op een default waarde in te stellen want steeds als je dan de PIC opnieuw start zal opnieuw de default waarde worden ingesteld EDATA doet dat niet Alleen de eerste keer tijdens het PIC programmeren zal de default waarde worden ingesteld Als het programma in de PIC later deze waarde wijzigt blijft het deze nieuwe waarde behouden en zal niet meer door EDATA worden overschreven ook niet als je de PIC opnieuw opstart of reset DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL AAN 0 Geinverteerd AAN SYMBOL UIT 1 Geinverteerd UIT Algemene constanten SYMBOL AntiDender 5 mSec Tijd tegen contactdender van toetsen SYMBOL VerstelSpeed 300 mSec Snelheid dat op neer telt bij vasthouden toets EEPROM adresnamen SYMBOL EE TempInstel 0 EEPROM adres Bevat het adres waar de ingestelde temp staat Poortnamen SYMBOL Hoger PORTB 0 Deze toets verhoogt de temperatuurinstelling SYMBOL Lager PORTB 1 Deze toets verlaagt de temperatuurinstelling Variabelen declareren DIM TempInstel AS BYTE Variabele waarin de ingestelde temperatuur staat EDATA 20 Bij PIC programmeren defaultwaarde 20 op EEPROM adres 0 zetten 76543210 TRISA 11111111 PORTA allen ingangen TRISB 11111111 PORTB allen ingangen PORTB PULLUPS ON On chip pull up weerstanden actief voor toets CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma TempInstel EREAD EE TempInstel Lees vanuit de EEPROM wat de ingestelde temperatuur is CLS PRINT Temp 223 C Plaats alvast tekst op het display WHILE 1 1 Oneindige lus CURSOR 1 7 Plaats cursor alvast op eerste regel zevende positie IF TempInstel 10 THEN PRINT Nulonderdrukking zie cursus deel 4 PRINT DEC TempInstel Plaats ingestelde temperatuur op het display DELAYMS VerstelSpeed Bepaalt snelheid van instelling bij vasthouden toets IF Hoger AAN AND TempInstel 32 THEN Toets ingedrukt EN temp nog niet maximaal dan INC TempInstel temperatuurinstelling verhogen ELSEIF Lager AAN AND TempInstel 5 THEN Toets ingedrukt EN temp nog niet minimaal dan DEC TempInstel temperatuurinstelling verlagen ELSEIF TempInstel EREAD EE TempInstel THEN Als instelling ongelijk is aan EEPROM dan EWRITE EE TempInstel TempInstel nieuwe instelling opslaan ENDIF WEND END Op EEPROM adres 0 wordt de ingestelde temperatuur bewaard Door adressen namen te geven is het makkelijker te onthouden Met SYMBOL geven we de naam EE TempInstel de waarde 0 Hierdoor is EREAD EE TempInstel dus hetzelfde als EREAD 0 Als na stroomuitval de PIC weer wordt opgestart leest het eerst adres EE TempInstel van de EEPROM uit en plaatst de waarde weer terug in de variabele TempInstel Dit zal een waarde tussen 5 C en 32 C zijn Als de PIC zelf echter wordt geprogrammeerd met de PIC programmer dan is de EEPROM nog leeg en zal de waarde nog 255 C zijn Dit is opgelost met EDATA die de default waarde de fabrieksinstelling op 20 zet zodat direct nadat de PIC geprogrammeerd is het programma al voorgeprogrammeerd is op 20 C Met bovenstaand voorbeeld is de temperatuur van een thermostaat in te stellen van 5 C t m 32 C Toets Lager verlaagt de temperatuur met 1 C zolang deze hoger is dan 5 C Toets Hoger verhoogt de temperatuur met 1 C zolang deze lager is dan 32 C Als een toets wordt vastgehouden verstelt de temperatuurinstelling automatisch Het voorbeeld van de temperatuurinstelling loopt in een lus Als je EWRITE zomaar zonder voorwaarden in de lus zou zetten wordt er continu dezelfde waarde naar de EEPROM geschreven de EEPROM slijt hierdoor Daarom wordt in het voorbeeldprogramma EWRITE pas uitgevoerd als de ingestelde temperatuur ongelijk is aan de temperatuurwaarde die is opgeslagen in de EEPROM Nadat de ingestelde temperatuur in de EEPROM is opgeslagen is deze weer gelijk aan de waarde in de variabele TempInstel en zal er de volgende keer dus niet opnieuw naar de EEPROM worden geschreven maar pas dan als TempInstel weer door de gebruiker is gewijzigd Ook wordt in bovenstaande voorbeeld pas naar de EEPROM geschreven als de toetsen zijn losgelaten anders zou bij verstelling van de temperatuur van bijvoorbeeld 18 C naar 22 C achtereenvolgens 19 20 21 en 22 naar de EEPROM worden geschreven wat nutteloos is en de EEPROM onnodig zou belasten Zoals het voorbeeld is geschreven wordt de waarde 18 in één keer verandert in 22 dus zonder die tussenwaarden Het uitlezen van de EEPROM is wél onbeperkt Je mag deze dus zo vaak uitlezen met EREAD als je wilt Dat gebeurt ook in bovenstaand voorbeeld

    Original URL path: http://www.picbasic.nl/beginners9.htm (2016-02-17)
    Open archived version from archive

  • Detail foto's etsbak
    Als het U profiel de print strak afklemt worden de randen niet geëtst omdat het etsmiddel er dan niet bij kan komen De twee U profielen zijn horizontaal te verstellen Zo is elke maat printplaat er tussen te klemmen Door de RVS schroeven niet te strak aan te draaien kun je de U profielen verschuiven zonder dat je de schroeven steeds moet losdraaien 8 8 Gebruik RVS roest vast stalen

    Original URL path: http://www.picbasic.nl/etsen_etsbak.htm (2016-02-17)
    Open archived version from archive

  • Automatische poster verplaatsing
    en remt dan weer af om het laatste stukje langzaam te blijven lopen totdat het tegen een eindschakelaar loopt Hierdoor is de poster altijd in uiterst linkse stand geparkeerd Aan de andere kant zit geen schakelaar de motor loopt gewoon een aantal seconden naar rechts om daarna automatisch langzaam tot stilstand te komen Door het aantal seconden in de PIC te wijzigen kan de poster zo op elke positie hangen als de beamer uit is Alles is natuurlijk geprogrammeerd in Proton PIC Basic 8 8 Het geprojecteerde beeld meet 2 5 x 1 4 meter Overdag hangt de poster waar nu de nieuwslezer zit De poster hangt nu links 8 8 De poster hangt aan een aluminium strip waaraan aan beide zijden een wieltje van een gordijnrail is bevestigd De twee wieltjes lopen in de gordijnrail zodat de poster niet zwaar loopt Alle overige wieltjes van de gordijnrail zijn er uit gehaald Om ervoor te zorgen dat de draad strak blijft gespannen is er een balpen veer tussen gezet zie foto ga met muis op de tekening staan 8 8 Een RB35 motor met 1 50 vertragingsbak verzorgt de aandrijving Eén deel van de nylondraad loopt dóór de gordijnrail daarin zit de aluminium strip Over de schakelaar zit een diode anders zou de poster niet terug kunnen De nylondraad slipt niet omdat de as van de motor van rubber is Deze is gemaakt van een rubber metalen lageringselement type AT Hiervan is één schroefdraaddeel afgezaagd Omdat de beamer nogal lang is uitgevallen ligt deze haaks bovenin een kast Het beeld wordt door een servomotor aangedreven spiegel haaks omgezet en gericht op de muur Als de beamer wordt aangezet opent de spiegel zich automatisch De beamer kan in deze positie het signaal van de afstandsbediening slecht ontvangen daarom is er een

    Original URL path: http://www.picbasic.nl/poster.htm (2016-02-17)
    Open archived version from archive

  • PIC programmeren met PIC Basic (6)
    hier met een BYTE variabele tellen en deze alleen een waarde kan bevatten van 0 t m 255 is 0 1 255 Zo is 5 4 1 5 5 0 5 6 255 en 5 7 254 enzovoort Hier zie je nu ook waarom dat inspringen van de programmatekst met 2 spaties of TAB zo belangrijk is Als je dat niet doet dan is niet snel te zien waar het begin en het eind van een lus is Ook zie je zo makkelijker welke NEXT bij welke FOR hoort SELECT CASE ENDSELECT Beslissingen nemen Een aanverwant commando van IF THEN ELSEIF ELSE ENDIF is SELECT CASE ENDSELECT Dit commando doet bijna hetzelfde als ELSEIF maar werkt overzichtelijker De SELECT CASE instructie is een soort multiple choise meer keuze SELECT bekijkt wat de waarde is van de constante variabele of berekening die er achter staat Daarna gaat hij deze waarde vergelijken met de testwaarden in de navolgende lijst met CASE s Zodra er een CASE testwaarde wordt tegengekomen die waar TRUE is wordt het instructieblok uitgevoerd die bij de desbetreffende CASE hoort De overige CASE blokken worden niet meer bekeken Wanneer geen enkele CASE waar is wordt CASE ELSE uitgevoerd Als er geen CASE ELSE is opgegeven dan wordt verder gegaan met de instructie die onder ENDSELECT staat De volgende paar onvolledige voorbeelden zullen overeenkomsten en verschillen tussen SELECT CASE en IF THEN ELSE laten zien Als er aan de potmeter wordt gedraaid levert Weerstand een waarde op van 0 9 omdat voor Schaal in de functie POT de waarde 5 is opgegeven zie cursus deel 5 Eerst hoe dit gaat met IF THEN ELSE Weerstand POT PORTA 1 5 Geef gemeten potmeterinstelling aan Weerstand IF Weerstand 4 THEN Als Weerstand gelijk is aan 4 dan PRINT Vier Vier op het display zetten ELSEIF Weerstand 5 THEN anders als Weerstand gelijk is aan 5 dan PRINT Vijf Vijf op het display zetten ELSEIF Weerstand 6 THEN anders als Weerstand gelijk is aan 6 dan PRINT Zes Zes op het display zetten ELSE anders in alle andere gevallen PRINT Andere waarde Andere waarde op het display zetten ENDIF Einde IF THEN ELSE blok PRINT AT 2 1 Klaar Zet Klaar op displayregel 2 Als de potmeterinstelling een waarde oplevert van 4 5 of 6 dan wordt dit op displayregel 1 in tekstvorm weergegeven Vier Vijf of Zes Heeft de potmeter een andere waarde 0 3 of 7 9 dan komt er Andere waarde op het display te staan Op regel 2 van het display staat Klaar Bij ELSEIF moet steeds opnieuw de variabele Weerstand worden opgegeven bij SELECT CASE geef je maar één maal de variabele Weerstand op Hieronder is het programma herschreven maar nu met de SELECT CASE instructie het resultaat is precies hetzelfde Weerstand POT PORTA 1 5 Geef gemeten potmeterinstelling aan Weerstand SELECT Weerstand We gaan de variabele Weerstand testen CASE 4 Als Weerstand is 4 dan PRINT Vier Vier op het display zetten CASE 5 Als Weerstand is 5 dan PRINT Vijf Vijf op het display zetten CASE 6 Als Weerstand is 6 dan PRINT Zes Zes op het display zetten CASE ELSE Anders PRINT Andere waarde Andere waarde op het display zetten ENDSELECT Einde SELECT CASE blok PRINT AT 2 1 Klaar Zet Klaar op displayregel 2 Eerst select eer je de variabele die vergeleken getest moet worden Dat doe je door achter SELECT de variabelenaam op te geven Achter elke CASE in het geval worden nu steeds vergelijkingen uitgevoerd CASE 4 betekent dus in het geval dat de opgegeven variabele Weerstand gelijk is aan 4 dan de daarop volgende instructie s uitvoeren in het voorbeeld dus PRINT Vier Het is duidelijk dat de instructie s onder CASE 5 worden uitgevoerd als de variabele Weerstand de waarde 5 heeft en voor CASE 6 als die waarde 6 is Instructies tussen CASE ELSE en ENDSELECT worden alleen uitgevoerd als geen van de andere CASE selecties een positief resultaat heeft opgeleverd Een CASE ELSE moet daarom altijd als laatste CASE in het blok staan Het is overigens niet verplicht om een CASE ELSE te plaatsen Stel dat in bovenstaand voorbeeld géén CASE ELSE is geplaatst en Weerstand de waarde 2 heeft dan wordt er niets van het blok uitgevoerd Het programma zal meteen verdergaan met de eerste instructie die na ENDSELECT komt In bovenstaand voorbeeld is dat PRINT AT 2 1 Klaar Het resultaat is dat dan alleen op displayregel 2 Klaar komt te staan regel 1 blijft leeg Niet alle beslissingen kunnen hiermee uitgevoerd worden Het volgende bijvoorbeeld kan niet met SELECT CASE worden uitgevoerd NTC POT PORTA 0 255 Geef gemeten temperatuur aan variabele NTC Weerstand POT PORTA 1 127 Geef gemeten potmeterinstelling aan Weerstand IF Weerstand 0 AND NTC 0 THEN PRINT Beide zijn nul ELSEIF Weerstand 0 THEN PRINT Weerstand is nul ELSEIF NTC 0 THEN PRINT NTC is nul ELSE PRINT Geen van beide nul ENDIF PRINT AT 2 1 Klaar Hier worden twee variabelen getest namelijk Weerstand en NTC Aangezien SELECT CASE maar één variabele kan testen moet hier wel gebruik worden gemaakt van de IF THEN ELSEIF ELSE instructie Om op meerdere waarden te kunnen testen moet je deze waarden scheiden door komma s In onderstaand programmavoorbeeld zal als Teller de waarde 4 6 8 of 10 heeft Even waarde op het display worden weergegeven Schreef je eerst IF Teller 4 OR Teller 6 OR Teller 8 OR Teller 10 THEN dan schrijf je nu simpel CASE 4 6 8 10 We gebruiken de zojuist beschreven FOR NEXT lus als teller Vanaf hier zijn de programma s weer volledig weergegeven DEVICE 16F628A We gebruiken een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal DIM Teller AS BYTE Deze variabele wordt gebruikt als teller in de FOR NEXT lus CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma FOR Teller 0 TO 15 Tel met de variabele Teller van 0 t m 15 CLS Wis scherm PRINT DEC Teller Zet de stand van Teller op het display CURSOR 2 1 Zet cursor alvast vooraan op displayregel 2 SELECT Teller We gaan de variabele Teller testen CASE 3 5 7 9 Als Teller 1 van deze waarden heeft dan PRINT Oneven waarde tekst op het display zetten CASE 4 6 8 10 Als Teller 1 van deze waarden heeft dan PRINT Even waarde tekst op het display zetten CASE 3 Als Teller kleiner is dan 3 dan PRINT Kleiner dan drie tekst op het display zetten CASE 10 Als Teller groter is dan 10 dan PRINT Groter dan tien tekst op het display zetten ENDSELECT DELAYMS 1000 Om de seconde tellen anders gaat het zo snel NEXT Teller verhogen en dan terug naar FOR CLS PRINT AT 2 1 Klaar Zet Klaar op displayregel 2 END Einde programma Er bestaan een paar mogelijkheden om een heel bereik te selecteren Om een bereik van 0 20 op te geven kun je schrijven CASE 20 of CASE 21 betekent kleiner dan en betekent kleiner dan of gelijk aan het getal dat er achter staat Let op is goed maar geeft een foutmelding Om een bereik van 5 t m 33 op te geven kun je schrijven CASE 5 TO 33 Wel altijd het laagste getal vooraan zetten CASE 33 TO 5 werkt dus niet In deze vorm kan er maar één bereik per CASE getest worden CASE 10 12 14 20 is dus gescheiden door komma s toegestaan Maar CASE 10 12 TO 15 20 is niet toegestaan en CASE 5 TO 8 10 TO 15 is ook niet toegestaan Stel je hebt voor één of ander project een puls die steeds 3 uitgangssignalen moet opleveren die bij elke nieuwe puls een nieuwe onlogische maar wel vastgestelde uitgangsituatie moet opleveren en na 16 pulsen moet dezelfde combinatievolgorde weer van voren af aan beginnen Dit alles volgens onderstaande tabel Teller 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 LED1 L H H H H H H H L H L L H L H H LED2 L L L L L H L H H L H H H L H H LED3 L H L H H H L H L L L L H H L H H Hoog LED brandt Met S1 geven we een puls op PORTB 0 en de LED s laten het niveau hoog of laag van de uitgangen zien Op het display staat de variabele Teller die steeds met 1 wordt verhoogt als je op S1 drukt Neem onderstaand programma over in de PIC Basic editor eventueel met behulp van Copy en Paste DEVICE 16F628A We gebruiken een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL AAN 0 Geinverteerd AAN SYMBOL OFF 0 UIT SYMBOL ON 1 AAN SYMBOL UIT 1 Geinverteerd UIT Poortnamen SYMBOL LED1 PORTA 0 Op poort A 0 zit LED1 aangesloten SYMBOL LED2 PORTA 1 Op poort A 1 zit LED2 aangesloten SYMBOL LED3 PORTA 2 Op poort A 2 zit LED3 aangesloten SYMBOL S1 PORTB 0 S1 verhoogt de teller Variabele declareren DIM Teller AS BYTE Byte variabele met naam Teller 76543210 PORTA 00000000 Alle PORTA uitgangen uitzetten laag maken TRISA 11111000 PORTA 2 A 1 en A 0 omschakelen als uitgang voor de LED s PORTB PULLUPS ON On chip pull up weerstanden actief voor S1 CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Wis display PRINT Druk op S1 Plaats tekst op display WHILE 1 1 Oneindige lus WHILE S1 UIT WEND Wacht tot S1 wordt ingedrukt Eerst vorige stand van 3 LED s uitzetten LED1 OFF LED1 uit LED2 OFF LED2 uit LED3 OFF LED3 uit SELECT Teller Variabele Teller wordt getest CASE 15 Als Teller boven de 15 komt dan CLEAR Teller Reset Teller Weer bij 0 beginnen CASE 2 6 9 Als Teller 2 6 of 9 is dan LED1 ON LED1 aan CASE 8 TO 11 Als Teller 8 t m 11 is dan LED2 ON LED2 aan CASE 13 Als Teller 13 dan LED3 ON LED3 aan CASE 14 Als Teller 14 dan LED1 ON LED1 aan LED2 ON LED2 aan CASE 5 Als Teller kleiner is dan 5 dan LED1 ON LED1 aan LED3 ON LED3 aan CASE ELSE In alle overige gevallen LED1 ON LED1 aan LED2 ON LED2 aan LED3 ON LED3 aan ENDSELECT Einde blok SELECT CASE CLS Wis display en zet cursor op 1 1 PRINT Teller DEC Teller Zet tellerstand op het display WHILE S1 AAN WEND Wacht tot toets is losgelaten DELAYMS 10 Vertraging tegen contactdender INC Teller Verhoog Teller met 1 WEND Ter controle moeten de volgende LED s branden Teller LED1 LED2 LED3 CASE 0 L L L 15 1 H L H 5 2 H L L 2 6 9 3 H L H 5 4 H L H 5 5 H H H ELSE 6 H L L 2 6 9 7 H H H ELSE 8 L H L 8 TO 11 9 H L L 2 6 9 10 L H L 8 TO 11 11 L H L 8 TO 11 12 H H H ELSE 13 L L H 13 14 H H L 14 15 H H H ELSE H LED brandt De meest rechtse kolom geeft aan door welke CASE de uitgangen zijn geactiveerd SELECT CASE wordt van boven naar beneden uitgevoerd als hij een CASE tegenkomt die aan de voorwaarde voldoet dan worden de opdrachten die in dat blok staan uitgevoerd Daarna wordt verder gegaan met de instructie die na ENDSELECT komt Er wordt dus altijd maar 1 blok uitgevoerd ook als er meer CASE gevallen zijn die aan de voorwaarde voldoen zoals in bovenstaand voorbeeld als Teller 2 dan is zowel CASE 2 6 9 waar TRUE als ook CASE 5 Maar omdat CASE 2 6 9 hoger in de lijst staat heeft deze een hogere prioriteit en worden de opdrachten van die CASE uitgevoerd en niet die van CASE 5 ook al is 2 kleiner dan 5 Datzelfde geldt als Teller de waarde 9 heeft CASE 2 6 9 staat hoger in de lijst dan CASE 8 TO 11 daarom worden de instructies die onder CASE 2 6 9 staan wel uitgevoerd maar de instructies van CASE 8 TO 11 niet Hieronder het voorbeeld uit cursus deel 5 meerdere puls schakelaars op 1 ingang inlezen met RCIN Alleen is ELSEIF nu vervangen door SELECT CASE het resultaat blijft precies hetzelfde maar het Basic programmaoverzicht is beter Alle toetsen worden via 4k7 weerstanden SIL netwerk of SMD aangesloten op maar één poort PORTA 1 met de naam Toets in dit geval Met de functie RCIN is nu te meten welke toets is ingedrukt omdat elke toets zijn eigen weerstandswaarde heeft Het onderstaand voorbeeldprogramma doet het volgende Toets 1 Beide LED s uitzetten Toets 2 Toggle de groene LED Toets 3 Toggle de rode LED Toets 4 Beide LED s aanzetten Toets 5 De groene LED aanzetten Toets 6 De rode LED aanzetten SIL weerstands netwerk Het uitfilteren van de waarde van de variabele Weerstand gebeurt door steeds de waarde die bij elke CASE is opgegeven te vergelijken met de waarde van Weerstand en zo de lijst van boven naar beneden af te werken totdat een bewering wordt gevonden die waar is DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL AAN 0 Geinverteerd AAN SYMBOL OFF 0 UIT SYMBOL ON 1 AAN Poortnamen SYMBOL Toets PORTA 1 Toetsen zitten aan PORTA 1 via een weerstandsnetwerk SYMBOL LED Groen PORTA 2 De groene LED zit op PORTA 2 aangesloten SYMBOL LED Rood PORTA 3 De rode LED zit op PORTA 3 aangesloten Variabele declareren DIM Weerstand AS WORD WORD variabele bevat straks waarden van de toetsindrukken 76543210 TRISA 11110011 PORTA 3 en PORTA 2 omschakelen als uitgang voor de LED s CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma CLS LCD scherm wissen WHILE 1 1 Oneindig door blijven meten IF Toets AAN THEN Als er op een toets wordt gedrukt dan PRINT AT 1 1 Toets Zet het woordje Toets alvast op de eerste display regel HIGH Toets Condensator ontladen DELAYMS 1 Even wachten zodat condensator helemaal leeg is Weerstand RCIN Toets HIGH Geef RC oplaadtijd aan WORD variabele Weerstand SELECT Weerstand We gaan de waarde van de variabele Weerstand testen CASE 31 Toets 1 ingedrukt dan LED Groen OFF beide LED s uit LED Rood OFF PRINT 1 Zet het toetsnummer achter Toets op het display CASE 94 Toets 2 ingedrukt dan LED Groen LED Groen 1 toggle de groene LED PRINT 2 Zet het toetsnummer achter Toets op het display CASE 159 Toets 3 ingedrukt dan LED Rood LED Rood 1 toggle de rode LED PRINT 3 Zet het toetsnummer achter Toets op het display CASE 228 Toets 4 ingedrukt dan LED Groen ON beide LED s aan LED Rood ON PRINT 4 Zet het toetsnummer achter Toets op het display CASE 300 Toets 5 ingedrukt dan LED Groen ON de groene LED aanzetten PRINT 5 Zet het toetsnummer achter Toets op het display CASE 999 Toets 6 ingedrukt dan LED Rood ON de rode LED aanzetten PRINT 6 Zet het toetsnummer achter Toets op het display ENDSELECT PRINT AT 2 1 DEC5 Weerstand Zet waarde van Weerstand op regel 2 van het display WHILE Toets AAN WEND Wacht hier tot toets en wordt losgelaten ENDIF WEND Terug naar WHILE Is de opgemeten weerstand kleiner dan 31 CASE 31 Zo ja dan is het toets 1 die is ingedrukt en dan moeten de bijbehorende instructies uitgevoerd worden LED Groen en LED Rood uitzetten en een 1 achter Toets op het display zetten Zoniet dan op naar de volgende CASE Dit betekent dat Weerstand in ieder geval 31 of groter is want anders zou CASE 31 zijn uitgevoerd Is de opgemeten weerstand misschien kleiner dan 94 CASE 94 Zo ja dan is het toets 2 die is ingedrukt en worden de bijbehorende instructies van deze toets uitgevoerd Zoniet dan op naar de volgende CASE enzovoort Meer info over het inlezen van meerdere puls schakelaars op 1 ingangspoort zie cursus deel 5 Het is ook mogelijk om constanten variabelen en zelfs berekeningen toe te passen In het voorbeeld zijn 2 constanten aangemaakt namelijk Maximum die constant de waarde 50 heeft en Minimum die symbool staat voor de waarde 10 SYMBOL Maximum 50 Maximum staat symbool voor 50 SYMBOL Minimum 10 Minimum staat symbool voor 10 SELECT Weerstand De variabele Weerstand wordt hier getest CASE Minimum Als Weerstand kleiner of gelijk is aan 10 Minimum dan LED Rood ON de rode LED aanzetten CASE 3 Minimum Als Weerstand 30 3 x Minimum dan LED Geel ON de gele LED aanzetten CASE 75 Als Weerstand 75 dan LED Blauw ON de blauwe LED aanzetten CASE Maximum Als Weerstand groter of gelijk is aan 50 Maximum dan LED Groen ON de groene LED aanzetten CASE ELSE Bij de overige waarden van Weerstand LED Wit ON de witte LED aanzetten en DELAYMS 1000 na 1 seconde LED Wit OFF de witte LED weer uitzetten ENDSELECT Einde SELECT CASE blok PRINT AT 2 1 Klaar Zet Klaar op displayregel 2 LED Rood wordt hier aangezet als Weerstand kleiner of gelijk is aan 10 de waarde van Minimum door CASE Minimum Het tweede geval is een CASE met een berekening erachter namelijk CASE 3 Minimum LED Geel wordt alleen aangezet als Weerstand de waarde 30 heeft want Minimum staat symbool voor 10 en er staat dus eigenlijk de berekening 3 10 oftewel CASE 30 Bij de derde CASE in het voorbeeld gaat LED Blauw aan als Weerstand de waarde 75 heeft De waarde 75 is weliswaar groter dan Maximum maar omdat CASE 75 hoger in het rijtje staat dan CASE Maximum wordt het daardoor eerder getest Er wordt immers maar één CASE per SELECT CASE blok uitgevoerd en dat is de hoogst geplaatste CASE die waar TRUE is ook al staan er meerdere CASE gevallen in die waar zijn Stel dat CASE Maximum boven CASE 75 stond dan wordt LED Groen aangezet in plaats van LED Blauw De volgorde van het rijtje CASE opsommingen kan dus in sommige gevallen wel degelijk verschil uitmaken Instructies met de hoogste prioriteit moeten dus bovenaan gezet worden LED Groen wordt aangezet als Weerstand groter of gelijk is aan Maximum CASE Maximum Als Weerstand de waarde 50 de opgegeven waarde van Maximum of hoger heeft dan brandt LED Groen behalve als deze waarde 75 is want dan wordt het programma één CASE eerder al uitgevoerd namelijk bij CASE 75 en daar wordt dus LED Blauw aangezet De programmaregel s onder CASE ELSE worden alleen afgehandeld als geen van de andere CASE gevallen waar TRUE zijn In bovenstaand voorbeeld zal LED Wit alleen een seconde oplichten als Weerstand een waarde heeft van 11 t m 49 met uitzondering van 30 want elke andere waarde wordt afgehandeld in één van de eerdere CASE selecties Nesten Ook SELECT CASE kun je nesten Achter een CASE kan dus een andere SELECT CASE instructie staan SYMBOL Maximum 50 Maximum staat symbool voor 50 SYMBOL Minimum 10 Minimum staat symbool voor 10 SELECT Weerstand De variabele Weerstand wordt hier getest CASE Minimum Als Weerstand kleiner is dan 10 Minimum dan LED Rood ON de rode LED aanzetten CASE 3 Minimum Als Weerstand 30 3 x Minimum dan SELECT PietJanHein De variabele PietJanHein wordt hier getest CASE 5 Als Weerstand 30 en PietJanHein kleiner 5 dan LED Rood ON de rode LED aanzetten CASE 10 Als Weerstand 30 en PietJanHein groter 10 dan LED Geel ON de gele LED aanzetten CASE ELSE Als Weerstand 30 en overige waarden van PietJanHein LED Wit ON de witte LED aanzetten en DELAYMS 1000 na 1 seconde LED Wit OFF de witte LED weer uitzetten ENDSELECT Einde binnenste SELECT CASE blok CASE Maximum Als Weerstand groter of gelijk is aan 50 Maximum dan LED Groen ON de groene LED aanzetten ENDSELECT Einde buitenste SELECT CASE blok PRINT AT 2 1 Klaar Zet Klaar op displayregel 2 Wanneer in dit voorbeeld Weerstand de waarde 30 heeft 3 Minimum dan wordt een andere SELECT CASE uitgevoerd die de variabele PietJanHein gaat testen Om van de vele mogelijke situaties die nu mogelijk zijn er één als voorbeeld te nemen De rode LED gaat hier branden als Weerstand kleiner is dan Minimum Maar de rode LED gaat ook branden als Weerstand de waarde 30 heeft en de waarde van PietJanHein kleiner is dan 5 Een functie mag rechtstreeks achter SELECT worden gezet Hieronder is de functie POT rechtstreeks achter SELECT gezet SELECT POT PORTA 1 Schaal De functie POT staat rechtstreeks in de SELECT instructie CASE 100 Als de ingelezen waarde kleiner of gelijk is aan 100 dan LED Rood ON de rode LED aanzetten ENDSELECT Einde SELECT CASE blok Het is echter niet aan te bevelen om dit zo te doen Dit neemt meer programmageheugen en RAM geheugen van de PIC in dan via een dummy variabele In onderstaand voorbeeld wordt de waarde van de functie POT eerst in de dummy variabele BD1 gelezen en daarna wordt op zijn beurt de dummy variabele getest in SELECT BD1 POT PORTA 1 Schaal De ingelezen waarde wordt eerst in de variabele BD1 gezet SELECT BD1 Daarna wordt de dummy variabele BD1 getest CASE 100 Als de ingelezen waarde kleiner of gelijk is aan 100 dan LED Rood ON de rode LED aanzetten ENDSELECT Einde SELECT CASE blok Het resultaat is hetzelfde maar neemt minder programma en RAM geheugen van de PIC in al zul je zo op het oog zeggen dat het juist meer geheugen in zou nemen Een volledige 8 bits poort kun je ook testen Ook hier is het aan te bevelen om de poort eerst in een dummy variabele in te lezen en dan op zijn beurt de dummy variabele te testen omdat dit ook in dit geval programma en RAM geheugen scheelt DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Variabele declareren DIM BD1 AS BYTE Byte Dummy 1 PORTB PULLUPS ON On chip pull up weerstanden actief CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma CLS LCD scherm wissen WHILE 1 1 Oneindig door blijven meten CURSOR 1 1 Zet cursor alvast links op regel 1 BD1 PORTB 00000011 Lees PORTB 1 en PORTB 0 in dummy BD1 SELECT BD1 Daarna de dummy variabele BD1 testen CASE 00000010 00000001 Als alleen PORTB 1 hoog is OF alleen PORTB 0 hoog is dan PRINT EEN EEN op het display zetten CASE 00000011 Als PORTB 1 EN PORTB 0 hoog zijn dan PRINT TWEE TWEE op het display zetten CASE 00000000 Als PORTB 1 en PORTB 0 beide laag zijn dan PRINT DRIE DRIE op het display zetten ENDSELECT Einde SELECT CASE blok WEND END Hier willen we alleen PORTB 0 en PORTB 1 inlezen Dus gaan we eerst de andere 6 poorten er uit filteren met behulp van de bitwise AND aangegeven met Door enen op de plaats van PORTB 0 en PORTB 1 te zetten en nullen op de plaats van PORTB 2 t m PORTB 7 te zetten dus 00000011 wordt een filter gemaakt die de andere 6 poorten van PORTB eruit filtert Stel dat de signalen op PORTB 7 PORTB 5 en PORTB 0 hoog zijn dan is dit de situatie 10100001 signalen op de poorten 00000011 ons opgegeven filter waarde 00000001 dit is het resultaat je ziet dat PORTB 7 en B 5 er uitgefilterd zijn Omdat we dit met de bitwise AND EN functie doen worden alleen die bits hoog die EN hoog is in ons opgegeven filter EN een hoog signaal heeft op zijn poort En in het voorbeeld voldoet alleen PORTB 0 aan die voorwaarde Alleen PORTB 1 heeft ook de mogelijkheid om er door te komen als deze een hoog signaal op zijn ingang krijgt de andere 6 poorten kunnen een hoog of laag signaal hebben ze kunnen het resultaat niet beïnvloeden kortom die zijn er uit gefilterd Beetje ingewikkeld Mwah maakt niet uit dan gebruik je deze manier gewoon niet Er is nog meer met SELECT CASE mogelijk met name het selecteren van tekst maar dit is niet mogelijk bij 14 bit PIC s en dus ook niet bij de PIC16F628 A Misschien wordt dat later nog behandeld Mocht de SELECT CASE instructie nog niet helemaal duidelijk zijn dan komt dat vanzelf in de volgende cursus delen En je kunt natuurlijk ook gewoon IF THEN ELSE blijven gebruiken GOSUB RETURN Programmeerwerk en geheugen besparen met subroutines Een subroutine is een afgerond stukje programma Wanneer in een programma dezelfde handelingen meerdere malen moeten worden uitgevoerd dan kunnen we deze handelingen in een subroutine zetten In het hoofdprogramma springen we dan naar de subroutine door middel van de instructie GOSUB Nadat de handelingen die in de subroutine staan zijn uitgevoerd wordt weer terug gesprongen naar het hoofdprogramma door middel van de instructie RETURN terugkeren en wel naar de eerste instructie die ná de GOSUB instructie komt Met GOSUB kun je programmadelen die op meerdere plekken in het programma voor komen en vrijwel identiek gelijk hetzelfde zijn aan elkaar dus vervangen door dat programmadeel maar één maal op te schrijven en daar dan even langs te lopen als het nodig is Een voorbeeld zal het duidelijker maken In het voorbeeld moet steeds op een pulstoets worden gedrukt die is aangesloten op PORTB 0 De toets wordt door DELAYMS AntiDender ontdendert Er wordt steeds gewacht op een toetsindruk en na elke toetsindruk verschijnt er nieuwe tekst op het display Dan wordt er gewacht tot de gebruiker de toets weer loslaat want anders zou alle tekst snel na elkaar verschijnen als de gebruiker de toets ingedrukt houdt Nu moet de gebruiker de toets wel eerst loslaten anders loopt het programma niet verder Eerst zoals dit zonder GOSUB gaat DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL AAN 0 Geinverteerd AAN SYMBOL UIT 1 Geinverteerd UIT Algemene constante SYMBOL AntiDender 10 mSec Tijd voor ontdendering van toetsen Poortnamen SYMBOL Toets PORTB 0 Pulstoets zit op PORTB 0 aangesloten PORTB PULLUPS ON On chip pull up weerstanden actief CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering Hoofdprogramma CLS Wis scherm van het display PRINT Druk op toets Begintekst er neer zetten WHILE 1 1 DELAYMS AntiDender Tegen contactdender bij het indrukken van de toets WHILE Toets AAN WEND Wacht tot toets wordt losgelaten DELAYMS AntiDender Tegen contactdender bij het loslaten van de toets WHILE Toets UIT WEND Wacht op een toetsindruk CLS Wis scherm van het display PRINT Met GOSUB is er Plaats tekst op het display DELAYMS AntiDender Tegen contactdender bij het indrukken van de toets WHILE Toets AAN WEND Wacht tot toets wordt losgelaten DELAYMS AntiDender Tegen contactdender bij het loslaten van de toets WHILE Toets UIT WEND Wacht op een toetsindruk CLS Wis scherm van het display PRINT meer structuur Plaats andere tekst op het display DELAYMS AntiDender enzovoort WHILE Toets AAN WEND DELAYMS AntiDender WHILE Toets UIT WEND CLS PRINT in het DELAYMS AntiDender WHILE Toets AAN WEND DELAYMS AntiDender WHILE Toets UIT WEND CLS PRINT Basic programma DELAYMS AntiDender WHILE Toets AAN WEND DELAYMS AntiDender WHILE Toets UIT WEND CLS PRINT te krijgen DELAYMS AntiDender WHILE Toets AAN WEND DELAYMS AntiDender WHILE Toets UIT WEND CLS PRINT Zie je wel WEND Je ziet dat hier heel vaak hetzelfde wordt opgeschreven Dit is allemaal extra werk voor de programmeur jij dus en kost onnodig veel geheugenruimte van de PIC In een subroutine schrijf je nu het gedeelte dat steeds hetzelfde is en dan spring je vanuit het hoofdprogramma steeds met de instructie GOSUB naar dat stukje programma Wanneer dat stukje programma is afgehandeld spring je met RETURN terug in het hoofdprogramma naar de plek waar je gebleven was Het volgende programma geeft hetzelfde resultaat als bovenstaande programma maar nu met behulp van een subroutine DEVICE 16F628A Gebruik een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal Logische constanten SYMBOL AAN 0 Geinverteerd AAN SYMBOL UIT 1 Geinverteerd UIT Algemene constante SYMBOL AntiDender 10 mSec Tijd voor ontdendering van de toets Poortnamen SYMBOL Toets PORTB 0 Pulstoets zit op PORTB 0 aangesloten PORTB PULLUPS ON On chip pull up weerstanden actief CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering GOTO HoofdProgramma Spring over de subroutine Subroutine WachtOpToets Label van subroutine met de naam WachtOpToets DELAYMS AntiDender Tegen contactdender bij het indrukken van de toets WHILE Toets AAN WEND Wacht tot toets wordt losgelaten DELAYMS AntiDender Tegen contactdender bij het loslaten van de toets WHILE Toets UIT WEND Wacht op een toetsindruk CLS Wis scherm van het display RETURN Ga terug naar waar je vandaan kwam HoofdProgramma Label van het hoofdprogramma met de naam HoofdProgramma CLS Wis scherm van het display PRINT Druk op toets Begintekst er neer zetten WHILE 1 1 Oneindige lus GOSUB WachtOpToets Ga even langs het programma in de subroutine PRINT Met GOSUB is er Plaats tekst op het display GOSUB WachtOpToets Ga even langs het programma in de subroutine PRINT meer structuur Plaats andere tekst op het display GOSUB WachtOpToets enzovoort PRINT in het GOSUB WachtOpToets PRINT Basic programma GOSUB WachtOpToets PRINT te krijgen GOSUB WachtOpToets PRINT Zie je wel WEND Nu is dit maar een eenvoudig voorbeeld maar het gaat erom dat je nu wat weet van GOSUB en RETURN omdat in de volgende cursusdelen de subroutine soms gebruikt gaat worden GOSUB zegt de PIC dat hij even langs een stuk programma moet lopen subroutine De RETURN aan het eind van de subroutine zegt dat hij weer terug moet gaan naar de plaats waar hij vandaan kwam Zowel voor de subroutines als voor het hoofdprogramma wordt het begin aangeduid met een label benaming Een label moet altijd met een letter beginnen en eindigen met een dubbele punt Kies duidelijke namen zodat je meteen weet wat die subroutine ook alweer doet Let op dat het label HoofdProgramma wat anders is dan de REM regel Hoofdprogramma die regelmatig als aanwijzing in de programmavoorbeelden stond Nesten Ook een GOSUB mag je nesten Met nesten van GOSUB s wordt bedoeld dat in een subroutine ook weer een GOSUB staat die naar een andere subroutine springt En ook in die subroutine kan weer een verwijzing naar wéér een andere subroutine staan enzovoort Nesten van GOSUB s kan dus alleen niet onbeperkt diep wat bij een lus wel mag Hóe diep je mag nesten is afhankelijk van het PIC type De PIC moet namelijk al die terugkeeradressen onthouden om zo later weer terug te kunnen keren naar de plaats waar hij vandaan kwam Zodra de PIC weer is teruggekeerd vergeet hij dit adres en is die plek weer vrij voor een nieuwe GOSUB Spring daarom ook nooit met een GOTO uit een subroutine maar doe dat altijd met een RETURN Als je met een GOTO uit de subroutine springt dan blijft de PIC het terugkeeradres onthouden terwijl hij al lang niet meer in de subroutine zit waardoor op een moment het stapelgeheugen volloopt stack overflow Een 14 bit PIC wat de PIC16F628A óók is kan maar 8 adressen onthouden Bovendien gebruikt de compiler daarvan al maximaal 4 niveaus voor zijn library bibliotheek subroutines dus ga nooit dieper nesten bij een PIC16F628 A dan 4 niveaus Bij een 16 bit PIC kan tot 28 niveaus diep genest worden Als je dieper gaat nesten dan mogelijk is dan vergeet de PIC zijn weg terug naar de allereerste GOSUB s Bedenk wel dat de beperking alleen voor het nesten geldt Je kunt dus gerust tientallen subroutines in een PIC16F628A programmeren GOTO Hoofdprogramma In tegenstelling tot de vroegere homecomputers waar de subroutines meestal onderin het programma werden geschreven wordt bij een PIC aanbevolen de subroutines juist zo hoog mogelijk in het programma te plaatsen Dit heeft te maken met hoe het geheugengebied van de PIC is opgebouwd Bij een klein programma zoals deze voorbeelden maakt het nog niet veel uit maar wel bij grotere programma s Daarom worden na de noodzakelijke instellingen met SYMBOL DIM CLEAR enzovoort eerst de subroutines geschreven en daarna pas het hoofdprogramma Het is daarom nodig om met de GOTO instructie over die subroutines naar het hoofdprogramma te springen omdat het programma anders meteen de subroutines induikt en de PIC een RETURN tegenkomt terwijl er nog geen GOSUB opdracht is geweest Het resultaat kan zijn dat de PIC rare onverwachte dingen gaat doen De instructie GOTO moet natuurlijk wel een punt oftewel een adres hebben waar hij naartoe kan springen Deze maak je door net als bij de subroutine een label te plaatsen op het punt waar het programma verder moet gaan In het voorbeeld heeft de label de naam HoofdProgramma gekregen maar dat had net zo goed PietJanHein kunnen zijn Zodra er in de volgende cursusdelen sprake is van een GOSUB dan zal er terplekke meer over de werking vertelt worden Onderstaand programma is een voorbeeld die is gebruikt bij de beschrijving van het nesten van FOR NEXT lussen zie hier Aangezien in dat voorbeeld de inhoud van de beide binnenste lussen precies hetzelfde zijn kunnen deze ook worden vervangen door GOSUB DEVICE 16F628A We gebruiken een 16F628A type CONFIG INTRC OSC NOCLKOUT WDT OFF PWRTE ON LVP OFF MCLRE OFF ALL DIGITAL TRUE Alle ingangen digitaal SYMBOL Vertraging 300 Vertraging van de binnenste lussen DIM Teller1 AS BYTE Teller1 is de lus teller van de buitenste lus DIM Teller2 AS BYTE Teller2 is de lus teller van de binnenste lus CLEAR Wis alle RAM geheugen DELAYMS 500 LCD stabilisering GOTO HoofdProgramma Spring over de subroutine Subroutine PrintTellers Deze subroutine zet Teller1 en Teller2 op het display PRINT AT 1 1 DEC2 Teller1 Zet de waarde van Teller1 op het display tellerstand PRINT AT 2 1 DEC2 Teller2 Zet de waarde van Teller2 op het display tellerstand DELAYMS Vertraging RETURN Ga terug naar waar je vandaan kwam HoofdProgramma Hier begint het hoofdprogramma CLS Wis display FOR Teller1 1 TO 5 Tel met Teller1 van 1 naar 5 FOR Teller2 0 TO 15 Tel met Teller2 van 0 naar 15 GOSUB PrintTellers Loop even langs het programmadeel in PrintTellers NEXT Teller2 verhogen en dan terug naar bijbehorende FOR FOR Teller2 15 TO 0 STEP 1 Tel met Teller2 terug van 15 naar 0 GOSUB PrintTellers Loop even langs het programmadeel in PrintTellers NEXT Teller2 verlagen en dan terug naar bijbehorende FOR NEXT Teller1 verhogen en dan terug naar bijbehorende FOR PRINT AT 1 1 Teller1 Teller1 Zet eindstand van Teller1 op displayregel 1 PRINT AT 2 1 Teller2 Teller2 Zet eindstand van Teller2 op displayregel 2 END Einde programma Ook als vaak de instructie RCIN in je programma voorkomt zie cursus deel 5 loont het om deze in een subroutine te zetten Bij RCIN moet je immers eerst de condensator ontladen met HIGH even wachten met DELAYMS en dan nog de instructie RCIN zelf Meten Potmeterinstelling meten HIGH PORTA 1 Condensator ontladen DELAYMS 1 Even wachten zodat condensator helemaal leeg is Weerstand RCIN PORTA 1 HIGH Geef RC oplaadtijd aan WORD variabele Weerstand RETURN Ga terug naar waar je vandaan kwam Zet deze subroutine bovenin je programma en je hoeft om de potmeterinstelling te meten alleen maar GOSUB Meten op die plaatsen neer te zetten waar anders steeds 3 programmaregels zouden moeten staan Als het programma dan is teruggekeerd vanuit de subroutine staat de actuele potmeterinstelling in de variabele Weerstand Het volgende onvolledige voorbeeld leest een 24 uurs

    Original URL path: http://www.picbasic.nl/beginners6.htm (2016-02-17)
    Open archived version from archive

  • PIC als SAA3049 vervanger
    een bepaalde code hoog of laag te maken verbinden met 5V of 0V reageert de PIC alleen als de afstandsbediening is ingesteld op dat ingestelde systeem De commando code op de pinnen C0 t m C6 wordt dan alleen doorgegeven als de systeemcode van de afstandsbediening hiermee overeenkomt Dus stel dat de PIC alleen op de toetsen mag reageren als de afstandsbediening op SAT staat ingesteld dan moet pin S3 met 5V worden verbonden en de overige vier systeempoorten met 0V De systeemcode die bij SAT hoort is namelijk 8 01000 Zie overzicht systeemcodes Opgelet als Mode pin 6 met GND is verbonden mogen de pinnen S0 t m S4 niet rechtstreeks zijn verbonden met 5V of GND Hierdoor kan de PIC onherstelbaar worden beschadigd omdat deze pinnen dan dus uitgangen zijn Om de schakeling waar de PIC wordt ingebouwd te kennen te geven dat er op de afstandsbediening wordt gedrukt en er een nieuwe code op de pinnen staat is pin 2 de CRI Command Received Indicator Eerst wordt de commando code en eventueel de systeemcode afhankelijk van Mode instelling op de betreffende uitgangen gezet Het CRI signaal verschijnt 0 3 milliseconde later Deze pin wordt hoog nadat de code op de uitgangen is gezet en weer laag als de toets op de afstandsbediening wordt losgelaten De code zelf blijft continu op de uitgangen staan totdat een nieuwe code is ontvangen Als Mode niet met GND is verbonden wordt CRI alleen hoog als het ingestelde systeem op de afstandsbediening overeenkomt met het ingestelde systeem op pinnen S0 t m S4 De Toggle pin 3 verandert steeds van niveau na iedere toetsindruk Het hoog of laag niveau wordt niet bepaald door de PIC maar door de afstandsbediening Deze poort is een open drain uitgang dat betekent dat als er van

    Original URL path: http://www.picbasic.nl/saa3049.htm (2016-02-17)
    Open archived version from archive



  •