Weektelling opnieuw starten na verloop

Hallo,

Mijn naam is Bertus en ben sinds enkele weken bezig met een automatiseringsprojectje.
Hiervoor wil ik een weektelling laten lopen vanaf het moment dat het programma wordt geladen, onafhankelijk van de tijd, welke zich na een bepaalde periode reset naar beginwaarde.
Ik heb al heel wat afgestruind, maar kom nergens tot een duidelijk antwoord.

Hiervoor heb ik de onderstaande code gebruikt.
Ik heb ook een RTC, maar op deze wijze kan ik eenvoudige de tijd aanpassen en wijzigen voor het testen.
De code bouw ik later om!

unsigned long time;

unsigned long startweeks = 1; // begin met tellen op week 01 
unsigned long periode = 4; // Weeknummer waarna gereset dient te worden

// eenvoudige klok instellen
unsigned long starthours = 14;
unsigned long startminutes = 00;
unsigned long startseconds = 00;

unsigned long millis(void);

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned long tijd = millis() / 1000; // tijd in seconden

  unsigned long week = (tijd / (1 /* 60 * 24 * 7*/)); // weektelling, deze voor het gemak op 1 seconde gezet omdat een 4 weken wachten te lang duurt om te testen ;)

  unsigned long ww = (week + startweeks); // Weergave weektelling

  unsigned long ss = (tijd + startseconds) % 60; // blijft hetzelfde
  unsigned long mm = ((tijd + startseconds) / 60 + startminutes) % 60;
  unsigned long hh = ((tijd + startseconds + 60 * startminutes) / 3600 + starthours) % 24;

  Serial.print("Week: ");
  if (ww < 10)
  {
    Serial.print("0");
  }
  Serial.print(ww);
  
  Serial.println();


  Serial.print("Tijd: ");
  if (hh < 10)
  {
    Serial.print("0");
  }
  Serial.print(hh);
  Serial.print(":");
  if (mm < 10)
  {
    Serial.print("0");
  }
  Serial.print(mm);
  Serial.print(":");
  if (ss < 10)
  {
    Serial.print("0");
  }
  Serial.print(ss);

  Serial.println("\n");

// reset waarde terug naar begin waarde als aan voorwaarde wordt voldaan
  if (millis() > (periode * week))
  ww = startweeks;

  delay (1000);
}

Weektelling werkt zoals het zou moeten, echter krijg ik de reset naar beginwaarde er niet in!

// reset waarde terug naar begin waarde als aan voorwaarde wordt voldaan
  if (millis() > (periode * week))
  ww = startweeks;

Kan iemand mij hiermee helpen???

bertusbeunhaas:
Kan iemand mij hiermee helpen????

Zei iemand millis() ? Zie: GitHub - Koepel/Fun_with_millis: Small Arduino examples using the millis() function..

Je gaat aan de slag met millis(), maar dat gaat mis na 50 dagen vanwege de rollover van millis().
Het is beter om een klok te maken die nooit overslaat, die altijd precies loopt, die geen last heeft van de rollover na 50 dagen. De nauwkeurigheid is dan met het crystal of resonator van het Arduino board.

De officiële Arduino Uno heeft een resonator, dat is pech hebben. Die zijn niet heel nauwkeurig.
De Arduino Leonardo heeft een crystal, dat is goed.

Een klok maken gaat net even iets anders dan de Blink Without Delay, https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay.

Zie je het verschil ?
Een ledje knipperen heeft de regel: previousMillis = currentMillis;
Een klok heeft de regel: previousMillis += interval;

unsigned long previousMillis;
const unsigned long interval = 1000UL;

void loop()
{
  unsigned long currentMillis = millis();

  if( currentMillis - previousMills >= interval)
  {
    previousMillis += interval;   // keep in sync with time
   
    // hier je klok code
  }
}

De code voor de klok kan de seconden verhogen, en dan de minuten, dan de uren, enzovoorts.

seconds++;
if( seconds == 60)
{
  seconds = 0;
  minutes++;
  if( minutes == 60)
  {
    minutes = 0;
    hours++;
    if( hours == 24)
    {
      hours = 0;
      dayOfWeek++;
      if( dayOfWeek == 7)
      {
        dayOfWeek = 0;
        week++;
      }
    }
  }
}

Als je geen klok nodig hebt, dan kunt je er ook voor kiezen om een millis() timer te maken die eens per week aktief wordt.

const unsigned long intervalWeek = 1000UL * 60UL * 60UL * 24UL * 7UL;

Stel dat je wilt aftellen naar dat moment, en je wilt aftellen met uren, minuten en seconden.
Dat is het vaak eenvoudiger om de hele sketch op millis() of op seconden te laten draaien, en alleen als je de tijd wilt laten zien, dan steeds even omzetten naar uren, minuten en seconden.

je zet bovenaan in de loop ww op week + en daar moet je dus als week> dan iets anders invullen

Hallo Koepel en Shooter,

Bedankt voor jullie reactie.
Helaas kom ik er nog steeds niet uit…

@Koepel,
De klok is in dit verhaal niet belangrijk.
Zoals aangegeven heb ik ook een RTC voor de tijd, die nauwkeurig werkt.
Het ding waarin ik vastloop, is dat wanneer ik het programma laad, de millis() moet gaan tellen.
Zover red ik het nog, ook met een weektelling vanaf het moment van starten (dus aan de hand van millis()).
Alleen wanneer een bepaalde tijd (lees: periode) is verstreken, dient de tellen weer op beginwaarde (week 01) gezet te worden.
Ik heb hiervoor inmiddels, zo’n beetje alle soorten timers op internet afgestruind en geprobeerd, maar loop telkens vast bij het resetten!

@Shooter,
Ik begrijp niet wat je bedoeld.
Indien ik + vervang voor > dan iets anders, loopt mijn script tegen een foutmelding aan.

Onderstaand nogmaals de code, maar dan zonder de klok en alleen de weektelling.
Waar gaat het fout?
Help me alstublieft… :zipper_mouth_face:

unsigned long startweeks = 1; // begin met tellen op week 01 
unsigned long periode = 4; // Weeknummer waarna gereset dient te worden

void setup() {
  Serial.begin(9600);
}

void loop() {
  unsigned long ww = ((millis() / 1000) / (1 /* 60 * 24 * 7*/) + startweeks); // weektelling, deze voor het gemak op 1 seconde gezet omdat een 4 weken wachten te lang duurt om te testen ;)

  Serial.print("Week: ");
  if (ww < 10)
  {
    Serial.print("0");
  }
  Serial.print(ww);
  
  Serial.println("\n");

// reset waarde terug naar begin waarde als aan voorwaarde wordt voldaan
  if (millis() > (periode * (1 /* 60 * 24 * 7*/)))
  ww = startweeks;

  delay (1000);

Mijn dank is wederom groot!

Alles wat ik schreef was bedoeld om duidelijk te maken dat je op die manier beter niet met millis() om kunt gaan.
Wat ik liet zien kan iedere week aktief worden, en iets resetten of zo is helemaal niet aan de orde.

Jij wilt millis() gebruiken, door bijvoorbeeld de waarde van millis() te delen.
Dat werkt niet. Vergeet dat.
Als het je gelukt is om dat te vergeten, lees dan de pagina van de Blink Without Delay :wink:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.