Sida 1 av 1

Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 12:28:06
av toffie
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: Markera allt

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: Markera allt

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!

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 12:33:10
av Zeela
Prova :
variabel3 = variabel1 *100 + variabel2;



.

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 12:34:16
av Kulla
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

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 12:36:01
av Swech
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

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 12:44:06
av Icecap
"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);

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 13:14:35
av adent
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.

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 13:36:52
av FormerMazda
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.

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 14:10:42
av svanted
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 ))
{




}

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 15:29:50
av ie
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

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 16:05:07
av arvidb
toffie skrev:

Kod: Markera allt

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.

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 16:26:45
av svanted
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.

Re: Lägg ihop två int's utan addering, för jämförelse

Postat: 26 augusti 2019, 17:12:10
av arvidb
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...