2

I'm writing my master thesis and I stuck with programming serial port device communication.

I'm writing photo-acoustic scanner. Application that will allow to create thermal images.

I'm using and USB device to control steeper motors and an National Instruments device to acquire signal.

My application is controlling two stepper motors (it should control).

I have an USB controller build to control those motors, it is visible in system as a COM device. I can control it with hyper terminal, and with a simple application, so communication isn't the issue.

I have problem with building a two way communication between device and my application.

I'm sending strings to device like so:

serial.Write("CAL\r"); - this calibrates the device. But it can return two responses - 'CAL OK' or 'BUSY' - calibration is OK or device is doing something else right now.

I can listen for DataRecived event on serial port and then do string.equals.

My application must control motors and wait for response.

In a simple scenario:

  1. Start application
  2. Using inputs enters size of sample that will be scanned.
  3. Press contour button - application start to move motors first to top left corner, then top right, bottom right and bottom left. (I can send simple command, but how to send one, wait for response, then send another and after fourth enable buttons on GUI?)
  4. If region is defined correctly click next and scanning starts.
  5. Motors move to point 1,1 (lets call it like that) and signal acquisition starts.
  6. Data collected is processed and then we move to point 1,2
  7. Whole region is complete and user gets message that scanning is complete.

I don't know how to start with that Serial Port communication. How to implement that two-way communication.

I have a simple class (singleton) that open com port, sends commands and has event that is raised on every data received.

Would it be a good solution to create a stack in my class and send all commands on it and then in loop take them and send to device?

But how to handle that in a threat? Do threat sleep and then check if all command are processed, if no then again threat sleep?

I will be grateful for any advice.

I'm editing this to show how I would like my application to look/work

I have a simple application, that has a TabControl (modified version that hides tabs in application, I can see them only in design mode).

First tab has some text and information (mostly statistics). Second allows acquisition.

User click on a button on first tab "Go to Acquisition", that tab shows, but all buttons are disabled on it.

He must click "Open Calibration" dialog. Then in that dialog he calibrates device and enters all the acquisition parameters (in that dialog he has option to do contour- move motor to 4 corners on sample that will be measured). After calibration is done he can close that dialog and all controls are then active on main form. Now he can click "start acquisition" button. After that steeper motors will move to specific position (calculated for every point), data will be acquired for that point, processed, saved to file and displayed as a pixel in imagebox. Then motors will move to another point and the process repeats until the end of sample. Basically I will scan a square sample, moving laser to specific points, collecting data and building thermal image from that, something like building an image pixel by pixel.

I'll try to illustrate my idea with a diagram or with a screenshot.

Misiu
  • 4,738
  • 21
  • 94
  • 198
  • 1
    This is fundamentally an asynchronous programming problem. Not just because of the serial port, the device you are controlling has highly asynchronous behavior. It accepts a command and does its thing, often taking seconds to complete the job. The fundamental sofware model to describe this behavior is a *state machine*. – Hans Passant Jan 28 '12 at 12:29
  • Thanks Hans for Your reply. I am reading about state machine right now. Could You please show/write a sample of how to do state machine with serial port? Do state machine must be implemented in whole application or only in my class that controls my device? – Misiu Jan 28 '12 at 14:51
  • Whole application usually. Just use an integer to keep track of state. 0 = idle, 1 = calibrating, etcetera. You go from 0 to 1 when sending the CAL command. Back to 0 when you receive DONE. You check the state all over the place in your code. You can't allow the user to press the "Calibrate" button unless the state is 0 for example. Additional state might be required, another one that indicates "Calibrated" for example. So you can disallow "Measure" before calibration was done. – Hans Passant Jan 28 '12 at 15:04
  • I've edited my question, because my comment was to long :) – Misiu Jan 28 '12 at 15:46
  • 1
    It's just another state machine whose state is incremented by the "motor in position" response from the controller. – Hans Passant Jan 28 '12 at 15:54
  • But how to implement it in my case? I would really be grateful for advice. Right now I'm building my class that controls the stepper motors. But maybe I should start with those states. Any snippets please? :) – Misiu Jan 28 '12 at 16:04
  • [Juliet's answer](http://stackoverflow.com/a/5924053/583044) in another question is a good place to start to learn about state machines in C#. Since a WinForms app is already very event oriented you can use the events (control clicks, serial port DataRecieved, BeginInvoke from a data processing thread if your processing will take some time) to drive the state machine. You do not actually need to use a thread in this case to handle the state machine. – tinman Jan 28 '12 at 16:12
  • I understand Juliet's answer, but in my case If I have 12 commands and 4 answers that gives me many states and state transitions. And of course 3 or 4 views in my application. BTW. How to handle state machine in winforms? Lets say how to do a simple form with button that will call command on my device, and when it is done it will enable second button. Could You please write ma a sample? – Misiu Jan 28 '12 at 17:18

0 Answers0