View previous topic :: View next topic |
Author |
Message |
Zer0flag Guest
|
Thoughts on a software protocol for controlling a device |
Posted: Wed Feb 20, 2008 8:56 am |
|
|
Hi all!
I have a device which contains a PIC. This device has to be controlled from a PC via RS232 and a user must be able to write his own software to interface the device (e.g. from LabView). So I am working on a software "protocol" for communicating with the device and I am not sure what is the best way to implement this protocol. Unfortunately I could not find much information on that topic.
Many manufacturers are implementing such a protocol in a way that the PC sends a command to the device and does not receive any response, unless the command is a query. This means that the user's software on the PC does not really know if a command could be executed at all or when command execution has finished. So the PC has to send an additional poll command to find out what happened.
Therefore my idea is to make the device ALLWAYS send some response. The response will be ERR + error code if the command could not be executed or it will be OK which is sent AFTER finishing with command execution. The user's software has to wait for that response before sending further commands as the device is not able to process multiple commands simultanously. I even thought about disabling the PIC's INT_RDA interrupt during command execution because the device is busy and should not be disturbed. Is that a good idea?
In addition to the described "command -> response pattern" i also want to implement another feature: The device shall send status information to the PC as soon as some internal device status changes. This means that the user's software must be able to handle such status reports (STA + status code) which do not really "fit" in the command -> response pattern. When a command is being executed the status change report will be sent AFTER the response resulting form command execution. I am not sure if such status reports will be a problem for the developer of control software?
Any comments and ideas are more than welcome.
Best regards,
Zer0flag |
|
|
jds-pic
Joined: 17 Sep 2003 Posts: 205
|
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Feb 20, 2008 10:11 am |
|
|
Can't help with the PC side, but from the PIC's point of view, this is pretty easy.
First, you don't have to make things stop while the PIC is processing a command. Just implement a receive buffer - x characters long - your RDA interrupt just places characters into it and sets a 'command received' flag when a CR/LF is received. The main loop of your program then parses the receive buffer to examine the last unprocessed command. The RDA interrupt can continue to receive commands into the buffer in the meantime. If the buffer gets close to filling, just send the standard soft handshake signal XOFF. When the buffer empties, send XON.
When it comes to acknowledging commands, I'd send as a response the command itself followed by ACK if successful or NACK, ERROR CODE if not successful.
The transmittal of status I'd make into a periodic thing (heartbeat) instead of being only done when things change. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: Thoughts on a software protocol for controlling a device |
Posted: Wed Feb 20, 2008 1:27 pm |
|
|
Zer0flag wrote: | a user must be able to write his own software to interface the device (e.g. from LabView). |
I'm sure LabView has built in support for MODBUS and a few other protocols. Basically all you have to do is let LabView know what registers to poll for data. There are a lot of applications already written to support existing protocols that can meet your need. Pick one and use it. |
|
|
Zer0flag Guest
|
Re: Thoughts on a software protocol for controlling a device |
Posted: Wed Feb 20, 2008 1:58 pm |
|
|
Thank you very much for the information. I looked at all tips and protocols suggested. There are really some very useful things I will implement.
The problem with my device is that I need to implement something that can also be used by humans in terminal mode. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: Thoughts on a software protocol for controlling a device |
Posted: Wed Feb 20, 2008 4:06 pm |
|
|
Zer0flag wrote: | Thank you very much for the information. I looked at all tips and protocols suggested. There are really some very useful things I will implement.
The problem with my device is that I need to implement something that can also be used by humans in terminal mode. |
MODBUS has an ASCII mode that can be used in terminal mode but I would hardly call it something useful by a human. It would appear that you need to use two protocols. I would go with MODBUS or some other documented protocol and then when the device receives a 'line feed' followed by a 'carage return' as a 2 byte packet switch to a terminal menu mode. You would basically have two code paths for packet handling. The menu path would be the more complex. |
|
|
Guest
|
Re: Thoughts on a software protocol for controlling a device |
Posted: Thu Feb 21, 2008 3:10 am |
|
|
Neutone wrote: | It would appear that you need to use two protocols. |
Because I don't really need checksums etc. I think that one ASCII protocol that can be used by humans and computers is enough. For example SCPI-compliant devices offer the same command set for PC and human interfacing. I think it was my mistake to use the word "protocol". What I mean is more the "pattern" of communication. The problem with SCPI is that it is often implemented together with GPIB. RS232 is just an addon if it is available on GPIB devices. GPIB allows command queuing and has special hardware service request lines that will report an error to the PC. This way the PC will know when it has to poll the device for the error code.
The question is if GPIB command queuing is a good idea. If you send a couple of commands you will never know if they got executed and when they got executed. This is especially a problem with commands which depend on each other. Therefore I wanted to implement the strict COMMAND -> RESPONSE pattern. I disable INT_RDA interrupts during command execution so that a fast PC cannot "disturb" the small PIC while it is processing a command.
The additional thing I wanted to implement is the status reporting mechanism so that the PC does not cause too much traffic because of polling my device too often (you never know how a programmer will interface the device). This could again "disturb" the small PIC too often and it would not be able to run its firmware properly.
Of course I have to take care that the status reports do not occur during a COMMAND -> RESPONSE.
Best regards,
Zer0flag |
|
|
SET
Joined: 15 Nov 2005 Posts: 161 Location: Glasgow, UK
|
|
Posted: Thu Feb 21, 2008 6:50 am |
|
|
A good way is COMMAND->RESPONSE->CONFIRM where command is from PC, response from PIC ('Ok I can do that and Im ready to go') and confirm (from PC) is 'lets do it then'. That forces your PC side to stay in lockstep with the PIC. Suitable timeouts could also be provided. |
|
|
Guest
|
|
Posted: Wed Jan 27, 2010 3:05 am |
|
|
SET wrote: | A good way is COMMAND->RESPONSE->CONFIRM where command is from PC, response from PIC ('Ok I can do that and Im ready to go') and confirm (from PC) is 'lets do it then'. That forces your PC side to stay in lockstep with the PIC. Suitable timeouts could also be provided. |
I'm programming an application that does this but I'm having problems with the timming. Baud rate is 9600.
PIC code:
Code: |
void process_test(void)
{
putc(ACK);
if(kbhit())
{
alr_test = getc();
putc(ACK);
}
else
{
putc(NAK);
}
}
|
This function is entered when the PC send the command "T". In PC side I do the same process:
Send "T"
Wait for ACK
Send Char
Wait for ACK or NAK
And I always receive the NAK.
Thanks! |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Jan 27, 2010 3:23 am |
|
|
The reason you always get a NAK after sending the char is because you do not have a period of time where you wait for the char in the PIC.
The PC sends a 'T' and before it has had time to send the char the PIC has already read kbhit, decided there is no char and sent the NAK.
You need to wait for a char to come in, preferably with a timeout.
Something like
Code: |
int timeout = 100; // 1 second
while (!kbhit())
{
timeout--;
delay_ms(10); // wait 1/100th of a second
}
if (timeout > 0) // got char
{
alr_test = getc();
putc(ACK);
}
else
putc(NAK);
|
|
|
|
Marc A. Guest
|
|
Posted: Wed Jan 27, 2010 9:47 am |
|
|
Ok! Thank you!
I have finally used a timer which activates a flag:
Code: |
set_timer0(0);
f_com_tout = 0;
while(!f_com_tout) //TIMEOUT
{
restart_wdt();
if(kbhit())
{
alr_test = getc();
putc(ACK);
return;
}
}
putc(NAK);
|
|
|
|
|