Tanoda
SerialController.cs
Go to the documentation of this file.
1
9using System.Threading;
10using UnityEngine;
11
26public class SerialController : MonoBehaviour
27{
28#if !UNITY_WEBGL
29 [Tooltip("Port name with which the SerialPort object will be created.")]
30 public string portName = "COM3";
31
32 [Tooltip("Baud rate that the serial device is using to transmit data.")]
33 public int baudRate = 9600;
34
35 [Tooltip("Reference to an scene object that will receive the events of connection, " +
36 "disconnection and the messages from the serial device.")]
37 public GameObject messageListener;
38
39 [Tooltip("After an error in the serial communication, or an unsuccessful " +
40 "connect, how many milliseconds we should wait.")]
41 public int reconnectionDelay = 1000;
42
43 [Tooltip("Maximum number of unread data messages in the queue. " +
44 "New messages will be discarded.")]
45 public int maxUnreadMessages = 1;
46
47 // Constants used to mark the start and end of a connection. There is no
48 // way you can generate clashing messages from your serial device, as I
49 // compare the references of these strings, no their contents. So if you
50 // send these same strings from the serial device, upon reconstruction they
51 // will have different reference ids.
52 public const string SERIAL_DEVICE_CONNECTED = "__Connected__";
53 public const string SERIAL_DEVICE_DISCONNECTED = "__Disconnected__";
54
55 // Internal reference to the Thread and the object that runs in it.
56 protected Thread thread;
57 protected SerialThreadLines serialThread;
58
59
60 // ------------------------------------------------------------------------
61 // Invoked whenever the SerialController gameobject is activated.
62 // It creates a new thread that tries to connect to the serial device
63 // and start reading from it.
64 // ------------------------------------------------------------------------
65 void OnEnable()
66 {
67 serialThread = new SerialThreadLines(portName,
71 thread = new Thread(serialThread.RunForever);
72 thread.Start();
73 }
74
75 // ------------------------------------------------------------------------
76 // Invoked whenever the SerialController gameobject is deactivated.
77 // It stops and destroys the thread that was reading from the serial device.
78 // ------------------------------------------------------------------------
79 void OnDisable()
80 {
81 // If there is a user-defined tear-down function, execute it before
82 // closing the underlying COM port.
83 if (userDefinedTearDownFunction != null)
84 userDefinedTearDownFunction();
85
86 // The serialThread reference should never be null at this point,
87 // unless an Exception happened in the OnEnable(), in which case I've
88 // no idea what face Unity will make.
89 if (serialThread != null)
90 {
91 serialThread.RequestStop();
92 serialThread = null;
93 }
94
95 // This reference shouldn't be null at this point anyway.
96 if (thread != null)
97 {
98 thread.Join();
99 thread = null;
100 }
101 }
102
103 // ------------------------------------------------------------------------
104 // Polls messages from the queue that the SerialThread object keeps. Once a
105 // message has been polled it is removed from the queue. There are some
106 // special messages that mark the start/end of the communication with the
107 // device.
108 // ------------------------------------------------------------------------
109 void Update()
110 {
111 // If the user prefers to poll the messages instead of receiving them
112 // via SendMessage, then the message listener should be null.
113 if (messageListener == null)
114 return;
115
116 // Read the next message from the queue
117 var message = (string) serialThread.ReadMessage();
118 if (message == null)
119 return;
120
121 // Check if the message is plain data or a connect/disconnect event.
122 if (ReferenceEquals(message, SERIAL_DEVICE_CONNECTED))
123 messageListener.SendMessage("OnConnectionEvent", true);
124 else if (ReferenceEquals(message, SERIAL_DEVICE_DISCONNECTED))
125 messageListener.SendMessage("OnConnectionEvent", false);
126 else
127 messageListener.SendMessage("OnMessageArrived", message);
128 }
129
130 // ------------------------------------------------------------------------
131 // Returns a new unread message from the serial device. You only need to
132 // call this if you don't provide a message listener.
133 // ------------------------------------------------------------------------
134 public string ReadSerialMessage()
135 {
136 // Read the next message from the queue
137 return (string) serialThread.ReadMessage();
138 }
139
140 // ------------------------------------------------------------------------
141 // Puts a message in the outgoing queue. The thread object will send the
142 // message to the serial device when it considers it's appropriate.
143 // ------------------------------------------------------------------------
144 public void SendSerialMessage(string message)
145 {
146 serialThread.SendMessage(message);
147 }
148
149 // ------------------------------------------------------------------------
150 // Executes a user-defined function before Unity closes the COM port, so
151 // the user can send some tear-down message to the hardware reliably.
152 // ------------------------------------------------------------------------
153 public delegate void TearDownFunction();
154
155 private TearDownFunction userDefinedTearDownFunction;
156 public void SetTearDownFunction(TearDownFunction userFunction)
157 {
158 userDefinedTearDownFunction = userFunction;
159 }
160#endif
161}
const string SERIAL_DEVICE_CONNECTED
string ReadSerialMessage()
const string SERIAL_DEVICE_DISCONNECTED
void SendSerialMessage(string message)
GameObject messageListener
void SetTearDownFunction(TearDownFunction userFunction)
delegate void TearDownFunction()
SerialThreadLines serialThread