PDA

View Full Version : Matching time conditions



malc-c
- 28th March 2010, 16:30
I want to be able to set a time period using a DS1307 where a condition is matched and an action (value ) is changed. EG between time A and time B value x=25, bur between time B and time A value X =32.

Here's the section of code I have that displays the time on the LCD


'
' Display Time on Line 1
' ----------------------
LCDOut $FE,$80
If RTCHour.6=1 then
' Work-Out 12 or 24 hour Display for Hours
CounterA=(RTCHour>>4)&$01
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F)
If RTCHour.6=1 then
' Display Hours appropriately for 12 or 24 hour Mode
LCDOut #CounterA
else
LCDOut #CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "


IF RTCHour.6=1 then
If RTCHour.5=1 then
LCDOut "PM"
else
LCDOut "AM"
endif
endif
'


From this it seems that CounterA dig0 and dig1 represent the hour and RTCMin the minutes. Is it a simple case of using a variable to match these and then toggle another variable that holds value X, something like

if CounterA dig0 + CounterA dig1 => 1 then tempset=26
if CounterA dig0 + CounterA dig1 => 6 then tempset=32

Or is there a better way (simpler?) to do this ?

malc-c
- 28th March 2010, 17:24
Using the LCD I obtained the values for DEC RTCHours, my logic being that this then gives me a variable which I can then use, eg 21hrs gives a value of 33.

I then tried to use this value thus



LCDOut $FE, $D4,"rtc value = ", dec rtchour
AlarmH1 = Dec(RTCHour)
If alarmH1=33 then
alarmled=1
endif


But I get a bad expression error with the AlarmH1 = Dec(RTCHour)

If I can get the value into a varaible somehow I have something to work with

mackrackit
- 28th March 2010, 17:40
Something like


HEXRTCHour = RTCHour $ $70

Should convert the BCD into HEX
I think....

malc-c
- 28th March 2010, 20:25
Dave, thanks for the reply, but I get a syntax error with that no matter how format it, (even added a HexRTCHour var byte in the code) - :mad:

mackrackit
- 28th March 2010, 20:37
Hmm..

This is from one of mine to change the I2C output to HEX then display the DEC via serial.


I2CRead DS_SDA, DS_SCL, RTC, SecReg, [sec,MINs,hr,day,date,mon,yr]

SEC_T = sec & $70
SEC_T = SEC_T>>4 'Tens place
Serout2 PORTC.6, 16572,["SEC_T ",DEC SEC_T, $d, $a]
SEC_O = sec & $0F 'Ones place
Serout2 PORTC.6, 16572,["SEC_O ",DEC SEC_O, $d, $a]

malc-c
- 28th March 2010, 20:59
Hmm..

This is from one of mine to change the I2C output to HEX then display the DEC via serial.


Dave - I note your deliberate mistake to keep me on my toes :)



HEXRTCHour = RTCHour $ $70




SEC_T = sec & $70


Thanks - that's compiled - will now go away and play :)

mackrackit
- 28th March 2010, 21:05
Dave - I note your deliberate mistake to keep me on my toes
That was not deliberate... dirty bifocals :p

malc-c
- 28th March 2010, 21:20
LOL -

Dave, whist I can display the DEC value using and LCD using that code, I still can't apply it to a variable that can be worked with,

any ideas... I simply want something like alarmhour= DEC(HEXRTCHour). It seems that whilst you can use DEC to convert and display a value or send a value via coms, you can't directly apply it.

mackrackit
- 28th March 2010, 21:35
I was thinking not to worry about comparing to a DEC. Convert the BCD and compare to the conversion.

If you can not get a solution I will work something up when I get back to the shop tonight.

malc-c
- 28th March 2010, 21:46
Dave, something like



HEXRTCHour = RTCHour & $70
if alarm & $70 = HEXRTCHour then
alarmled=1
endif


If so then how do I set the value for the variable alarm ?

Thanks for the offer of some assistance. If you prefer to drop me a pm with e-mail addy, it might save space on the forum server ? - there is also no rush...

Darrel Taylor
- 29th March 2010, 00:22
Here's an idea from a previous thread ...

Calculating Time for clock's preset
http://www.picbasic.co.uk/forum/showthread.php?p=58913#post58913
<br>

mackrackit
- 29th March 2010, 03:19
How about something like this?


alarm = %1001 ' The ninth hour...
RTCHour_BIN = ((RTCHour >> 4) * 10) + (RTCHour & $0f) ' Converts BCD to Binary

BobK
- 30th March 2010, 02:17
Hi Malc-c,

I think I have a grip on what you want to do.

Have you given any thought to using a DS1337 RTC? It has 2 alarms. You can set the alarm times any time you need to change the times. I use it for a clock project and work the entire program including sending time/date information out to a serial display all in HEX. I operate the clock in the 24 hour mode. I even have a test routine that changes the alarm times from the programmed alarm times to 1 minute + current time and put that time in the alarm A register and 2 minutes + current time in the alarm B register then lets me test the actual operation of my project in just a few minutes then restores the normal alarm times. I have had 75 of these clocks out in the field since April of 2007.

Let me know if this is of any interest to you.

BobK

malc-c
- 30th March 2010, 07:18
Hi Bob,

The reason I'm using the 1307 is that it's fitted to the module used with the EasyPIC 5 board, however I could always breadboard a 1337, so your offer of assistance would be very welcome.

I'll drop you a pm as from what you are saying, the two alarms are ideal for my project

Thanks

Acetronics2
- 30th March 2010, 07:25
Hi, Malc

The other RTC Module from MKE ( W/a PCF8583 ) has an Alarm function ...

no comment needed ???

Alain

malc-c
- 30th March 2010, 07:29
Alain, another module to add to my collection.... :)

Don't tell the wife I'm spending more money on this project :)

malc-c
- 5th April 2010, 17:08
Alain,

Quick question, I take it this new module will still work with the same code for the DS1307, ie


I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]

Incidentally, can someone break down that line. I understand it's the code to read the I2C channel, data pin, clock pin, and then the current value for each of the time / date fragments, but in what format is the raw code. It mentions BCD ?

Also, do you have to read [RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl] in one hit, or could you choose to read back just the hours and mins ?

Melanie
- 5th April 2010, 17:56
DATASHEET!!!!

Just as you wouldn't have a clue what CMCON was for a PIC that you never met before, in the same way you need to know what Registers you've got inside your DS1307, in what sequence you arrive at them, and what their contents are.

Download the DATASHEET for the DS1307.

You will follow the SAME proceedure for ANY complex chip (or device) that you come across. Copying and relying on other peoples code is insufficient. It's worse than trying to decypher Egyptian without the Rosetta stone.

And in answer to your question, you can choose to read back whatever you want in whatever sequence you want (though not nescessarilly in one I2C instruction)... the DATASHEET will explain how and reveal other Registers, features and goodies which you may be unaware of, and which the code you are copying from does not take advantage of.

isaac
- 5th April 2010, 21:12
Why not simply usesomething like a DS1337
where you can have an alarm time and compare it with the current time and if there is a match the DS1337 has a pin that either goes high or low ( cant remember check the data sheet)
This can then be connected to your interupt pin
here is an example
http://www.picbasic.co.uk/forum/showthread.php?t=662&highlight=toni

Isaac

malc-c
- 5th April 2010, 21:38
Isaac,

many thanks for the link - I'll study that and will look at breadboarding the 1337 chip.

Melanie,

I've looked at the datasheet on many occasions, but to those of us who can only grasp the basics, these datasheets tend to be somewhat daunting, and whilst I don't possess the Rosetta Stone, sometimes Egyptian would probably seem easier than many a datasheet by half :)

Also, for me I learn far more about PBP from example code written by those more advanced at programming than trying to fathom out the ins and outs of complicated chip structure. After all, this is a forum on PicBASIC Pro. I guess I should of registered at Maxim's forum (assuming one exists) to ask for technical assistance with the data format from the DS1307.

Melanie
- 5th April 2010, 23:24
After all, this is a forum on PicBASIC Pro. I guess I should of registered at Maxim's forum (assuming one exists) to ask for technical assistance with the data format from the DS1307.

Just do as you're told and download that Datasheet!

Then, and ONLY THEN you will be able to compare that I2C Statement with the DS1307's Registers. IT IS the Rosetta stone... until you've looked you won't see it.

I'm NOT being iffy or off-hand with my answer to your query... I'm actually telling you EXPLICITLY that IT WILL HELP YOU UNDERSTAND.

Skip all the crap and jump straight into the section on the Registers... look, it's all laid out crystal clear - it shows you what sequence they're in, how they're addressed, what's inside them... how on earth can you possibly understand what's going on in a piece of code if you don't understand what a particular BYTE of DATA has got inside it at any point in time.

If I told you that Bit 7 of the SECONDS Register was kinda IMPORTANT - How would you know? I could be talking Greek (sorry Ioannis)!

One look, and you know what the $D0 is all about in the I2C Statement. And what about $00 - what's it there for? The answer is screaming at you from the pages of the PBP Manual description of the I2C Command, and the DS1307's Datasheet. The two of them go together hand-in-hand. There's NO other secret document, no Training Course in Electronics or programming... just those two items together allow you fully understand, manipulate and control that chip. Don't handicap yourself unnescessarilly by dismissing it's 'beyond' your understanding. The DS1307 is a simple chip. But more importantly it's a stepping stone on the path to progressing to more complex hardware devices.

Armed with that information, THEN come on the forum and ask your questions. Then folks can point you as to WHY something is the way it is. YOU ASKED about accessing Data out of sequence... that $00 holds the key, and that Datasheet tells you what you should change it to if you wanted just to extract say HOURS. But if I simply said you change it to $02, my answer would be totally meaningless unless you knew WHY!

That is WHY I really PUSH folks to TRY and get to grips with Datasheets. The Ds1307 only has a dozen pages or so, and a chunk of those are irrelevant, so it's not like I'm asking you to digest Tolstoy's War & Peace.

malc-c
- 11th April 2010, 16:57
The other RTC Module from MKE ( W/a PCF8583 ) has an Alarm function ...



Well after a lot of searching I've just ordered that module...

Seems that none of the usual electronics outlets stock the DS1337 (RS, Rapid etc). Hopefully the module will be here mid week so I can start playing again :)

Better start reading the datasheet - even if it's only to keep Mel happy :)

malc-c
- 11th April 2010, 17:52
... And what about $00 - what's it there for? The answer is screaming at you from the pages of the PBP Manual description of the I2C Command, and the DS1307's Datasheet. The two of them go together hand-in-hand.

Mel,

Bear with me on this as I'm sure quite a few of us still have difficulties in getting our heads round bits and bytes and registers etc. But to try and answer your question and see if I've got some grips with the data sheet, here's my take on the above.

$00 is the start of the register address (00H). This byte stores the seconds, bits 0-4 for the digits and bits 5-7 the 10's. The next byte (01H) is the same but for mins. 02H stores the hours, with bit 6 setting the device up for 12/24 hrs depending if set high or low. Bits 0-2 of 03H stores the days, 04H date, 05H month, 06H year (1st 4 bits for digits, last 4 bits decades).

The only part I don't grasp is the $D0 part - The manual stated


I2CREAD DataPin,ClockPin,Control,{Address,}[Var{,Var...}]{,Label}


so in the code I have


I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]


which transpires as datapin, clockpin, then control. but the only control reference I can find in the data sheet is for SQW (square wave out), and I'm still at a loss as to where you arrive at the $D0

malc-c
- 11th April 2010, 18:34
The only part I don't grasp is the $D0 part -

OK now got it...



from the datasheet The address byte contains
the 7 bit DS1307 address, which is 1101000, followed by the *direction bit (R/W ) which, for a write,
is a 0.

I used a binary to decimal / hex convertor.... 11010000 is D0, therefore the $D0 is the address which the PIC looks for to locate the DS1307 on the I2C buss and sets the DS1307 to either receive data or to send it ?

Melanie
- 11th April 2010, 19:13
You've nailed it Malcolm.

I know I was a bit hard on you, but now you see how simple it all is with that Datasheet and how near impossible it is to understand without.

malc-c
- 11th April 2010, 20:39
Thanks...

Although I now have an understanding of how the DS1307 is accessed and what the registers are... I'm still a long way from understanding a 300 + page data sheet on one of the more complex PICs !, and I must confess I'm still at a loss on how to use the 1307 to match a value in the code an in turn set a value of a variable.

I assume that each byte for each register (01H, 02H etc) is converted from binary into BCD (which I gather is 4bit type code format of binary)... or does pbp simply read each byte at each register.

I guess the simple answer is to wait until I receive the new chip with the alarm function and use that ?

Melanie
- 11th April 2010, 21:12
The I2CRead command will simply grab the content of each Register.

With the DS1307, you find that bit 7 in some of the registers is used for odd things. So, stripping that out, the first four bits (0-3) is the units digit (in binary), and bits 4-6 is the tens digit (in Binary). Which is why they fiendishly called it Binary Coded Decimal.

You've noticed it's in BCD. The first thing is to convert it to something that is useable. So I end up with a single variable that is HOURS, another variable for MINUTES etc. It's easier to have a single byte whose content varies from 0 (zero) to 59 representing MINUTES, because then you can perform math on it directly.

If your Alarm time is stored in the PIC (say your morning alarm at 07 Hours and 15 Minutes) it's a simple matter to compare if those two variables (say ALARMHour and ALARMMinute) match what you've read from the RTC (after converting from BCD). I tend to ignore seconds because unless you're polling better than once a second (or have a hardware interrupt on receipt of the SQUARE wave the RTC can output), or if your code is sloppy, you can easily miss one second.

If you're really clever, you can convert the Date and Time to JULIAN Date & Time, which gives you a single variable which holds a linear combination of Year, Month, Day, Hour, Minute and Second. Now this is great, because then you can simply add 3600 to advance an hour etc etc. There's another thread somewhere on this forum where I did just that with another DS series chip (albeit some years ago). This is the method I choose to use for things like Alarms with a DATE attached (eg Central Heating Timers), whereas Alarms with just TIME (such as your bedside radio's) usually comparing Hours and Minutes suffices.

malc-c
- 12th April 2010, 00:02
Mel,

Thanks for that explanation. I've been watching the US Masters on TV so it's just coming up to midnight here in the UK, so will look at your suggestion tomorrow after work.



If your Alarm time is stored in the PIC (say your morning alarm at 07 Hours and 15 Minutes) it's a simple matter to compare if those two variables (say ALARMHour and ALARMMinute) match what you've read from the RTC (after converting from BCD).

Which is basically what I'm after. I intend to have an ALARMHour1 and ALARMHour2 to set an on time and off time to monitor.

Thanks once again for the push to try and understand these data sheets. It's somewhat clearer now :)

malc-c
- 12th April 2010, 19:52
Help !

I'm struggling with the conversion bit, and would appreciate some assistance.

To keep things simple I'm going to restrict the alarm values to just hours, so I have one Alarm variable called AlarmH1 which I'm trying to match to the RTCHour.

The I2C statement is thus


I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]


I'll now post the part of the code I'm using for testing in it's current state (sorry it's somewhat messy)


LCDOut $FE,$80
If RTCHour.6=1 then
' Work-Out 12 or 24 hour Display for Hours
CounterA=(RTCHour>>4)&$01
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F)
If RTCHour.6=1 then
' Display Hours appropriately for 12 or 24 hour Mode
LCDOut #CounterA
else
LCDOut #CounterA Dig 1,#CounterA Dig 0
endif

LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
LCDOut $FE, $D4,"value = ", #RTCHour;dec CounterA ;Dig 1,#CounterA Dig 0

alarmhour = 25
if alarmhour = rtchour then
alarmled=1
endif



The LCD is used to display the time and date, with line 4 used to "debug" what's happening with whatever I choose to display, eg as you can see dig1 and 0 og CounterA, ascii value of RTCHour, even tried DEC RTCHour etc. In the above example the LCD gives an ascii value of 25 for RTCHour hence the value for alarmhour. I've also tried using something like if DEC alarmhour = DEC RTChour but that still fails...

Can someone (Mel ?) point me in the right direction on how I convert the value stored in the RTCHour register into some usable format (decimal say ) that I can use. I'm hoping to use a repeat of the set up routine to allow me to set the on hour and off hour, but that will come later. For now I just need to find the best way to match the value....

Byte_Butcher
- 12th April 2010, 20:32
I use these with a DS1302 to convert RTC minutes, hours, etc, to BCD minutes.



decminutes =(rtcmin>>4)*10+(rtcmin & $0F) 'convert BCD minutes into Decimal minutes .




rtcmin=((decminutes DIG 1)<<4)+decminutes DIG 0 'convert Decimal back to BCD .



steve

Melanie
- 12th April 2010, 21:31
DecimalHours=RTCHours>>4
DecimalHours=(DecimalHours&$03)*10
DecimalHours=DecimalHours+(RTCHours&$0F)

RTCHours is read from the DS1307. It is in BCD format.

The first line takes bits 4 thru 7 and loads them into Decimal Hours as bits 0 thru 3. These are the DECIMAL TENS DIGIT VALUE of the BCD HOURS (plus a couple of additional control bits).

If you notice from the Datasheet, only bits 4 and 5 are the BCD TENS DIGIT (which we have moved to bits 0 and 1 of variable DecimalHours. Since we only need those two bits, we exclude all others with the AND '&' operator, ANDing it with $03. The result of that operation we simply multiply by ten. We now have our TENS DIGIT value extracted.

The third line takes the lower four bits ONLY (by ANDing them with $0F) of the RTCHours variable (those four bits being the BCD UNITS VALUE) and we ADD them to our previously extracted TENS VALUE.

We now have a BYTE variable called DecimalHours which contains a value between 0-23 (assuming you are running a 24 hour clock). You can Output it to your LCD with the command...

LCDOUT #DecimalHours

If you wanted your alarm at say 7am you can now simply say...

AlarmHours=7
If AlarmHours=DecimalHours then goto SoundKlaxxon

malc-c
- 12th April 2010, 21:31
Steve,

Thanks for that, which I guess is similar to some of the code posted above.

This is the section of code based on your suggestion, and it too displays the value of AlarmH1 as 21 when the rtc is displaying 21 hrs, however the led on D7 fails to light (I've tested an the hardware works)



// Alarmh1 =(rtchour>>4)*10+(rtchour & $0F)
alarmhour = 21

LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
LCDOut $FE, $D4,"value = ", dec alarmh1

if alarmhour = alarmh1 then
PORTD.7=1
endif


Welcome any comments... even if it's to point out the illogical of my logical coding.

malc-c
- 12th April 2010, 21:37
Mel, thanks for the post, which happened whilst I was typing mine.

It's not the displaying of the time I'm having a brain freeze on, it's working out how to do the comparison with another variable so that if the condition is true (ie the hour set ( between 0 and 23) matches the RTC hour) the LED can be made to light (or a value in another variable can be set)

Melanie
- 12th April 2010, 21:44
Last three lines of my post Malcolm...

malc-c
- 12th April 2010, 21:49
Last three lines of my post Malcolm...

Mel,

I've used your example but still can't make the LED go high



AlarmH1=(RTCHour>>4)
AlarmH1=(AlarmH1&$03)*10
AlarmH1=AlarmH1+(RTCHour&$0F)

alarmhour = 21

LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
LCDOut $FE, $D4,"value = ", # AlarmH1

if AlarmH1 = alarmhour then
PORTD.7=1
endif


The LCD displays 21 as the value for AlarmH1

what am I doing wrong ???

Melanie
- 12th April 2010, 21:55
You've set TRIS for PORTD.7 for Output?

You've checked that anything else that share that pin is switched off (eg any Analogue or other devices).

You've connected your LED the correct way around (with a current limiting Resistor) and it works?

Personally I like to use HIGH and LOW... eg...

HIGH PortD.7

eg

If AlarmH1=AlarmHour then
HIGH PortD.7
else
LOW PortD.7
endif

malc-c
- 12th April 2010, 21:56
If I use the LCD to check, I get 21 for both values of AlarmH1 and alarmhour, so the two do match... and I've tried PortB.5 just in case port D wasn't set for output (well it's been along day !)



LCDOut $FE, $D4,"value = ", # alarmh1, #alarmhour

malc-c
- 12th April 2010, 21:59
You've set TRIS for PORTD.7 for Output?

You've checked that anything else that share that pin is switched off (eg any Analogue or other devices).

You've connected your LED the correct way around (with a current limiting Resistor) and it works?

Personally I like to use HIGH and LOW... eg...

HIGH PortD.7

eg

If AlarmH1=AlarmHour then
HIGH PortD.7
else
LOW PortD.7
endif

Scrub my last post - I used your HIGH LOW example and it worked :confused::confused:

Thank you.....

malc-c
- 12th April 2010, 22:03
LOL - the LED just went out as the clock turned to 22:00 hrs :)

The best bit is I've learned more about datasheets through this thread, and some of the pitfalls of my poor coding :)

Thank you for your patience Mel - I do appreciate it

Byte_Butcher
- 12th April 2010, 22:26
Scrub my last post - I used your HIGH LOW example and it worked :confused::confused:


If HIGH / LOW works, but PORTD.7 = 1 DOESN'T work, that sounds like a sure sign that you don't have your pin correctly set as an output.

Using HIGH or LOW automatically sets the pin as an output first before it sets it high or low

Check your TRIS settings again. PORTD.7 = 1 SHOULD work if the port is set up right....


steve

malc-c
- 12th April 2010, 23:05
Thanks Steve... I had the TRISO for port D set so no Idea !

One last thing (for tonight)

I added a section for minutes too and could get the LED to come on at say 22:34 and go out at 22:35.



AlarmH1=(RTCHour>>4)
AlarmH1=(AlarmH1&$03)*10
AlarmH1=AlarmH1+(RTCHour&$0F)

AlarmM1=(RTCMin>>4)
AlarmM1=(AlarmM1&$03)*10
AlarmM1=AlarmM1+(RTCMin&$0F)

AlarmHour1 = 22
Alarmmin1 = 34

LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
LCDOut $FE, $D4,"value = ", # alarmh1, #alarmhour1

If AlarmH1 = AlarmHour1 and AlarmM1 = alarmmin1 then
HIGH PortD.7
else
LOW PortD.7
endif


So I added a a few more variables to try and set a time range but whilst it compiles it no longer lights the LED.




AlarmH1=(RTCHour>>4)
AlarmH1=(AlarmH1&$03)*10
AlarmH1=AlarmH1+(RTCHour&$0F)

AlarmM1=(RTCMin>>4)
AlarmM1=(AlarmM1&$03)*10
AlarmM1=AlarmM1+(RTCMin&$0F)

AlarmHour1 = 22
Alarmmin1 = 53
alarmhour2 = 22
Alarmmin2 = 55

LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
LCDOut $FE, $D4,"value = ", # alarmh1, #alarmhour1

If AlarmH1 >= AlarmHour1 and AlarmH1 <= alarmhour2 and AlarmM1=>alarmmin1 and alarmM1<= alarmmin2 then
HIGH PortD.7
else
LOW PortD.7
endif


Any ideas ?

Darrel Taylor
- 12th April 2010, 23:18
Hi Malcolm,

I'm wondering if you missed the link I showed in post 11 (http://www.picbasic.co.uk/forum/showthread.php?p=87316#post87316).

I really think that's what you're looking for.
<br>

malc-c
- 12th April 2010, 23:31
Hi Darrel,

Must of overlooked that... I'll have a read at work in the morning, and the see if I can implement the suggestions... It's getting late, my two little gray cells have gone to sleep...

Melanie
- 13th April 2010, 00:51
Malcolm, you can't have '&$03' for MINUTES (the way you have for HOURS)... but can you figure why and what value it should be if not $03? Correct that small omission and your code will run (there's incentive for you).

malc-c
- 13th April 2010, 08:08
Malcolm, you can't have '&$03' for MINUTES (the way you have for HOURS)... but can you figure why and what value it should be if not $03? Correct that small omission and your code will run (there's incentive for you).

I have a hunch it's to do with the register map

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=4184&d=1271142517

Only the 1st 4 bits are used for hours (0-23) when in 24 Hr mode, where as the minutes use 7 bits of the byte, the latter 3 to store the tens. However I confess at the moment I'm at a loss as to what value I need

Melanie
- 13th April 2010, 14:53
Never Cut & Paste without first knowing what it is you're doing, otherwise I'll be tempted to put up some code so your PIC will email me the passwords to your Bank Account.

Let's do this real slow step by step...

Look at the HOURS Register... and the first line of code...



Bit 7 6 5 4 3 2 1 0

x x f e d c b a = RTCHour

0 0 0 0 x x f e = DecimalHour after >>4 rotation


the 'x' bits we're not interested in, the other bits we are... I've named them from a (Bit 0) through to f (Bit 5). Notice after the >>4 where we shift everything four places to the right we're left with the bits that were in positions 4 thru 7 shifted into positions 0 thru 3, the bits that previously occupied 0-3 have been shifted into oblivion and with zero's shifted into the upper four bits (positions 4-7).

The next stage is we AND it with $03... this is because we're only interested in the bits located at 0 and 1, and those two x's could be crap we don't want...



Bit 7 6 5 4 3 2 1 0

0 0 0 0 x x f e = DecimalHour

0 0 0 0 0 0 1 1 = AND'd with $03

0 0 0 0 0 0 f e = Result after AND operation


We then multiply the resultant by ten (since it's the TENS digit, and we finally add in the lower four bits of RTCHour ... and that just to clarify visually what ANDing with $0F accomplishes...



Bit 7 6 5 4 3 2 1 0

x x f e d c b a = RTCHour

0 0 0 0 1 1 1 1 = AND'd with $0F

0 0 0 0 d c b a = Result after AND operation (the enitire UNITS DIGIT of the BCD RTCHour Register)


NOW, when you're dealing with MINUTES (see your Datasheet Register for MINUTES) you will notice we have bits 0 thru 6 which are significant (not bits 0 thru 5 as with the HOUR). So if you use $03, you will be happy ONLY if you have 00-39 minutes (because bit 6 of the TENS DIGIT is never extracted - it's masked out - therefore minutes 40-59 won't work)... so instead of $03 you need to do $07 as follows...



Bit 7 6 5 4 3 2 1 0

x g f e d c b a = RTCMinute

0 0 0 0 x g f e = DecimalMinute after >>4 rotation

0 0 0 0 0 1 1 1 = AND'd with $07

0 0 0 0 0 g f e = DecimalMinute AFTER ANDing with $07


Only then you can multiply it by ten (since it's the TENS DIGIT) and add-in the units as previously.

Clear as mud I trust?

malc-c
- 13th April 2010, 18:13
Mel,

Thanks for the very detailed explanation, it has helped as I wasn't sure how the $xx was related to the binary (ie 07 in binary being 111) and what exactly the >> related to.

I'll try your suggestion tonight - Thanks for the lesson, and I promise to do my homework from now on :)

malc-c
- 13th April 2010, 19:38
Mel, with your help I now have something I can work with



AlarmH1=(RTCHour>>4)
AlarmH1=(AlarmH1&$03)*10
AlarmH1=AlarmH1+(RTCHour&$0F)

AlarmM1=(RTCMin>>4)
AlarmM1=(AlarmM1&$07)*10
AlarmM1=AlarmM1+(RTCMin&$0F)

AlarmH2=(RTCHour>>4)
AlarmH2=(AlarmH2&$03)*10
AlarmH2=AlarmH2+(RTCHour&$0F)

AlarmM2=(RTCMin>>4)
AlarmM2=(AlarmM2&$07)*10
AlarmM2=AlarmM2+(RTCMin&$0F)

AlarmHour1 = 19
Alarmmin1 = 07
AlarmHour2 = 19
AlarmMin2 = 09


LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
LCDOut $FE, $94,"H1M1= ",#AlarmH1,":",#AlarmM1," ",#AlarmH2,":",#AlarmM2
LCDOut $FE, $D4,"set= ",#alarmhour1,":",#alarmmin1," ",#alarmhour2,":",#AlarmMin2

If AlarmHour1=AlarmH1 and alarmmin1=AlarmM1 then
HIGH PortD.7
endif
if alarmhour2=AlarmH2 and AlarmMin2=alarmm2 then
LOW PortD.7
endif



Ignore the lcdout alarmm1 etc, that was just to view the values. Interestingly it shows 19:05 as 19:5, but works regardless.

Thanks to everyone who contributed (both on the board and via e-mail), especially Mel for taking so much trouble to explain things in layman terms

Melanie
- 13th April 2010, 20:22
Malc... if you want 05:05:07 rather than 5:5:7 then...

LCDOut DEC2 DecimalHours,":",DEC2 DecimalMinutes,":",DEC2 DecimalSeconds

hmmmm... DEC2 seems to be something to look up in the manual here...