DS1307 - help with display

adumas

Member
I compiled this simple program reading every forum message I could find...

It is nearly working.... The display is only showing part of each byte... Could someone let me know what is wrong with the code... I have commented the result I am looking for...


'******************************************************
; set picaxe type
#picaxe 18x

'******************************************************
; set COM port used for download
#com 5


'******************************************************
i2cslave %11010000, i2cslow, i2cbyte 'set slave parameter


'******************************************************
'arbitrarily setting the clock to begin with:
' 37:14:03 03:08:10
' ss:mi:hh yy:dd:mm

'******************************************************
'b0, b1, b2, b3, b4, b5, b6, b7
writei2c 0, ($37, $14, $03, $04, $03, $08, $03, $10)

pause 500

'**************** read back the results ***************
readi2c 0,(b0,b1,b2,b3,b4,b5,b6,b7)

pause 500

let b13 = b0
gosub trans

let b13 = b1
gosub trans

let b13 = b2
gosub trans

let b13 = b3
gosub trans

let b13 = b4
gosub trans

let b13 = b5
gosub trans

let b13 = b6
gosub trans

end


trans:
b10 = b13 / $F0 + $30
b11 = b13 and $0F + $30
'**************** display the results ***************
sertxd (b10,b11,cr,lf)
return
 

hippy

Ex-Staff (retired)
Looks okay to me. You can change the SerTxd to "sertxd (#b13," ",b10,b11,cr,lf)" to check the raw data is coming back as expected.
 

adumas

Member
I think if you run the program you will see the problem...

This is the data that is returned via sertxd:
07
04
03
03
08
00


I should be getting:

37
14
03
03
08
10

Is this a high byte / low byte issue?
 

hippy

Ex-Staff (retired)
I think if you run the program you will see the problem...
I think if I run the program I'll see complete garbage, especially with not having a DS1307 ;-)

Hence, SerTxd(#b13," ",b10,b11,cr,lf), and a follow-up report on what that does.

That way we can see if the msb's of b13 are zero which would explain why b10 always appears to be "0". If the value of b13 never gets over 15 then there's some issue with the I2C interfacing, if it exceeds 15 then there's some issue in the way it's being converted and sent back to the PC.

Looking at the final output shows something is wrong but doesn't show what is wrong. There are a number of possibilities. Getting more information allows the cause of the problem to be identified. It's not always a case of finding what's wrong, but finding what's right, take that away and what you're eventually left with must contain the problem.
 

inglewoodpete

Senior Member
I think MartinM has solved the problem. In the original code, dividing a byte by $F0 will give a result of 0 in most cases.
 

hippy

Ex-Staff (retired)
@ Inglewoodpete, MartinM57 : Yes, I forgot to acknowledge that looks to be the problem ! I missed "b13 / $F0" when I first looked at the code.
 

MartinM57

Moderator
So for adumas....
....you want b10 to be the high byte of b13

e.g 0101xxxx -> 00000101

So you need to shift right 4 times, which is also known as divide by 16...

..then you add $30 to make it an ASCII character
 

adumas

Member
Ok... One other question.

To assign a variable then the final calculation, I would have thought it would be a simple concatenation... I tried this below, but it doesn't work...

What am I doing wrong?

symbol minutes = b6

b10 = b13 / 16 + $30
b11 = b13 and $0F + $30
minutes = b10 & " " & b11
 

MartinM57

Moderator
b6 (and any other bX) is just a 8-bit variable capable of holding just one byte of information...

...so attempting to concatenate 3 bytes (b10, a space, and b11) into it is not going to work.
 

adumas

Member
Ok...

Then if I use a word I should be able to concatenate the 2 bytes, right?

'******************************************************
; set picaxe type
#picaxe 18x

'******************************************************
; set COM port used for download
#com 5

symbol secondsword = w4


'******************************************************
i2cslave %11010000, i2cslow, i2cbyte 'set slave parameter


'******************************************************
'arbitrarily setting the clock to begin with:
' 37:14:03 03:08:10
' ss:mi:hh yy:dd:mm

'******************************************************
'b0, b1, b2, b3, b4, b5
writei2c 0, ($37, $14, $03, $03, $08, $10)

pause 500

main:

pause 100

'**************** read back the results ***************
readi2c 0,(b0,b1,b2,b3,b4,b5 )

pause 100

secondsword = 0

let b13 = b0
b10 = b13 / 16 + $30
b11 = b13 and $0F + $30
sertxd ("Seconds: ", b10,b11 ,cr,lf)
secondsword = b10 & b11
sertxd ("Seconds: ", secondsword ,cr,lf)

end
 

BCJKiwi

Senior Member
Since the original query was "- help with display", then this last step is unnecessary as the two sertxd lines will display the same.
If however the output is required as a word for some other reason then this step may be required.
 

Mycroft2152

Senior Member
Back in the early days of the Apple, TRS-90 and Commodore computer games, this kind of "text packing" was used to encrypt the text error messages and also to save memory space.
 
Last edited:

adumas

Member
Hi BCJKiwi. I'm still having a problem...

The output is not coming out the same...

For the 2 sertxd's, I'm getting:

Seconds: 37
Seconds: 3

Both should be 37....

I'm sorry to be persisting in this problem but I'm trying to make sense of it all... By defining a word variable (secondsword = w4), I thought it would essentially hold the concatenation of b10 & b11 - but it is truncating...

What am I doing wrong?
 

hippy

Ex-Staff (retired)
b10 = b13 / 16 + $30
b11 = b13 and $0F + $30
sertxd ("Seconds: ", b10,b11 ,cr,lf)
secondsword = b10 & b11
sertxd ("Seconds: ", secondsword ,cr,lf)
That won't work for a number of reasons. That "&" is a bit-wise AND of two byte variables ( the PICAXE doesn't run Visual Basic ), and SerTxd will only send the byte value of the lsb's of a word when used anyway. There's nothing to gain from doing this 'concatenation', it won't transmit any faster and would probably use more program memory.

If you want to save a few bytes of program memory ...

b10 = b13 / $10
b13 = b13 & $0F
SerTxd( "Seconds: ", #b10, #b13, CR, LF )
 

adumas

Member
Thanks for answering Hippy... Picked up on the VB, eh... Couldn't hide it...

I'm starting to think that perhaps my approach to gathering data may be wrong...

My thought was to gather up all of the data from multiple sources (e.g., temperature, clock, etc.) and then do a final write... To do this I normally would assign the data to various variables and then write the final variables out later on.

In the below example, there are 6 values that make up time and date. So... My normal way of thinking is to assign each to something more meaningful than b0, b1 etc...

But I'm thinking maybe this is not a good approach e.g., I'll be consuming too much memory? And that is not how a picaxe programmer would do it?

Do I have that right? Just checking...
 

inglewoodpete

Senior Member
:eek:(in a small voice from the back of the class) i didn't see the second page of the thread before replying:eek:
 
Last edited:

BCJKiwi

Senior Member
adumas;
It all depends on the overall program.

At this stage all you have indicated is DS-1307 with display to the terminal in the Editor.

There are two basic approaches, the one you have indicated - collect all the data and output once,
Or
Collect the data you need for one step and output that, then move on to the next step.

The second approach would allow more re-use of standard variables (i.e. b0,b1 etc could be used in multiple places) and less program size or complication. However, when writing to an LCD it may require more positioning commands for the LCD.

These two approaches can be mixed;
In a data logger typically all the data is collected and processed, then written out at once as you don't want to keep initiating writes to the (relatively) slow logging device. However this can be done by writing to consecutive Ram addresses to keep the variables free for the next program section, then writing the output from Ram.

On the 18X you are limited to the standard b0,b1, w0,w1 type variables, and peek/poke to Addresses $50 to $7E and $C0 to $EF.
So it will probably be better to modularise your code as much as possible and output as you go, thus avoiding running out of variables and keeping the code small and fast.
If this is too messy, then output with pokes (draw yourself a memory map of where to put each piece of data), then retrieve all the data in one pass with Peeks for final output.

If you create symbols for the variables then it may simplify the coding of the modules but be aware that you can create multiple symbols for the same variable.

Creating symbols does not add to the program length.
 
Last edited:

Technical

Technical Support
Staff member
a byte variable b6 (minutes) cannot be a concatenation string - it can only be a number between 0 and 255!

You need to do

let b13 = b10
gosub trans
let b13 = " "
gosub trans
let b13 = b11
gosub trans
 
Top