diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config
new file mode 100644
index 0000000..936d45d
--- /dev/null
+++ b/.vs/config/applicationhost.config
@@ -0,0 +1,1038 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MonoBrickFirmware/MonoBrickFirmware.csproj b/MonoBrickFirmware/MonoBrickFirmware.csproj
index 298ba77..dff10ad 100644
--- a/MonoBrickFirmware/MonoBrickFirmware.csproj
+++ b/MonoBrickFirmware/MonoBrickFirmware.csproj
@@ -35,6 +35,7 @@
+
@@ -172,11 +173,5 @@
font.profont_7
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/MonoBrickFirmware/Sensors/EV3ColorSensor.cs b/MonoBrickFirmware/Sensors/EV3ColorSensor.cs
index 5e1b515..21bc423 100644
--- a/MonoBrickFirmware/Sensors/EV3ColorSensor.cs
+++ b/MonoBrickFirmware/Sensors/EV3ColorSensor.cs
@@ -5,31 +5,30 @@
namespace MonoBrickFirmware.Sensors
{
public class EV3ColorSensor : UartSensor{
-
- ///
- /// Initializes a new instance of the NXTColorSensor class in color mode
- ///
- public EV3ColorSensor (SensorPort port) : this(port, ColorMode.Color)
- {
-
- }
-
- ///
- /// Initializes a new instance of the NXTColorSensor class.
- ///
- /// Mode.
- public EV3ColorSensor (SensorPort port, ColorMode mode) : base(port)
- {
- base.Initialise(base.uartMode);
- Mode = mode;
-
- }
-
- ///
- /// Gets or sets the color mode.
- ///
- /// The color mode.
- public ColorMode Mode {
+ ///
+ /// Initializes a new instance of the EV3ColorSensor class in color mode
+ ///
+ /// refresh rate for pollThread
+ public EV3ColorSensor(SensorPort port, int pollInterval = 50) : this(port, ColorMode.Color, pollInterval)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the EV3ColorSensor class.
+ ///
+ /// Mode.
+ /// refresh rate for pollThread
+ public EV3ColorSensor(SensorPort port, ColorMode mode, int pollInterval = 50) : base(port, pollInterval)
+ {
+ base.Initialise(base.uartMode);
+ Mode = mode;
+ }
+
+ ///
+ /// Gets or sets the color mode.
+ ///
+ /// The color mode.
+ public ColorMode Mode {
get{return SensorModeToColorMode(base.uartMode);}
set{
base.SetMode(ColorModeToSensorMode(value));
@@ -80,7 +79,7 @@ public int ReadRaw ()
///
/// Read the intensity of the reflected or ambient light in percent. In color mode the color index is returned
///
- public int Read()
+ public override int Read()
{
int value = 0;
switch (Mode)
diff --git a/MonoBrickFirmware/Sensors/EV3GyroSensor.cs b/MonoBrickFirmware/Sensors/EV3GyroSensor.cs
index 83f7f87..b757687 100644
--- a/MonoBrickFirmware/Sensors/EV3GyroSensor.cs
+++ b/MonoBrickFirmware/Sensors/EV3GyroSensor.cs
@@ -25,30 +25,29 @@ public enum GyroMode {
/// Class for the EV3 Gyro sensor
///
public class EV3GyroSensor :UartSensor{
-
- ///
- /// Initializes a new instance of the Gyro sensor.
- ///
- public EV3GyroSensor (SensorPort port) : this(port, GyroMode.Angle)
- {
-
- }
-
- ///
- /// Initializes a new instance of the Gyro sensor.
- ///
- /// Mode.
- public EV3GyroSensor (SensorPort port, GyroMode mode) : base(port)
- {
- base.Initialise(base.uartMode);
- Mode = mode;
- }
-
- ///
- /// Gets or sets the Gyro mode.
- ///
- /// The mode.
- public GyroMode Mode {
+
+ ///
+ /// Initializes a new instance of the Gyro sensor.
+ ///
+ public EV3GyroSensor(SensorPort port, int pollInterval = 50) : this(port, GyroMode.Angle, pollInterval)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the Gyro sensor.
+ ///
+ /// Mode.
+ public EV3GyroSensor(SensorPort port, GyroMode mode, int pollInterval = 50) : base(port, pollInterval)
+ {
+ base.Initialise(base.uartMode);
+ Mode = mode;
+ }
+
+ ///
+ /// Gets or sets the Gyro mode.
+ ///
+ /// The mode.
+ public GyroMode Mode {
get{return (GyroMode) base.uartMode;}
set{SetMode((UARTMode) value);}
}
@@ -106,7 +105,7 @@ public int RotationCount ()
///
/// Read the gyro sensor value. The returned value depends on the mode.
///
- public int Read ()
+ public override int Read ()
{
if (Mode == GyroMode.Angle) {
return BitConverter.ToInt16(ReadBytes(2),0)%360;
diff --git a/MonoBrickFirmware/Sensors/EV3IRSensor.cs b/MonoBrickFirmware/Sensors/EV3IRSensor.cs
index 377a220..06cc5f1 100644
--- a/MonoBrickFirmware/Sensors/EV3IRSensor.cs
+++ b/MonoBrickFirmware/Sensors/EV3IRSensor.cs
@@ -68,26 +68,25 @@ public class BeaconLocation{
///
public class EV3IRSensor : UartSensor{
- ///
- /// Initializes a new instance of the class.
- ///
- /// Port.
- public EV3IRSensor (SensorPort port) : this(port, IRMode.Proximity)
- {
-
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Senosr port.
- /// IR Mode.
- public EV3IRSensor (SensorPort port, IRMode mode) : base(port)
- {
- base.Initialise(base.uartMode);
- Mode = mode;
- Channel = IRChannel.One;
- }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Port.
+ public EV3IRSensor(SensorPort port, int pollInterval = 50) : this(port, IRMode.Proximity, pollInterval)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Senosr port.
+ /// IR Mode.
+ public EV3IRSensor(SensorPort port, IRMode mode, int pollInterval = 50) : base(port, pollInterval)
+ {
+ base.Initialise(base.uartMode);
+ Mode = mode;
+ Channel = IRChannel.One;
+ }
///
/// Gets or sets the IR mode.
@@ -125,7 +124,7 @@ public override string ReadAsString ()
/// Read the sensor value. The returned value depends on the mode. Distance in proximity mode.
/// Remote command number in remote mode. Beacon location in seek mode.
///
- public int Read(){
+ public override int Read(){
int value = 0;
switch ((IRMode)base.uartMode)
{
diff --git a/MonoBrickFirmware/Sensors/EV3UltraSonicSensor.cs b/MonoBrickFirmware/Sensors/EV3UltraSonicSensor.cs
index 420b0b8..46d06dd 100644
--- a/MonoBrickFirmware/Sensors/EV3UltraSonicSensor.cs
+++ b/MonoBrickFirmware/Sensors/EV3UltraSonicSensor.cs
@@ -7,29 +7,28 @@ namespace MonoBrickFirmware.Sensors
/// Class for the EV3 ultrasonic sensor
///
public class EV3UltrasonicSensor : UartSensor{
- ///
- /// Initializes a new instance of the EV3 Ultrasonic Sensor.
- ///
- public EV3UltrasonicSensor (SensorPort port) : this(port, UltraSonicMode.Centimeter)
- {
-
- }
-
- ///
- /// Initializes a new instance of the EV3 Ultrasonic Sensor.
- ///
- /// Mode.
- public EV3UltrasonicSensor (SensorPort port, UltraSonicMode mode) : base(port)
- {
- base.Initialise(base.uartMode);
- Mode = mode;
- }
-
- ///
- /// Gets or sets the Gyro mode.
- ///
- /// The mode.
- public UltraSonicMode Mode {
+ ///
+ /// Initializes a new instance of the EV3 Ultrasonic Sensor.
+ ///
+ public EV3UltrasonicSensor(SensorPort port, int pollInterval = 50) : this(port, UltraSonicMode.Centimeter, pollInterval)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the EV3 Ultrasonic Sensor.
+ ///
+ /// Mode.
+ public EV3UltrasonicSensor(SensorPort port, UltraSonicMode mode, int pollInterval = 50) : base(port, pollInterval)
+ {
+ base.Initialise(base.uartMode);
+ Mode = mode;
+ }
+
+ ///
+ /// Gets or sets the Gyro mode.
+ ///
+ /// The mode.
+ public UltraSonicMode Mode {
get{return (UltraSonicMode) base.uartMode;}
set{SetMode((UARTMode) value);}
}
@@ -59,7 +58,7 @@ public override string ReadAsString ()
///
/// Read the sensor value. Result depends on the mode
///
- public int Read ()
+ public override int Read ()
{
if (Mode == UltraSonicMode.Listen)
{
diff --git a/MonoBrickFirmware/Sensors/SensorFactory.cs b/MonoBrickFirmware/Sensors/SensorFactory.cs
index d2a9f82..b649ee8 100644
--- a/MonoBrickFirmware/Sensors/SensorFactory.cs
+++ b/MonoBrickFirmware/Sensors/SensorFactory.cs
@@ -158,6 +158,11 @@ public override string ReadAsString ()
{
return "";
}
+
+ public override int Read()
+ {
+ return 0;
+ }
///
/// Gets the name of the sensor.
diff --git a/MonoBrickFirmware/Sensors/UARTSensor.cs b/MonoBrickFirmware/Sensors/UARTSensor.cs
index e824d87..dd123b7 100644
--- a/MonoBrickFirmware/Sensors/UARTSensor.cs
+++ b/MonoBrickFirmware/Sensors/UARTSensor.cs
@@ -3,6 +3,8 @@
using System.Collections.Generic;
using MonoBrickFirmware.Native;
using MonoBrickFirmware.Tools;
+using System.Threading;
+using System.ComponentModel;
namespace MonoBrickFirmware.Sensors
{
@@ -51,17 +53,56 @@ public abstract class UartSensor:ISensor
protected const int NumberOfSensorPorts = SensorManager.NumberOfSensorPorts;
protected SensorPort port;
protected UARTMode uartMode{get; private set;}
-
- public UartSensor (SensorPort port)
- {
- this.port = port;
- uartMemory = SensorManager.Instance.UartMemory;
- UartDevice = SensorManager.Instance.UartDevice;
- }
-
- public abstract string ReadAsString ();
-
- public abstract void SelectNextMode();
+
+ private int pollTime = 50;
+ private EventWaitHandle stopPolling = new ManualResetEvent(false);
+ private QueueThread queue = QueueThread.Instance;
+ private Thread pollThread = null;
+ public UartSensor(SensorPort port, int pollTime = 50)
+ {
+ this.port = port;
+ this.pollTime = pollTime;
+ uartMemory = SensorManager.Instance.UartMemory;
+ UartDevice = SensorManager.Instance.UartDevice;
+ pollThread = new Thread(sensorPollThread);
+ pollThread.Start();
+ }
+
+ ///
+ /// Stop polling this instance
+ ///
+ public void Kill()
+ {
+ stopPolling.Set();
+ pollThread.Join();
+ }
+
+
+ ///
+ /// thread that checks the sensor' state, and raises the propertyChanged event in queue when it is changed.
+ ///
+ private void sensorPollThread()
+ {
+ Thread.CurrentThread.IsBackground = true;
+ int lastState = Read();
+ while (!stopPolling.WaitOne(pollTime))
+ {
+ int currenState = Read();
+ if (currenState != lastState)
+ {
+ queue.Enqueue(propertyChangedEvent, this, new PropertyChangedEventArgs(GetSensorName()));
+ lastState = currenState;
+ }
+ }
+ }
+
+ public event PropertyChangedEventHandler propertyChangedEvent;
+
+ public abstract string ReadAsString();
+
+ public abstract int Read();
+
+ public abstract void SelectNextMode();
public abstract string GetSensorName();
diff --git a/MonoBrickFirmware/Tools/EventNode.cs b/MonoBrickFirmware/Tools/EventNode.cs
new file mode 100644
index 0000000..599b2b4
--- /dev/null
+++ b/MonoBrickFirmware/Tools/EventNode.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MonoBrickFirmware.Tools
+{
+ public class EventNode
+ {
+ private Delegate EventToRaise;
+ private Object[] Parameters;
+
+ public EventNode(Delegate Event, Object[] Parameters)
+ {
+ this.EventToRaise = Event;
+ this.Parameters = Parameters;
+ }
+
+ public Delegate eventToRaise {
+ get { return this.EventToRaise; }
+ }
+ public Object[] parameters {
+ get { return this.Parameters; }
+ }
+ }
+}
diff --git a/MonoBrickFirmware/Tools/QueueThread.cs b/MonoBrickFirmware/Tools/QueueThread.cs
index 90f544a..e35e04a 100644
--- a/MonoBrickFirmware/Tools/QueueThread.cs
+++ b/MonoBrickFirmware/Tools/QueueThread.cs
@@ -1,57 +1,83 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using MonoBrickFirmware.Display;
namespace MonoBrickFirmware.Tools
{
- public class QueueThread : IDisposable
- {
- public QueueThread ()
- {
- Thread t = new Thread(ThreadFunc);
- t.IsBackground = true;
- t.Start();
- }
- private Queue queue = new Queue();
- private EventWaitHandle stop = new EventWaitHandle(false, EventResetMode.ManualReset);
- private void ThreadFunc()
- {
- while (!stop.WaitOne(0))
- {
- Action action = null;
- lock (queue)
- {
- if (queue.Count > 0)
- {
- action = queue.Dequeue();
- }
- else
- {
- Monitor.Wait(queue);
- }
- }
- if (action != null)
- action();
- }
- }
-
- public void Enqueue(Action a)
- {
- lock (queue)
- {
- queue.Enqueue(a);
- Monitor.Pulse(queue);
- }
- }
-
- public void Dispose()
- {
- lock (queue)
- {
- stop.Set();
- Monitor.Pulse(queue);
- }
- }
- }
+ public class QueueThread : IDisposable
+ {
+ private QueueThread()
+ {
+ Thread t = new Thread(ThreadFunc);
+ t.IsBackground = true;
+ t.Start();
+ }
+
+ public static QueueThread Instance
+ {
+ get { return Nested.instance; }
+ }
+
+ private class Nested
+ {
+ static Nested() { }
+ internal static readonly QueueThread instance = new QueueThread();
+ }
+
+ private Queue queue = new Queue();
+ private EventWaitHandle stop = new EventWaitHandle(false, EventResetMode.ManualReset);
+ private void ThreadFunc()
+ {
+ while (!stop.WaitOne(0))
+ {
+ EventNode nodeToRaise = null;
+ lock (queue)
+ {
+ if (queue.Count > 0)
+ {
+ nodeToRaise = queue.Dequeue();
+ }
+ else
+ {
+ Monitor.Wait(queue);
+ }
+ }
+ if ((nodeToRaise != null) && (nodeToRaise.eventToRaise != null))
+ {
+ Delegate eventToRaise = nodeToRaise.eventToRaise;
+ object[] parameters = nodeToRaise.parameters;
+
+ try
+ {
+ eventToRaise.DynamicInvoke(parameters);
+ }
+ catch (Exception ex)
+ {
+ LcdConsole.WriteLine(ex.ToString());
+ }
+ }
+ }
+ }
+
+ public void Enqueue(Delegate eventToEnqueue, params Object[] paramaters)
+ {
+ lock (queue)
+ {
+ EventNode node = new EventNode(eventToEnqueue, paramaters);
+ queue.Enqueue(node);
+ Monitor.Pulse(queue);
+ }
+ }
+
+ public void Dispose()
+ {
+ lock (queue)
+ {
+ stop.Set();
+ Monitor.Pulse(queue);
+ }
+ }
+ }
}
diff --git a/MonoBrickFirmware/UserInput/ButtonEvents.cs b/MonoBrickFirmware/UserInput/ButtonEvents.cs
index ebed80a..7936183 100644
--- a/MonoBrickFirmware/UserInput/ButtonEvents.cs
+++ b/MonoBrickFirmware/UserInput/ButtonEvents.cs
@@ -9,7 +9,7 @@ public class ButtonEvents : IDisposable
{
EventWaitHandle stopPolling = new ManualResetEvent (false);
private int pollTime = 50;
- QueueThread queue = new QueueThread ();
+ QueueThread queue = QueueThread.Instance;
Thread pollThread = null;
public ButtonEvents (int pollInterval = 50)