Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 23:35 25 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 : MM COM1 buffer control

Author Message
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 01:27pm 03 May 2012
Copy link to clipboard 
Print this post

I've written a small MMBasic program to send commands to a "Priority1" RFID232-R/W rfid reader module - as below.

'--------------------------------------------------------
'Simple "Priority1" model RFID232-R/W command program - via COM1
'--------------------------------------------------------
SendCommand: Open "com1:" As #1 'open COM1 to the RFID R/W unit
Input "RFID command =", cmd$ 'request RFID command from keyboard
cmd$ = UCase$(cmd$) 'make input uppercase
exitchk$ = Left$(cmd$,1) 'look for Exit, Quit, E or Q to stop pgm
If exitchk$ = "E" Then Close #1:End
If exitchk$ = "Q" Then Close #1:End
Print #1,cmd$+Chr$(13) 'send command and <CR> to RFID unit
Pause 200 'give it time to respond - a guess
n=Loc(1) 'check if characters received in input buffer from RFID
If n=0 Then Print "No reply in input buffer"
reply$ = "" 'initialize reply variable for input from buffer
reply$ = Input$(36,#1) 'read the buffer. 36 characters should be plenty
Print "RFID reply =" reply$ 'display what was read
If Left$(reply$,1)="?" Then ErrorHandler(reply$) 'RFID errors start with ?
Close #1 'empty input buffer and close
GoTo SendCommand 'loop for another command
End
'---------------------------
Sub ErrorHandler (ercode$) 'RFID error codes are: ?0,?1,?2,?3,?4
erno = Val(Mid$(ercode$,2,1)) 'get the error no. and convert to numeric
If erno = 0 Then 'display appropriate error description
? "Command not understood"
ElseIf erno = 1 Then
? "Tag not present"
ElseIf erno = 2 Then
? "Tag failure to Read/Write"
ElseIf erno = 3 Then
? "Access to block 0 not allowed"
ElseIf erno = 4 Then
? "Page address invalid for this tag"
EndIf
End Sub


----------------------------------------------------
The comms parameters are the same as the MMBasic defaults and commands are simple ASCII strings with a carriage return character CHR$(13) added to terminate them.

If I e.g. send "VER" (to obtain the firmware code version no.) it should return "306", which it does about half the time, but then only the "30" for the other half, in a seemingly random manner.

Am I clearing the buffer properly with the "Close #1" statement before sending each command or should I do something else?

I've added the "Pause 200" (msecs) to allow time for the module to respond to the command but even "Pause 1000" seems not to change the problem. Can someone point me in the right direction here please?

Greg
 
rhamer
Senior Member

Joined: 06/06/2011
Location: Australia
Posts: 174
Posted: 05:17am 04 May 2012
Copy link to clipboard 
Print this post

You have a few delays you need to understand and contend with.

1 the time it takes to send your command.
2 the time it takes for the other unit to process your command and begin to respond.
3 the time it takes for the other unit to full send the reply.

Your code initiates the send, waits 200ms then expects to see the reply, which is likely very unreliable.

I don't have the actual syntax in front of me so you'll have to look it up but one way to do it is.

Send your command
Sit in a tight loop checking for the receipt of the first character of the reply.
Pause for an appropriate amount of time to let the entire message arrive (1ms/char@9600)
Read the whole message.

What I have described above is not the best way, but usually good enough for simple slow comms.
Be aware that the process is blocking, meaning it does nothing until a char is received. It also assumes it will eventually arrive otherwise it is stuck forever.

Now before I get jumped on by the purists, I know there is a whole lot of better ways, but with that comes code complexity and possibly even the need to use interrupts.

Cheers

Rohan
Rohan Hamer
HAMFIELD Software & Hardware Solutions

Makers of the Maximite Expander.

http://www.hamfield.com.au
 
paceman
Guru

Joined: 07/10/2011
Location: Australia
Posts: 1329
Posted: 02:54pm 04 May 2012
Copy link to clipboard 
Print this post

  rhamer said   You have a few delays you need to understand and contend with.

1 the time it takes to send your command.
2 the time it takes for the other unit to process your command and begin to respond.
3 the time it takes for the other unit to full send the reply.


Your code initiates the send, waits 200ms then expects to see the reply, which is likely very unreliable.

Rohan


Hi Rohan, thanks for looking at it. I played with it some more and then realised I hadn't suppressed the auto generation of CR/LF at the "PRINT #1 cmd$" statement. Putting a semicolon at the end of it made all the difference. It must have been reading an extra CR/LF and that wasn't a valid command.

I also found that PAUSE 50 was plenty to return everything OK - it started to stuff up when I tried PAUSE 10.

I checked two other things: The variable "reply$" initialisation wasn't required - I should have known that. The "CLOSE #1" and then re-open with "OPEN COM1..." definitely was required before putting in another command - I wasn't at all sure about that. I guess emptying the buffer is mandatory.

I'll load up Geoff's V3.2A tomorrow and do some more.

Greg



 
Print this page


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

© JAQ Software 2024