Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 18:57 25 Apr 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 : UART TIMEOUT

Author Message
Frank N. Furter
Guru

Joined: 28/05/2012
Location: Germany
Posts: 813
Posted: 06:45pm 22 Sep 2019
Copy link to clipboard 
Print this post

Can anyone help me?

I am looking for a way to wait a certain time for characters of a serial interface, as it was realized with the PBP compiler for example:

SERIN Pin,Mode,{Timeout,Label,}

Does anyone have a code snippet for a timeout like this?
Do I have to implement this via TIMER and LOC?

Any help is appreciated!

THANKS!

Frank
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1094
Posted: 12:38am 23 Sep 2019
Copy link to clipboard 
Print this post

Frank,

This may not be the most elegant way and does not cater for day over-run but it may give you some ideas.

It is a blocking routine (that is, it loops internally for the timeout period). A neater solution would be to do something with flags.


Option explicit
dim S_Timeout,s_port

print "Wait for 10 seconds then print all characters waiting in Rx buffer"
' example: call routine, wait 10 seconds then print all characters
'   entered from console (s_port = 0)
print SerIn$(10,0)

function SerIn$(S_timeout,s_port)
' function to wait S_Timeout seconds from current time and
' return all characters waiting in Rx buffer of COM port s_port
' Note: this is a blocking routine
 local tout,start_secs,s_chars$
 tout = S_timeout
 start_secs = T_now()
 do
 loop while T_now() < start_secs + tout
 s_chars$ = input$(255,s_port) ' will get up to 255 characters from com port
 SerIn$ = s_chars$
end function
   
Function Time_now(arg1) ' arg1 unused
' returns current time in seconds, does not cater for day over-run
 local t_n
 t_n=(val(left$(time$,2))*3600)+(val(mid$(time$,4,2))*60)+val(right$(time$,2))
 T_now = t_n
end function


panky
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5900
Posted: 02:37am 23 Sep 2019
Copy link to clipboard 
Print this post

It depends a lot on the flow of the rest of the program.

This routine uses the console as input but a serial port would be much the same.
Instead of k$=INKEY$, use IF LOC(#1) > 0 THEN doKEY

I choose to check for input in the main loop instead of using interrupts because the program is doing time critical things and I don't want them interrupted.

SUB doKey is entered when there is at least one character available.
It then loops through, gathering additional characters until
there is a LF indicating end of data or
empty k$ indicating data flow has stopped or
more than 20 characters have been received because in this setup, that would be an error condition or
there has been more than 500 * 2 mS

The size of the delay needs to match the baud rate and take into account any delays in the sending device (such as manual key entry)

Remove any condition tests that don't suit your data input method.

  Quote    DO
   
IF readNow = 1 THEN doread
   
IF loopNow = 1 THEN doLoop
   
'if debugNow = 1 then debugSub
   IF quit = 1 THEN EXIT DO
   k$=
INKEY$
   
IF k$ <> "" THEN doKey
   
 
LOOP
 
END
 
'
SUB doKey
 cmd$ =
""
 w =
0
 
DO
   
PAUSE 2
   cmd$ = cmd$+k$
   k$=
INKEY$
   w = w +
1
 
LOOP UNTIL k$="" OR k$ = lf$ OR LEN(cmd$)>=20 OR w > 500
 DoCMD
END SUB
 
SUB DoCMD
 
LOCAL temp$
 cmd$ =
UCASE$(cmd$)
 
'print #1, cmd$+cr$
 IF cmd$ = lf$ THEN ' wake up call
   PRINT cr$;
 
ENDIF
 
' etc
END SUB
 


Jim
VK7JH
MMedit   MMBasic Help
 
goc30

Guru

Joined: 12/04/2017
Location: France
Posts: 425
Posted: 08:13am 23 Sep 2019
Copy link to clipboard 
Print this post

for serial time out


Option EXPLICIT

const maxto = 500  'exemple time out 5 sec
dim cptto as integer  'count time$
dim flgeot as integer

SETTICK 10,sptim
Open "COM1:9600,255,spcomrec" As #2

flgeot=0


do

'  if need to read serial
 cptto=maxto
 ....
 if flgeot=1 then
flgeot=0
.....   'task receive text
 end if
'
...
'if no need read serail
 cptto=0
 

loop

sub sptim
 if cptto>0 then  'if cptto=0 then do nothing
   cptto=cpto-1
   if cptto=0 then 'if end of time-out do task "timeout"
     ....
   end if
 end if
end sub

sub spcomrec
Local tx$ As string
Local i2 As integer
Local a$ As string length 1
 nbcar=Loc(#2)
 If nbcar>0 Then
   tx$=Input$(nbcar,#2)
     cptto=maxto
     'do task read serial
       'exemple
       For i2=1 To nbcar
         a$=Mid$(tx$,i2,1)
         If (asc(a$)=13 or asc(a$)=10) Then  'end rec texte
             .....
           flgeot=1
         end if
       next i2
 end if
end sub


Edited 2019-09-23 18:19 by goc30
 
Frank N. Furter
Guru

Joined: 28/05/2012
Location: Germany
Posts: 813
Posted: 12:20pm 23 Sep 2019
Copy link to clipboard 
Print this post

Many thanks to everyone - I will try it!

Frank
 
PicFan
Senior Member

Joined: 18/03/2014
Location: Austria
Posts: 133
Posted: 12:37pm 23 Sep 2019
Copy link to clipboard 
Print this post

If I understood the problem correctly, an example with the console as input:


SUB conINP(tm)
 TIMER = 0
 DO WHILE((inp$ = "") AND (TIMER < tm))
   inp$ = INKEY$
 LOOP
END SUB



Maybe it,s help ?

Wolfgang
Edited 2019-09-23 23:25 by PicFan
 
goc30

Guru

Joined: 12/04/2017
Location: France
Posts: 425
Posted: 02:36pm 23 Sep 2019
Copy link to clipboard 
Print this post

  PicFan said  If I understood the problem correctly, an example with the console as input:

Wolfgang


your code is good but not the best, bcause on return from your subroutine, you don't know why you come back. You must test inp$ to know, and  remenber that timer work all time (and you can use timer on other sub) and for that an loop "do..while" with timer cond is not the more stable coding.

I propose other code, with 2 more var in call: status return who say why you come back, and string var with key receive


SUB conINP(tm,inp$,stat%)
' stat%=0 if sub in work (no timeout and waiting key$)
' stat%=1 if end on time-out
' stat%=2 if end on inkey buffer not empty and inp$=key$
local vtm as integer
 vtm = TIMER
 inp$ = ""
 stat% = 0
etq1:
 if  TIMER - vtm > tm then stat% = 1: exit sUB
 inp$ = INKEY$
 if inp$ <> "" then stat% = 2: exit SUB
 goto etq1
END SUB


Edited 2019-09-24 00:39 by goc30
 
Frank N. Furter
Guru

Joined: 28/05/2012
Location: Germany
Posts: 813
Posted: 07:02am 24 Sep 2019
Copy link to clipboard 
Print this post

@ goc30 and PicFan:

Thank you very much. Your last two solutions look very interesting - i will give it a try!

Frank
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9060
Posted: 10:20pm 24 Sep 2019
Copy link to clipboard 
Print this post

You could also consider using the SerialRx C-function on any I/O pin, as it has a built-in timeout feature.

r = SerialRx( pin, baud-rate, string$, timeout, maxchars, termchars)

For example, r = SerialRx( 5, 9600, T$, 1000 )  will look for data for one second then return with whatever was received in T$.  You need to DIM T$ before you call this.

Here is the PDF for the Cfunction:
SerialRx.pdf

This works well, if you KNOW when to expect data, and then you go and look for it, or perhaps the data is continuously being sent with a delay between packets etc, and you just want to intercept the most current packet.
Edited 2019-09-25 08:21 by Grogster
Smoke makes things work. When the smoke gets out, it stops!
 
Frank N. Furter
Guru

Joined: 28/05/2012
Location: Germany
Posts: 813
Posted: 07:09am 25 Sep 2019
Copy link to clipboard 
Print this post

Hi Grogster,

that looks very interesting!
I know exactly when the characters come (when they come) - and if they don't, I need the timeout. I will try it!
I have to read out a barcode reader - and if it fails I have to start error handling.

THANKS!

Frank
 
goc30

Guru

Joined: 12/04/2017
Location: France
Posts: 425
Posted: 12:28pm 25 Sep 2019
Copy link to clipboard 
Print this post

hi grogster

I completely forgot about your solution which is, by far, the best for the mentioned problem
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024