Serial Communication data loss and the best way to send 'parameters' to a BS2?
EEder
Posts: 12
My BS2 is running a program which reads input from the Serial line connected to my PC and depending on the input, it does a few different things (turns on/off lights, moves a servo). While a lot of this is already technically working, I'm having a few problems I'm sure you fellas have encountered beofre.
1) I'm noticing that if I load up my PC and send out the TURN_ON_GREEN_LIGHT command, nothing happens. But if I put my PC in a loop sending out that command constantly, it works! I'm getting the feeling the BS2 is missing some of the serial data. Whats going on here? (My BS2 code is below)
(PC sends a ! before the op_code
2) One of the functions that needs to happen is for the BS2 to move two different servos to a position. For this, my PC needs to send
a) The opcode for "Move to"
b) The X coordinate
c) The Y coordinate
d) The rate of movement
My initial thought was:
But this doesn't seem to work, and I presume its because some of the data is being missed over the serial line, like I mentioned in my first problem.
Whats the best way to essentially pass parameters to your BS2?
Thanks ahead of time for the help!
-Brad
1) I'm noticing that if I load up my PC and send out the TURN_ON_GREEN_LIGHT command, nothing happens. But if I put my PC in a loop sending out that command constantly, it works! I'm getting the feeling the BS2 is missing some of the serial data. Whats going on here? (My BS2 code is below)
(PC sends a ! before the op_code
sync CON "!" DO SERIN 16, 84,[noparse][[/noparse]WAIT(sync), DEC op_code] IF (op_code = TURN_ON_GREEN_LIGHT) THEN HIGH 5 'turns on the light ENDIF '... check for other op_codes LOOP
2) One of the functions that needs to happen is for the BS2 to move two different servos to a position. For this, my PC needs to send
a) The opcode for "Move to"
b) The X coordinate
c) The Y coordinate
d) The rate of movement
My initial thought was:
MOVE_CODE CON 1 sync CON "!" x_coord VAR Word y_coord VAR Word rate VAR Word SERIN 16, 84,[noparse][[/noparse]WAIT(sync), DEC opcode] if (opcode = MOVE_CODE) THEN SERIN 16, 84,[noparse][[/noparse]WAIT(sync), DEC x_coord] SERIN 16, 84,[noparse][[/noparse]WAIT(sync), DEC y_coord] SERIN 16, 84,[noparse][[/noparse]WAIT(sync), DEC rate] '...execute the movement on the servos ENDIF
But this doesn't seem to work, and I presume its because some of the data is being missed over the serial line, like I mentioned in my first problem.
Whats the best way to essentially pass parameters to your BS2?
Thanks ahead of time for the help!
-Brad
Comments
The Stamp needs time to go through the loop between each SERIN read. That may be why multiple writes works.
Larry
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
How long would you think an appropriate amount of time?
I have paused for up to 10 full seconds after the PC writes the first piece of data onto the serial port. Then upon reading, the PC reads the exact data it just wrote onto the port. It can't possibly take ten seconds for the BS2 to go through a loop of :
My PC code looks something like:
It basically write "!3" to the port, sleeps for 10 seconds, then reads whats on the port and prints it out if its not the ACK its looking for and keeps looking.
Is it possible that the PC is somehow holding onto the port and preventing the BS2 from reading from the serial line?
My suspicion is that the "DEC dat" may not be completing as quickly as you expect it will. Check the manual for what terminates a DEC formatter. In the meantime, try this:
aPort.write("!3 ", 2); <== space added after !3 modified as appropriate
::Sleep(10000);
while (!((z = aPort.read()) == ack))
{
std::cout << "read: " << z << std::endl;
}
That will immediately terminate the DEC formatter, so see how that fares. You may also want to consider using a TIMEOUT parameter in your SERIN statement in a future version to prevent possible hangs. Just as an added thought, at least during testing to know when control is being transferred between the PC and the Stamp, you might want to consider the use of FLOW CONTROL. Later if you get your timing down to a science, it could be removed.
Regards,
Bruce Bates
Do you use XP or a USB dongle?
I beleive there are work-arounds, but since I don't use XP, I never looked into them.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
MIGHT I SUGGEST, YOU MIGHT CONSIDER HAVING THE STAMP ECHO BACK TO THE PC, THE DATA AFTER IT HAS BEEN RECEIVED.
73
SPENCE
K4KEP
Thats an interesting suggestion, and I just tried it with no luck. I added the extra space after my opcode to make it "13 " which didn't change anything. Then, I changed the formatter to DEC1 instead of just DEC, which according to the manual should look specifically for a 1 digit decimal number, which is exactly what the 3 is that follows the !. That too didn't work. Executing the above C++ code sends out the command and then waits for 10 seconds, then reads it right back. All the while , the BS2 is sitting there without putting on its lights.
Interestingly enough, look at the following:
If I change my C++ code to:
Every time, on the third iteration, the light goes on, regardless of the ::Sleep() time.
Any ideas?
*Note - Yes, I am using Windows XP. Its going straight through a Serial Cable.
It seemed to be a quick and straightforward method of accessing ports, but seeing as how I've never used it, I shouldn't rule it out as whats causing the problem.
I'm inclined to think this is the case.
I've loaded up HyperTerminal and connected it to COM2. The first time I enter the command, nothing happens. But once I enter it again, it goes out ot the BS2, the command is executed, and the BS2 sends back the ACK character. From this point on, I can test out my BS2 Microprogram and it seems to be working perfectly, which is good news.
The bad part is that the C++ program I have doesn't seem to be working properly. It still sits there and sends out the command, waits the sleep time and then reads its own command off the serial port... unless I put it in a loop and just flood it. Anyone have any suggestions on a good class for accessing the serial port?
Post Edited (EEder) : 2/28/2005 9:59:28 AM GMT
At this juncture I'd stop using pin port 16 on the Stamp and use some other pin port. Any other pin port can be used for serial communications, as you're not restricted to pin port 16.
There is a ECHO which is occuring, unbeknownst to you, and reflecting the data back to the PC from the characters sent to the Stamp. The ECHO can not be disabled as it occurs at the Stamp hardware level. That ECHO, of the transmitted characters is probably screwing up your ACK detect routine on the C++ side. The echoing is unique to pin port 16. Sorry I didn't notice it earlier.
Regards,
Bruce Bates
Stamp:
SEROUT 16, 16468, [noparse][[/noparse]ReadyCmd] ' Send Ready 'R'.
SERIN 16, 16468, [noparse][[/noparse]Cmd] ' Wait for command.
Code:
try
{
// Note: Cycle looking for requests ('R') from stamp. //
while(Terminated == false && ComReady == true)
{
// Note: Thread not event driven, give CPU a break.
Sleep(10);
try
{
char InC;
// Note: Something in the input buffer. //
if(COM->CharReady())
{
InC = COM->GetChar();
// Note: Stamp ready for more commands. //
if(InC == 'R')
PushCmd();
}
}
catch (Exception &E)
{
//
}
}
}
__finally
{
// Note: Free Stack. //
if(COM != NULL)
{
COM->Open = false;
delete COM;
COM = NULL;
}
}
The COM code is in its own thread so the above code looks tougher than it is.
Basically any command I send to the stamp goes into a software FIFO buffer.
When the stamp receives a command it performs the action required then sends
an 'R' back through the com port.
The code waits for an 'R' from the stamp and then sends the next command in the software buffer.
Then waits for a 'R' from the stamp, etc.... until the buffer is empty.
In other words its a manual software flow control.
I found that trying to sync the timing with code is luke warm at best. Even if you
got it to work, on a faster machine the code would start failing again.
Another solution is to use two pins on the stamp and use a hardware flow control and let
the serial hardware do the buffering.
Post Edited (PLJack) : 2/28/2005 4:36:42 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Is there any other pins that has an rs232 driver ?
according to this thread, pin 2 and 3 has a built-in driver, is this true?
http://forums.parallax.com/forums/default.aspx?f=5&m=64976
http://www.parallax.com/dl/docs/cols/nv/vol3/col/nv89.pdf
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA