Ik ben bezig met een prg voor de wikkelmachine. Daarin zit een aantal digitale poort controles als in
// Draadgeleider init
void Dgw(){
Serial.println("Ga naar sensor");
while (aR2 > sw) { dgf(); }
Serial.print("Stopwaarde is:");
Serial.println(aR2);
Serial.println("Ga naar Midden");
for (int d = 0; d < (350); d++){dgb(); }
Serial.println("Midden uitlijning O.K.?");
while (digitalRead(wstopPin) == HIGH {}
Serial.println("Naar begin 1e laag en bevestig draad.");
for (int d = 0; d < (lw/2); d++){dgf(); }
Serial.println("Controleer uitlijning draad en wikkellichaam.");
Serial.println("Begin met wikkelen, O.K.?");
while (digitalRead(wstopPin) == HIGH) {}
Met de while code wordt dus gewacht met vervolg tot wstopPin LOW is
Nu wilde ik daar behalve een 'goedkeur' ook een afkeur toets gebruiken op de poort op dstopPin.
// Draadgeleider init
void Dgw(){
Serial.println("Ga naar sensor");
while (aR2 > sw){Serial.println(aR2); dgf();}
Serial.print("Stopwaarde is:");
Serial.println(aR2);
Serial.println("Ga naar Midden");
for (int d = 0; d < (350); d++){dgb(); }
Serial.println("Midden uitlijning O.K.?");
while (digitalRead(wstopPin) == HIGH || dstopPin == HIGH){
if (digitalRead(wstopPin) == LOW) {
Serial.println("Naar begin 1e laag en bevestig draad.");
for (int d = 0; d < (lw/2); d++){dgf(); }
Serial.println("Controleer uitlijning draad en wikkellichaam.");
Serial.println("Begin met wikkelen, O.K.?");
while (digitalRead(wstopPin) == HIGH) {}
}
else if (dstopPin == LOW) {
Serial.println("Zet draadgeleider handmatig in het midden.");
Serial.println("Druk O.K als de draadgeleider in het midden staat.");
Serial.println("De draadgeleider gaat nu 30mm naar de sensor");
Serial.println("die wordt uitgelezen.");
for (int d = 0; d < (300); d++){dgf(); }
Serial.print("Nieuwe Sensorwaarde is:");
Serial.println(aR2);
sw = aR2;
Dgw();
}
}
}Echter de dstopPin doet niets met:
while (digitalRead(wstopPin) == HIGH || dstopPin == HIGH){
Het idee was dat als één van de pinnen laag wordt de while uit de lus komt met de OR. Maar niet dus.
Hoe doe ik dat?
KGE
Golden Member
Maar dan moet je wel && gebruiken ipv ||
Als beide hoog zijn dan mag de lus doorlopen en anders als één van de beide laag wordt moet de lus stoppen toch?
Ja, daar kwam ik achter toen beide poortjes geen reactie gaven. 
Nu werkt het wel. Ik heb de code nog wat aangepast:
#define wstopPin digitalRead(5)
#define dstopPin digitalRead(9)
#define aR0 analogRead(A0)
#define aR1 analogRead(A1)
#define aR2 analogRead(A2)
Dus nu kan ik wel met gewoon de variable werken.
// Draadgeleider init
void Dgw(){
Serial.println("Ga naar sensor");
while (aR2 > sw){dgf();}
Serial.print("Stopwaarde is:");
Serial.println(aR2);
Serial.println("Ga naar Midden");
for (int d = 0; d < (350); d++){dgb(); }
Serial.println("Midden uitlijning O.K.?");
while (wstopPin == HIGH && dstopPin == HIGH){}
if (wstopPin == LOW) {
Serial.println("Naar begin 1e laag en bevestig draad.");
for (int d = 0; d < (lw/2); d++){dgf(); }
Serial.println("Controleer uitlijning draad en wikkellichaam.");
Serial.println("Begin met wikkelen, O.K.?");
while (wstopPin == HIGH) {}
}
else if (dstopPin == LOW) {
Serial.println("Zet draadgeleider handmatig in het midden.");
Serial.println("Druk O.K als de draadgeleider in het midden staat.");
while (wstopPin == HIGH) {}
Serial.println("De draadgeleider gaat nu 35mm naar de sensor");
Serial.println("die wordt uitgelezen.");
for (int d = 0; d < (350); d++){dgf(); }
Serial.print("Nieuwe Sensorwaarde is:");
Serial.println(aR2);
sw = aR2;
Dgw();
}
}
if (wstopPin == LOW) {
...
while (wstopPin == HIGH) {}
Volgens mij doet die while niet veel. De kans dat wstopPin veranderd is tussen de if en de while is niet zo heel groot volgens mij.
En later gaat gebeurt hetzelfde met dstopPin.
benleentje
Golden Member
Dat doet precies wat het doen moet?
Als wstopPin laag is dan word dit blok met code uitgevoerd en aan het aan van dat blok met code word er gewacht totdat de pin weer hoog is. Of anders gezegd wstopPin moet wel veranderen want ander blijft het daar eeuwig wachten.
Van de while is het i.d.d. de bedoeling dat er gewacht wordt tot er een bepaalde actie is uitgevoerd. Zoals b.v. dat er gewacht wordt als de trekkracht te hoog is, tot de oorzaak daarvan verholpen is.
// Winding motor stap
void wstap() {
// These four lines result in 1 step:
digitalWrite(wstepPin, HIGH);
// delayMicroseconds (1/wKHz*1000);
// digitalWrite(wstepPin, LOW);
draadmeter();
if (aR0 >575){
Serial.println("STOP! Draadspanning te hoog");
while (wstopPin == HIGH) {}
}
digitalWrite(wstepPin, LOW);
}
benleentje
Golden Member
#define aR2 analogRead(A2)
Serial.println(aR2);
sw = aR2;Realiseer je wel dat hier 2 keer de analoge waarde van aR2 gelezen word en die heel verschillend kunnen zijn.
Beter is denk ik om ze om te draaien
sw = aR2;
Serial.println(sw);
while (aR2 > sw){dgf();}
Serial.print("Stopwaarde is:");
Serial.println(aR2);Hier print je een andere waarde voor aR2 dan waarmee je de while () ingaat.
Volgens mij is sw de stopwaarde en noem het dan ook stopwaarde ipv sw. Maar ipv de stopwaarde print je de actuele waarde. Op zich niet zo erg is meer een verbeter puntje denk ik.
Op zaterdag 19 juli 2025 18:22:22 schreef benleentje:
Dat doet precies wat het doen moet?Als wstopPin laag is dan word dit blok met code uitgevoerd en aan het aan van dat blok met code word er gewacht totdat de pin weer hoog is. Of anders gezegd wstopPin moet wel veranderen want ander blijft het daar eeuwig wachten.
??
Als wstopPin laag is dan komt ie inderdaad in het blok, maar dan racet hij ook ineen keer door de while. Dat lijkt mij toch niet de bedoeling?
Maar misschien blijft hij lang genoeg in de for-loop hangen, dat kan ik van hier niet zien.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
De volgorden tussen "==", "&&", "||" en "? .. : .." en zo is een beetje vaag.
Enerzijds kan ik het niet goed onthouden, anderzijds, doen sommige compilers het "verkeerdom". Dat zal wel een overblijfsel zijn uit vervlogen tijden, maar "niet onthouden" en "zeker weten" zijn belangrijk.
Dus ik heb de gewoonte om niet:
while (wstopPin == HIGH && dstopPin == HIGH){}
maar
while ( (wstopPin == HIGH) && (dstopPin == HIGH) ){}
te schrijven.
[Bericht gewijzigd door rew op (17%)]
while (wstopPin == HIGH && dstopPin == HIGH){}
if (wstopPin == LOW) {
Serial.println("Naar begin 1e laag en bevestig draad.");
...
while (wstopPin == HIGH) {}
}
...
}
Ik vind de geneste high,low,high vergelijkingen wat curieus. Ik denk dat het makkelijk fout gaat als de timing net verkeerd valt. In dit geval lijkt dat je bijna onmogelijk bij die "1e laag" komt.
De && while moet immers starten met wstop HIGH en dan exact 1 read later moet deze wstop LOW zijn.
Het is zoiets als een kaartje controleren een halve meter na het draaihekje. Ja er zal er 1 op de miljoen zijn die in die halve meter zijn kaartje verliest.
benleentje
Golden Member
De && while moet immers starten met wstop HIGH en dan exact 1 read later moet deze wstop LOW zijn.
Is dat wat DeKees bedoelde? Dat had ik inderdaad nog niet gezien.
IK zat me nog te concentreren op wat de "#define wstopPin digitalRead(5)" en de rest van de define's wel verstandig is. Of dat je niet verder in de problemen kan helpen omdat elke keer als je wstopPin gebruik hij altijd een digitalRead() doet terwijl dat soms niet de bedoeling is.
Het is zoiets als een kaartje controleren een halve meter na het draaihekje. Ja er zal er 1 op de miljoen zijn die in die halve meter zijn kaartje verliest.
Toch niet helemaal? Zolang beide voorwaarden hoog zijn blijft hij toch al die tijde in de While() hangen, en als je daar zo lang in blijft dan word de wstopPin echt wel een keer laag.
Of zoals in je analogie. Die ene bezoeker laat 1 miljoen keer zijn kaartje zien en moet dan gelijk weer terug behalve als hij zijn kaartje verliest. Of eigenlijk mogen alleen degene door die het kaartje naar 1 meter verliezen, Of zie ik dat verkeerd?
[Bericht gewijzigd door benleentje op (40%)]
Wel de code is niet erg gemakkelijk te lezen en daardoor wordt je snel op het verkeerde spoor gezet.
Hier dus ook: Let op de "{}" na de while(). Die is gemakkelijk te missen.
while (wstopPin == HIGH && dstopPin == HIGH){}
if (wstopPin == LOW)
benleentje
Golden Member
Had ik ook gemist vooral omdat de If daarna is ingesprongen lijkt het dus dat je na de While in dat blok gaat.
Maar volgens mij maakt het ook niet veel uit. OF je niet op de while wacht en daarna kijkt of wstopPin laag is of dat je dat continu in de while blijft doen. Tenminste ik zie geen verschil.
Ik denk zelf dat het laatste beter is dat de if in de while staat. Want datzijn de condities voor mij tenminste duidelijk. Maar goed is zou het denk ook niet op de manier programmeren.
Wel, zonder die haakjes komt hij alleen binnen de while als wstopPin HIGH is.
Die is dan dus niet LOW, dus dan gaat hij nooit in het if-blok, tenzij de status verandert precies tussen de while en de if.
Maar met de haakjes blijft hij in de while hangen totdat 1 van de 2 LOW wordt.
En daarna kun je dus testen welke dat is.
#define wstopPin digitalRead(5)
#define dstopPin digitalRead(9)
uint8_t ws, ds;
do
{
ws = wstopPin;
ds = dstopPin;
}
while ((ws == HIGH) && (ds == HIGH));
if ((ws == LOW) && (ds == HIGH)) {...}
else if ((ws == HIGH) && (ds == LOW)) {...}
else {...}
Op zaterdag 19 juli 2025 23:11:22 schreef deKees:
Wel, zonder die haakjes komt hij alleen binnen de while als wstopPin HIGH is.
Die is dan dus niet LOW, dus dan gaat hij nooit in het if-blok, tenzij de status verandert precies tussen de while en de if.Maar met de haakjes blijft hij in de while hangen totdat 1 van de 2 LOW wordt.
En daarna kun je dus testen welke dat is.
Mijn (simpele beginners) idee is/was dat de arduino dan niet al die code tussen de haakjes (accolades?) van de while hoeft uit te voeren.
Toen het nog niet werkte omdat ik die ene digitalRead vergeten was, had ik dat stuk code er wel tussen gezet omdat ik toen nog dacht dat dat de oorzaak was.
Verder is programmeren niet m'n sterkste kant en heb ik er weinig ervaring in.
De software is nu geschreven in termen die de processor vertelt wat hij doen. En het werkt, dus in dat opzicht is het project geslaagd.
Maar zoals gezegd is het niet gemakkelijk om te volgen wat er nu gebeurt. Meerdere mensen hebben bijv de krulhaakjes gemist. Om dat op te lossen kun je de zaak opsplitsen in functionele blokken. en een leesbare indentering toepassen. Dat kost niks, maar maakt de code al wel een stuk leesbaarder.
Dan krijg je bijv iets als dit - met alleen wat extra linefeeds en verplaatsen van haakjes:
#define wstopPin digitalRead(5)
#define dstopPin digitalRead(9)
#define aR0 analogRead(A0)
#define aR1 analogRead(A1)
#define aR2 analogRead(A2)
// Winding motor stap
void wstap()
{
// These four lines result in 1 step:
digitalWrite(wstepPin, HIGH);
// delayMicroseconds (1/wKHz*1000);
// digitalWrite(wstepPin, LOW);
draadmeter();
if (aR0 > 575)
{
Serial.println("STOP! Draadspanning te hoog");
while (wstopPin == HIGH)
{}
}
digitalWrite(wstepPin, LOW);
}
// Draadgeleider init
void Dgw()
{
Serial.println("Ga naar sensor");
while (aR2 > sw)
{ dgf();
}
Serial.print("Stopwaarde is:");
Serial.println(aR2);
Serial.println("Ga naar Midden");
for (int d = 0; d < (350); d++)
{ dgb();
}
Serial.println("Midden uitlijning O.K.?");
while (wstopPin == HIGH && dstopPin == HIGH)
{}
if (wstopPin == LOW)
{
Serial.println("Naar begin 1e laag en bevestig draad.");
for (int d = 0; d < (lw/2); d++)
{ dgf();
}
Serial.println("Controleer uitlijning draad en wikkellichaam.");
Serial.println("Begin met wikkelen, O.K.?");
while (wstopPin == HIGH)
{}
}
else if (dstopPin == LOW)
{
Serial.println("Zet draadgeleider handmatig in het midden.");
Serial.println("Druk O.K als de draadgeleider in het midden staat.");
while (wstopPin == HIGH)
{}
Serial.println("De draadgeleider gaat nu 35mm naar de sensor");
Serial.println("die wordt uitgelezen.");
for (int d = 0; d < (350); d++)
{ dgf();
}
Serial.print("Nieuwe Sensorwaarde is:");
Serial.println(aR2);
sw = aR2;
Dgw();
}
}
Zelf zou ik nog wel een paar stappen verder gaan, en termen gebruiken die aangeven wat nu eigenlijk de bedoeling is, en minder in termen die aangeven wat de processor moet doen om dat voor elkaar te krijgen.
Bijv:
wstopPin blijkt een OkButton te zijn. Die kun je dan ook zo noemen.
Funktienamen Dgw(), dgf() dgb() zeggen mij niks. Daar zou ik andere namen voor gebruiken.
aR0 aR1 aR2 zeggen mij ook niks. Wat probeer je daar te meten?
Je gebruikt een paar keer
while (wstopPin == HIGH)
{}
Daar zou ik dan een funktie voor maken:
void WaitForOkButton()
{ while (wstopPin == HIGH)
{}
}
.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Over het leesbaarder maken...
Vaak zijn er knoppen voor users en schakelaars om "einde beweging" te signaleren. Daar is het signaal dan laag als de gebruiker op de knop drukt of de mechanica bij het eind.
Wat jij in een define stopt is het lezen van de pin en gaat dan in de main code met == HIGH en == LOW werken.
Mijn voorstel is om met een define (of gewoon functie)(*) ergens te "verstoppen" dat het signaal laag is (of niet) als er op die knop gedrukt is.
je krijgt dan code
// wacht zolang 1 van beide knoppen ingedrukt is.
while (stopbuttonpressed () || startbuttonpressed () ) {}
Merk op dat het ook ineens veel leesbaarder wordt als je de bedoeling van de code in een comment zet.
Die "lege lus" kan je ook doen met een ; (puntcomma) ipv {}. Als je die dan in z'n eentje op de volgende regel zet, dan is het duidelijker dat er niets in de lus zit. Of je kan je comment: "doe niets terwijl we wachten op loslaten" daar zetten.
(*) Een moderne compiler ziet dat een functie maar zeer kort is en zal hem vanzelf inlinen als dat sneller is.
Vergeet ook niet om je schakelaars te ontdenderen. Kan in hardware met een filtertje of in software. In software kun je een teller laten oplopen als de pin hoog is, en laten aflopen als de pin laag is. Bereikt de teller een bovengrens, bijvoorbeeld 10, dan is de pin definitief hoog. Bereikt de teller 0 dan is de pin definitief laag. Het mooiste is als je de pin sampled in een timer interrupt, dan is het gedrag altijd hetzelfde. Maar in de arduino wereld is het volgens mij meer gebruikelijk om dat gewoon in de main lus te doen... met af toe wat onvoorspelbaar (maar geaccepteerd?) gedrag tot gevolg.
Ik had e.e.a. aangepast met als gevolg dat het nu niet meer, of nog slechter
werkt dan voorheen.
Ik ga de gehele code van nul af aan opnieuw schrijven met alle tips en adviezen. 
Wel jammer dat het niet meer werkt.
Maar dat is inderdaad wel het risico van elke wijziging, dan kun je wel eens iets over het hoofd zien.
Meestal is het dan puzzelen om te vinden waar het mis gaat. Helemaal opnieuw beginnen is dan wel erg drastisch.
Maar ik heb wel ooit een printer-driver opnieuw geschreven omdat er een bug inzat die we niet konden vinden. Die nieuwe driver had precies dezelfde bug die we toen wel konden oplossen doordat we wisten bij welke wijziging het weer misging.
Op zaterdag 19 juli 2025 21:33:29 schreef K7Jz:
while (wstopPin == HIGH && dstopPin == HIGH){} if (wstopPin == LOW) { Serial.println("Naar begin 1e laag en bevestig draad."); ...Ik vind de geneste high,low,high vergelijkingen wat curieus...
Inderdaad ik was gefopt door het inspringen van die regel onder de while na het niet opmerken van de {}.
Balen dat het niet meer werkt. Gewoon rustig opnieuw beginnen, niets aannemen, veel naar de Serial printen. De genoemde tips van rew en deKees (leesbare heldere functienamen, buttonXPressed() zijn absoluut aan te raden. Ik hou het zelf graag ook volledig engels tenzij het displayuitvoer is voor een zeer beperkte ééntalige doelgroep is.
De while(){} truuk belemmert je iets anders met de controller te doen. Niet erg, maar ook debugging kan lastig worden omdat je niet weet waar de controller nu hangt als je meerder van die loopjes hebt.
while( ! buttonXPressed ) { SerialPrint "buttonX not pressed" } // zoiets kan kan verhelderend zijn (krijg je wel veel serial text van, eventueel kleine delay toevoegen).
Bedenk ook dat elke programmeur elke keer weer ook zijn eigen code opnieuw zou kunnen schrijven, dus de perfect code waar iedereen stil van is bestaat denk ik niet 
Op maandag 21 juli 2025 11:30:37 schreef deKees:
Wel jammer dat het niet meer werkt.Maar dat is inderdaad wel het risico van elke wijziging, dan kun je wel eens iets over het hoofd zien.
Meestal is het dan puzzelen om te vinden waar het mis gaat. Helemaal opnieuw beginnen is dan wel erg drastisch.
Maar ik heb wel ooit een printer-driver opnieuw geschreven omdat er een bug inzat die we niet konden vinden. Die nieuwe driver had precies dezelfde bug die we toen wel konden oplossen doordat we wisten bij welke wijziging het weer misging.
Het deel voor deel opnieuw schrijven heeft wel als voordeel dat ik nieuwe inzichten er in kan verwerken.
Dus stap voor stap zou het goed moeten komen. 
Bij deze vast de eerste resultaten. Ik heb i.i.g. zo goed mogelijk op die inspring gelet. 
// Wikkelmachine besturing versie 2.0
// Definieer (stepper)motor, steps per 360 graden,
// sensor aansluitingen en stuursignalen.
#include <EEPROM.h>
#define windingrichting 2
#define windingenable 3
#define draadrichting 4
#define draadenable 5
#define stap 6
#define hardwarefout digitalRead(7)
#define draadmeter_A 8 digitalRead(8)
#define draadmeter_B 9 digitalRead(9)
#define draadtensiesensor analogRead(A0)
#define draadreferentie analogRead(A1)
#define Steps 6400
int positiewaarde = 0;
float wikkellichaam_MM = 30.00;
int totaalwindingen = 5000;
int draaddiameter = 100;
int wikkellichaam = wikkellichaam_MM * 1000;
int laagwindingen;
int wikkellagen;
int restantwikkelingen;
void setup() {
Serial.begin(9600);
EEPROM.get(0,positiewaarde);
//Declare pins als output or input:
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
pinMode (4, OUTPUT);
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
pinMode (7, INPUT_PULLUP);
pinMode (8, INPUT_PULLUP);
pinMode (9, INPUT_PULLUP);
berekendata();
printsetupdata();
}
void berekendata () {
laagwindingen = wikkellichaam / draaddiameter;
wikkellagen = totaalwindingen / laagwindingen;
restantwikkelingen = totaalwindingen % laagwindingen;
}
void stepping() {
for (int s=0; s < Steps;) {
digitalWrite(stap, HIGH);
delayMicroseconds(20);
digitalWrite(stap, LOW);
s++;
}
}
void printsetupdata () {
Serial.print("Totaal aantal windingen ");
Serial.print(totaalwindingen);
Serial.println(" op een ");
Serial.print("wikkellichaam van ");
Serial.print(wikkellichaam_MM);
Serial.println(" millimeter.");
Serial.print("De draaddiameter is ");
Serial.print(draaddiameter);
Serial.println(" micrometer.");
Serial.println();
Serial.print("Het aantal wikkellagen is ");
Serial.print(wikkellagen);
if (restantwikkelingen != 0) {
Serial.print(" plus 1");
wikkellagen++;
}
Serial.println(".");
Serial.print("Het aantal windingen per laag is ");
Serial.print(laagwindingen);
Serial.println(".");
Serial.println();
if (restantwikkelingen != 0) {
Serial.print("Het aantal restantwikkelingen is ");
Serial.println(restantwikkelingen);
Serial.println("windingen op één extra laag.");
Serial.print("Het aantal wikkellagen is nu ");
Serial.print(wikkellagen);
Serial.println(".");
}
}
void loop() {
digitalWrite(windingrichting, LOW);
digitalWrite(windingenable, HIGH);
for (int w=0; w < totaalwindingen;) {
stepping();
w++;
}
digitalWrite(windingenable, LOW);
while (hardwarefout == HIGH);
delay(1000);
}