Loop probleem

algemene C code
Berichten: 340
Geregistreerd: 23 Okt 2016, 20:29

Loop probleem

Berichtdoor benvo » 20 Dec 2016, 16:10

Hallo allemaal,

Even vooraf: Deze sketch is een deel van een te ontwikkelen programma!

Middels een RTC klok wil ik een ledbalk op een bepaalde tijd laten branden op een bepaalde helderheid.

Laten we zeggen dat onderstaand sketch deel om 8:00 uur is aangegaan om van 0% lichtsterkte in of op te faden naar 10% .

Dit werkt.

Nu het probleem; zo gauw het programma de 10% heeft bereikt begint het weer bij 0 (nul) en doet het geheel overnieuw. Logisch zou je zeggen, je zit tenslotte in void loop.

Maar wat ik wil is dat het programma na het bereiken van de hoogste waarde, hier dus 25.5 (10% lichtsterkte, zie de array), stopt én die waarde vasthoudt.

Want stel dat ik wil dat de sketch om 10:00 uur de lichtsterkte van de eerder vastgehouden 10% naar 30% brengt en bijvoorbeeld om 12:00 uur van 30% naar 100%.

Hoe kan ik dit oplossen? De hier geprobeerde “break” brengt geen oplossing. Verder had ik gedacht aan een “derde” toevoeging als bijvoorbeeld , “roodpercentageoud” die dan telkens de voorgaande waarde vasthoudt en weer als beginwaarde invoert. Hoe dan ook, hier kom ik niet uit tot nu toe.
Kunnen jullie mij op weg helpen?

cpp code
Code: Alles selecteren

float roodpercentage[11]={0, 25.5, 51, 76.5, 102, 127.5, 153, 178.5, 204, 229.5, 255}; //array voor de wit-rode balk legt middels PWM de max. helderheid percentages vast in stappen van ca. 10%.
uint8_t q;                                                                             //q is de variabele voor de elementkeuze
uint8_t PWMrood=9;                                                                     //wit-rode balk wordt middels pin 9 aangestuurd.

void setup() {
 
 pinMode(PWMrood, OUTPUT);                                                            //zet de pin voor de wit-rode balk als uitgang
 

 
}


void loop() {

   // fade up loop.

    Serial.begin(9600);
 
     
    q=1;
    float y;
   
   for(y;y<=roodpercentage[q];y=y+0.1)
   { 
    analogWrite(9,y);                                                                 // fade up van de wit-rode balk tot aan de max. (roodpercentage) waarde
 
   Serial.println((y/2.55),0);                                                       //drukt helderheid waarde van de wit-rode balk af in procenten.
   delay(250);                                                                       // wacht een kwart seconde
 



// Onderstaande zou een oplossing moeten zijn om uit de loop te komen én om y de hoogste waarde, in dit geval element 1 uit de array, vast te laten houden. Maar dit werkt niet.
   
    if (((y/2.55),0)==10)
    {
     y=25.5;
     break;
    }         
   
 

   }
 

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Loop probleem

Berichtdoor Koepel » 20 Dec 2016, 16:49

Maak een tekening met op de x-as de uren en op de y-as het percentage.
Daarna kun je iets bedenken die dat doet.

Je wilt dus met geleidelijk faden de lichtsterkte naar een van de 10 vaste waarden laten gaan. Waarom ?
Kun je misschien meteen de lichtsterkte zetten, die voor ieder moment elke waarde kan zijn ?
Bijvoorbeeld om 8 uur beginnen en pas om 12 uur de volle sterkte. Dat zou dan kunnen met een curve, zodat het heel zachtjes toeneemt bij lage lichtsterkte.

Dan kun je bijvoorbeeld iedere minuut of iedere seconde de tijd opvragen. Dan daar een berekening mee doen waar de lichtsterkte uit komt.

Je gebruikt nu voor het faden een loop met delay(). In die tijd kun je geen andere dingen doen.

Kun je in woorden uitleggen, wat je met deze regel code wilt doen?
Code: Alles selecteren
if (((y/2.55),0)==10)

Berichten: 340
Geregistreerd: 23 Okt 2016, 20:29

Re: Loop probleem

Berichtdoor benvo » 20 Dec 2016, 17:25

Hallo Koepel,

De sketch waar ik mee bezig ben is een sketch bedoelt voor aquariumverlichting. Daar is het nodig dat je de leds kunt laten branden op een bepaalde helderheid. Zoals in de natuur zal dat midden overdag het helderst zijn. In de led nabootsing dus te vertalen in 100% Maar in de morgen maar ook in de avonduren is het licht veel minder. Bovendien verloopt de lichtsterkte altijd geleidelijk. Er is nog een aspect, nl. dat er in de morgen meer rood in het licht zit en s'avonds meer blauw. Dat laatste ondervang ik door gebruik van een wit rode balk en een wit blauwe balk die onafhankelijk van elkaar worden aangestuurd. Er is ook nog een witte balk die alleen op het middengedeelte van de dag wordt toegevoegd.
De rood-witte balk start in de morgen rond 8:00 uur van 0%tot 10% en gaat na een half uur verder van 10% naar 30%. Vanaf 9:00 uur gaat de fade up van 30% naar 100% (Meer rood licht in de morgen.) De blauw witte balk gaat om 9:00 uur aan van 0% tot 40% en rond 10:uur van 40% naar 100%. Deze balk blijft s"avonds nog branden op laten we zeggen 30% terwijl de wit-rode balk al uit is. (s'avonds meer blauw in het licht.) Let op dit zijn maar voorbeelden maar ze geven aan hoe e.e.a. zou moeten werken.

Weet je nog dat ik een vraag stelde over een Ja/nee keuze? Ik kwam daar niet verder mee maar ook ik had al bedacht dat het mooiste zou zijn dat ik tijden in zou kunnen voeren die dan op de een of andere manier, min of meer, automatisch gekoppeld zouden moeten worden aan helderheid graduaties. Inderdaad heb ik daarvoor moeten graven in mijn wiskunde verleden, héél lang geleden, ik ben 65 geweest, en kwam óók op de X,Y as. Ook kwam als gevolg daarvan de gedachte op twee dimensionale arrays. Dit liep wat dood.

Omdat in de meeste gevallen de helderheidsgraduaties in de aquarium wereld fluctueren zo rond de 10%, bedacht ik deze array en het sketchdeel als aangegeven. Wanneer ik nu uit de loop kan komen met behoud van de hoogste helderheid die tot dan is gebruikt ben ik al een stukje verder.

De code regel geeft tussen haakjes een waarde van 10 (is gelijk aan 10 (%)) aan. Zodra die waarde behaalt is zou er uit de loop gesprongen moeten worden terwijl y de waarde 25.5 vasthoudt, zijnde het eerste element uit de array. Dat is dan weer de hoogste helderheid waarde tot dan toe. Maar dat werkt niet. De loop gaat door en begint gewoon weer bij nul. Je snapt al wat er gebeurt; de led, ik test op een breadboard met een led, gloeit op tot op 10% van z'n helderheid en gaat uit om vervolgens weer op te gloeien, etc, etc.
Hopelijk begrijp je waar ik naar toe wil?
Dank voor je reactie!

Groet,
Ben.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Loop probleem

Berichtdoor Koepel » 20 Dec 2016, 20:08

Probeer zoveel mogelijk basis dingen te gebruiken. Het wordt anders voor mij te ingewikkeld.
Je mag gerust de code uitschrijven over meerdere regels, en tijdelijke variabelen gebruiken.

Het programmeren van het geleidelijk wijzigen van de ledbalken kan in de code of met een tabel.
Met een tabel zou je zelf de curve kunnen programmeren, of iets gebruiken dat al bestaat.
Dit is de MultiMap : http://playground.arduino.cc/Main/MultiMap.
Scroll op de MultiMap bladzijde naar beneden voor het voorbeeld, en je ziet een array 'out' en een array 'in'. Dat zijn de waarden van de x-as en y-as.
Dit heb ik nog niet eerder gezien, misschien wel aardig : http://playground.arduino.cc/Main/Smoothstep.


Dit kunnen een paar mogelijkheden zijn om het geleidelijk te doen:
Afbeelding
Curve A is het eenvoudigste. Van 0% tot 100% in drie uur is een lineair verband.
Curve B is een uitbreiding van curve A, met een extra formule. Bijvoorbeeld een logaritmische of exponentiële formule, zodat het overeenkomt met wat je als mens ervaart. Dit kun je later eenvoudig toevoegen als je curve A hebt.
Curve C is waarschijnlijk niet nodig. Ik heb ergens gebruikt om een hartslag te simuleren in een RGB led. Het is een standaarddeviatieformule y = exp ( - 0.5 * x * x )
Curve D is het moeilijkste. Het bestaat uit twee delen (de verschillende stappen, en het faden), en als je een delay() gebruikt dan kan tijdens het faden er niets anders gedaan worden.


Het volgende stukje code is te ingewikkeld. Het gaat nooit werken, maar dat is lastig te zien:
Code: Alles selecteren
if (((y/2.55),0)==10)
Er staat: Neem de 'float' variabele 'y'. Deel dat door '2.55'. De waarde van 'y' blijft trouwens ongewijzigd. Gooi dat resultaat vervolgens weg. Neem vervolgens de integer '0', en vergelijk dat met de integer '10', doe vervolgens nooit wat binnen de if-statement staat.
Het zou me niet verbazen als de compiler dat door heeft, en het if-statement overslaat.

Je kunt het je gemakkelijker maken door meer variabelen te gebruiken:
Code: Alles selecteren
float z = y / 2.55;
if( z == 10.0)  // Dit is fout !
{
}
Op die manier is de code wel te lezen. Het is trouwens fout, want een 'float' getal zal waarschijnlijk nooit 10.0 zijn, maar bijvoorbeeld 10.000001 of 9.999999

Berichten: 340
Geregistreerd: 23 Okt 2016, 20:29

Re: Loop probleem

Berichtdoor benvo » 20 Dec 2016, 22:30

Bij de volgende sketch telt het programma wel door met het volgende element van de array. Eigenlijk zou ik dus een manier moeten hebben om een te programmeren tijd te koppelen aan een element. Vaak zijn er wel sketches te vinden die bij een gegeven tijd een led laten "up faden" naar maximale sterkte (0-255) en bij een eindtijd dit andersom doen. (255-0) Lineair dus. Voor mijn doel heb ik hier niet veel aan. De "tussenstanden" zijn echt nodig. We zoeken wél verder natuurlijk! Alvast dank!

Toch maar even een wat duidelijker sketch:


cpp code
Code: Alles selecteren

float roodpercentage[11]={0, 25.5, 51, 76.5, 102, 127.5, 153, 178.5, 204, 229.5, 255}; //array voor de wit-rode balk legt middels PWM de max. helderheid percentages vast in stappen van ca. 10%.
float y;
uint8_t q;                                                                             //q is de variabele voor de elementkeuze
uint8_t PWMrood=9;                                                                     //wit-rode balk wordt middels pin 9 aangestuurd.
uint8_t t;
void setup() {
 
 pinMode(PWMrood, OUTPUT);                                                            //zet de pin voor de wit-rode balk als uitgang
 

 
}


void loop() {

   // fade up loop.

    Serial.begin(9600);
 
     
    q=q+1;
   
   
   for(y;y<=roodpercentage[q];y=y+0.1)
   { 
    analogWrite(9,y);                                                                 // fade up van de wit-rode balk tot aan de max. (roodpercentage) waarde
 
                                                         //drukt helderheid waarde van de wit-rode balk af in procenten.
   delay(250);                                                                        // wacht een kwart seconde
   Serial.println((y*100/255),0);
   
   if (y>=roodpercentage[q])
   {
    break;
   }
 
   }
Laatst gewijzigd door benvo op 20 Dec 2016, 22:44, in totaal 1 keer gewijzigd.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Loop probleem

Berichtdoor Koepel » 20 Dec 2016, 22:40

Sorry, ik weet niet waar je naar toe wilt werken, en met die code kan ik niet zoveel. Ik ben bang dat ik af moet haken :cry:

Berichten: 118
Geregistreerd: 28 Dec 2014, 23:20
Woonplaats: Bilzen BE

Re: Loop probleem

Berichtdoor Dries » 22 Dec 2016, 15:02

Dag Ben,
kijk hier eens naar: https://github.com/benjaf/LightController ik heb dit programma lopen ook voor mijn aquarium, en werkt hier al een tijd perfect. je kan op verschillende tijdstippen de lichtsterkte instellen 0-100% (0-255).
echt mooi programma vind ikzelf, als je vragen hebt laat maat weten.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: Loop probleem

Berichtdoor Koepel » 22 Dec 2016, 18:33

@Dries, die LightController ziet er goed uit :D

@benvo, misschien dat ik mijn punt niet duidelijk genoeg gemaakt heb. Ik had 4 curves getekend, en curve D is veruit de allermoeilijkste die misschien uiteindelijk niet eens uitvoerbaar is. Curve D is de curve die jij wilde, en je bleef daar op door gaan :(
Misschien was ik te voorzichtig om duidelijk te maken dat je op het verkeerde spoor zat.
Curve A is de eenvoudigste en kan gemaakt worden met de MultiMap, daarom gaf ik een link naar die MultiMap.

Die link die Dries geeft is in feite curve A met MultiMap, maar dan eenvoudig gemaakt en speciaal voor een aquarium. Er zit zelfs een mogelijkheid in om de helderheid exponentieel te doen, dat is dus wat ik bij curve B had getekend.

Het onderliggende principe is dat voor ieder willekeurig tijdstip de helderheid te berekenen is. Dan is het te overzien en dan is het nog te begrijpen wat er gebeurt.

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Loop probleem

Berichtdoor shooter » 22 Dec 2016, 20:20

je kunt zeker 2 dimensionaal arrays gebruiken.
gebruik een array van 24 lijnen en zet daar dan de helderheden in van de diverse lampen.
als het bijvoorbeeld 9:30 is dan moet de stand van de blauwe lamp tussen 10 en 20% zijn bijvoorbeeld. dus 10+0.5*(20-10) is dus 15 in totaal, en dat stuur je elke minuut naar je analogWrite en in de rest van de tijd doe je helemaal niets.
elke minuut verandert dus die 0.5 en elk uur veranderen de getallen.
10 is eigenlijk array[9] en 20 is array[9+1] in dit voorbeeld.
dus met een timer van 60000 millis in de loop ga je telkens naar een functie die bovenstaand uitrekent en de poorten zo goed zet.
zie het als een camswitch.
zo zijn natuurlijk allerlei vormen te maken, door de tijden te veranderen.
maar begin maar eens met een 24uurcam.
paul deelen
shooter@home.nl

Berichten: 340
Geregistreerd: 23 Okt 2016, 20:29

Re: Loop probleem

Berichtdoor benvo » 22 Dec 2016, 21:46

@ Koepel: Het probleem voor mij is dat ik een absoluut beginner in de Arduino wereld ben. Wat voor jullie duidelijk is pik ik mogelijk op een foute manier op en geef daardoor een reactie die tot opgetrokken wenkbrauwen leidt. Het curve verhaal heb ik wel begrepen. Ik probeerde duidelijk te maken dat ik niet wist hoe de X-as en Y-as middels de taal C te koppelen. Kennelijk had jij dit al wel door want het Multimap verhaal wijst, voor zover ik het begrijp, in de richting waarin ik zoek. Het zal nog wel even vergen tot dat ik helemaal doorheb hoe e.e.a. in elkaar steekt. Heb dus nog even geduld met me.

Fijn dat je je reactie gaf! Dank!

@Dries:Dit lijkt op iets wat ik zoek. Het is, zo lees ik, een aanpasbaar programma. Dat is fijn want ik ben niet twee maar drie kanalen nodig voor drie led balken. Verder gebruik ik de DS 3231 RTC clock module. Deze aanpassingen lijken niet moeilijk te maken zo op het eerste gezicht. Wat me (nog) niet helemaal duidelijk is wat er bedoelt wordt met lineaire optie en de exponentiële optie voor de lichtsterkte instelling. Van 0 tot 255 is, als je dat op een X-as en Y-as afzet lineair.
Bedoelt hij dat wanneer ik tussenstanden van laten we zeggen 25.5 (10%) en 51 (20%) lichtsterktes invoer dat ik dan exponentieel bezig ben?

Dank je wel, Dries, voor deze reactie!

Groet,
Ben.

Volgende

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 13 gasten