PDA

View Full Version : Sending multiple serial strings.



Zebryk
- 26th September 2014, 18:30
Hello,

What is the best way to save and send multiple strings via serial?

I need to send motion commands to a stepper motor controller. Each command (Stop, Left, Right, etc.) is comprised of (8) Hex codes. These are sent TTL 9600BPS, 8N1.

My thought was to save each of these to a VAR (which could be a constant?) and then reference each when calling HSEROUT.

' Instead of directly:
HESEROUT [HEX 55, AA, 1, FF, 0, 0, AA, 56]

' Use something like this:
HESEROUT [mcuStop]

Although directly works fine, it is quite awkward when creating elaborate motion profiles.

I am not sure how to store these strings as VAR's/Array's/Tables or how to call them?

Thanks!


' Partial list of about 24 commands.
mcuStop = [HEX 55, AA, 1, FF, 0, 0, AA, 56]
mcuCoast = [HEX 55, AA, 12, EE, 0, 0, AA, 56]
mcuForward = [HEX 55, AA, 3, FD, 0, 0, AA, 56]
mcuReverse = [HEX 55, AA, 4, FC, 0, 0, AA, 56]
mcuLeft = [HEX 55, AA, 5, FB, 0, 0, AA, 56]
mcuRight = [HEX 55, AA, 6, FA, 0, 0, AA, 56]
mcuSpeed1 = [HEX 55, AA, 17, E9, 0, 0, AA, 56]
mcuSpeed2 = [HEX 55, AA, 1A, E6, 0, 0, AA, 56]
mcuSpeed3 = [HEX 55, AA, 18, E8, 0, 0, AA, 56]
mcuSpeed4 = [HEX 55, AA, 19, E7, 0, 0, AA, 56]

HenrikOlsson
- 26th September 2014, 20:05
Hi,
One way to do what you're asking for is something like

mcuStop VAR BYTE[8] ' Array of 8 bytes
mcuStop[0] = $55
mcuStop[1] = $AA
mcuStop[2] = $01
mcuStop[3] = $FF
mcuStop[4] = $00
mcuStop[5] = $00
mcuStop[6] = $AA
mcuStop[7] = $56

HSEROUT [STR mcuStop]
However, with 24 commands, each consisting of 8 bytes you're going to "waste" 152 bytes of RAM on this - which may or may not matter.

Another aproach would be to create 24 subroutines and call them using GOSUB

mcuStop:
HESEROUT [$55, $AA, $01, $FF, $00, $00, $AA, $56]
RETURN

mcuCoast:
HSEROUT [$55, $AA, $12, $EE, $00, $00, $AA, $56]
RETURN

GOSUB mcuStop
GOSUB mcuCoast


Yet another posibillity might be the user command feature in PBP3 but that's a quite advanced feature.

It looks like all of the commands starts and ends with the same sequenct of bytes, 55, AA, xx, xx, 00, 00, AA, 56 where xx are the actual data. Is that valid for all commands?

/Henrik.


55, AA, 1, FF, 0, 0, AA, 56

Zebryk
- 26th September 2014, 23:06
Option 1 is quite logical.
Why does it "waste" RAM? Could it be stored in ROM instead?
Option 2 is simple.
In composing the moves, I do want to avoid typing those long strings over and over.
Good observation.
Each packet does have the same beginning and end. (55, AA and then AA, 56)
The four bytes in between is the payload.

Demon
- 26th September 2014, 23:27
Henrik is right. You can then tweak his approaches to use headers (prefix codes) and footers (suffix codes).

Robert


Edit: "waste" is relative. It depends on your PIC, program size and variables used. If you have little codespace, option 1 might be better.

If you "have" to use memory and you have little left on the PIC, is I/O time to external storage a concern?

It all depends on your PIC, application requirements and personal preference.

HenrikOlsson
- 27th September 2014, 10:53
Hi,


Why does it "waste" RAM? Could it be stored in ROM instead?
Waste may not have been the best word. What I mean is that the string for each command is static, they don't change, so there's no real need for them to live in RAM - which they'll do if you follow option 1 in my previous post. Again, there's nothing inherently wrong with this and it might be the easiest way if you have the RAM to spare.


It IS stored in ROM (FLASH actually) when you do it like

HESEROUT [$55, $AA, $01, $FF, $00, $00, $AA, $56]
Which means that option 2 does, obviously, use less amount of RAM.

With PBP3 there are ways to create unique usercommands but it's a pretty advanced topic. With the information given so far I'd go for option 2. Create a subroutine for each of the 24 commands and call them in sequence using GOSUB.

/Henrik.

EDIT: And if you DO go for option 2 and want to save some codespace you could probably do that by creating a "send header" and a "send footer" sub so you don't need to store the same 4 bytes for each command 24 times.

mcuStop:
GOSUB SendHeader : HESEROUT [$01, $FF, $00, $00] : GOSUB SendFooter
RETURN

SendHeader:
HSEROUT [$55, $AA]
RETURN

SendFooter:
HSEROUT [$AA, $56]
RETURN


EDIT2: And now, if you use an 18F part and have LONGs enabled you COULD possibly do something like:

[code]
Header CON $55AA
Footer CON $AA56
MotorStop CON $01FF0000

mcuStop:
GOSUB SendHeader : HESEROUT [MotorStop] : GOSUB SendFooter
RETURN

SendHeader:
HSEROUT [Header]
RETURN

SendFooter:
HSEROUT [Footer]
RETURN

Watch out for Little vs big endian, I'm not sure, off the top of my head how it's being sent here so you may need to reverse it.

Zebryk
- 30th September 2014, 16:03
Yet another approach would be create mcuCMD array and just dynamically change interior bytes to a specific motion command.

Boy, lots of options!
Thanks for getting me started!

For the immediate, I am going with Option 2 using the 24 GoSubs which is both pretty efficient and easy to read or maintain.

Z