tijd vergelijken probleempje

Arduino specifieke Software
Berichten: 19
Geregistreerd: 03 Mei 2017, 09:18
Woonplaats: Almere

Re: tijd vergelijken probleempje

Berichtdoor PeterZ » 04 Mei 2017, 09:51

Koepel schreef:Het is wel degelijk even op te lossen in software, en meerdere mensen hebben ook zoiets gemaakt.

Zien zelf de logica wel, maar Arduino omgeving is even wennen, vooral de taal.. had veel eerder aan C taaltje moeten beginnen :D

Koepel schreef:Het probleem is dat ik je project moeilijk kon voorstellen. Alsof je vraagt hoe je een gerecht moet maken, terwijl de ingrediënten in een doos zitten en ik van een paar meter afstand mag ruiken wat de ingrediënten zijn :lol:

Mijn sorry in deze, zal m'n leeftijd zijn denk k :lol:

Koepel schreef:Ik zou bijvoorbeeld ook graag willen weten hoe vaak en in welk formaat de tijden binnen komen.
Doordat de tijd vóór en ná de 24:00 kan liggen, kom je automatisch uit bij de basis van de tijd, en dat is het aantal seconden sinds 1970.

De seriële data ontvang ik 1 keer met een vraag voor bevestiging die terug verwacht word, zo niet dan komt na 1 minuut opnieuw, de data wordt 3 x herhaald, hier heb ik geen probleem, die seriële data heb ik er zo in en weg geschreven naar eeprom. de data bestaat uit board info en setup mogelijkheid met passw. protection, setup met o.a. tijd notatie in 12 of 24uur, baudrate, lokale timers en aantal pompen.


Koepel schreef:De unix tijd of 'epoch' of aantal seconden sinds 1970 is nu juist niet het uur en de minuut zoals je schrijft. Het is het aantal seconden sinds 1970.

Dat begrijp ik, moet de tijd omzetten in unix tijd en krijg dan aantal seconden retour.

Koepel schreef:Nico is duidelijk en vergelijken met de unix tijd is eenvoudig zoals jij schrijft. Dus met die twee dingen zie ik uit de dichte mist de contouren van iets verschijnen. Dit is wat ik zie:

Wanneer de tijden binnen komen, dan de tijden omzetten naar seconden sinds 1970. Dat gaat met makeTime(). Het vullen van de structure zie je in setTime() https://github.com/PaulStoffregen/Time/blob/master/Time.cpp. De 'Wday' mag je overslaan, die wordt niet gebruikt. Dan krijg je dus twee 'time_t' variabelen (dat is gewoon een 32-bit unsigned long).
Dan twee singleshot AlarmOnce TimeAlarms zetten (dat kan met 'time_t' of met losse variabelen voor de uren, minuten, enzovoorts).
Die beide 'time_t' tijden ook opslaan in EEPROM. Bij voorkeur met een checksum, want de Arduino zou kunnen uitvallen tijdens het schrijven naar EEPROM.

Gaan daar opnieuw naar kijken of er ergens een voorbeeldje is, mijn probleem is dat ik het begin van de code (nog)niet kan rijmen, ik pluk voor Arduino de code overal vandaan van het net en kan dat aanpassen, alleen het zelf schrijven in die taal lukt me nog niet lekker, maar je beschrijft hier al wat functies die ik bij elkaar kan zoeken en zien of ik er wat mee kan maken..

Koepel schreef:Wanneer de Arduino wordt aangezet, dan de huidige tijd omzetten naar het aantal seconden sinds 1970 en de twee opgeslagen tijden ophalen uit de EEPROM. Dan kun je die eenvoudig vergelijken. Ondanks dat het 'time_t' variabelen zijn, zijn het gewoon 32-bit getallen die je kunt vergelijken.

Hier gaan ik naar opzoek.

Koepel schreef:Afhankelijk van het formaat van de tijd die binnenkomt van de 80C552, zou ik een functie maken die als parameters de tijden als losse getallen heeft en die ze omzet naar 'time_t'. Vervolgens zou ik diezelfde functie gebruiken bij het aanzetten van de Arduino.

Sla ze nu op als 2x2 bytes, kan daar wel een tijd notatie van maken voor time_t

Koepel schreef:Het grote voordeel is dat de Arduino nu ook meer dan een dag kan uit staan, want je weet tot op de seconde precies de datum en tijd van de verschillende tijden.

dat hoop ik dan niet, dan is mijn broertje niet vrolijk.

Bedankt, gaan weer zoeken en kijken of ik wat bruikbaars kan vinden in een leesbare code voor die Arduino.

Zal vandaag overdag even niet veel worden.. denk later op de middag weer.

Advertisement

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: tijd vergelijken probleempje

Berichtdoor nicoverduin » 04 Mei 2017, 11:16

Dat getalletje maken kun je hier vinden :
https://www.pjrc.com/teensy/td_libs_Time.html
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

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

Re: tijd vergelijken probleempje

Berichtdoor Koepel » 04 Mei 2017, 11:43

PeterZ schreef:Mijn sorry in deze, zal m'n leeftijd zijn denk k :lol:

Sorry dat ik wat traag van begrip ben, dat zal mijn leeftijd zijn :lol:

Een voorbeeld:
cpp code
// Test sketch
// Using Arduino IDE 1.8.2 and Arduino Uno
//
// Check the time_t values with: epochconverter.com
//

#include <EEPROM.h>
#include <TimeLib.h> // The pjrc.com TimeLib

void setup()
{
time_t t;

Serial.begin( 9600);
Serial.println();
Serial.println( "Test sketch with time_t");

Serial.print( "The \"time_t\" is ");
Serial.print( sizeof( time_t));
Serial.println( " bytes");

Serial.print( "Compiler time_t = ");
t = CompilerTime_t();
Serial.println( t);

Serial.print( "My test time = ");
t = TimeToTime_t( 2017, 5, 4, 12, 0, 0); // Y, M, D, HH, MM, SS
Serial.println( t);

time_t tBegin, tEnd;
EEPROM.get( 0, tBegin);
EEPROM.get( 4, tEnd);
Serial.print( "In EEPROM stored: ");
Serial.print( tBegin);
Serial.print( ", ");
Serial.println( tEnd);

// How to store the time_t
tBegin = TimeToTime_t( 2000, 1, 1, 0, 0, 0);
tEnd = TimeToTime_t( 2020, 1, 1, 0, 0, 0);
EEPROM.put( 0, tBegin);
EEPROM.put( 4, tEnd);

// Use the compiler date and time to start the TimeLib
setTime( CompilerTime_t());
}

void loop()
{
Serial.print( "Year:");
Serial.print( year()); // 2017...
Serial.print( ", Month:");
Serial.print( month());
Serial.print( ", Day:");
Serial.print( day());
Serial.print( ", Hour:");
Serial.print( hour());
Serial.print( ", Minute:");
Serial.print( minute());
Serial.print( ", Second:");
Serial.print( second());
Serial.println();
delay( 5000);
}


// -----------------------
// TimeToTime_t
// -----------------------
// year : 2017...
// month : 1...12
// day : 1...31
// hour : 0...23
// minute : 0...59
// second : 0...59
// -----------------------
time_t TimeToTime_t( int year, int month, int day, int hour, int minute, int second)
{
tmElements_t tm;

tm.Second = second;
tm.Minute = minute;
tm.Hour = hour;
tm.Wday = 0; // not used, don't care
tm.Day = day; // Day Of Month
tm.Month = month;
tm.Year = CalendarYrToTm(year); // the year since 1970 is needed

return( makeTime( tm)); // return the time_t created by makeTime
}


// -----------------------
// CompilerTime_t
// -----------------------
// The moment when the sketch was compiled,
// in the time_t format.
// -----------------------
time_t CompilerTime_t()
{
char monthbuf[10];
int h, m, s, d, mnth, y;
const char *pMonths = "JanFebMarAprMayJunJulAugSepOctNovDec";

sscanf( __DATE__ " " __TIME__, "%s %d %d %d:%d:%d", monthbuf, &d, &y, &h, &m, &s);
mnth = (strstr( pMonths, monthbuf) - pMonths) / 3 + 1;

return( TimeToTime_t( y, mnth, d, h, m, s));
}

Het gaat om de functie "TimeToTime_t()", de rest is spielerei omdat ik me niet kon inhouden :geek:

Berichten: 19
Geregistreerd: 03 Mei 2017, 09:18
Woonplaats: Almere

Re: tijd vergelijken probleempje

Berichtdoor PeterZ » 04 Mei 2017, 20:22

Koepel schreef:Het gaat om de functie "TimeToTime_t()", de rest is spielerei omdat ik me niet kon inhouden :geek:

top en dank, ik ga daar nu mee spelen ;)

Linkje van Nico is ook wel even handig.

Heb nu de hele avond om even te spelen ;)

Berichten: 19
Geregistreerd: 03 Mei 2017, 09:18
Woonplaats: Almere

Re: tijd vergelijken probleempje

Berichtdoor PeterZ » 04 Mei 2017, 22:16

Kan nu de Unix tijd zien en voor 1 dag gebruiken dat het goed loopt in tijdblok dat de Output pin hoog moet zijn.
De navolgende dagen gaat het dan wel mis omdat ik geen datum krijg wanneer tijd gezet 'gaat worden/of gezet is' en dan gaat mijn vergelijking niet meer op met de start en stop tijd.
Maar zeker een goede leer hoe je Unix time kan kan gebruiken, via de seriële interface is wel een leuke om tijd over te nemen van je pc..

Moet toch iets anders verzinnen...

Intussen dan bezig met deze vergelijking, maar dat gaat ook nog niet goed, krijg alleen maar true terug
Code: Alles selecteren
bool isStartTime()

  time_t t = now();                                                   // Read in what our current datestamp is

  int nowHH = hour(t); int nowMM = minute(t); int nowSS = second(t);             // put into local variables for easier read the time

  if ((
        (nowHH>StartHH)                                                                            // check hours first
        || ((nowHH==StartHH) && (nowMM>StartMM))                                     // check minutes if in same hour
        || ((nowHH==StartHH) && (nowMM==StartMM) && (nowSS>=StartSS))    // check seconds if in same hour & minute
      )
      &&                                                                                                  // both conditions must be valid
      (
        (nowHH<StopHH)                                                                            // check hours first
        || ((nowHH==StopHH) && (nowMM<StopMM)))                                    // check minutes if in same hour
        || ((nowHH==StopHH) && (nowMM==StopMM) && (nowSS<=StopSS))     // check seconds if in same hour & minute
      )
  { return true; } else { return false; }
}


Bovenstaande zal wel iets fout in staan, werd beetje gek van de haakjes :lol:

Berichten: 19
Geregistreerd: 03 Mei 2017, 09:18
Woonplaats: Almere

Re: tijd vergelijken probleempje

Berichtdoor PeterZ » 04 Mei 2017, 23:38

Ok, heb het nu werkend als het op dezelfde dag staat (met start en stop tijd) met bovenstaande stukje code en kleine aanpassing, die Bool werkt niet(zal het wel ergens iets fout doen) maar heb nu onderstaande.

Code: Alles selecteren

#include <TimeLib.h>
#include <TimeAlarms.h>

AlarmId id;

int U2Time = 0;

// variable start time
int StartHH = 21;
int StartMM = 55;
int StartSS = 0;
// Stop time
int StopHH = 23;
int StopMM = 2;
int StopSS = 0;

// check for start/stop time
int isStartTime()

  time_t t = now();                                                                        // Read in what our current datestamp is

  int nowHH = hour(t); int nowMM = minute(t); int nowSS = second(t);  // put into local variables for easier read the time

  if ((
        (nowHH>StartHH)                                                                // check hours first
        || ((nowHH==StartHH) && (nowMM>StartMM))                         // check minutes if in same hour
        || ((nowHH==StartHH) && (nowMM==StartMM) && (nowSS>=StartSS))    // check seconds if in same hour & minute
      )
      &&                                                                                     // both conditions must be valid
      (
        (nowHH<StopHH)                                                               // check hours first
        || ((nowHH==StopHH) && (nowMM<StopMM)))                       // check minutes if in same hour
        || ((nowHH==StopHH) && (nowMM==StopMM) && (nowSS<=StopSS))       // check seconds if in same hour & minute
      )
   return 1; 
   else  return 0;
}

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for Arduino Serial Monitor

  // Set test time
  setTime(22,59,50,5,3,17); // set time to Wednesday 23:29:50 Mei 3 2017

  // create timers, to trigger relative to when they're created
  id = Alarm.timerRepeat(2, Repeats2);      // timer for every 2 seconds

// Temp varable for testing
  U2Time = 0;
}

void loop() {
  digitalClockDisplay();
  Alarm.delay(1000); // wait one second between clock display

 }



// functions to be called when an alarm triggers:
// For test. look for time between given time
void Repeats2() {
  Serial.println("2 second timer");
 if (hour() >= 0 && hour() <= 6){
    Serial.println("Midnight");   
   }

   if (isStartTime()) {
    Serial.println("Start time");             // ... when the Starttime is now or passed or before Stop time
  } else {
    Serial.println("Stop time");              // ... when the Stoptime is now or passed or before start time
  }

 }


void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}



nu alleen de stop tijd na nacht nog, want dat blijft fout gaan.

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

Re: tijd vergelijken probleempje

Berichtdoor Koepel » 05 Mei 2017, 07:09

PeterZ schreef:werd beetje gek van de haakjes :lol:

Wij ook :!: Ik ga niet eens moeite doen om dat te begrijpen.

Stel dat 'tBegin' en 'tEnd' uit de EEPROM zijn gelezen zoals in mijn voorbeeld.
Stel dat 't' de huidige tijd is.
Dan wordt het zo iets:

Code: Alles selecteren
void setup()
{
  time_t tBegin, tEnd, t;

  ...

  EEPROM.get( 0, tBegin);
  EEPROM.get( 4, tEnd);
  t = now();

  if( t > tBegin && t < tEnd)
  {
    // De huidige tijd is tussen de tijden dat het aktief is !
    ...
  }

Wat hierboven staat is de bedoeling met de 'time_t' tijden. Waarom je dan alsnog de uren en minuten gaat proberen te vergelijken is me niet duidelijk. Dat je dan vastloopt doordat de tijd voor en na 24:00 kan liggen, dat wisten we al.

Met 'time_t' hoef je dus alleen maar dit te doen: if ( t > tBegin && t < tEnd )
En dat hoort ook nog in setup().
Jouw manier om de status naar de seriële monitor te sturen vind ik nog steeds verwarrend.

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: tijd vergelijken probleempje

Berichtdoor nicoverduin » 05 Mei 2017, 08:26

soms is het handig om ff een tijdlijntje te tekenen en dan de verschillende intervallen te bekijken.
Voor wat betreft de de nacht overgang, hoe je alleen maar te testen of de start_tijd < stop_tijd. Dan tel je gewoon een extra dag op bij de datum.
Alles omzetten naar een Unix Tijd en dan pas vergelijken.

Als voorbeeld:
Afbeelding

Op de grafiek heb ik ff de Unix seconden erbij gezet. Gebruik hiervoor bijvoorbeeld deze calculator: https://www.epochconverter.com/

Aangezien je niets met de datum doet in dit geval, kun je gerust een struct t_ maken waarbij je default de datum op elke willekeurige datum zet. In dit geval 1-1-2017. Nu kun je een functie schrijven die de vergelijking maakt tussen 2 intervallen:
cpp code
a: Geef als parameters door de start, stop en werkelijke tijd door
b: Maak van alle tijden een uint16_t getal (unsigned int) door uren x 100 + minuten te nemen
c: In de functie converteer je alle tijden om in een unix getal waarbij je de datum zet op 1-1-2017
d: als de start groter is dan stop (daar heb je die uint16_t getallen voor nodig) dan verhoog je de datum met een dag en bereken je het unix getal EN
e: Als de werkelijke tijd kijk je of deze ook kleiner is dan de stop tijd. Dan verhoog je voor dit blok ook de dag en reken je om naar Unix tijd.

Nu heb je 3 getallen waarbij je kan kijken of de gezochte tijd in het interval valt.
En dan geef je bijv. een true of false terug. Tutti.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: tijd vergelijken probleempje

Berichtdoor nicoverduin » 05 Mei 2017, 09:16

Peuk en een bak koffie verder.....
Het kan nog veel eenvoudiger:
cpp code
bool KijkOfInInterval(uint16_t startTijd, uint16_t eindTijd, uint16_t nuTijd){
uint16_t start = startTijd;
uint16_t eind = eindTijd;
uint16_t nu = nuTijd;
//
// kijk of het een 24 uurs overlap is
//
if (eind < start ){
//
// ja dus
//
eind = eind + 2400; // verhoog het eind tijdstip met 2400 (volgende dag)
//
// kijk tevens of de huidige tijd ook in de nieuwe dag valt
//
if (nu < eindTijd) {
//
// ook dus eveneens verhogen met een dag
//
nu = nu + 2400;
}
}
//
// de feitelijke vergelijking
//
if (nu >= start && nu <= eind){
return true;
} else {
return false;
}
}


De parameters zijn allemaal uren*100 + minuten.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: tijd vergelijken probleempje

Berichtdoor nicoverduin » 05 Mei 2017, 10:27

En met een eenvoudige test sketch
cpp code
/**
* programma : testtijdinterval
* Auteur : Nico Verduin
* Datum : 5-5-2017
* Doel : bepalen of een tijdstip in een interval valt
*/

#include "Arduino.h"
struct interval {
uint16_t start; // start van interval
uint16_t eind; // einde interval
};
//
// interval Array
//
interval intervalArray[] = {
{ 800, 1200}, // van 08:00 tot 12:00
{2300, 400} // van 23:00 tot 04:00
};

const int LED = 13;

char printBuffer[100]; // buffertje voor de serial

/**
* Initialiseren programma
*/
void setup()
{
Serial.begin(115200);
Serial.println("Test programma tijd intervallen");
pinMode (LED, OUTPUT);
digitalWrite(LED, LOW);
//
// loop door de tijden per uur te beginnen bij 00:30
//
for (uint16_t i = 30; i < 3000; i+= 100) {
for (uint8_t j = 0; j < sizeof(intervalArray) / sizeof(interval); j++) {
//
// correctie bij dag wisseling
//
uint16_t nu;
if (i > 2400) {
nu = i - 2400;
} else {
nu = i;
}
//
// kijk of de tijd in een van de intervallen valt
//
if (KijkOfInInterval(intervalArray[j].start, intervalArray[j].eind, nu)) {
//
// yep dus LED aan
//
digitalWrite(LED, HIGH);
//
// toon het resultaat
//
sprintf(printBuffer, "Interval %02d:%02d-%02d:%02d Tijd : %02d:%02d Pomp = Aan\n",
intervalArray[j].start / 100,
intervalArray[j].start % 100,
intervalArray[j].eind / 100,
intervalArray[j].eind %100,
nu / 100,
nu % 100
);
Serial.print(printBuffer);
} else {
digitalWrite(LED, LOW);
}
delay(500);
}

}
}
/**
* runs endlessly
*/
void loop()
{
//Add your repeated code here
}

/**
* KijkOfInInterval
* @param startTijd uren*100 + minuten
* @param eindTijd uren*100 + minuten
* @param nuTijd uren*100 + minuten
* @return true or False
* Valideert of nuTijd in het interval startTijd en eindTijd valt.
*/
bool KijkOfInInterval(uint16_t startTijd, uint16_t eindTijd, uint16_t nuTijd){
uint16_t start = startTijd;
uint16_t eind = eindTijd;
uint16_t nu = nuTijd;
//
// kijk of het een 24 uurs overlap is
//
if (eind < start ){
//
// ja dus
//
eind = eind + 2400; // verhoog het eind tijdstip met 2400 (volgende dag)
//
// kijk tevens of de huidige tijd ook in de nieuwe dag valt
//
if (nu < eindTijd) {
//
// ook dus eveneens verhogen met een dag
//
nu = nu + 2400;
}
}
//
// de feitelijke vergelijking
//
if (nu >= start && nu <= eind){
return true;
} else {
return false;
}
}
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

VorigeVolgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Seo-Ul-Gag en 21 gasten