Simply3DScan
ArduinoCommands.cs
Go to the documentation of this file.
1 using System;
2 using System.IO.Ports;
3 using System.Threading;
4 using System.Threading.Tasks;
5 using Logging;
6 using SharedObjects;
7 
9 {
13  public class ArduinoCommands
14  {
15 
16  private readonly int baudRate;
17  private SerialPort currentPort;
18 
25  public bool PortFound { get; private set; }
26 
33  public string PortString { get; private set; }
34 
40  [Log]
41  [LogException]
42  public ArduinoCommands(int baudRate, string portString = "")
43  {
44  Singleton<Logger>.Instance.LogInfo(String.Format("Starting arduino connection with baudrate:{0}", baudRate));
45 
46  this.baudRate = baudRate;
47  if (String.IsNullOrEmpty(portString))
48  this.FindComPort();
49  else
50  {
51  this.PortString = portString;
52  this.currentPort = new SerialPort(this.PortString, baudRate) {ReadTimeout = 2000};
53  }
54 
55  if (null != this.currentPort)
56  this.currentPort.ErrorReceived += this.CurrentPortOnErrorReceived;
57 
58  }
59 
60  [Log]
61  [LogException]
62  private void CurrentPortOnErrorReceived(object sender, SerialErrorReceivedEventArgs serialErrorReceivedEventArgs)
63  {
64  if (null != this.currentPort)
65  {
66  this.currentPort.ErrorReceived -= this.CurrentPortOnErrorReceived;
67  this.currentPort.Dispose();
68  this.currentPort = null;
69  }
70 
71  this.currentPort = new SerialPort(this.PortString, this.baudRate) { ReadTimeout = 2000 };
72 
73  if (null != this.currentPort)
74  this.currentPort.ErrorReceived += this.CurrentPortOnErrorReceived;
75  }
76 
82  [Log]
83  public string FindComPort()
84  {
85  try
86  {
87  string[] ports = SerialPort.GetPortNames();
88  foreach (string port in ports)
89  {
90  string testPort = port;
91  Task<string> detectPort = Task<string>.Factory.StartNew(() =>
92  {
93  Singleton<Logger>.Instance.LogInfo(String.Format("Testing COM port:{0}", testPort));
94  SerialPort serialPort = new SerialPort(testPort, this.baudRate) {ReadTimeout = 2000};
95  return this.DetectArduino(serialPort) ? testPort : String.Empty;
96  });
97 
98  if (detectPort.Wait(5000))
99  {
100 
101  string detectedPort = detectPort.Result;
102 
103  if (String.IsNullOrEmpty(detectedPort))
104  this.PortFound = false;
105  else
106  {
107  Singleton<Logger>.Instance.LogInfo(String.Format("Using Arduino on COM port:{0}",
108  detectedPort));
109  this.PortString = detectedPort;
110  this.PortFound = true;
111  this.currentPort = new SerialPort(testPort, this.baudRate) {ReadTimeout = 2000};
112  return this.PortString;
113  }
114  }
115  else
116  {
117  this.PortFound = false;
118  }
119  }
120  }
121  catch (Exception ex)
122  {
123  Singleton<Logger>.Instance.LogException(ex);
124  }
125  return string.Empty;
126  }
127 
132  [Log]
133  public void ActivateLaser(bool on = true)
134  {
135  this.SendCommand(@on
138  }
139 
145  [Log]
146  public void ActivateLight(bool on, int hue)
147  {
148  if (on)
149  this.SendCommand(CommandRepresentations.EnableLightCommand, hue);
150  else
152  }
153 
158  [Log]
159  public void RotateTurnTableCw(int steps)
160  {
161  this.SendCommand(CommandRepresentations.RotateTurnTableCwCommand, steps);
162  }
163 
168  [Log]
169  public void RotateTurnTableCcw(int steps)
170  {
171  this.SendCommand(CommandRepresentations.RotateTurnTableCcwCommand, steps);
172  }
173 
178  [Log]
179  public void RotateLaserCw(int steps)
180  {
181  this.SendCommand(CommandRepresentations.RotateLaserCwCommand, steps);
182  }
183 
188  [Log]
189  public void RotateLaserCcw(int steps)
190  {
191  this.SendCommand(CommandRepresentations.RotateLaserCcwCommand, steps);
192  }
193 
197  [Log]
198  public void EnableMicroStepping()
199  {
201  }
202 
206  [Log]
207  public void DisableMicroStepping()
208  {
210  }
211 
220  [Log]
221  [LogException]
222  private bool DetectArduino(SerialPort serialPort)
223  {
224  try
225  {
226  //The below setting are for the Hello handshake
227  byte[] buffer = new byte[1];
228  buffer[0] = Convert.ToByte(CommandRepresentations.Ping);
229 
230  Singleton<Logger>.Instance.LogInfo(String.Format("Try open port {0}", serialPort));
231  serialPort.Open();
232 
233  Singleton<Logger>.Instance.LogInfo(String.Format("Ask for reply on port {0}", serialPort));
234  serialPort.Write(buffer, 0, 1);
235  try
236  {
237  Singleton<Logger>.Instance.LogInfo(String.Format("Wait for result on port {0}", serialPort));
238  int intReturnAscii = serialPort.ReadByte();
239  Singleton<Logger>.Instance.LogInfo(String.Format("Detected on port {0}", serialPort));
240  return intReturnAscii == CommandRepresentations.ACK;
241  }
242  catch (TimeoutException)
243  {
244  Singleton<Logger>.Instance.LogInfo(String.Format("Not detected on port {0}", serialPort));
245  return false;
246  }
247  }
248  catch (Exception ex)
249  {
250  Singleton<Logger>.Instance.LogInfo(String.Format("Not detected on port {0}", serialPort));
251  Singleton<Logger>.Instance.LogException(ex);
252  }
253  finally
254  {
255  Singleton<Logger>.Instance.LogInfo(String.Format("Close port {0}", serialPort));
256  if(serialPort.IsOpen)
257  serialPort.Close();
258  }
259 
260  return false;
261  }
262 
273  [LogException]
274  private bool SendCommand(int command, int parameter = -1, int retry = 5)
275  {
276  try
277  {
278  byte[] buffer = parameter == -1 ? new byte[1] : new byte[2];
279 
280  buffer[0] = Convert.ToByte(command);
281  if (parameter != -1)
282  buffer[1] = Convert.ToByte(parameter);
283  this.currentPort.Open();
284  this.currentPort.Write(buffer, 0, parameter == -1 ? 1 : 2);
285 
286  return this.currentPort.ReadByte() == CommandRepresentations.ACK;
287  }
288  catch (TimeoutException)
289  {
290  Singleton<Logger>.Instance.LogWarning(String.Format("Command took longer then expected: {0}", command));
291  return false;
292  }
293  catch (UnauthorizedAccessException uax)
294  {
295  // happens if port is not ready.
296  if (retry <= 0)
297  {
298  Singleton<Logger>.Instance.LogException(uax);
299  return false;
300  }
301 
302  Thread.Sleep(20);
303  return this.SendCommand(command, parameter, retry - 1);
304 
305  }
306  catch (Exception ex)
307  {
308  Singleton<Logger>.Instance.LogException(ex);
309  return false;
310  }
311  finally
312  {
313  if (this.currentPort.IsOpen)
314  this.currentPort.Close();
315  }
316  }
317  }
318 }
const int RotateTurnTableCcwCommand
The rotate turn table counter clockwise command
void ActivateLight(bool on, int hue)
Activates the light.
const int DisableLightCommand
The disable light command
Class for detecting an arduino and sending commands to it
void RotateLaserCw(int steps)
Rotates the laser clockwise.
const int RotateLaserCwCommand
The rotate laser clockwise command
const int DisableMicroSteppingCommand
The disable micro stepping command
void DisableMicroStepping()
Disables the micro stepping.
const int RotateTurnTableCwCommand
The rotate turn table clockwise command
Class for creating a singleton for a generic class
Definition: Singleton.cs:9
const int EnableMicroSteppingCommand
The enable micro stepping command
void EnableMicroStepping()
Enables the micro stepping.
const int RotateLaserCcwCommand
The rotate laser counterclockwise command
Representations of commands and states to control arduino sketch
const int DisableLaserCommand
The disable laser command
Definition: Logger.cs:5
const int EnableLaserCommand
The enable laser command
void RotateTurnTableCcw(int steps)
Rotates the turn table counter clockwise.
void RotateTurnTableCw(int steps)
Rotates the turn table clockwise.
string PortString
Gets the port string.
static T Instance
Gets the instance.
Definition: Singleton.cs:27
void ActivateLaser(bool on=true)
Activates the laser.
ArduinoCommands(int baudRate, string portString="")
Initializes a new instance of the ArduinoCommands class.
void RotateLaserCcw(int steps)
Rotates the laser counter clockwise.
const int EnableLightCommand
The enable light command
string FindComPort()
Finds the COM port used by arduino
bool PortFound
Gets a value indicating whether [port found].