Buggfix Plus
Aktuellt datum och tid: 09.13 2020-02-17

Alla tidsangivelser är UTC + 1 timme




Svara på tråd  [ 12 inlägg ] 
Författare Meddelande
InläggPostat: 11.28 2019-08-26 
Användarvisningsbild

Blev medlem: 20.38 2004-07-22
Inlägg: 1600
Ort: Stockholm - Linköping
Hej på er,

Har helt kört fast i huvudet.. jag kör en Arduino plattform, dvs C språket.

Jag har sparat timme och minut som läses in i en byte array (eepromvarArray). Där jag har timme från (position eepromvarArray[4]) och minut från (position eepromvarArray[5]) m.m.

Dessa skulle jag vilja lägga ihop i en gemensam variabel av valfri typ, så länge jag kan jämföra mot annan likvärdig variabel enligt tid/klocka.

Jag vill alltså ha ex. timme 10 och minut 09 att sitta ihop i en variabel 1009 och givetvis går inte 10 + 9 eftersom det blir 19. Givetvis går inte (10*10) + 9 eftersom det blir 109.. jag behöver verkligen 1009 och jag lyckas verkligen inte...

Anledningen till att jag läser ur EEPROM med timme i en byte och minuter i en byte, är därför att "ramverket" i övrigt är byggt så och jag tyckte det fungerade rätt så bra.

Innan jag kom på att jag behöver jämföra både timme och minut samtidigt så jämförde jag timme med timme och minut med minut, då var det absolut inga problem. Men, utan att ha råkat ut för det, så tror jag att om jag har följande.. att klockan "nu" är säg 1326 och vi jämför med en starttimme som är 10 så är vi ju efter det värdet. Men om vi har en startminut på säg 30 så kommer vi de första 30 minuterna att få fel, varje timme. Därav så började jag titta på att få ihop timme med minut i en variabel för att jämföra det som ett enda värde istället..

Har provat med följande som inte fungerar..

Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
uint16_t   nowHour         = 0;
uint16_t   nowMinutes      = 0;
uint16_t   nowSeconds      = 0;
uint16_t   nowYear         = 0;
uint16_t   nowMonth         = 0;
uint16_t   nowDay         = 0;
uint16_t   nowWday         = 0;
uint16_t   validYear         = 0;
uint16_t   validMonth      = 0;
uint16_t   validDay         = 0;
uint16_t   validHourFrom      = 0;
uint16_t   validMinFrom      = 0;
uint16_t   validHourUntil      = 0;
uint16_t   validMinUntil      = 0;
uint16_t   validWday         = 0;

validYear      = eepromvarArray[1];
validMonth      = eepromvarArray[2];
validDay      = eepromvarArray[3];
validHourFrom   = eepromvarArray[4];
validMinFrom   = eepromvarArray[5];
validHourUntil   = eepromvarArray[6];
validMinUntil   = eepromvarArray[7];
validWday      = eepromvarArray[8];

nowHour      = tm.Hour;
nowMinutes   = tm.Minute;


tm.Hour och tm.Minute kommer från ett DS1307 bibliotek, tm-Hour och tm.Minute ska vara decimal enligt biblioteket.. men kan inte se att de har specifikt satt värdena som detta.


Med följande kod;
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
char validTimeFrom[5];
char validTimeUntil[5];
char timeNow[5];
sprintf(validTimeFrom,   "%.2d%.2d",validHourFrom,validMinFrom);
sprintf(validTimeUntil,   "%.2d%.2d",validHourUntil,validMinUntil);
sprintf(timeNow,      "%.2d%.2d",nowHour,nowMinutes);

if ( validTimeFrom <= timeNow )
{
   Serial.println("Efter starttid");
}
else
{
   Serial.println("Innan starttid");
}

if ( validTimeUntil >= timeNow )
{
   Serial.println("Innan sluttid!");
}
else
{
   Serial.println("Efter sluttid!");
}


.. får jag alltid samma resultat med <= och >=, dvs alltid "innan" det jämförda värdet.

Det som "lurar" mig är ju att om jag kör en Serial.print på validTimeFrom, validTimeUntil, timeNow så ser de ju helt korrekta ut.. Jag får ut validTimeFrom = 1000, validTimeUntil = 2359, timeNow = 1921

Men med checken ovan validTimeFrom <= timeNow så får jag alltid else med "Innan starttid"... Jag vill ju ha att vi är efter starttid.. och det bör det ju vara i detta läge med timeNow = 1921, men är inte så..

Vad jag förmodar så är det därför jag jämför fel sorts värden!??



Har säkerligen missat hälften av vad jag tänkt skriva, även fast jag korrläst..

Blir galen av det här.. alltid "hatat" siffror och de där galna pilarna, större/mindre än, bråkar alltid med mig.. Använder de hur mycket som helst, men jag tror inte att jag förstår dem ändå efter 20 år plus det antal år man gick i skolan, det har helt enkelt aldrig fastnat..



Men det jag vill åstadkomma är hur som helst..

variabel1 = 10
variabel2 = 00

sättas ihop till variabel3 = 1000

Hur!?


Många tack på förhand!


Upp
 Profil  
 
InläggPostat: 11.33 2019-08-26 

Blev medlem: 10.23 2008-08-28
Inlägg: 170
Ort: Åtvidaberg
Prova :
variabel3 = variabel1 *100 + variabel2;



.


Upp
 Profil  
 
InläggPostat: 11.34 2019-08-26 

Blev medlem: 10.06 2010-01-07
Inlägg: 990
Ort: Sandared
Du kan inte göra det med int, bara med string, så du kan konvertera det i string och sen lägga de ihop

typ variabel3 = String(variabel1) + String (variabel2)

Eller ja, du kan göra det, men då får du räkna ut decimaler och allt annat för att få det som du vill.

variabel 3 = variabel1 * 1000 + variabel2


Upp
 Profil  
 
InläggPostat: 11.36 2019-08-26 
EF Sponsor
Användarvisningsbild

Blev medlem: 21.43 2006-11-06
Inlägg: 4308
Ort: Munkedal, Sverige (Sweden)
Annars om du jämför timmar och minuter
t.ex starttid 13.24
din tid 13.45

Om starttid (timme) < din tid (timme) så är din tid efter
om starttid (timme) = din tid(timme) så kolla om starttid (minut) < din tid(minut)

Swech


Upp
 Profil  
 
InläggPostat: 11.44 2019-08-26 
Användarvisningsbild

Blev medlem: 14.52 2005-01-10
Inlägg: 24285
Ort: Aabenraa, Danmark
"tm-Hour och tm.Minute ska vara decimal enligt biblioteket..."
Är du SÄKER på att de inte ska vara BCD istället?

Alltså så att värdet 35 anges som 0x35... Nästan alla av DS RTC-kretsar som har datum, timmar, minuter osv. kör nämligen med BCD.

Det är enkelt att omforma om man vill:
binärt värde = ((BCD >> 4) * 10) + (BCD & 0x0F);


Upp
 Profil  
 
InläggPostat: 12.14 2019-08-26 
Användarvisningsbild

Blev medlem: 22.56 2008-11-27
Inlägg: 3400
Ort: Utanför Jönköping
Om du verkligen har en siffra för timmar och en för minuter så är det lättaste och mest rätta följande imho:

om variabeln A innehåller timmar och B minuter:

C = A*60+B

Sedan använder du C för att jämföra mot andra siffror av samma typ.


Upp
 Profil  
 
InläggPostat: 12.36 2019-08-26 

Blev medlem: 14.59 2006-02-27
Inlägg: 4573
Ort: Tranås (Jönköping)
Som nämnt innan:
* Antingen göra om till sträng och jämföra strängarna. Men då kan du bara se om en sträng är lika med en annan sträng såklart. Inte om motsvarande värde i INT är större eller mindre.
* Om det är på samma dygn en tid ska jämföras med en annan så konvertera tiderna till minuter eller sekunder. Sen bara jämföra INTar.

Men spänner det över midnatt, och särskilt över flera dagar med kalenderdagar att ta hänsyn till så blir det mycket jobbigare.

Det här är förmodligen inte applicerbart i detta fall, men när jag ska hålla koll på timers som spänner över flera dagar så har jag i det språk jag jobbar i en timer som räknar sekunder från 1970-nåt-datum-minns-inte-exakt. Då spelar ju inga midnätter eller nyår nån roll.


Upp
 Profil  
 
InläggPostat: 13.10 2019-08-26 

Blev medlem: 20.20 2010-08-30
Inlägg: 3518
Ort: Umeå
jag skulle gjort funktioner som gör om klockslag till antal minuter efter midnatt, och sen jämföra dessa

if( timeToMin( 10, 06 ) < timeToMin( 13, 34 ))
{




}


Upp
 Profil  
 
InläggPostat: 14.29 2019-08-26 
EF Sponsor

Blev medlem: 12.12 2006-10-23
Inlägg: 989
Ort: Tyresö
Som jag förstår det har du två lika arrayer med resp tidsstämpel i samma format (typ ÅÅMMDDHHMMSS).

Då kan du använda memcmp som jämför arrayerna tecken för tecken tills de inte matchar varandra. Resultatet är -1 eller 1 om den ena är mindra resp större än den andra och 0 om de är lika.

/Ingvar


Upp
 Profil  
 
InläggPostat: 15.05 2019-08-26 
Användarvisningsbild

Blev medlem: 11.56 2004-05-08
Inlägg: 3730
Ort: Stockholm
toffie skrev:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
char validTimeFrom[5];
char validTimeUntil[5];
char timeNow[5];
sprintf(validTimeFrom,   "%.2d%.2d",validHourFrom,validMinFrom);
sprintf(validTimeUntil,   "%.2d%.2d",validHourUntil,validMinUntil);
sprintf(timeNow,      "%.2d%.2d",nowHour,nowMinutes);

if ( validTimeFrom <= timeNow )
{
   Serial.println("Efter starttid");
}
else
{
   Serial.println("Innan starttid");
}

if ( validTimeUntil >= timeNow )
{
   Serial.println("Innan sluttid!");
}
else
{
   Serial.println("Efter sluttid!");
}


.. får jag alltid samma resultat med <= och >=, dvs alltid "innan" det jämförda värdet.

Det som "lurar" mig är ju att om jag kör en Serial.print på validTimeFrom, validTimeUntil, timeNow så ser de ju helt korrekta ut.. Jag får ut validTimeFrom = 1000, validTimeUntil = 2359, timeNow = 1921

Men med checken ovan validTimeFrom <= timeNow så får jag alltid else med "Innan starttid"... Jag vill ju ha att vi är efter starttid.. och det bör det ju vara i detta läge med timeNow = 1921, men är inte så..

Vad jag förmodar så är det därför jag jämför fel sorts värden!??

Precis. Du kan inte jämföra innehållet i strängar på det sättet. Uttrycket if (validTimeFrom <= timeNow) jämför de två strängarnas position i minnet, inte deras innehåll! Både validTimeFrom och timeNow är ju pekare till början av respektive sträng i minnet.

Som t.ex. adent redan sagt: räkna om till minuter (och strunta i att använda textsträngar) eller jämför direkt mot eepromvarArray med memcmp() som ie tipsar om. Det senare får väl anses som en rätt avancerad programmering så jag rekommenderar absolut att du gör det första - det blir mer kod men betydligt enklare att förstå vad som händer, tror jag.


Upp
 Profil  
 
InläggPostat: 15.26 2019-08-26 

Blev medlem: 20.20 2010-08-30
Inlägg: 3518
Ort: Umeå
hur får du ut t.e.x. eepromvarArray[4] till värde "10"?
om det är en char kan det inte beskriva ascii "10" då det är två byte, eller är det en int?

"uint16_t validHourFrom" är ju en 16 bitars int, och måste behandlas som en int

typ



uint16_t fromMinutes, untilMinutes;


fromMinutes = (validHourFrom * 60) + validMinFrom;

nowMinutes = (nowHour * 60) + nowMinues;


if ( fromMinutes <= nowMinutes )
{
Serial.println("Efter starttid");
}

e.d.


Upp
 Profil  
 
InläggPostat: 16.12 2019-08-26 
Användarvisningsbild

Blev medlem: 11.56 2004-05-08
Inlägg: 3730
Ort: Stockholm
Han skriver ju att han "läser ur EEPROM med timme i en byte och minuter i en byte", så jag tolkar det som att eepromvarArray är en byte-array. Och i så fall funkar det ju (varje position kan lagra värde 0-255).

Att separera år, månader, dagar, timmar, minuter och sekunder istället för att bara räkna sekunder är för övrigt samma misstag som Microsoft gjorde för att lagra tid i DOS, i MS DOS Date & Time Format: 32 bitar där 7 bitar används för att representera antalet år från 1980 (år 1980-2108), 4 bitar används för månad, 5 bitar för dag i månaden, 5 bitar för timmar (0-23), 6 bitar för minuter (0-59), och 5 för sekunder (0-30, det vill säga upplösningen är 2 sekunder).

Hade de använt alla 32 bitarna för att räkna sekunder istället så hade de fått sekundupplösning och ett tidsspann på 136 år istället för 127 år...


Upp
 Profil  
 
Visa inlägg nyare än:  Sortera efter  
Svara på tråd  [ 12 inlägg ] 

Alla tidsangivelser är UTC + 1 timme


Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 1 gäst


Du kan inte skapa nya trådar i denna kategori
Du kan inte svara på trådar i denna kategori
Du kan inte redigera dina inlägg i denna kategori
Du kan inte ta bort dina inlägg i denna kategori
Du kan inte bifoga filer i denna kategori

Sök efter:
Hoppa till:  
   
Drivs av phpBB® Forum Software © phpBB Group
Swedish translation by Peetra & phpBB Sweden © 2006-2010