Waarom voert een 16F886 random deze flankdetectie niet uit ondanks aan de voorwaarde is voldaan?
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN
INC Teller
IF Teller = 100 THEN
CLEAR Teller
ENDIF
ENDIF
SW_1Hz_Prev = SW_1HzHet signaal komt van een CD4521 aan een ST ingang van de 16F886.
Hoe ziet de rest van het programma eruit?
Ik zie maar een klein stukje. Misschien clear je de teller voordat je naar de waarde van de teller kijkt.
Waar komt die SW_1Hz vandaan?
Op vrijdag 2 januari 2026 20:54:14 schreef EgbertG:
Maak er >= 100 van ... ik vermoed dat Teller wordt verhoogd in een ISR?
Dat is sowieso een goede verbetering. Testen of teller de waarde 100 heeft is in deze situatie gewoon fout.
Het If statement wordt random niet uitgevoerd zodat Testpunt niet toggled.
Een 1Hz bloksignaal van een CD4521 output staat op een ST ingang van de mcu genoemd SW_1Hz
Zelfs bij enkel deze code is het euvel aanwezig. Geen Interrupt
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN
TOGGLE TestPunt
ENDIF
SW_1Hz_Prev = SW_1Hzfatbeard
Honourable Member
Een goed begin is geen excuus voor half werk; goed gereedschap trouwens ook niet. Niets is ooit onmogelijk voor hen die het niet hoeven te doen.
moet die vergelijing niet zijn
IF SW_1Hz XOR SW_1Hz_Prev THENAls alternatief kun je gebruik maken van een interrupt-on-chage, als die tenminste voor die pin beschikbaar is.
nonius
set SCE to AUX.
Klopt het dat er alleen op een neergaande flank wordt gedetecteerd? Genereert de hardware niet een opgaande flank?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Houd er ook rekening mee dat de logische '1' levels van S/T pinnen hoog ligt (0.8*Vdd), haal je dat wel?
De XOR is een leuke tip voor zowel op- als afgaande flank te detecteren.
De ST drempels zijn 1V en 4V die met CMOS uitgang van CD4521 los gehaald worden.
Maar ik ga het controleren.
Met een Led1 = SW_1Hz en Led2 = SW_1Hz_Prev net voor het If statement waarbij hun status weergeeft dat het resultaat True is wordt de bijhorende instructie toch niet uitgevoerd.
Lijkt er op dat er soms wat mis gaat tijdens de mcu cyclussen tussen de instructie SW_1Hz_Prev = SW_1Hz en het If-statement.
Ik zie het voorlopig niet.
Ga vanavond wat verder experimenteren.
Ik ken die 16F886 niet, maar kun je niet gewoon instellen dat er alleen een interrupt wordt afgevuurd op een neergaande flank op de ingang? Dan hoef je daar niet op te controleren in de ISR.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Op vrijdag 2 januari 2026 22:39:37 schreef OXO:
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN TOGGLE TestPunt ENDIF SW_1Hz_Prev = SW_1Hz
Dit gaat ALTIJD zo nu en dan fout. Je moet IN de ifstatement de "oude versie" opslaan, Nu kan de "SW_1Hz" van 0 naar 1 gaan NA de if en VOOR de SW_1Hz_Prev = SW_1Hz.
Dus:
curSW = SW_1Hz
IF curSW = 0 AND SW_1Hz_Prev = 1 THEN
TOGGLE TestPunt
ENDIF
SW_1Hz_Prev = curSWAls ie nu tussen de if en de assignment verandert, dan pak je hem de volgende keer.
Het binnen de IF updaten van de "prev" waarde werkt als je beide flanken pakt:
curSW = SW_1Hz
IF curSW != SW_1Hz_Prev THEN
TOGGLE TestPunt
SW_1Hz_Prev = curSW
ENDIFOp zaterdag 3 januari 2026 18:39:35 schreef rew:
[...]Dit gaat ALTIJD zo nu en dan fout. Je moet IN de ifstatement de "oude versie" opslaan, Nu kan de "SW_1Hz" van 0 naar 1 gaan NA de if en VOOR de SW_1Hz_Prev = SW_1Hz.
???
Gaat het altijd fout of gaat het zo nu en dan fout?
Hoezo kan "SW_1Hz"veranderen van waarde na het if-statement? Er is geen enkele tussenliggende instructie die dat regelt. 
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN
TOGGLE TestPunt
ENDIF
SW_1Hz_Prev = SW_1Hz
Goed gezien van rew.
SW_1Hz is de status van de pin, dus die wordt door hardware aangestuurd.
Dus als je vaak genoeg bovenstaande code uitvoert dan kan het zomaar gebeuren (dwz dan komt er gegarandeerd ooit een moment) dat SW_1Hz nog hoog is op het moment van de if, en laag op het moment van de update van SW_1Hz_Prev. Dan heb je dus een flank gemist.
Je moet de update wel buiten de if doen om ook de andere flank te detecteren.
Maar inderdaad eerst een copietje maken en die copie gebruiken zowel voor de if als voor de update van SW_1Hz_Prev.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Het ingangsniveau is niet het issue.
Een TTL poort ipv een ST poort helpt ook niet.
Dit werkt dus voor geen meter
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN
TOGGLE TestPunt
ENDIF
SW_1Hz_Prev = SW_1Hz Zodra er genoeg delay (of genoeg code) bijkomt gaat het wel goed.
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN
TOGGLE TestPunt
ENDIF
SW_1Hz_Prev = SW_1Hz
DELAYUS 1000 En de analyse van REW is er boenk op, werkt feilloos
Mb_SW_1Hz = SW_1Hz
IF Mb_SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN
TOGGLE TestPunt
ENDIF
SW_1Hz_Prev = Mb_SW_1Hz
En het is niet de eerste keer dat dit me parten speelt.
Bij een eerder project was er ook een sporadisch probleem dat ik enkel kon herleiden tot een issue met een flankdetectie.
Nooit gevonden waarom en de code van het project dan maar herschreven zonder er flankdetectie te gebruiken.
Dus mensen die flankdetectie willen gebruiken ... denk hieraan
En er zijn inderdaad meerdere en simpelere wegen naar Rome 
Zodra er genoeg delay (of genoeg code) bijkomt gaat het wel goed.
IF SW_1Hz = 0 AND SW_1Hz_Prev = 1 THEN TOGGLE TestPunt ENDIF SW_1Hz_Prev = SW_1Hz DELAYUS 1000
Dat klopt niet helemaal. Het gaat nu nog steeds af en toe fout. De delay lost het probleem niet op.
Het zorgt er wel voor dat de kans dat het fout gaat kleiner wordt, dus dan gaat het ´tamelijk vaak´ goed. Maar dus niet altijd.
En korte pulsen worden dan volledig gemist. Dat wil je ook niet.
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
En precies hoe hadden wij moeten weten dat die "SW_1Hz" een live waarde van iets was? Ik dacht gewoon een variabele die ergens anders geschreven wordt (aan het begin van een loop of zo), basic kent toch geen macro's?
Als het nu C was zou ik gevraagd hebben of dat niet stiekem een macro was.
Goede vraag. Dat kun je niet zien aan het code fragment.
En ik heb trouwens ook geen verstand van Basic met al zijn dialecten. Ik weet niet eens welke basic dit is.
Eigenlijk kun je het alleen afleiden uit het feit dat er pulsen gemist worden met dit stukje code.
Op zaterdag 3 januari 2026 21:35:56 schreef SparkyGSX:
En precies hoe hadden wij moeten weten dat die "SW_1Hz" een live waarde van iets was?
Dat is ook precies de reden dat ik om de rest van het programma vroeg. Die paar regeltjes code zijn gewoon goed.
Ik zag de bui al hangen en had al een vermoeden dat SW_1Hz op een onfrisse manier gemaakt werd. PIC-basic laat dat toe en met macro's of define's in C kan je dit soort nare ongein ook maken.
Voor OXO en andere PIC-basic programmeurs:
Lees één keer in het begin van je programma bij elkaar alle inkomende signalen in en stop ze in (static) variabelen. Gebruik geen #define's of macro's
Gebruik in het programma de variabelen. Die blijven nu de gehele machineslag ongewijzigd.
Stuur op het eind van je programma bij elkaar in één keer alle uitgangssignalen aan vanuit (static) varariabelen.
Dan ben je van dit soort nare ongein af.
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Voordat ik de post van 'rew' zag had ik ook al gezien dat het aan de SW_1Hz lag.
In de 1-ste post staat het namelijk: Het signaal komt van een CD4521 aan een ST ingang van de 16F886.
Dat is ook een reden waarom in graag pinnen PIN_xxxx noem. Waarbij in dit geval xxxx bijvoorbeeld "1Hz" is.
Design rules en naming conventions zijn zo gek nog niet.
Op zaterdag 3 januari 2026 22:08:51 schreef ohm pi:
Ik zag de bui al hangen en had al een vermoeden dat SW_1Hz op een onfrisse manier gemaakt werd.
Dit noem ik niet onfris, het is maar net hoe je het bekijkt.
PIC-basic laat dat toe en met macro's of define's in C kan je dit soort nare ongein ook maken.
Daar is niks mis mee, mits je het niet te bont maakt (daarmee bedoel ik hele stukken code in een macro proppen).
Voor OXO en andere PIC-basic programmeurs:
Lees één keer in het begin van je programma bij elkaar alle inkomende signalen in en stop ze in (static) variabelen. Gebruik geen #define's of macro's
Gebruik in het programma de variabelen. Die blijven nu de gehele machineslag ongewijzigd.
Stuur op het eind van je programma bij elkaar in één keer alle uitgangssignalen aan vanuit (static) varariabelen.
Dan ben je van dit soort nare ongein af.
Dat is wat een PLC ook doet: input cycle, afhandeling programma, output cycle, background tasks etc.
Op zich niks mis mee. (arduino style loop programming dus)
Maar het hangt heel sterk af wat je precies wilt. Een sequentiele executie is niet altijd wat je wilt.
Op zaterdag 3 januari 2026 22:09:26 schreef henri62:
Een sequentiele executie is niet altijd wat je wilt.
Om programma's te schrijven die werken met niet-sequentiële executies ben ik niet slim genoeg voor.
Op zaterdag 3 januari 2026 22:09:26 schreef henri62:
[...] Dit noem ik niet onfris, het is maar net hoe je het bekijkt.
Het programma doet dingen die een buitenstaander niet verwacht. Dat noem ik onfris programmeren. Maar er zijn wedstrijden wie bijvoorbeeld de kortste programma's kan schrijven. Daar is alles toegestaan. Het gevolg is wel dat zo'n programma onleesbaar is.
[Bericht gewijzigd door ohm pi op (45%)]
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Er zijn zelfs wedstrijden voor het schrijven van het meest onleesbare programma, en voor programma's die er onschuldig uitzien maar intussen iets vervelends doen.
Mijn gouden regel is dat macros en andere #defines volledig uit hoofdletters bestaan, dan is het direct duidelijk dat het niet zomaar een variabele is. Daarnaast moet je bij globale variabelen op bedacht zijn, als ze volatile zijn gedeclareerd, dat ze mogelijk ergens in een ISR gewijzigd kunnen worden; daarvoor moet de programmeur dus een mechanisme voorzien om problemen te voorkomen. Dat kan zo simpel zijn als interrupts uitzetten, snel alles wat je nodig hebt kopiëren, en de interrupts terug aanzetten.
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Op zaterdag 3 januari 2026 22:29:18 schreef ohm pi:
[...]Om programma's te schrijven die werken met niet-sequentiële executies ben ik niet slim genoeg voor.[...]Het programma doet dingen die een buitenstaander niet verwacht. Dat noem ik onfris programmeren. Maar er zijn wedstrijden wie bijvoorbeeld de kortste programma's kan schrijven. Daar is alles toegestaan. Het gevolg is wel dat zo'n programma onleesbaar is.
Puur sec is alles (mits op 1 CORE) seqentieel. 
Wat ik bedoel is dat je ook multithreading (RTOS) en interrupts kunt gebruiken. Dan gaat het niet meer lukken om alles (simpel) in 1 loop te stoppen met een in/output cycles etc.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Wat ik al zei:
Voor een betrouwbare werking heb je een (IOC) interrupt nodig, dan mis je nooit meer pin changes. Met delays is een onbetrouwbare boel.
Ik kan het weten, ik heb al heel veel van die pulstest firmware ontwikkeld in de loop der tijd, met delays is het altijd huilen...
(En je houdt de processor onnodig heel erg bezig...)
