Note:
I fixed this problem, albeit in a work-around way.
I wrote a module which has functions to open the serial communication to the device (a syringe pump), close the serial port, and print any commands relevant to me to the serial port.
It turned out that, while not the cleanest implementation, opening and closing the serial port for each and every command string sent was pretty fast; not noticeably slower than opening the serial port once at load time. I'd imagine this approach can prevent hang-ups if the socket gets broken or something, which is a side-benefit.
The screen loads the module with this code in the screen load script:
package.path = package.path .. ";./Modules/?.lua;"
package.cpath = package.cpath .. ";./Modules/?.dll;"
package.loaded.SyringePump = nil
sp=require "SyringePump"
And I used the following lines at the start of my macro to get the module loaded for the separate Lua instance that runs for macros:
package.path = package.path .. ";./Modules/?.lua;"
package.cpath = package.cpath .. ";./Modules/?.dll;"
sp=require "SyringePump"
In this way, all the commands in my module are available for both the screen and MCodes.
Again, it's not a very clean implementation -- the serial object could have conflicts if the screen and a macro try to open it at the same time -- but it's code-efficient (the functions live in one file) and it works fairly robustly. What I wouldn't give for some semaphores, or, a single Lua instance, or god forbid some thread-safe implementation of Mach4 :-D
Hope someone finds this useful!