PDA

View Full Version : Why doesn't my SERIN command seem to work?



EEder
02-25-2005, 11:35 AM
I've got my PC hooked up to my BS2 via the standard serial port. I'm writing a C++ program to talk to my BS2.

I can have my BS2 send data to my C++ Program / PC and my PC reads the data perfectly.

But when I try to send data from my PC's c++ program to my BS2, the SERIN command doesn't seem to work.

For the BS2->PC, I'm using " SEROUT 16, 84, ["!",DEC5 counter]" and that works great.

For the PC->BS2, I'm using " SERIN 16, 84,[DEC dat]" and that never seems to work.

Any ideas?

steve_b
02-25-2005, 08:51 PM
Have you tried using a terminal program (Hyperterm...) to do the same thing?!
what's your indication that it would work (from PCtoBS2)....since you're using the debug/programming port, you couldn't debug a message toa Pbasic terminal window.

I think most ppl would recommend you leave the programming port for programming purposes....although it is nice to use it with it's level shifter.

Also, your PC can listen and talk at the same time (well, does both so quickly it seems like the same time) but your stamp has to be ready to listen when the PC talks. So, if you're PC sends a message and your program is busy doing something else...it won't pick it up.
Try using a "start of text" character at the beginning of each data string. This way you could have your serin command WAIT for that character and then grab the rest.

So it's something like: serin [pin], 84 [WAIT("start character"), DEC dat]
Now, your stamp will sit there forever, until it sees this start character....so if you can't do anything else until you get this string, then that's fine....but if you have other things to do...then you'll want a timeout in there.
So: serin [pin], 84, [time to wait], [where to go if no data received within time stated],[WAIT("start character"), DEC dat]
So: serin [pin], 84, [2000], [no_data],[WAIT("start character"), DEC dat]...this would wait at the serin function for 2seconds for data...if none received it will go to the no_data subroutine.

Stick with using pin16 for now....but eventually you might consider using other pins, so you can debug. You might want to try a MAX232 chip (you can get them so that they have the caps embedded as opposed to having external caps). BUT, you don't really need one if it's a short distance. But you'll have to change your baud values. So, you're serout baud value will have to represent a true value (so the 84 would work), but the serin baud value would have to represent an inverted value (so 16468) BUT, you would need a 22kohm resistor in series with this line as the rs232 level is upwards of 12volts!

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Steve
http://members.rogers.com/steve.brady (http://members.rogers.com/steve.brady)
"Inside each and every one of us is our one, true authentic swing. Something we was born with. Something that's ours and ours alone. Something that can't be learned... something that's got to be remembered."

allanlane5
02-25-2005, 11:44 PM
One thing you need to know -- when you connect your PC's serial port directly, it normally raises the DTR signal. On the BS2, a raised DTR signal holds the BS2 in 'RESET', unless you are using the BOE board. The BOE board has two capacitors which decouple the DTR signal.

EEder
02-26-2005, 03:39 AM
steve_b said...
Have you tried using a terminal program (Hyperterm...) to do the same thing?!

what's your indication that it would work (from PCtoBS2)....since you're using the debug/programming port, you couldn't debug a message to a Pbasic terminal window.



I think most ppl would recommend you leave the programming port for programming purposes....although it is nice to use it with it's level shifter.



Also, your PC can listen and talk at the same time (well, does both so quickly it seems like the same time) but your stamp has to be ready to listen when the PC talks. So, if you're PC sends a message and your program is busy doing something else...it won't pick it up.

Try using a "start of text" character at the beginning of each data string. This way you could have your serin command WAIT for that character and then grab the rest.



So it's something like: serin [pin], 84 [WAIT("start character"), DEC dat]

Now, your stamp will sit there forever, until it sees this start character....so if you can't do anything else until you get this string, then that's fine....but if you have other things to do...then you'll want a timeout in there.

So: serin [pin], 84, [time to wait], [where to go if no data received within time stated], [WAIT("start character"), DEC dat]

So: ...this would wait at the serin function for 2seconds for data...if none received it will go to the no_data subroutine.

<FONT color=black>

Stick with using pin16 for now....but eventually you might consider using other pins, so you can debug. You might want to try a MAX232 chip (you can get them so that they have the caps embedded as opposed to having external caps). BUT, you don't really need one if it's a short distance. But you'll have to change your baud values. So, you're serout baud value will have to represent a true value (so the 84 would work), but the serin baud value would have to represent an inverted value (so 16468) BUT, you would need a 22kohm resistor in series with this line as the rs232 level is upwards of 12volts!



Thanks for the helpful reply, steve!

A few things:

The indicator for whether or not it works is that the BS2 is actually hooked up to two other servo controllers which are controlling a little doodad that moves (roughly) around an x-y plane. And, after getting the same suggestion from another Parallax.com forum member via e-mail about using start signals and acks, I made that change too. So the actual code read:






ra VAR Byte
x VAR Word
y VAR Word
baud CON 396
dat VAR Word
synch CON "!"
ack CON "#"


x = 770 'X coordinate to move the servo to
ra = 10 'Rate to move the servo at
DO
SERIN 16, 84,[WAIT(synch),dat]
SEROUT 15, baud+$8000,["!SC", 1, ra, x.LOWBYTE, x.HIGHBYTE, CR] 'Serial command to pin 15 to move the servo
x = x + 5 'on the next run, move it a bit further so its noticable
SERIN 16, 84,[WAIT(ack)] 'wait for the PC to send ACK



PAUSE 1000 ' pause just in case this happens really, really fast; dont want to break the servo by moving it to too high of an X value
LOOP




So my c++ code is basically:




Port.write("!5") // where 5 is just some random decimal data





The problem is, in doing this, the servos never seem to move, and they should move at least once, right?

Before I run this code, I run a different program which centers the servos at a different position, so I'm sure to notice that moving the X coordinate to 770 is noticable.

Another person told me that the BS2 sends a "!SC110770" string as an Acknowlegment of some kind... does this happen automatically? It shouldn't matter either way, because my BS2 isn't reading the first "!5" data... but just curious.

Lastly, I apologize if I'm a bit of a BS2 newbie :)

Thanks for the help so far, and any further!

steve_b
02-26-2005, 04:07 AM
I'm afraid I can't help you any in C....couldn't quite grasp it very well in college...which is why I ended up taking electronics instead of computers!

I didn't see how you were positioning your servo.

You need a pause 20 in between your pulsout commands.

DO
PULSOUT 12, 750
PAUSE 20
LOOP

I think that 750 was my centering for that particular servo....but you have to update it every so often to keep it moving or standing still.

20 is the magic number....not to say the only one...just the quickest starting point.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Steve
http://members.rogers.com/steve.brady (http://members.rogers.com/steve.brady)
"Inside each and every one of us is our one, true authentic swing. Something we was born with. Something that's ours and ours alone. Something that can't be learned... something that's got to be remembered."

EEder
02-26-2005, 04:16 AM
steve_b said...
I'm afraid I can't help you any in C....couldn't quite grasp it very well in college...which is why I ended up taking electronics instead of computers!

I didn't see how you were positioning your servo.

You need a pause 20 in between your pulsout commands.

DO
PULSOUT 12, 750
PAUSE 20
LOOP

I think that 750 was my centering for that particular servo....but you have to update it every so often to keep it moving or standing still.

20 is the magic number....not to say the only one...just the quickest starting point.



Actually, I just made the above code work correctly. I think I had a C++ problem, the BS2 code was perfect.

As far as the servo controller,


SEROUT 15, baud+$8000,["!SC", 1, ra, x.LOWBYTE, x.HIGHBYTE, CR]



Tells the servo to move to position X at RA speed. To be honest, I'm working on this device (BS2 and servos together) for a partner, and I'm not too familiar with the setup. Thats the code he uses to move the servo to position X, so I just kept it.
The "x = x + 5" line in each loop serves to increment X, so when it says "Move to X," its a litlte farther than the previous iteration of the loop.

But as I said, I got the basic code working, which is great. The servo moved as my PC wrote out data to the BS2, which is awsome! Thanks for the help.

As far as talking back and forth, what is th preferred method of sending acks and what not?

Currently, I have:

PC sends "(Start Character)(Data)"
BS2 processes data, does whatever its going to do, then sends "ACK" back to the PC
PC reads ACK, knows its okay to send another command.


Is this whats considered "efficient" or the correct standard for BS2 programming?