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: AustraliaPosts: 1329 |
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: AustraliaPosts: 174 |
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: AustraliaPosts: 1329 |
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 |