Difficulty acquiring and using data from Applied Motion RS232 motor controller
I'm new to writing spin code and I'm already in it up to my eyeballs. I am following the work of a coworker and thus far I've been able to tweak his code for my needs. I've written some code to give direct control of one of our servos (an applied motion TSM23S) to simplify the operation of our device.
I'm assuming a pro will see some error immediately but this code sortof works. By pressing the "stop" key the propeller sends a command to the servo that should report (via ASCII) the servo's current encoder position. I have the prop storing this info as a byte array and spitting it out to the serial terminal. If I can make this work reliably I'd like to be able to use the encoder position elsewhere in the code.
The problem is that the output isn't reliable. After initiating a move or encoder zero it takes quite a few "stop" keypresses before the correct encoder position is displayed in the debug terminal. I don't know if it's failing to read or print the value correctly and I don't know how to determine the difference. I have verified using the Applied Motion tool that the servo controller is receiving and responding to the messages. Can you please help me?
Jamie (code snippets below, unsure of correct code posting syntax on this forum so I'll use italics- EDIT- found it and fixed it!)
I'm assuming a pro will see some error immediately but this code sortof works. By pressing the "stop" key the propeller sends a command to the servo that should report (via ASCII) the servo's current encoder position. I have the prop storing this info as a byte array and spitting it out to the serial terminal. If I can make this work reliably I'd like to be able to use the encoder position elsewhere in the code.
The problem is that the output isn't reliable. After initiating a move or encoder zero it takes quite a few "stop" keypresses before the correct encoder position is displayed in the debug terminal. I don't know if it's failing to read or print the value correctly and I don't know how to determine the difference. I have verified using the Applied Motion tool that the servo controller is receiving and responding to the messages. Can you please help me?
Jamie (code snippets below, unsure of correct code posting syntax on this forum so I'll use italics- EDIT- found it and fixed it!)
VAR
long SMstack[20],WPstack[20]
long iLay, nLay
long SLD_LimLeft, SLD_LimRight
byte SM_ID, WP_ID
byte SlidePos[25]
...(other code here)
PRI Traverse_Adjust
repeat
if pin.In(JOG_L_PIN)==0 'Jog left
fds.str(DEBUG,string(CR,"Jogging to the left",CR))
fds.str(SLD,string("SJ",CR)) 'stop jog
fds.str(SLD,string("JS0.10",CR)) 'jog speed set
fds.str(SLD,string("DI-1000",CR)) 'direction set
fds.str(SLD,string("CJ",CR)) 'commence jog
time.Pause(250)
elseif pin.In (JOG_R_PIN)==0 'Jog right
fds.str(DEBUG,string(CR,"Jogging to the right",CR))
fds.str(SLD,string("SJ",CR)) 'stop jog
fds.str(SLD,string("JS0.10",CR)) 'jog speed set
fds.str(SLD,string("DI1000",CR)) 'direction set
fds.str(SLD,string("CJ",CR)) 'commence jog
time.Pause(250)
elseif pin.In (JOG_STOP)==0 'Stops jog
fds.str(SLD,string("SJ",CR))
fds.str(DEBUG,string(CR,"Stopping!",CR))
time.Pause(20)
fds.str(SLD,string("EP",CR)) 'requests current encoder pos from TSM23S
time.Pause(50)
dio.StrIn(SLD,@SlidePos) 'stores string to byte array
time.Pause(50)
dio.str(DEBUG,@SlidePos) 'sends string to debug terminal
fds.str(DEBUG,string(CR))
time.Pause(250)
elseif pin.In(SET_ZERO)==0 'Set current position to EP=0
fds.str(SLD,string("SJ",CR)) 'Stops motor jog
time.Pause(20)
fds.str(SLD,string("EP0",CR)) 'Sends 1st command to make current position zero
time.Pause(20)
fds.str(SLD,string("SP0",CR)) 'Sends 2nd command to make current position zero
time.Pause(250)
else
time.Pause(50)

Comments
For me it's tricky to deal with snippets. Can you post an archive of your project so others can compile on their ends?
I'm happy to post my code but I've since made a giant mess of things in an effort to fix issues. It is becoming clear that I don't yet know how to manage cogs and use them simultaneously and that could be a problem. I was about to start breaking out and testing the individual parts of my code.
I've enclosed an archive. By commenting out portions of it the various aspects seem to work but as it applies to controlling the traverse (serial port called SLD) I can't seem to share control between the adjustment and main processes. This is part of a cable winding machine. Initial attempts were highly automated but didn't give enough flexibility. It seems that the ability to stop and manually adjust will be a huge help and more important than counting the number of layers wound or continuing unassisted.
The complication is that we are using external motor controllers that don't automatically report their position. My initial question relates to being able to query the position, store and interpret the ASCII string, and eventually use that string to make control choices.
Jamie
Here's an idea to get you going. If you can get these working then building your system should be a little easier.
pub set_value(p_cmd, value) '' Set value in drive '' -- p_cmd is pointer to 2-letter parameter string '' -- value is new setting comx.str(p_cmd) comx.dec(value) comx.tx(13) pub get_value(p_cmd, p_buf) | len, c, idx, sign, value '' Get value from drive '' -- p_cmd is pointer to 2-letter parameter string '' -- p_buf is pointer to buffer for receiving response '' * 16 or more bytes recommended comx.rxflush ' clear rx buffers bytefill(p_buf, 0, BUF_SIZE) comx.str(p_cmd) ' request parameter value comx.tx(13) len := 0 repeat c := comx.rxtime(COM_TIME_OUT) if (c => 0) byte[p_buf][len++] := c else quit ' verify response comerror := false ' clear global coms error flag repeat idx from 0 to 1 if (byte[p_buf][idx] <> byte[p_cmd][idx]) ' mismatch? comerror := true return 0 if (byte[p_buf][2] <> "=") comerror := true return 0 sign := 1 value := 0 p_buf += 3 ' skip past = sign ' check for sign c := byte[p_buf] if (c == "-") sign := -1 p_buf++ ' extract value repeat c := byte[p_buf++] if ((c => "0") and (c =< "9")) value := value * 10 + (c - "0") else quit return sign * valueI've searched the internet for "comx" and I'm not familiar with it. Is it a serial object? Can you point me to a manual or page for it?
It seems the various different serial objects have very different ways of being used. This job requires quite a few serial ports, some of which aren't even implemented yet. Would the method you show above be translatable to the four port serial object that I'm using?
Jamie