Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 08:29 29 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : DS3231 code mmbasic

     Page 2 of 3    
Author Message
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 12:18am 08 Mar 2014
Copy link to clipboard 
Print this post

Hi Grogster,

It is probably better to always read to an array rather than a single byte variable, in which case, dim an array with the maximum number of elements that you are likely to need. e.g. in the case of the RTC, DIM RTC_data(12) then when you specify the number of bytes to read each register will fit in the array.

DIM rtc_data(12)
i2c write RTC_address,0,1,0
i2c read RTC_address,0,3,rtc_data(0)

This will read the seconds, minutes and hours into RTC_data(0), (1) and (2)

The data will be in BCD format.

In your example, you are trying to assign a byte value to a string instead of a numeric variable.

(sorry I didn't get back straight away but visitors dropped in for a cuppa.)
David M.
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9308
Posted: 12:34am 08 Mar 2014
Copy link to clipboard 
Print this post

  MOBI said  DIM rtc_data(12)
i2c write RTC_address,0,1,0
i2c read RTC_address,0,3,rtc_data(0)

This will read the seconds, minutes and hours into RTC_data(0), (1) and (2)

The data will be in BCD format.

In your example, you are trying to assign a byte value to a string instead of a numeric variable.


OK, but how does the read NOT just end up putting ALL the bytes, one after another, into rtc_data(0)? Is this being handled internally by MMBasic?

Not sure I understand the BCD data being returned by the RTC - I seem to recall having similar problems understanding things when I was trying to get it working on the PICAXE(and on their forums too).

EDIT: @ MOBI - I warned you about me and I2C!!!!

ANOTHER EDIT:
  MOBI said  i2c read RTC_address,0,3,rtc_data(0)


This does not seem to want to work on the uM chip - it is rejected - see above image I posted.
Edited by Grogster 2014-03-09
Smoke makes things work. When the smoke gets out, it stops!
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 01:17am 08 Mar 2014
Copy link to clipboard 
Print this post

  Quote  OK, but how does the read NOT just end up putting ALL the bytes, one after another, into rtc_data(0)? Is this being handled internally by MMBasic?


Yes, it looks like that, but MMBasic puts the received bytes in successive array positions.

  Quote  Not sure I understand the BCD data being returned by the RTC


I don't know if you understand BCD ? If you do, then sorry about the sucked eggs. If not, in BCD, a byte is divided into a left nybble and right nybble each of 4 bits and each with a numeric value 0 to 9. When you print it, it will come up with the binary version of the variable. If you look at the example in the back of Geoff's uMite manual, it might (or might not ) make things there a bit clearer.

BCD 23 would look like 100011 but displays as decimal 35. BCD makes displaying numeric data easier.

Don't know why your read command isn't working - it is here ok. Unless you are still trying to read to a string variable?
David M.
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 03:37am 08 Mar 2014
Copy link to clipboard 
Print this post

Hi,

this Basic code works for me with the ds3231 and mmbasic Beta 10 and the 28 pin pic.
Connect Clock and Data from the RTC to Pins 18/17 of the pic with short wires.
pin 18 I2C DATA
pin 17 I2C CLOCK

Tis Routine doesnt make any conversions.
It only reads and prints the BCD values.
You have to convert the BCD values to human readable "Numbers"....

The datasheet is your friend ;-)

Dietmar



Dim RTCbuff(6) ' Received data is stored here
I2C OPEN 100,100 ' Start up the I2C module
I2C WRITE &b1101000, 0, 1, 0 ' Request the time
If MM.I2C <> 0 Then Error "RTC not responding"
I2C READ &b1101000, 0, 7, RTCbuff(0) ' Get 7 bytes from RTC
I2C CLOSE ' Close the I2C function
For i=0 To 6
Print rtcbuff(i)
Next i
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 08:54am 08 Mar 2014
Copy link to clipboard 
Print this post

@ Grogster

here an advanced example how to extract and calculate the seconds from the ds3231.

Try the rest yourself ;-)

Dietmar



Dim RTCbuff(19) ' Received data is stored here

I2C OPEN 100,100 ' Start up the I2C module
I2C WRITE &b1101000, 0, 1, 0 ' Request the time
If MM.I2C <> 0 Then Error "RTC not responding"
I2C READ &b1101000, 0, 7, RTCbuff(0) ' Get 7 bytes from RTC
I2C CLOSE ' Close the I2C function
For i=0 To 19
Print rtcbuff(i)
Next i


seconds = rtcbuff(0) And &b00001111
zehnerseconds = rtcbuff(0) And &b01110000
zehnerseconds = (zehnerseconds \ 16) + zehnerseconds Mod 16
zehnerseconds = zehnerseconds * 10
Print zehnerseconds + seconds
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 09:00am 08 Mar 2014
Copy link to clipboard 
Print this post

And here the minutes...;-)


minutes= rtcbuff(1) And &b00001111
zehnerminutes = rtcbuff(1) And &b01110000
zehnerminutes = (zehnerminutes \ 16) * 10 + zehnerminutes Mod 16
Print zehnerminutes + minutes
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 09:04am 08 Mar 2014
Copy link to clipboard 
Print this post

zehner is german for "ten" or "tens"


Hours :

hours = rtcbuff(2) And &b00001111
zehnerhours = rtcbuff(2) And &b00110000
zehnerhours = (zehnerhours \ 16) + zehnerhours Mod 16
Print zehnerhours + hours
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 10:54am 08 Mar 2014
Copy link to clipboard 
Print this post

Try this program to read your DS3231. It may have some syntax errors. I can't test it all. Unless you have set the clock and date data then the output may be crap although the temperature should read correct.

' Read first 19 registers of RTC DS3231
' Bob D 2014 03 09

'how much data do we want
BuffLen = 19
' RTC address
RTCaddr = &h68

Dim RTCdata(Bufflen) Length 2
I2C open 100,100
I2C write RTCaddr, 0,1,0
If MM.I2C <> 0 then
print "I2C error"
end
Endif
I2C read RTCaddr, 0, Bufflen, RTCdata(0)
I2C close

' Convert time and date data
' the data in the registers is BCD (aka Packed Decimal) format
' with a decimal number from 0 to 9 in each half byte (nibble)
' each byte has a 10s decimal and a units decimal
' except day of the week which is units only
' Not all bits are used in each half byte - only what is needed for that data
' Example: Day of month range is 1 - 31 so we need 2 bits for the 10s (decimal 0 to 3)
' and 4 bits for the units (decimal 0 - 9) so we can then express
' all decimal numbers from 1 - 31 in one byte
' each half byte needs to be processed 4 bits at a time and then added together
' this done by right shifting the left nibble 4 bits right (\16) and multiply by 10
' to get the 10s value and then add the right nibble

Seconds = (RTCdata(0) and &h70)\16*10 + (RTCdata(0) and &h0f)
Minutes = (RTCdata(1) and &h70)\16*10 + (RTCdata(1) and &h0f)
Hours = (RTCdata(2) and &h70)\16*10 + (RTCdata(2) and &h0f)
DoW = (RTCdata(3) and &h07)
DoM = (RTCdata(4) and &h30)\16*10 + (RTCdata(4) and &h0f)
Month = (RTCdata(5) and &h10)\16*10 + (RTCdata(5) and &h0f)
Year = (RTCdata(6) and &hf0)\16*10 + (RTCdata(6) and &h0f)

print Hours; Minutes; Seconds
print DoM; Month; Year

' from here is optional but is dependent on previous code

' Convert Day of the week to day name
' Sunday=1 - Saturday=7

DayNames$ = "123456789Sunday 6Monday 6Tuesday 7Wednesday9Thursday 8Friday 6Saturday 8"
Day$ = Mid$(DayNames$, DoW*10, 10)
L = Val(Right$(Day$, 1))
Day$ = Left$(Day$,L)
Print "The day of the week is "; Day$

' Convert temperature and Aging Offset data
' This data is in Twos Complement format
' in register 17 and bits 7 & 6 of register 18

If RTCdata(17) < &h80 Then
Temperature = RTCdata(17) + (RTCdata(18) / 256)
Else
Temperature = -(((RTCdata(17) Xor &hFF) + 1) + (RTCdata(18) / 256))
EndIf
t$=Format$(Temperature,"%+6.2f")
Print "Temperature is "; T$; "degrees Celsius"

If RTCdata(16) < &h80 then
Offset = RTCdata(16)
Else
Offset = -(RTCdata(16) Xor &hFF)
Endif
Print "The Aging Offset data is "; Offset

End


 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 04:33am 09 Mar 2014
Copy link to clipboard 
Print this post

Hi BobD,

your code is definitely much more elegant than what i wrote!;-)

Do you also have such an elegant sample code for writing to the rtc??

Thank you

Dietmar


  BobD said   Try this program to read your DS3231. It may have some syntax errors. I can't test it all. Unless you have set the clock and date data then the output may be crap although the temperature should read correct.

' Read first 19 registers of RTC DS3231
' Bob D 2014 03 09

'how much data do we want
BuffLen = 19
' RTC address
RTCaddr = &h68

Dim RTCdata(Bufflen) Length 2
I2C open 100,100
I2C write RTCaddr, 0,1,0
If MM.I2C <> 0 then
print "I2C error"
end
Endif
I2C read RTCaddr, 0, Bufflen, RTCdata(0)
I2C close

' Convert time and date data
' the data in the registers is BCD (aka Packed Decimal) format
' with a decimal number from 0 to 9 in each half byte (nibble)
' each byte has a 10s decimal and a units decimal
' except day of the week which is units only
' Not all bits are used in each half byte - only what is needed for that data
' Example: Day of month range is 1 - 31 so we need 2 bits for the 10s (decimal 0 to 3)
' and 4 bits for the units (decimal 0 - 9) so we can then express
' all decimal numbers from 1 - 31 in one byte
' each half byte needs to be processed 4 bits at a time and then added together
' this done by right shifting the left nibble 4 bits right (\16) and multiply by 10
' to get the 10s value and then add the right nibble

Seconds = (RTCdata(0) and &h70)\16*10 + (RTCdata(0) and &h0f)
Minutes = (RTCdata(1) and &h70)\16*10 + (RTCdata(1) and &h0f)
Hours = (RTCdata(2) and &h70)\16*10 + (RTCdata(2) and &h0f)
DoW = (RTCdata(3) and &h07)
DoM = (RTCdata(4) and &h30)\16*10 + (RTCdata(4) and &h0f)
Month = (RTCdata(5) and &h10)\16*10 + (RTCdata(5) and &h0f)
Year = (RTCdata(6) and &hf0)\16*10 + (RTCdata(6) and &h0f)

print Hours; Minutes; Seconds
print DoM; Month; Year

' from here is optional but is dependent on previous code

' Convert Day of the week to day name
' Sunday=1 - Saturday=7

DayNames$ = "123456789Sunday 6Monday 6Tuesday 7Wednesday9Thursday 8Friday 6Saturday 8"
Day$ = Mid$(DayNames$, DoW*10, 10)
L = Val(Right$(Day$, 1))
Day$ = Left$(Day$,L)
Print "The day of the week is "; Day$

' Convert temperature and Aging Offset data
' This data is in Twos Complement format
' in register 17 and bits 7 & 6 of register 18

If RTCdata(17) < &h80 Then
Temperature = RTCdata(17) + (RTCdata(18) / 256)
Else
Temperature = -(((RTCdata(17) Xor &hFF) + 1) + (RTCdata(18) / 256))
EndIf
t$=Format$(Temperature,"%+6.2f")
Print "Temperature is "; T$; "degrees Celsius"

If RTCdata(16) < &h80 then
Offset = RTCdata(16)
Else
Offset = -(RTCdata(16) Xor &hFF)
Endif
Print "The Aging Offset data is "; Offset

End


 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 08:09am 09 Mar 2014
Copy link to clipboard 
Print this post

Dietmar, thanks for that. I hope it works OK for you. I was unable to test it as presented because I don't have a working machine, MM or uM. The hardest part was commenting it for publication given that the format of the time and date data (in the RTC) is not an easy concept for some of us.

I do have the code to load the DS3231 but it will require some preparation. I am also doing some house renovations at the moment (I am under instructions from the boss).

If anyone is impatient to load the RTC it can be done by computing the register values manually, putting them into an array and dumping the content of the array to the RTC.

Example: put time (UTC now) and date into an array

RTCdata(0) = &h00 ' seconds
RTCdata(1) = &h09 ' minutes
RTCdata(2) = &h18 ' hours
RTCdata(3) = &h01 ' Day of Week - Sunday
RTCdata(4) = &h09 ' Day of Month
RTCdata(5) = &h03 ' Month
RTCdata(6) = &h14 ' Year

then give it some I2C code and you should be off and running.
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9308
Posted: 01:11pm 09 Mar 2014
Copy link to clipboard 
Print this post

Have been away Sunday, and lots of activity here!
I will read all these posts and try some of the demo codes and post back in due course. Thanks guys! Lots of info for me to play with.
Smoke makes things work. When the smoke gets out, it stops!
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 01:35am 10 Mar 2014
Copy link to clipboard 
Print this post

Hi Bob,

it will be some more effort to put the right values to the RTC.
We have to do BCD conversion, you know that the RTC uses it for the internal Format.

I stuck in Problems for writing to the RTC..
I2C write seems to have some Problems with writing to the RTC.
So strange things happen, that i can't explain what ist going on here.
I hope there is not a bug in the micromite..
In most cases i'am the bug;-)

Dietmar


  BobD said   Dietmar, thanks for that. I hope it works OK for you. I was unable to test it as presented because I don't have a working machine, MM or uM. The hardest part was commenting it for publication given that the format of the time and date data (in the RTC) is not an easy concept for some of us.

I do have the code to load the DS3231 but it will require some preparation. I am also doing some house renovations at the moment (I am under instructions from the boss).

If anyone is impatient to load the RTC it can be done by computing the register values manually, putting them into an array and dumping the content of the array to the RTC.

Example: put time (UTC now) and date into an array

RTCdata(0) = &h00 ' seconds
RTCdata(1) = &h09 ' minutes
RTCdata(2) = &h18 ' hours
RTCdata(3) = &h01 ' Day of Week - Sunday
RTCdata(4) = &h09 ' Day of Month
RTCdata(5) = &h03 ' Month
RTCdata(6) = &h14 ' Year

then give it some I2C code and you should be off and running.
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 01:37am 10 Mar 2014
Copy link to clipboard 
Print this post

This part of code is working very well.
I Ddidn't test the optional part, tried to do some writes to set the RTC first, with th above described probs..



' Read first 19 registers of RTC DS3231
' Bob D 2014 03 09

'how much data do we want
BuffLen = 19
' RTC address
RTCaddr = &h68

Dim RTCdata(Bufflen) Length 2
I2C open 100,100
I2C write RTCaddr, 0,1,0
If MM.I2C <> 0 then
print "I2C error"
end
Endif
I2C read RTCaddr, 0, Bufflen, RTCdata(0)
I2C close

' Convert time and date data
' the data in the registers is BCD (aka Packed Decimal) format
' with a decimal number from 0 to 9 in each half byte (nibble)
' each byte has a 10s decimal and a units decimal
' except day of the week which is units only




' Not all bits are used in each half byte - only what is needed for that data
' Example: Day of month range is 1 - 31 so we need 2 bits for the 10s (decimal 0 to 3)
' and 4 bits for the units (decimal 0 - 9) so we can then express
' all decimal numbers from 1 - 31 in one byte
' each half byte needs to be processed 4 bits at a time and then added together
' this done by right shifting the left nibble 4 bits right (\16) and multiply by 10
' to get the 10s value and then add the right nibble

Seconds = (RTCdata(0) and &h70)\16*10 + (RTCdata(0) and &h0f)
Minutes = (RTCdata(1) and &h70)\16*10 + (RTCdata(1) and &h0f)
Hours = (RTCdata(2) and &h70)\16*10 + (RTCdata(2) and &h0f)
DoW = (RTCdata(3) and &h07)
DoM = (RTCdata(4) and &h30)\16*10 + (RTCdata(4) and &h0f)
Month = (RTCdata(5) and &h10)\16*10 + (RTCdata(5) and &h0f)
Year = (RTCdata(6) and &hf0)\16*10 + (RTCdata(6) and &h0f)

print Hours; Minutes; Seconds
print DoM; Month; Year
 
atmega8

Guru

Joined: 19/11/2013
Location: Germany
Posts: 722
Posted: 08:41am 10 Mar 2014
Copy link to clipboard 
Print this post

Here an Example of how to write to the DS3231.
Not complete, but it shows the principles.

It will not take to much time to complete it.

If someone wants do this for all, so please use it..

Tested un 28 PIN OIC with latest umite version

Dim RBUFF(10)
Sekunden = 55
Minuten = 59
Stunden = 23
'if use i2c write do not beginn with 0 in array but with one..
' I would call it a litte bug in mmbasic ?? what do you think geoff?
' It is strange to beginn with 1 in the Array, but to start with 0 in i2c write..
' i think i saw somewhere in the docu an option to configure where the Array
' index starts??; then it is a Feature not a bug ;-)
RBUFF(1) = (sekunden \ 10*16 + sekunden Mod 10)
RBUFF(2) = (Minuten \ 10*16 + minuten Mod 10)
RBUFF(3) = (Stunden \ 10*16 + Stunden Mod 10)
RBUFF(4) = &b00010001
RBUFF(5) = &b00010001
RBUFF(6) = &b00010011
RBUFF(7) = &b00010001
RBUFF(8) = &b00010001

I2C OPEN 100,100
I2C write &H68, 0, 8,RBUFF(0)
I2C close Edited by atmega8 2014-03-11
 
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 08:51am 10 Mar 2014
Copy link to clipboard 
Print this post

Try this to set the time
It will get the current Time and date from the uMite and write it
to the RTC


SetTime:

' Get time from time$ and date$
tempdec = val(left$(time$, 2))
BCDtoHex TempDec
hours = hex

tempdec = val(mid$(time$, 4, 2))
BCDtoHex TempDec
minutes = hex

tempdec = val(right$(time$, 2))
BCDtoHex TempDec
seconds = hex

tempdec = val(left$(date$, 2))
BCDtoHex TempDec
day = hex

tempdec = val(mid$(date$, 4, 2))
BCDtoHex TempDec
month = hex

tempdec = (val(right$(date$, 4)) - 2000)
BCDtoHex TempDec
year = hex

rtcctrl = &h10
rtcwday= &h1

' Write Time to RTC
i2caddr = &h68 ' RTC I2C address
i2c Open 100,100 ' Enable I2C

' i2csend i2caddr, 1, 1 , 1
I2C Write i2caddr, 0, 9, &h0, seconds, minutes, hours, rtcwday, day, month, year, rtcctrl
I2C Close

? "0=ok 1=nack 2=timeout"; mm.i2c
? "RTC has been set to ";time$;" ";date$
end

' Convert to Hex
Sub BCDtoHex TempDec
hex = fix(tempdec / 10) * 16
hex = hex OR ((tempdec / 10) - (fix(tempdec / 10))) * 10
return


Regards
Jman
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 12:23pm 10 Mar 2014
Copy link to clipboard 
Print this post

I originally wrote this for the MM using only i2c devices. I've modded it for uMite but still with I2c keys and i2c LCD. The structure at least might be of some use.

It works on my uM. I don't know how many TBS members have i2c LCD and 12 Key keypad but I can supply the source, hex and schema for those interested.

Pressing the "*" key activates the register set mode. Other wise it is a timing loop.


Option autorun on
Option break 3

Dim RTCbuff(12) ' Received data is stored here
Dim keys(2)
Dim bcd_byte
Dim bcd
blank$ = " "

mylcd = &b0111000 'LCD address
myrtc = &b1101000 'real time clock address
mykeypad = &b0110100 'key pad address

I2C OPEN 100,100 ' Start up the I2C module


I2C write mylcd,0,3,0,0,2
I2C write mylcd,0,3,0,1,4: Pause 100 'LCD reset. (my LCD pic module)
I2C write mylcd,0,3,0,44,2 'two line display
'I2C write mylcd,0,3,0,15,2

'Main Routine starts here

Do
'scan past keys - check for keypress
If readkey() = 42 Then set_rtc 'if Keypad "*" key then modify register.

I2C write mylcd,0,3,0,12,2 'LCD On, Cursor Off

I2C WRITE myrtc, 0, 1, 0 ' Request the time
If MM.I2C <> 0 Then Error "PCF8563 not responding"
I2C READ myrtc, 0, 7, RTCbuff(0) ' Get the time as 7 bytes
bcdtemp = RTCBuff(0) And &H7F ' Get just the bits that we want
sec$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16)
bcdtemp = RTCBuff(1) And &H7F
min$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16)
bcdtemp = RTCBuff(2) And &H3f
hours$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16)
bcdtemp = RTCBuff(4) And &H3f
day$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16)
bcdtemp = RTCBuff(5) And &h1F
month$ = Str$((bcdtemp \ 16) * 10 + bcdtemp Mod 16)
bcdtemp = rtcbuff(6)
year$ = Str$((bcdtemp \ 16) * 10 + (bcdtemp Mod 16) + 2000)
If Len(sec$)<2 Then sec$ = "0" + sec$ 'insert leading 0s for appearances
If Len(min$)<2 Then min$ = "0" + min$
t$ = hours$+":"+min$+":"+sec$+" "
D$ = day$+"/"+month$+"/"+year$+" "

disp_str(128,t$) 'display time - or use uMite LCD commands
disp_str(192,d$) 'and date on LCD
Loop

'end of main routine

Function getkey() 'wait for a key
Do
I2C write mykeypad,0,1,0 'request a key
I2C read mykeypad,0,1,keys(0) 'read keypad
Loop Until keys(0) <> 0 'non zero value means a valid key
getkey = keys(0)
I2C write mykeypad,0,2,0,0 'Tell the keypad that it can send new data
End Function


Function readkey() 'read a key value no waiting for key press
I2C write mykeypad,0,1,0 'request key
Pause 10
I2C read mykeypad,0,1,keys(0) 'read keypad regardless
readkey = keys(0)
I2C write mykeypad,0,1,0
End Function


Sub set_rtc 'read RTC register and new time value
I2C write mylcd,0,3,0,14,2 'cursor on
I2C write mykeypad,0,2,0,0 'clear any leftover key press
I2C write mylcd,0,3,0,1,2 'clear LCD
disp_str(192,blank$):disp_str(192,"Register ") 'blank lines 1 and 2
register = get_dec() 'get register number in decimal format
disp_str(128,blank$): disp_str(128,"# to accept ")
If getkey() <> 35 Then Exit Sub '35 is # key

disp_str(128,blank$)
disp_str(192,blank$):disp_str(192,"Value ")
bcd=get_bcd() 'get Register value in BCD format
disp_str(128,blank$): disp_str(128,"# to accept ")
If getkey() <> 35 Then Exit Sub
I2C write myrtc,0,2,register,bcd 'write the new time value to the appropriate register
End Sub

Sub disp_str(ptr,a$) 'display a string to numinated screen position
Local x, char$
I2C write mylcd,0,3,0,ptr,2
For x = 1 To Len(a$)
char$=(Mid$(a$,x,1))
I2C write mylcd,0,3,0,Asc(char$),1)
Next x
End Sub


Function get_dec() 'get a 2 key decimal value include leading zero
Do
key=getkey()
Loop Until key >= 48
I2C write mylcd,0,3,0,key,1 'display key
left = (key-48)*10
Do
key=getkey()
Loop Until key >= 48
I2C write mylcd,0,3,0,key,1 'display key
right=key-48
get_dec=left+right 'combine digits
End Function

Function get_bcd() 'get 2 key BCD value include leading zero
Do
key = getkey()
Loop Until key >= 48 'i.e, a number
left = (key-48)*16
I2C write mylcd,0,3,0,key,1 'display key
Do
key = getkey()
Loop Until key >= 48 'a number
right = key-48
I2C write mylcd,0,3,0,key,1 'display key
get_bcd=left Or right 'combine digits
End Function

David M.
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 05:55pm 10 Mar 2014
Copy link to clipboard 
Print this post

  atmega8 said   Here an Example of how to write to the DS3231.
Not complete, but it shows the principles.

It will not take to much time to complete it.

If someone wants do this for all, so please use it..

Tested un 28 PIN OIC with latest umite version

Dim RBUFF(10)
Sekunden = 55
Minuten = 59
Stunden = 23
'if use i2c write do not beginn with 0 in array but with one..
' I would call it a litte bug in mmbasic ?? what do you think geoff?
' It is strange to beginn with 1 in the Array, but to start with 0 in i2c write..
' i think i saw somewhere in the docu an option to configure where the Array
' index starts??; then it is a Feature not a bug ;-)
RBUFF(1) = (sekunden \ 10*16 + sekunden Mod 10)
RBUFF(2) = (Minuten \ 10*16 + minuten Mod 10)
RBUFF(3) = (Stunden \ 10*16 + Stunden Mod 10)
RBUFF(4) = &b00010001
RBUFF(5) = &b00010001
RBUFF(6) = &b00010011
RBUFF(7) = &b00010001
RBUFF(8) = &b00010001

I2C OPEN 100,100
I2C write &H68, 0, 8,RBUFF(0)
I2C close


The I2C write command to a DS3231 needs to have a pointer to DS3231 register 0 followed by the data. This makes it impossible to use an array to write the data unless the register pointer is in the first used array index followed by the data in subsequent contiguous indexes.

This is either a bug, a feature or a limitation (select one) of the MMBasic I2C implementation.

Example: this works

dim array(7) length 2
I2Cen
I2Csend &H68, 0, 7, array(0)
I2Cdis


Example: This does not work

dim array(7) length 2
I2Cen
I2Csend &H68, 0, 8, 0, array(0)
I2Cdis

It gets an error
Error: Insufficient Arguments

It seems it is not possible to mix non arrayed variables or constants with arrayed variables in an I2Csend command.

I have used the MMBasic I2C commands because I tested on MMBasic v4.4. It seems that Dietmar has run into similar problems with MicroMite basic.




Edited by BobD 2014-03-12
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6102
Posted: 06:33pm 10 Mar 2014
Copy link to clipboard 
Print this post

  BobD said  
This is either a bug, a feature or a limitation (select one) of the MMBasic I2C implementation.

Example: this works

dim array(7) length 2
I2Cen
I2Csend &H68, 0, 7, array(0)
I2Cdis


Example: This does not work

dim array(7) length 2
I2Cen
I2Csend &H68, 0, 8, 0, array(0)
I2Cdis

It gets an error
Error: Insufficient Arguments

It seems it is not possible to mix non arrayed variables or constants with arrayed variables in an I2Csend command.



I am surprised that this line didn't give an error:
dim array(7) length 2

LENGTH is only valid for string arrays.

According to the MicroMite manual, You can send data as either individual bytes OR a one dimensional array (but not mixed)

You can start the data in the array from any position in the array.
This is valid:

dim mydata(10)
I2Csend &H68, 0, 7, mydata(2)

which would send 7 bytes starting at mydata(2)


Jim
VK7JH
MMedit   MMBasic Help
 
MOBI
Guru

Joined: 02/12/2012
Location: Australia
Posts: 819
Posted: 06:41pm 10 Mar 2014
Copy link to clipboard 
Print this post

In the second example, the array is set to 7 but 8 bytes are being sent. Wouldn't this throw an error?
David M.
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 06:54pm 10 Mar 2014
Copy link to clipboard 
Print this post

  MOBI said   In the second example, the array is set to 7 but 8 bytes are being sent. Wouldn't this throw an error?

Two reasons it didn't happen is the mixed variables bombs it first but if mixed variables were allowed then it is legit because all after the length is data including the 0 preceding the array. It is the address of register 0 of the RTC.
 
     Page 2 of 3    
Print this page
© JAQ Software 2024