PropBasic and RTC
in Propeller 1
I have a system running the Propeller coded in "C" that includes an RTC in one COG.
Is there a PropBasic program that does the same thing...setting and reading year, month, date, day, hour, minute, and seconds?
I really like PropBasic and would like to rebuild these systems using PropBasic.
Sincerely,
Discovery
Is there a PropBasic program that does the same thing...setting and reading year, month, date, day, hour, minute, and seconds?
I really like PropBasic and would like to rebuild these systems using PropBasic.
Sincerely,
Discovery
Comments
Can't even find the DS1307 module right now. Will dig deeper over the weekend.
Making a COG count seconds is pretty simple, although you do need a bit of code to initialize the correct time at the start.
Has this been accomplished?
Sincerely,
Discovery
'' '' simple real time clock running in another cog '' const FREQUENCY = 80_000_000 ' hours, minutes, seconds: 00-23, 00-59, 00-59 dim as ubyte hours, mins, secs ' month, day in month: 1-12, 1-31 dim as ubyte month, day ' year: 4 digits dim as integer year ' stack space for the RTC COG dim stack(10) '' '' helper subroutine; return number of days in month '' function daysInMonth() as uinteger ' february is a special case if month = 2 then if (year mod 4 = 0) then ' possible leap year if (year mod 100 <> 0) or (year mod 1000 = 0) then return 29 ' definite leap year endif endif return 28 endif if (month = 4) or (month=6) or (month=9) or (month=11) return 30 return 31 end function '' '' routine to keep the clock up to date '' this is launched in another COG and just runs forever, '' waking once per second to update the time '' sub updateClock dim nextSecond nextSecond = getcnt() + FREQUENCY do waitcnt(nextSecond) nextSecond = nextSecond + FREQUENCY secs = secs + 1 if (secs >= 60) then secs = 0 mins = mins + 1 if (mins >= 60) then mins = 0 hours = hours + 1 if (hours >= 24) then hours = 0 day = day + 1 endif endif endif if (day > daysInMonth()) then day = 1 month = month + 1 if (month > 12) then month = 1 year = year + 1 endif endif loop end sub '' '' main program '' '' initialize the time print "Enter year month day as YYYY-MM-DD "; '' read 10 characters into s$ var s$ = input$(10) print '' split out the month, year, day year = val(left$(s$, 4)) month = val(mid$(s$, 6, 2)) day = val(right$(s$, 2)) print "Enter time as hh:mm:ss "; s$ = input$(8) print hours = val(left$(s$, 2)) mins = val(mid$(s$, 4, 2)) secs = val(right$(s$, 2)) ' start the RTC update thread on another COG var x = cpu(updateClock, @stack(1)) ' now loop printing the time do print using "####_-%%_-%% "; year, month, day; print using "##:%%:%%"; hours, mins, secs pausems(1000) loop
'----------------------------------------- ' Badge WX PropBasic Demo '----------------------------------------- DEVICE P8X32A, XTAL1, PLL16X FREQ 80_000_000 ' Libraries LOAD "Lib_BWX_OLED.pbas" hub_time HUB BYTE(4) = 0 ' seconds, minutes, hours, seconds RTC TASK AUTO 'VARs seconds VAR LONG minutes VAR LONG hours VAR LONG temp VAR LONG PROGRAM Start LMM '{$DEFINE LMM} Start: WRBYTE hub_Time, 50,58,23 OLED_Start DO ' Read until seconds is stable DO RDBYTE hub_Time, seconds, minutes, hours, temp LOOP UNTIL seconds = temp OLED_Locate 0,2 IF hours < 10 THEN OLED_PrintLGChar "0" ENDIF OLED_PrintLGValue hours OLED_PrintLGChar ":" IF minutes < 10 THEN OLED_PrintLGChar "0" ENDIF OLED_PrintLGValue minutes OLED_PrintLGChar ":" IF seconds < 10 THEN OLED_PrintLGChar "0" ENDIF OLED_PrintLGValue seconds LOOP END TASK RTC clocks VAR LONG seconds VAR LONG minutes VAR LONG hours VAR LONG clocks = CNT + 80_000_000 DO WAITCNT clocks, 80_000_000 RDBYTE hub_Time, seconds, minutes, hours INC seconds IF seconds = 60 THEN seconds = 0 INC minutes IF minutes = 60 THEN minutes = 0 INC hours IF hours = 24 THEN hours = 0 ' adjust date here ENDIF ' hours = 24 ENDIF ' minutes = 60 ENDIF ' seconds = 60 WRBYTE hub_Time, seconds, minutes, hours, seconds LOOP ENDTASK
Bean
Sincerely,
Discovery
My first step in using the program information you provided is to: (1) set the clock time in the COG and (2) read the hours, minutes, and seconds from the main program to activate and deactivate propeller outputs at specific times during the course of a 24 hour day. I have no use for the display at this time.
What additions or changes do I make to accomplish this task.
Sincerely,
Discovery
I figured it out...thanks.
Discovery
I inserted into your program a HIGH LED1 instruction just after the DO LOOP UNTIL instruction so that I can tell the Propeller Activity Board propeller clock is working. In the main LMM section I compare the Hours, Minutes, and Seconds to turn ON and OFF I/O. Once in a while it works. Most of the time the program does not get out of the DO LOOP UNTIL block. After about twelve or thirteen attempts...the clock synchronizes the seconds and the program runs perfectly well.
Have you encountered this problem?
Sincerely,
Discovery
Discovery
With the Propeller Activity Board powered by a 12 volt external power source, the prop was loaded with the program. However, the second synchronization code was modified somewhat. The DO and LOOP UNTIL instructions were removed. The clock ran right off and kept excellent time except it took 2 seconds for the clock to start. So, there is a 2 second constant error. It is important to disconnect the USB cable from the computer because when the computer shuts OFF and you power the computer back ON...the prop coded is removed. This modification appears to work fine.
Discovery
Every so often the code that is sent to the propeller will not execute. The code compiles and down loads but does not run. When the code starts, I turn on LED1 to make sure that the code is actually running. When I made the change to remove the DO LOOP UNTIL instructions, the Propeller would not execute. I removed the USB cable from the computer, reinserted it, ran the program, but it would not execute. I turned cycled the power on the Activity board but the same result occurred. Other programs that ran fine a few minutes before would not execute either.
I did notice that when I shut cycled power on the computer and bring PropellerIDE back on line all the programs run even the clock program that has the seconds synchronizer in it. The Propeller develops this state every so often but when I restart PropellerIDE it clears the Propeller and programs then run on the Propeller.
I can now get the clock program to run and control the I/O for clock start and stop times.
Discovery
I suspected that this was a ViewPort quirk so I simply hit the board's hardware reset, prior to downloading. No biggie for me.
Testing shows that pressing the reset, removing the USB cable, and moving the power switch to OFF will not clear the problem. Code is downloaded with no error but the propeller will not execute the code. The only method I found to get the propeller to execute the code after it encounters this condition is to reload the PropellerIDE and download the code again...then the propeller executes the code correctly. Strange!
Sincerely,
Discovery
Your PropBasic clock program is working perfectly. It keeps time really well.
The code is simple...and elegant, thank you.
My next step is to write and read data to/from the removable memory on the Propeller Activity Board using PropBasic...half a gigabyte or more. What coding would you recommend. I would like the code to run as fast as possible with PropBasic.
Sincerely,
Discovery
If it is SD card, I'm afraid I haven't done any coding to read/write an SD card.
It would be quite a project, and I just don't have the time right now.
Bean
DenO
Bean...rats, I was hoping.
One of the guys on the FORUM spent a great deal of time and some of my money to write the "C" code to write and read the SD memory on the Propeller Activity Board. The code is not pretty but it does the job. I cannot stand "C" but like PropBasic.
I understand that you are very busy. Maybe some time in the future perhaps?
Sincerely,
Discovery
What do you think the chances are that I can convert line-by-line the "C" code I have for Writing/Reading the SD memory into PropBasic code?
Sincerely,
Discovery
Discovery
I downloaded and unpacked the above 7z file and put it into the zip file below.
Thank you.
Discovery
By any chance, would you happen to have a short PropBasic program that uses the library functions you sent to write and read some data onto and off of the SD?
Sincerely,
Discovery
Take a look at the https://forums.parallax.com/discussion/122615/propbasic-sd-card forum entries. These entries appear to be posted by the creator of the sd.lib library
Mike R.
' ====================================================================== ' ' File...... SDplay10 ' Purpose... Attempt to develop SD read/write routines with PropBASIC ' Author.... Maxwin ' E-mail.... max@winsoft.hu ' Started... 17 05 2010 ' Updated... 09 09 2010 ' ' ====================================================================== ' A BIG thank you to JonnyMac for serial.lib & delays.lib ' A BIG thank you to Bean for PropBasic ! Why I Propeller. ' ---------------------------------------------------------------------- ' Program Description / Notes ' ---------------------------------------------------------------------- ' Low level SD card interfacing for PropBasic. ' The idea is to use an SD card as a mass storage device. ' Ideal for datalogging applications. ' Read/Write data in 512 byte blocks into sectors 1 to X (depending on card size) ' Tip: To read the card contents with a PC, use software such as "HxD", http://mh-nexus.de/en/hxd/ ' run the program, choose the "Extras" menu, then select "Open disc..." ' or write your own application in .NET and open a filestream on PhysicalDriveX ' some advice available here: http://www.fort-awesome.net/blog/2010/03/25/MBR_VBR_and_Raw_Disk ' The various serial TX statements output diagnostic messages ' to the standard PST on pin 30 at the baud rate set by CONstant. ' Instructions: ' ''''''''''''' ' Connect an SD card using the standard Parallax SD card adapter (or equivalent) ' and use (or change) the PIN declarations shown below as required. ' Then run the program - the PST (Parallax Serial Terminal) connected ' to pins 30/31 of the propeller will display some details about the sd card ' Terminal will display some card info! ' ---------------------------------------------------------------------- ' Conditional Compilation Symbols ' ---------------------------------------------------------------------- ' ---------------------------------------------------------------------- ' Device Settings ' ---------------------------------------------------------------------- DEVICE P8X32A, XTAL1, PLL16X XIN 5_000_000 ' ---------------------------------------------------------------------- ' Constants ' ---------------------------------------------------------------------- Baud CON "T57600" ' serial.lib HOME CON 1 LF CON 10 CR CON 13 CLS CON 16 SPACE CON 32 COMMA CON 44 ' ---------------------------------------------------------------------- ' I/O Pins ' ---------------------------------------------------------------------- TX PIN 30 HIGH ' serial.lib SD_CSPIN PIN 23 HIGH ' sd.lib SD_DIPIN PIN 24 HIGH ' sd.lib SD_SCLKPIN PIN 25 OUTPUT ' sd.lib SD_DOPIN PIN 26 INPUT ' sd.lib SD_CARDINPIN PIN 27 INPUT ' sd.lib ' ---------------------------------------------------------------------- ' Shared (hub) Variables (Byte, Word, Long) ' ---------------------------------------------------------------------- ' ---------------------------------------------------------------------- ' Shared (hub) Data (DATA, WDATA, LDATA, FILE) ' ---------------------------------------------------------------------- ' ---------------------------------------------------------------------- ' TASK Definitions ' ---------------------------------------------------------------------- ' ---------------------------------------------------------------------- ' Cog Variables (Long only) ' ---------------------------------------------------------------------- tmp VAR LONG idx VAR LONG ' ---------------------------------------------------------------------- ' SUB/FUNC Definitions ' ---------------------------------------------------------------------- LOAD "Library/sd.lib" LOAD "Library/serial.lib" LOAD "Library/delays.lib" ' ====================================================================== PROGRAM Start LMM ' ====================================================================== Start: ' user start-up code DELAY_MS 2500 TX_BYTE CLS TX_STR " - SDplay - " TX_BYTE CR ' ---------------------------------------------------------------------- Main: ' Wait for SD Card to be inserted. TX_STR " Insert card : " DO IF SD_CARDINPIN = 0 THEN EXIT DELAY_MS 250 LOOP TX_STR "Card inserted." TX_BYTE CR ' -------------------------------------------------------------- ' Open SD card tmp = SD_OPEN IF tmp = 1 GOTO Main ' -------------------------------------------------------------- ' Read card name & serial number, then display tmp = SD_READID ' TX_STR "Card name=" FOR idx = 0 TO 4 TX_BYTE SD_name(idx) NEXT TX_STR " ,Serial number=" TX_DEC SD_serialnumber TX_BYTE CR ' -------------------------------------------------------------- ' Read size of card, then display tmp = SD_READSIZE ' TX_STR "Blocksize=" TX_DEC SD_blocksize 'TX_STR " ,Sectorsize=" 'TX_DEC SD_sectorsize TX_STR " ,Totalsectors=" TX_DEC SD_totalsectors TX_STR " ,Totalcapacity=" TX_DEC SD_totalcapacity TX_BYTE CR ' -------------------------------------------------------------- ' Write block to card ' First populate SD_bytebuffer with the data bytes ' SD_bytebuffer is 128 LONGS. Use BB_PUT to populate the buffer ' Store test data in buffer: ABCDEF...WXYZ (repeated!) tmp = 65 FOR idx = 0 TO 511 BB_PUT idx, tmp INC tmp IF tmp = 90 THEN tmp = 65 ' Reset back to 'A' char ENDIF NEXT ' Write test data to card tmp = SD_WRITE 1 ' Write SD_bytebuffer to sector 1 IF tmp = 0 THEN TX_STR " -- Data Written OK! -- " ELSE TX_STR " Writing failed! " ENDIF ' -------------------------------------------------------------- ' For demo, empty the SD_bytebuffer! FOR idx = 0 TO 511 BB_PUT idx, 0 NEXT TX_BYTE CR ' -------------------------------------------------------------- ' Read block from card into SD_bytebuffer using BB_GET sub tmp = SD_READ 1 ' Read sector 1 into SD_bytebuffer IF tmp = 0 THEN TX_STR " -- Data Read OK! -- " ELSE TX_STR " Reading failed! " ENDIF ' Display SD_bytebuffer on serial terminal (.. well, only first 20 bytes!) TX_BYTE CR TX_STR "20 bytes of data back from card:" TX_BYTE CR FOR idx = 0 TO 19 tmp = BB_GET idx TX_BYTE tmp NEXT ' -------------------------------------------------------------- ' Close card when finished SD_CLOSE ' -------------------------------------------------------------- TX_BYTE CR TX_STR "End." ' -------------------------------------------------------------- 'DELAY_MS 2500 'GOTO Main END ' ---------------------------------------------------------------------- ' SUB/FUNC Code ' ---------------------------------------------------------------------- ' ====================================================================== ' TASK Code ' ======================================================================
Now I can get started.
Sincerely,
Discovery
I don't suppose there is an easy way to adjust the clock to be precise?
Sincerely,
Discovery
How fast? Since crystals are involved, they have a certain PPM tolerance.