@sterretje wat vindt jij van de code ?
Wil je antwoord #13 (klik !) nog eens doorlezen ?
Daar staan voorstellen in om dit efficiënter te doen, en ook meer voorstellen die voor de toekomst gebruikt kunnen worden.
Je bedoeld dit stukje :
Eerder had ik het ook al over basic wiskunde.
Dat kun je gebruiken voor de richting en voor de snelheid.
Ook hiervoor gebruiken we het geheugen.
We maken dus ook variabelen en ik zou dan spd voor snelheid en dir voor richting gebruiken, maar daar mag je zelf namen voor bedenken die jij handiger vind.
Je hoeft nu aan dir maar 2 waarden toe te kennen, te weten 1 of -1.
Vervolgens hoog je currentLed op met de waarde uit dir.
Daarna kun je nog een snelheid gaan verwerken.
Dat kun je doen door iets te bedenken (kan misschien wel op verschillende manieren) waardoor je niet alleen bepaalt of de knop links of rechts van het midden zit, maar ook hoe ver.
Het resultaat daaruit kun je schalen (dat heb je al eerder toegepast meen ik) naar bruikbare waardes en die vermenigvuldig je vervolgens met een basiswaarde waarvan dat resultaat dan weer in spd terecht komt.
spd bepaalt vervolgens de vertraging tussen tussen het eind van loop() en het begin van de volgende stap.
De uitdaging die daarna zou kunnen komen, is dit dan weer op de blink without delay manier te doen.
Zie even niet hoe -1 en 1 meer efficient kunnen werken als de if then's die ik nu gebruik.
Snelheid wil ik pas doen als ik hier helemaal tevreden over ben.
Hetzelfde met het herschrijven naar blink zonder delay
Dan heb je me niet begrepen.
Ook dit voorstel is met het oog op de toekomst bedacht.
Je maakt nu telkens een beslissing of je meer of minder gaat doen en schrijft daar dan een stuk code voor.
Maar wanneer je eerst bekijkt of je meer of minder wil doen en daar een waarde voor opslaat, kun je de afhandeling in een paar regels doen die je niet hoeft te herhalen.
Dan hoef je dus niet meer -- of ++ te doen, maar tel je de waarde van die variabele op bij currentLed.
Wanneer je een negatieve waarde optelt, wordt het resultaat dus niet groter, maar kleiner (en dat is dus een stukje basis wiskunde).
Je kunt dan ook in 2 opeenvolgende regels controleren of je een negatieve of een positieve overflow krijgt, en die afhandelen.
Daarmee win je dan dus overzicht en is de code efficiënter.
Dankzij deze aanpak zit hier ook nog een stukje toekomst is, maar daar gaan we nu nog even niet verder op in.
Ik hoop dat je dit begrijpt en kunt verwerken in je huidige code.
Post nummer 13 is dus met veel mogelijkheden voor toekomstige uitbreidingen bedacht en wanneer je dit na afloop nog eens doorleest zul je zien dat daar al veel meer of minder subtiele aanwijzingen in zitten.
Oke
Zo zoiets als dit :
if (Potvalue < 512)
{
richting = 1
} else {
richting = -1
}
currentLed += richting
if (currentLed == sizeof(ledPins))
{
currentLed = 0;
}
if (Potvalue > 512) {
if (currentLed == 0) {
currentLed = sizeof(ledPins) -1 ;
}
}
Zie niet hoe dit zaken efficienter maken.
Zie alleen maar meer en meer code die eigenlijk hetzelfde doet , als mijn "oude" code.
Subtiele aanwijzingen helpen bij mij helaas niet. Heb zoals ik al gezegd heb, autisme en ben heel slecht in de vinden en begrijpen van subtiele aanwijzingen
Ja die aanpassing die je zojuist gemaakt hebt, had je dus al in je code maar staan nu gewoon naast elkaar.
Veel meer overzicht dus.
Deze code is ook een heel stuk compacter dan de code die je eerder had.
Oke
Dus veel meer kleinere stappen.
Zit ik op een goed spoor met mijn nieuwe code ?
Dit stukje ziet er goed uit.
Pas het maar eens toe in je simulatie.
Neem maar even voor lief dat de simulator de LEDs niet werkelijk afbeelden als wat je zou zien met echte LEDs.
Er zit nog ergens een fout in als de waarde van de potmeter groter dan 512 is.
Dan lijkt er helemaal niks te gebeuren als in geen leds gaan branden.
Dat klopt ook met de code die je daar toont, je doet niets met currentLed op dat moment.
Zet de regel waar je wel wat doet met currenLed helemaal nadat je de beide richtingen hebt bekeken en niet daar tussenin.
Dus om het overzicht te behouden, gaan we vanaf nu proberen om eerst dingen klaar te zetten.
Daarna gaan we ze pas uitvoeren.
Sommige dingen moet je wel na elkaar doen en soms ook in een bepaalde volgorde, maar voor de meeste dingen is dat niet zo.
Als je wil kan ik daarvoor een paar aanwijzingen als commentaar regels zetten in je huidige code, maar dat doe ik niet meteen omdat ik moe ben van te veel werken en het wel goed wil doen.
Kan zijn dat dat pas aankomend weekend wordt.
Dank je
Had ik ook al bedacht toen ik afdrukte wat currentLed was .
Dit lijkt te werken:
// Alle pinnen van de leds
const uint8_t ledPins[] = { 9, 11, 10, 6, 3, 5 };
// de pin van de potmeter
byte Potpin = A3;
// de waarde die de potmeter aangeeft
int Potvalue;
// geeft de richting aan waar de led moeten draaien.
byte richting;
// houdt de index bij van de huidige brandende led
byte currentLed = 0;
// houdt de index bij van de eerste led van de staart
byte trail1 = 0 ;
// houdt de index bij van de tweede led van de staart
byte trail2 = 0 ;
// houdt de index bij van de derde led van de staart
byte trail3 = 0;
void setup()
{
// Zet de seriele monitor aan
Serial.begin(115200);
for (uint8_t cnt = 0; cnt < sizeof(ledPins); cnt++)
{
// Zet alle leds uit
analogWrite(ledPins[cnt], 0);
// Zet de pin mode op output
pinMode(ledPins[cnt], OUTPUT);
}
}
void loop()
{
// Lees de waarde van de potmeter
Potvalue = analogRead(Potpin);
////////////////////////
// aansturen LEDs
////////////////////////
// Zet de led die de index currentLed heeft aan.
analogWrite(ledPins[currentLed], 255);
analogWrite(ledPins[trail1], 117);
analogWrite(ledPins[trail2], 54);
analogWrite(ledPins[trail3], 25);
delay(200);
analogWrite(ledPins[trail1],0);
analogWrite(ledPins[trail2],0);
analogWrite(ledPins[trail3], 0);
trail3 = trail2;
trail2 = trail1;
trail1 = currentLed;
if (Potvalue < 512)
{
richting = 1;
} else {
richting = -1;
}
if (currentLed == sizeof(ledPins))
{
currentLed = 0;
}
if (Potvalue > 512) {
if (currentLed == 0) {
currentLed = sizeof(ledPins) -1 ;
}
}
currentLed += richting;
}
Maar nog steeds niet helemaal het effect wat ik in mijn hoofd heb.
Zie nog steeds een lampje uitgaan en de andere aan waar ik in mijn hoofd heb dat het meer op de lijn beweegt als een soort rups.
Ziet er toch bijna goed uit, maar nog niet helemaal.
Afhankelijk van de richting die je nu op gaat (dat werkt dus), brandt de eerste of de laatste LED nooit.
Daar is wat te verbeteren, en dat heeft te maken met de controle op currentLed overflow.
Die waarde wordt aangepast wanneer de eerste of de laatste waarde is bereikt.
Maar dan wordt die eerste of laatste waarde die wel wel willen hebben dus nooit verwerkt.
Dus moeten we niet controleren of we aan de grens komen, maar of we over de grens zijn gegaan, en daarna pas aanpassen.
Alleen kan een byte geen negatieve waarde worden en dan zou het daar weer fout gaan (dan loopt er echt iets vast).
Hier moet ik even heel goed over nadenken.
Eerste idee was dit :
if (Potvalue < 512)
{
richting = 1;
} else {
richting = -1;
}
if (currentLed > sizeof(ledPins))
{
currentLed = 0;
}
if (Potvalue > 512) {
if (currentLed < 0) {
currentLed = sizeof(ledPins) -1 ;
}
}
maar dan brandt de eerste of laatste nog steeds niet.
Nee, ik zie het niet.
Kan iemand me helpen ?
Edit1 : Heb net currentLed uitgeprint en het is nu 1 t/m 7.
Dus het moet wel gelijk aan teken(==) zijn.
Maar dan zie ik even niet waarom het laatste of eerste lampje niet aangaat.
Hier moet ik nog even op terugkomen, want het klopt niet helemaal.
Daar heb ik nu geen tijd voor, moet zo gaan werken.
Maar het is wel van belang dat je dingen in de juiste volgorde doet en dat gebeurt nu nog niet helemaal.
Ik heb jouw simulatie beter laten werken door de volgorde aan te passen.
En door rekening te houden met het feit dat een byte niet negatief kan worden.
Daarna zag ik nog een dingetje dat dan nog steeds niet klopt en waar ik nog niet helemaal uit ben dus daar moet nog even over nagedacht worden.
Meer over dit alles later, zou kunnen zijn dat dat pas in het weekend gaat lukken (sorry daarvoor).
Oke
Wacht ik even op wat de juiste volgorde is en wat er dan nog steeds niet klopt en hoe dat op te lossen.
Lange werkdag gehad en wat teveel stress vandaag.
Maar ook een uur of 3 gereden, en dat is een goed moment voor mij om eens te mijmeren over dingen.
Ik denk nu dat een paar stappen terug alles wel correct was, maar de volgorde niet helemaal.
De LED die aan of juist uit blijft, is wel verklaarbaar.
Want die LED zit aan het begin of aan het eind, en dan moet dat met je overflow controle te maken hebben.
We hogen de waarde van currentLed op, en controleren dan of deze gaat overlopen, of later of deze al overgelopen is.
Wanneer dat dan zo blijkt te zijn, wordt deze waarde meteen aangepast naar de nieuwe waarde die we verwachten.
Dus 0 of 6.
Maar daarmee slaan we dus wel wat over.
De volgorde moet dus eigenlijk zijn hoog currentLed op.
Zet de volgende stap in het oplichten van de betreffende LED(s).
De controle moet nu niet meer zijn is dit de laatste LED, maar moet worden was het de laatste LED.
Daarmee verhinder je dan dus niet meer dat de laatste stap gezet wordt, wat voorheen wel zo was.
Ik zag ook nog wat anders tijdens het aanpassen van jouw code in Wokwi, om dit alles nader te onderzoeken.
Namelijk dat dan de ene kant op alles correct werkte, en de andere kant op niet.
Dan werd er 1 rondje gemaakt, en bleef daarna de laatste LED hangen in de laagste helderheid.
Ik denk dat dat komt doordat we 2 limieten controleren, en wanneer we daar aankomen, een stap zetten naar de limiet aan de andere kant.
Dus gaan we naar nul, en wanneer we daar aankomen zetten we 'm op 6.
Vervolgens kijken we of we op 6 zitten, en wanneer dat zo is, zetten we 'm op 0.
En daarmee hebben we dan onszelf opgesloten in een situatie waar we pas uitkomen als we de andere kant op gaan bewegen.
De oplossing daarvoor is niet 2 keer naar 1 voorwaarde te kijken, maar 1 keer naar 2 voorwaarden.
Daarmee bedoel ik dan we kijken als we linksom draaien (das de eerste voorwaarde), of we op de nul zijn aangekomen (en dat de 2e voorwaarde).
Dat kan op 1 regel door het controleren van 2 voorwaarden in 1 opdracht (dan koppel je dus beide voorwaarden, en dat doe je met &&.
Ik hoop dat je hier begrijpt wat ik bedoel.
Ik ga nog even nadenken over de volgordes en hoe we die mooi gestructureerd kunnen neerzetten zodat het er een stuk overzichtelijker gaat uitzien.
IK heb je denk ik toch niet helemaal begrepen
Heb de code verandert naar :
f (Potvalue < 512)
{
richting = 1;
} else {
richting = -1;
}
if (richting = 1 && currentLed > sizeof(ledPins))
{
currentLed = 0;
}
if (richting == -1 && currentLed < 0) {
currentLed = sizeof(ledPins) -1 ;
}
Maar nu is er helemaal geen beweging meer ![]()
oke
Met deze code :
if (Potvalue < 512)
{
richting = 1;
} else {
richting = -1;
}
if (richting = 1) {
if (currentLed > sizeof(ledPins)) {
currentLed = 0;
}
}
if (richting == -1) {
if (currentLed < 0) {
currentLed = sizeof(ledPins) -1 ;
}
}
maar wordt led met de index 0 naar beide kanten overgeslagen.
heb je nog ideeën hoe dit op te lossen
Ben net thuis van werk, dus weer veel te lang bezig geweest en deze week daardoor teveel gesloopt.
Wat ik in mijn vorige antwoord vertelde, is dat we niet meer gaan kijken of we onder de nul of boven sizeof(ledPins) uitkomen, maar of we daar precies op zitten.
En dat we dat doen als we de juiste richting op gingen.
Wat ik niet weet, is of we bij nul naar richting 1 of naar richting -1 moeten kijken, maar dart moet natuurlijk wel met elkaar overeenstemmen.
Deze controle doen we niet meteen na het ophogen van currentLed, maar we gaan eerst de LEDs aanzetten en daarna pas controleren of we wat met een overflow moeten doen.
Ik kan hier nu (op dit tijdstip) even niet verder op ingaan want ben te moe en moet echt mijn rust gaan pakken dit weekend.