View Full Version : Serial data transmission period
Scampy
- 9th January 2018, 19:50
Guys,
Need some advice for a bit of crude dirty code to send the time and temperature out via serial port.
main:
OWOUT TEMPIN,1,[$CC,$44]
OWOUT TEMPIN,1,[$CC,$BE]
OWIN TEMPIN,0,[TempT.LowByte,TEMPT.HighByte]
TempC = (TempT*/1600)
LCDout $FE,$80,"Temp ",DEC (TempC/100),".",#TempC dig 1,"C"
tempc=tempc/10
I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl] ; read DS1307 chip
LCDOut $FE,$c0+11,hex2 RTCHour,":",hex2 RTCMin
timeH=(RTCHour>>4) 'convert the BCD format of the hours register and store in variable timeH
timeH=(timeH &$03)*10
timeH=timeH+(RTCHour&$0F)
timeM=(RTCMin>>4)
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F)
Hserout [dec TimeH,":",dec TimeM," ",DEC(TempC/10),".",#TempC dig 1,13,10]
Pause 5000
goto main
This works fine, although I would rather data is sent once every 5 minutes. I did try and do a time match so that if minutes = 5 and seconds =0 it would send, but the program loops so fast that I still got multiple results.
So I'm just after a quick and simple bit of code to allow me to record the temperature and time stamp every 5 minutes
TIA
Malc
HenrikOlsson
- 9th January 2018, 21:36
Since your code executes about once every 5 seconds
LoopCount VAR BYTE
LoopCount = 0
' ------------------
' Rest of code goes here
' ------------------
LoopCount = LoopCount + 1
If LoopCount = 59 THEN ' 60 times 5 seconds = 300 seconds = 5 minutes.
Hserout [dec TimeH,":",dec TimeM," ",DEC(TempC/10),".",#TempC dig 1,13,10]
LoopCount = 0
ENDIF
/Henrik.
Scampy
- 9th January 2018, 23:24
Cheers Henrik,
That works fine. But, is there a way of getting rid of the pause 5000 as that is obviously slowing down the sampling of the temperatures. I'm running the PIC with an OSC value of 40 with a 10 mhz crystal
TIA
Malc
Edit, ignore me, I reduced the pause wait and increased the loopcount value - now have a more workable solution
richard
- 10th January 2018, 00:02
since you have a rtc and convert time to binary
why not
If (TimeM//5)==0 then
Hserout [dec TimeH,":",dec TimeM," ",DEC(TempC/10),".",#TempC dig 1,13,10]
ENDIF
sayzer
- 10th January 2018, 07:44
since you have a rtc and convert time to binary
why not
If (TimeM//5)==0 then
Hserout [dec TimeH,":",dec TimeM," ",DEC(TempC/10),".",#TempC dig 1,13,10]
ENDIF
This is one good way :)
It seems that when this condition gets true, then it will send data for the duration of whole 1 minute.
If you also add "Second" to this condition, it will also send the data for the duration of "1" whole Second.
So a better way is to insert a flag into it.
For example;
If (TimeM//5) = 0 and SendFlag = 0 then
Hserout [dec TimeH,":",dec TimeM," ",DEC(TempC/10),".",#TempC dig 1,13,10]
SendFlag = 1
ELSE
If (TimeM//6) = 0 then SendFlag = 0
ENDIF
Scampy
- 10th January 2018, 11:21
Thanks for the additional suggestions guys. I'll give them a try as well. Anything that removes the pause option from the code is good.
Scampy
- 10th January 2018, 17:05
This is one good way :)
It seems that when this condition gets true, then it will send data for the duration of whole 1 minute.
If you also add "Second" to this condition, it will also send the data for the duration of "1" whole Second.
So a better way is to insert a flag into it.
Uhmmmm.. still not working using the example you gave
SendFlag var byte
Sendflag =1
main:
OWOUT TEMPIN,1,[$CC,$44]
OWOUT TEMPIN,1,[$CC,$BE]
OWIN TEMPIN,0,[TempT.LowByte,TEMPT.HighByte]
TempC = (TempT*/1600)
LCDout $FE,$80,"Temp ",DEC (TempC/100),".",#TempC dig 1,"C"
tempc=tempc/10
I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl] ; read DS1307 chip
LCDOut $FE,$c0+11,hex2 RTCHour,":",hex2 RTCMin
LCDOut $FE,$c0, dec sendflag
timeH=(RTCHour>>4) 'convert the BCD format of the hours register and store in variable timeH
timeH=(timeH &$03)*10
timeH=timeH+(RTCHour&$0F)
timeM=(RTCMin>>4)
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F)
If (TimeM//5) = 0 and SendFlag = 0 then
Hserout [hex2 RTCHour,":",hex2 RTCMin," ",DEC(TempC/10),".",#TempC dig 1,13,10]
SendFlag = 1
ELSE
If (TimeM//6) = 0 then SendFlag = 0
ENDIF
'pause 1000
goto main
At 8:00 for example (the programmed initial time on startup), the code would send data to the serial port as a constant stream every loop of the program rather than a single entry. I added a pause statement (commented out in the code above) so I could see what was happening, and the flag kept changing from 0 to 1 and back each loop of the code. When the time changed to 8:01 the value of the flag remained static at 1, and the data stream stopped, having sent 41088 bytes through the serial port.
At 8:05 the flag remained at 1 and no data was sent. At 8:06 the flag changed to a value of 0 but again no data was sent, presumably as the condition to do so hasn't been met as whilst the flag is now zero, TimeM doesn't equal the 5 minute value ?
The flag value remained at 0 until 8:10 when a single entry was sent to the serial port. The flag then changed to 1 remained at 1 as the time changed to 8:11 until 8:12 when it changed to 0 and remained at zero
At 8:15 a single entry was sent to the port, the flag was set to 1 and remained at 1 until 8:18 when the flag value changed to 0
The flag value remained at 0 until 8:20 when a single entry was sent to the serial port. The flag then changed to 1 remained at 1 until 8:24 when it changed to 0 and remained at zero
At 8:25 a single entry was sent to the port, the flag was set to 1 and remained at 1
At 8:30 the code sent data to the serial port as a constant stream every loop of the program rather than a single entry, with the LCD displaying a blur as the value alternated between 0 and 1. At 8:31 the data stream stopped and the flag was set to 0,
So it seems to be following a pattern. Hope this feedback helps debug the code... it's beyond me !!
edit:
At 9:00 the code sent data to the serial port as a constant stream every loop of the program
sayzer
- 10th January 2018, 17:49
It is my bad.
(TimeM//6) may take another 2,3,4,5 minutes depending on the minute value :)
You may want use "Second". Example;
SendFlag var bit
Begin:
Sendflag = 0
Main:
If (TimeM//5) = 0 then
if RTCsec = 0 and SendFlag = 0 then
Hserout [hex2 RTCHour,":",hex2 RTCMin," ",DEC(TempC/10),".",#TempC dig 1,13,10]
sendflag = 1
ELSE
If RTCsec > 0 then SendFlag = 0
ENDIF
ENDIF
or another way could be to use DIG ;
SendFlag var bit
Begin:
Sendflag = 0
Main:
SELECT CASE TimeM DIG 0
Case 0,5 ' Every 5 minutes.
if SendFlag = 0 then
Hserout [hex2 RTCHour,":",hex2 RTCMin," ",DEC(TempC/10),".",#TempC dig 1,13,10]
sendflag = 1
ENDIF
case 1,6 ' Reset flag 1 minute later.
SendFlag = 0
END SELECT
This one looks cleaner for my eyes.
Scampy
- 10th January 2018, 18:31
I've used the second example with the case statement, and that appears to be working as expected
Can you comment the code so that I can understand why it works
Thanks
Malc
sayzer
- 10th January 2018, 18:45
I've used the second example with the case statement, and that appears to be working as expected
Can you comment the code so that I can understand why it works
Thanks
Malc
CASE 0,5 will work on minutes 0,5,10,15,20,25,30,35,40,45,50,55 as the DIG 0 is always either 0 or 5.
CASE 1,6 will work on minutes 1,6,11,16,21,26,31,36,41,46,51,56 as the DIG 0 is always either 1 or 6. And this gives you "1 minute pass" after your HSEROUT condition is executed.
If you want to speed up the frequency of sending data, then change 0,5 to say 0,2,4,6,8 and 1,6 to 1,3,5,7,9. This way you can send data in every 2 minutes.
If you want to slow down the frequency change 0,5 to 0 only and 1,6 to 1 only. This way you can send data in every 10 minutes.
Hope this helps.
Scampy
- 10th January 2018, 20:18
Thanks for the explanation. I've copied and pasted it as notes in the code for use in later projects
Powered by vBulletin® Version 4.1.7 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.