Delays vervangen in millis()

Projecten die niet passen in bovenstaande onderwerpen
Berichten: 50
Geregistreerd: 12 Mrt 2016, 23:38

Re: Delays vervangen in millis()

Berichtdoor Pexy » 14 Mrt 2018, 04:31

Wauw! Echt super bedankt Koepel.
Ik ga het vanmiddag testen en verder uitwerken.

Ik zie inderdaad hoe de Blink Without Delay hierin is verwerkt, maar daar was ikzelf echt niet opgekomen.

En nogmaals bedankt!

Advertisement

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

Re: Delays vervangen in millis()

Berichtdoor Koepel » 14 Mrt 2018, 09:07

Werkend maken

Het faden alleen doen als beide niet actief zijn, dat zal wel lukken.
Code: Alles selecteren
// if not active led 1 with blinking and not active led 2 with blinking
if( !L1Active && !L2Active)


De andere led alleen uit zetten, als die niet bezig is met knipperen:
Code: Alles selecteren
// start or restart the blinking of L1 led.
...
if( !L2Active)
{
  digitalWrite( L2Pin, LOW);
}


Zag je dat ik jouw "PI" heb verandert naar "M_PI" ?
De "M_PI" is gedefinieerd in de compiler en is meer algemeen voor de 'c' taal. De "PI" heeft Arduino er zelf bij verzonnen, dat vonden ze leuk. Het maakt dus uiteindelijk niets uit.


Beter maken

Wanneer je hetzelfde stuk code dubbel hebt voor beide leds, dan heb je slechte code :(
Als je dan iets wijzigt, dan zou je dat bij de andere kunnen vergeten, en dan heb je twee stukken code die verschillende dingen doen.
Wanneer je alle variabelen omzet naar een een array, en met een for-loop die code doet, dan wordt het een stuk beter. Dan kun je ook betere namen voor de variabelen bedenken.

Dan heb je één of twee regels extra code nodig om de andere led uit te zetten. Dat kan op verschillende manieren.

Met alle variabelen voor een led als array ben ik al heel tevreden. Je kunt ook alles voor een led in een class zetten. Dus als je iets met 'c++' en objecten wilt gaan doen, dan is dat ook mogelijk.

Die berekening voor het maken van een sinus, dat zit me niet lekker. Ik vraag me af of dat wel goed gaat.


Mooier maken

Er mag wat meer commentaar bij.
Bijvoorbeeld een header bovenaan, met daarin de naam van de sketch; de datum; welk Arduino board; welke Arduino IDE versie; een link naar deze thread; enzovoorts.

Het zou mooier zijn als de led na het knipperen even uit blijft voordat het faden begint.

Je doet een PWM signaal met een sinus. Maar het menselijk oog ziet de helderheid logaritmisch. Wat ik zie is dat de led meestal fel is, met af en toe een dipje. Een soort van gaussiaanse curve zou mooier zijn.


Aan de slag

Nou, je hebt genoeg te doen :geek:
Ik heb het liefst, dat wanneer je een komma anders zet, dan je dan de hele sketch weer laat zien.

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

Re: Delays vervangen in millis()

Berichtdoor shooter » 14 Mrt 2018, 10:48

Onder het kopje mooer zou ik het faden uit een kleine tabel halen, dat geeft mooie resultaten en is goed in te stellen. dan krijg je dus een mooie balans die loopt dan bijvoorbeeld van 64 tot aan 200, afhankelijk van de leds en wat er nog meer tussen zit.
paul deelen
shooter@home.nl

Berichten: 163
Geregistreerd: 15 Dec 2012, 21:02
Woonplaats: Delfzijl

Re: Delays vervangen in millis()

Berichtdoor FPCUser » 14 Mrt 2018, 10:56

Nico heeft jaren geleden eens een formule en een tabel gegeven.....
http://arduinoforum.nl/viewtopic.php?f=8&t=1018&hilit=Fading+led#p7775

Berichten: 50
Geregistreerd: 12 Mrt 2016, 23:38

Re: Delays vervangen in millis()

Berichtdoor Pexy » 14 Mrt 2018, 22:58

Hallo, ik ben een beetje aan het spelen geweest met de sketch en ben tegen een aantal dingen aangelopen.
Zoals dat als de ene led knippert de andere led uitgaat werkt niet optimaal, als ik heel snel achter elkaar de knoppen indrukt brand er totaal geen led.
En zonder ''digitalWrite( L1Pin, LOW);'' en ''digitalWrite( L2Pin, LOW);'' werkt het wel perfect alleen, blijft de ene led wel aan terwijl de andere led knippert.


Het zou mooier zijn als de led na het knipperen even uit blijft voordat het faden begint.
Dat krijg ik niet uitgevonden hoe ik dat erin moet zetten, ik staar mij eigen blind op die boolean maar kom er niet uit.


Hieronder de sketch van Koepel die ik nu bewerkt heb voor 2 knoppen en 2 leds.
cpp code
// Arduino IDE 1.0.5
// Led knoppen millis timing
// Maart 2018
// viewtopic.php?f=25&t=2920


const int S1Pin = 2; // switch P1
const int S2Pin = 3; // switch P2
const int L1Pin = 10; // led P1
const int L2Pin = 11; // led P2

unsigned long L1PreviousMillis;
const int L1Interval = 100; // led blink interval in milliseconds
boolean L1Active = false; // indicates if led L1 is blinking
int L1Count; // count the blinks
int L1State; // the state of the led

unsigned long L2PreviousMillis;
const int L2Interval = 100; // led blink interval in milliseconds
boolean L2Active = false; // indicates if led L1 is blinking
int L2Count; // count the blinks
int L2State; // the state of the led

int periode = 8000;
int displace = 4000;


void setup()
{
// initialize the digital pins.
// assume switches will wire from ground to input pins
pinMode( S1Pin, INPUT_PULLUP);
pinMode( S2Pin, INPUT_PULLUP);
pinMode( L1Pin, OUTPUT);
pinMode( L2Pin, OUTPUT);
}


void loop()
{
if( digitalRead( S1Pin) == LOW) // low is pressed
{
// start or restart the blinking of L1 led.
L1Active = true;
L1PreviousMillis = millis();
L1Count = 0;
L1State = HIGH;
digitalWrite( L1Pin, HIGH);
}

if( digitalRead( S2Pin) == LOW) // low is pressed
{
// start or restart the blinking of L1 led.
L2Active = true;
L2PreviousMillis = millis();
L2Count = 0;
L2State = HIGH;
digitalWrite( L2Pin, HIGH);
}

if( L1Active)
{
digitalWrite( L2Pin, LOW);

if( millis() - L1PreviousMillis >= L1Interval)
{
L1PreviousMillis = millis();

L1Count++;
if( L1Count >= 20)
{
L1Active = false;
}

if( L1State == HIGH)
L1State = LOW;
else
L1State = HIGH;

digitalWrite( L1Pin, L1State);
}
}

if( L2Active)
{
digitalWrite( L1Pin, LOW);

if( millis() - L2PreviousMillis >= L2Interval)
{
L2PreviousMillis = millis();

L2Count++;
if( L2Count >= 20)
{
L2Active = false;
}

if( L2State == HIGH)
L2State = LOW;
else
L2State = HIGH;

digitalWrite( L2Pin, L2State);
}
}

// if not active led 1 with blinking and not active led 2 with blinking
if( !L1Active && !L2Active)
{
// Fade leds using the bare value of millis().
// That might cause a glitch once per 50 days, but it is only for leds.

unsigned long time = millis();
int value1 = 128 + 127 * cos( 2 * M_PI / periode * time); // calculation not checked, could be wrong
int value2 = 128 + 127 * cos( 2 * M_PI / periode * (displace + time));

analogWrite( L1Pin, value1); // sets the value (range from 0 to 255)
analogWrite( L2Pin, value2); // sets the value (range from 0 to 255)

}
}


Nico heeft jaren geleden eens een formule en een tabel gegeven.....
http://arduinoforum.nl/viewtopic.php?f= ... +led#p7775

Als ik de sketch van Nico wil compileren voor het faden van led krijg ik fout meldingen:
Fade_Led.ino: In function 'void loop()':
Fade_Led:38: error: expected `)' before '{' token
Fade_Led:45: error: expected primary-expression before '}' token
Fade_Led:45: error: expected `;' before '}' token
Fade_Led:62: error: expected `}' at end of input
Zie sketch van Nico:
cpp code
int LED_PIN = 13;

byte fadeArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 22, 26,
30, 35, 40, 45, 50, 56, 62, 68, 74, 81, 88, 95, 102, 110, 118, 126, 135,
143, 152, 161, 170, 180, 190, 200, 210, 221, 232, 243, 249, 254 };

int16_t fadeIndex=0; // index in de fade tabel
unsigned long fadeTimer; // timer om van stap naar stap te springen
#define FADE_TIJD 100 // verspringen van sterkte 1 x per 100 msec
bool richting = 1; // beginnen met oplopen van <span class="posthilit">fading</span> effect

void setup() {
pinMode(LED_PIN, OUTPUT);
fadeTimer = millis();
}

void loop() {
//
// kijk of de fade timer loopt
//
if (fadeTimer != 0) {
//
// timer loopt dus controleer of deze is verlopen
//
if (millis() - fadeTimer > FADE_TIJD){
//
// timer is verlopen dus nu kijken of we op of neer moeten gaan
//
if (richting == 1){
//
// oplopend dus verhoog de fade index
//
fadeIndex++;
//
// en kijk of we op het maximum zitten
//
if (fadeIndex == sizeof(fadeArray) {
//
// we zitten op de top dus richting omzetten en aflopen
//
richting = !richting;
fadeIndex--; // op de hoogste positie van de tabel
}
} else {
//
// richting is aflopend dus verlaag de index
//
if (fadeIndex == -1){
//
// we hebben de laatste index bereikt dus gaan we weer omhoog
//
richting = !richting;
fadeIndex = 0; // op de laagste positie van de tabel
}
}
//
// nu nog de output wegschrijven
//
analogWrite(LED_PIN, fadeArray[fadeIndex]);
}
}

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

Re: Delays vervangen in millis()

Berichtdoor Koepel » 14 Mrt 2018, 23:19

Volgens mij werkt wel zoals ik in gedachten had.

Kun je het uitzetten bij beide weghalen ?
Code: Alles selecteren
  if( L1Active)
  {
//    digitalWrite( L2Pin, LOW);    <--------- deze weg
 
    if( millis() - L1PreviousMillis >= L1Interval)
    {
      L1PreviousMillis = millis();
      ...


En het uitzetten bij beide toevoegen zoals ik voorstelde:
Code: Alles selecteren
  if( digitalRead( S1Pin) == LOW)   // low is pressed
  {
    // start or restart the blinking of L1 led.
    L1Active = true;
    L1PreviousMillis = millis();
    L1Count = 0;
    L1State = HIGH;
    digitalWrite( L1Pin, HIGH);

    if( !L2Active)               // <---- toevoegen
    {                      // <---- toevoegen
      digitalWrite( L2Pin, LOW);     // <---- toevoegen
    }      // <---- toevoegen
  }


De loop() wordt heel vaak heel snel achter elkaar uitgevoerd. Misschien wel duizenden keren per seconde. Waar jij de andere led uit zette, dat wordt dus heel vaak gedaan. Daarom werkt millis() zo goed, dan wordt er gekeken of het al tijd is om iets te gaan doen.

Ik maak het me gemakkelijk door niet te kijken of de knop wordt ingedrukt, maar het knipperen te (her)starten zolang de knop ingedrukt gehouden wordt. Dus het starten van het knipperen wordt dan ook heel vaak uitgevoerd. Dat kan later altijd nog uitgebreid worden naar iets beters.

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

Re: Delays vervangen in millis()

Berichtdoor Koepel » 14 Mrt 2018, 23:46

Die fading sketch was nog niet compleet. Ik heb het aangepast voor jouw leds op pin 10 en 11.

Ik zit hier nu als een konijntje naar de ledjes te staren, ooooooooh ;)
cpp code
const int ledPin1 = 10;
const int ledPin2 = 11;


// Later in de code is "sizeof(fadeArray)" gebruikt,
// dat kan omdat het enkele bytes zijn.

byte fadeArray[] =
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 22, 26,
30, 35, 40, 45, 50, 56, 62, 68, 74, 81, 88, 95, 102, 110, 118, 126, 135,
143, 152, 161, 170, 180, 190, 200, 210, 221, 232, 243, 249, 254
};

int fadeIndex = 0; // index in de fade tabel
unsigned long fadeTimer; // timer om van stap naar stap te springen
const int fade_interval = 100; // verspringen van sterkte 1 x per 100 msec
bool up = true; // beginnen met oplopen van fading effect
bool enableFade;

void setup()
{
pinMode( ledPin1, OUTPUT);
pinMode( ledPin2, OUTPUT);

enableFade = true; // start the fading
}

void loop()
{
//
// kijk of de fade timer loopt
//
if( enableFade)
{
//
// timer loopt dus controleer of deze is verlopen
//
if( millis() - fadeTimer > fade_interval)
{
fadeTimer = millis();
//
// timer is verlopen dus nu kijken of we op of neer moeten gaan
//
if( up)
{
//
// oplopend dus verhoog de fade index
//
fadeIndex++;
//
// en kijk of we op het maximum zitten
//
if( fadeIndex == sizeof(fadeArray))
{
//
// we zitten op de top dus richting omzetten en aflopen
//
up = !up;
fadeIndex--; // op de hoogste positie van de tabel
}
}
else
{
//
// richting is aflopend dus verlaag de index
//
fadeIndex--;
//
// kijk of we onderaan de array zitten
//
if( fadeIndex == -1)
{
//
// we hebben de laatste index bereikt dus gaan we weer omhoog
//
up = !up;
fadeIndex = 0; // op de laagste positie van de tabel
}
}
//
// nu nog de output wegschrijven
//
analogWrite( ledPin1, fadeArray[fadeIndex]);

// Als de ene led op het helderste punt is, dan is de andere het meest gedimd.
// En halverwege de tabel komen ze elkaar tegen.
// De hoogste index is "sizeof(array) - 1"
int fadeIndex2 = sizeof( fadeArray) - 1 - fadeIndex;
analogWrite( ledPin2, fadeArray[fadeIndex2]);
}
}
}

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

Re: Delays vervangen in millis()

Berichtdoor Koepel » 15 Mrt 2018, 00:02

Ook het even uitlaten na het knipperen heb ik er in weten te prutsen.
Ik laat de timer wat langer doorlopen, en forceer de uitgang naar laag.
Dit is wel gepruts hoor, het is geen logische code:
Code: Alles selecteren
      if( L1Count > 24)   // count longer
      {
        L1Active = false;
      }
 
      if( L1State == HIGH || L1Count > 20)  // force low above 20
        L1State = LOW;
      else
        L1State = HIGH;

Berichten: 50
Geregistreerd: 12 Mrt 2016, 23:38

Re: Delays vervangen in millis()

Berichtdoor Pexy » 15 Mrt 2018, 18:37

Geweldig! de sketch werkt precies zoals ik het in gedachten had.
Zonder je hulp was mij dit echt nooit gelukt.

Vraag mij alleen nog wel af waarom het faden van de leds met sinus vloeiender oogt dan het linear faden,
zeker wanneer je de fade tijd lager zet zie je dat het linear faden in stapjes gaat.

Hieronder de sketch hoe hij nu is:
cpp code
// Arduino IDE 1.0.5
// Led knoppen millis timing
// Maart 2018
// viewtopic.php?f=25&t=2920


const int S1Pin = 2; // switch P1
const int S2Pin = 3; // switch P2
const int L1Pin = 10; // led P1
const int L2Pin = 11; // led P2

unsigned long L1PreviousMillis;
const int L1Interval = 100; // led blink interval in milliseconds
boolean L1Active = false; // indicates if led L1 is blinking
int L1Count; // count the blinks
int L1State; // the state of the led

unsigned long L2PreviousMillis;
const int L2Interval = 100; // led blink interval in milliseconds
boolean L2Active = false; // indicates if led L1 is blinking
int L2Count; // count the blinks
int L2State; // the state of the led


// Later in de code is "sizeof(fadeArray)" gebruikt,
// dat kan omdat het enkele bytes zijn.
byte fadeArray[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 18, 22, 26,
30, 35, 40, 45, 50, 56, 62, 68, 74, 81, 88, 95, 102, 110, 118, 126, 135,
143, 152, 161, 170, 180, 190, 200, 210, 221, 232, 243, 249, 254
};

int fadeIndex = 0; // index in de fade tabel
unsigned long fadeTimer; // timer om van stap naar stap te springen
const int fade_interval = 100; // verspringen van sterkte 1 x per 100 msec
bool up = true; // beginnen met oplopen van fading effect


void setup()
{
// initialize the digital pins.
// assume switches will wire from ground to input pins
pinMode( S1Pin, INPUT_PULLUP);
pinMode( S2Pin, INPUT_PULLUP);
pinMode( L1Pin, OUTPUT);
pinMode( L2Pin, OUTPUT);
}


void loop()
{
if( digitalRead( S1Pin) == LOW) // low is pressed
{
// start or restart the blinking of L1 led.
L1Active = true;
L1PreviousMillis = millis();
L1Count = 0;
L1State = HIGH;
digitalWrite( L1Pin, HIGH);

if( !L2Active)
{
digitalWrite( L2Pin, LOW);
}
}

if( digitalRead( S2Pin) == LOW) // low is pressed
{
// start or restart the blinking of L1 led.
L2Active = true;
L2PreviousMillis = millis();
L2Count = 0;
L2State = HIGH;
digitalWrite( L2Pin, HIGH);

if( !L1Active)
{
digitalWrite( L1Pin, LOW);
}
}

if( L1Active)
{
if( millis() - L1PreviousMillis >= L1Interval)
{
L1PreviousMillis = millis();

L1Count++;
if( L1Count > 24) // count longer
{
L1Active = false;
}

if( L1State == HIGH || L1Count > 20) // force low above 20
L1State = LOW;
else
L1State = HIGH;


digitalWrite( L1Pin, L1State);
}
}

if( L2Active)
{
if( millis() - L2PreviousMillis >= L2Interval)
{
L2PreviousMillis = millis();

L2Count++;
if( L2Count > 24) // count longer
{
L2Active = false;
}

if( L2State == HIGH || L2Count > 20) // force low above 20
L2State = LOW;
else
L2State = HIGH;

digitalWrite( L2Pin, L2State);
}
}

//
// kijk of de fade timer loopt
//
if( !L1Active && !L2Active)
{
//
// timer loopt dus controleer of deze is verlopen
//
if( millis() - fadeTimer > fade_interval)
{
fadeTimer = millis();
//
// timer is verlopen dus nu kijken of we op of neer moeten gaan
//
if( up)
{
//
// oplopend dus verhoog de fade index
//
fadeIndex++;
//
// en kijk of we op het maximum zitten
//
if( fadeIndex == sizeof(fadeArray))
{
//
// we zitten op de top dus richting omzetten en aflopen
//
up = !up;
fadeIndex--; // op de hoogste positie van de tabel
}
}
else
{
//
// richting is aflopend dus verlaag de index
//
fadeIndex--;
//
// kijk of we onderaan de array zitten
//
if( fadeIndex == -1)
{
//
// we hebben de laatste index bereikt dus gaan we weer omhoog
//
up = !up;
fadeIndex = 0; // op de laagste positie van de tabel
}
}
//
// nu nog de output wegschrijven
//
analogWrite( L1Pin, fadeArray[fadeIndex]);

// Als de ene led op het helderste punt is, dan is de andere het meest gedimd.
// En halverwege de tabel komen ze elkaar tegen.
// De hoogste index is "sizeof(array) - 1"
int fadeIndex2 = sizeof( fadeArray) - 1 - fadeIndex;
analogWrite( L2Pin, fadeArray[fadeIndex2]);
}
}
}

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

Re: Delays vervangen in millis()

Berichtdoor Koepel » 15 Mrt 2018, 19:34

Dat stapsgewijze van leds viel mij ook op, ik heb daar nog niet verder naar gekeken. Dat is misschien een optimalisatie voor later. Ik vermoed dat de lage waarden eerst sneller gingen waardoor het niet opviel.

Die PWM is beperkt van 0 tot en met 255. Dat zijn grove stappen.
Bij de meeste ledstrips zijn er meer stapjes, en kun je ook veel geleidelijker de lichtsterkte aanpassen bij lage waarden.

Weet je dat ik een paar berichten terug schreef: "Wanneer je hetzelfde stuk code dubbel hebt voor beide leds, dan heb je slechte code" ?

Kun je jouw sketch omzetten naar arrays ?

De variabelen worden dan:
Code: Alles selecteren
const int switchPins[2] = { 2, 3};
const int ledPins[2] = { 10, 11};

unsigned long previousMillis[2];
boolean active[2] = { false, false };  // indicates if led is blinking
int count[2]; // count the blinks
int ledState[2]; // the state of the led


Je code wordt dan:
Code: Alles selecteren
for( int i=0; i<2; i++)
{
  if( digitalRead( switchPins[i]) == LOW)   // low is pressed
  {
    // start or restart the blinking of L1 led.
    active[i] = true;
    previousMillis[i] = millis();
    count[i] = 0;
    ledState[i] = HIGH;
    digitalWrite( ledPins[i], HIGH);
    ...


Ik schreef ook al dat er wat extra code nodig om de andere led pin te krijgen. Dus als 'i' een '0' is, dan is '1' de andere en omgekeerd. Kun je daar zelf iets voor verzinnen ?

VorigeVolgende

Terug naar Overige projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 13 gasten