On 2021-04-28, Cetin Aslantepe <
cetin.asl...@gmail.com> wrote:
> Dear Supporter,
>
> I have been trying to control a stepper motor via GUI(WinForms) with
> my little programming knowledge.
Little programming knowledge + threads = bad mix.
> With the example programs of device, I get commands (movements)
> performed.
>
> I was told that only by applying threads two main programs (device and
> winforms) is possible. Are threads necessary?
Threads are almost never necessary; anyone who insists you need threads
to control a stepper motor with a GUI is incompetent.
You already have three independent actors in the mix: the computer,
the GUI user and the stepper motor.
Throwing more concurrency into the situation than that won't achieve
anything.
> If yes, how should I design the program with threads best?
Correct use of threads requires considerable expertise in concurrent
programming. Acquiring concurrent programming expertise requires a very
solid background in sequential programming.
There is already concurrency inherent in the control of a motor,
because a motor doesn't instantly react to the step commands. Your
progrm has to take that into account.
> Are there other solutions?
The details depend on what kind of API do you have available for
controlling the stepper motor?
I'm imagining you have some buttons on the GUI to step the motor. Is it
acceptable for your GUI to block (i.e. become unresponsive) when the
clicks a button, until the motor has finished stepping?
Is the underlying API blocking or asynchronous: is there a function
to step the motor which returns when the motor has finished stepping, or
is there a function which returns instantly, and another function for
monitoring whether the motor is done? Is it possible to get a
notification when the motor is done (e.g. callback function or some
other event)? Failing that, a timer could fake this out. If we know that
the motor can step in 50 milliseconds, we can set a 60 millisecond
timer. When the timer goes off, it will post an event into the GUI event
loop and we interpret that event as that the motor has finished
stepping.
If you can start the motor and get a notification when it's done, the
notification can be posted as an event into the GUI event loop. In that
case, the GUI can remain responsive at all times, and take various
strategies to deal with the motor. For instance, until it receives the
completion event from the motor API, it can disable the buttons (gray
them out).
Another possibility is to maintain a command queue. The buttons do not
send commands directly to the motor, but put them into a queue
maintained by the GUI. Whenever a command is put into the queue and the
motor is not busy, the oldest command is removed from the queue and
given to the motor. The motor is then marked busy to prevent further
commands from being sent. Whenever an event arrives indicating that the
motor has finished stepping, the GUI's event handler for the motor takes
the next event from the queue and sends it to the motor. If it finds
the queue empty, though, it clears the busy flag.
None of this requires threads. Threads could be there "under the hood":
for instance, the motor API might be using threads internally. Or if a
timer is used, the timer could be based on a thread. Those things are
encapsulated from us; we don't directly interact with their internals.
All of our logic is in a single thread centered around a GUI event loop.
--
TXR Programming Language:
http://nongnu.org/txr
Cygnal: Cygwin Native Application Library:
http://kylheku.com/cygnal