PDA

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