Example #1
0
        public static ArduinoDriver.ArduinoDriver InitializeArduinoDriver()
        {
            if (driver == null)
            {
                driver = (ArduinoCOMPort() == null) ? null : new ArduinoDriver.ArduinoDriver(ArduinoModel.Mega2560, ArduinoCOMPort(), true);
            }
            if (driver != null)
            {
                foreach (string Key in ConfigurationManager.AppSettings.AllKeys)
                {
                    string Value = ConfigurationManager.AppSettings.Get(Key);

                    //Use regex to search teh appconfig values for the pin numbers and pin types
                    if (Regex.IsMatch(Value, @"Type=(\D+)InputPin") == true)
                    {
                        DriverFunctions.SetInput(driver, Convert.ToByte(Regex.Match(Value, @"(?<=Pin=)\d+").Value));
                    }
                    if (Regex.IsMatch(Value, @"Type=(\D+)OutputPin") == true)
                    {
                        DriverFunctions.SetOutput(driver, Convert.ToByte(Regex.Match(Value, @"(?<=Pin=)\d+").Value));
                        if (ConfigurationManager.AppSettings.Get("InvertPinPolarity") == "True" && Regex.IsMatch(Value, @"Type=RelayOutputPin") == true)
                        {
                            driver.Send(new DigitalWriteRequest(Convert.ToByte(Regex.Match(Value, @"(?<=Pin=)\d+").Value), DigitalValue.High));
                        }
                    }
                }
            }

            //Send the initialized driver object (or null) back to whatever called this sub
            return(driver);
        }
Example #2
0
 public static BackgroundWorker InitializeFanController2(ArduinoDriver.ArduinoDriver driver, Dispatcher MainDispatcher)
 {
     //Turns fan set 2 on, off, up and down
     //The idea here is to start the fan at half speed, see if and see it has any noticable effect on temperature -- if the temperature drops maintain the speed, if it rises increase the speed, if it drops lower the speed
     FanController2 = new BackgroundWorker();
     FanController2.WorkerSupportsCancellation = true;
     FanController2.DoWork += new DoWorkEventHandler((state, args) =>
     {
         int LastTemp  = Main.CondensorTemp;
         byte FanSpeed = 125;
         do
         {
             if (Main.Run != true || FanController2.CancellationPending == true)
             {
                 break;
             }
             try
             {
                 System.Threading.Thread.Sleep(10000);
                 if (Main.CondensorTemp > LastTemp)
                 {
                     FanSpeed = Convert.ToByte((int)FanSpeed + 5);
                     MainDispatcher.Invoke(new Action(() => { driver.Send(new AnalogWriteRequest(SystemProperties.FanController1, FanSpeed)); }));
                 }
                 else if (Main.CondensorTemp < LastTemp)
                 {
                     FanSpeed = Convert.ToByte((int)FanSpeed - 5);
                     MainDispatcher.Invoke(new Action(() => { driver.Send(new AnalogWriteRequest(SystemProperties.FanController1, FanSpeed)); }));
                 }
             }
             catch { MainDispatcher.Invoke(new Action(() => { driver = Periphrials.InitializeArduinoDriver(); })); }
         } while (true);
     });
     return(FanController2);
 }
Example #3
0
 public static BackgroundWorker InitializeFanController1(ArduinoDriver.ArduinoDriver driver, Dispatcher MainDispatcher)
 {
     //Turns fan set 1 on, off, up and down
     //The target temperature should be just under the distillation plateau temp so it doesnt slow down the distillation process but keeps the column cool enough that only the target substance can come over
     FanController1 = new BackgroundWorker();
     FanController1.WorkerSupportsCancellation = true;
     FanController1.DoWork += new DoWorkEventHandler((state, args) =>
     {
         int TargetTemp = Main.PlateauTemp - 1;
         byte FanSpeed  = 50;
         do
         {
             if (Main.Run != true || FanController1.CancellationPending == true)
             {
                 break;
             }
             try
             {
                 System.Threading.Thread.Sleep(10000);
                 if (Main.RefluxTemp > TargetTemp)
                 {
                     FanSpeed = Convert.ToByte((int)FanSpeed + 5);
                     MainDispatcher.Invoke(new Action(() => { driver.Send(new AnalogWriteRequest(SystemProperties.FanController1, FanSpeed)); }));
                 }
                 else if (Main.RefluxTemp < TargetTemp)
                 {
                     FanSpeed = Convert.ToByte((int)FanSpeed - 5);
                     MainDispatcher.Invoke(new Action(() => { driver.Send(new AnalogWriteRequest(SystemProperties.FanController1, FanSpeed)); }));
                 }
             }
             catch { MainDispatcher.Invoke(new Action(() => { driver = Periphrials.InitializeArduinoDriver(); })); }
         } while (true);
     });
     return(FanController1);
 }
        /// <summary>
        /// Creates a new ArduinoDriver instance. The relevant portname will be autodetected if possible.
        /// </summary>
        /// <param name="arduinoModel"></param>
        /// <param name="autoBootstrap"></param>
        public static async Task <ArduinoDriver> CreateAsync(ArduinoModel arduinoModel, bool autoBootstrap = false)
        {
            logger.Info(
                "Instantiating ArduinoDriver (model {0}) with autoconfiguration of port name...",
                arduinoModel);

            var    possiblePortNames   = SerialPortStream.GetPortNames().Distinct();
            string unambiguousPortName = null;

            try
            {
                unambiguousPortName = possiblePortNames.SingleOrDefault();
            }
            catch (InvalidOperationException)
            {
                // More than one posible hit.
            }
            if (unambiguousPortName == null)
            {
                throw new IOException(
                          "Unable to autoconfigure ArduinoDriver port name, since there is not exactly a single "
                          + "COM port available. Please use the ArduinoDriver with the named port constructor!");
            }

            var arduinoDriver = new ArduinoDriver();
            await arduinoDriver.InitializeAsync(new ArduinoDriverConfiguration
            {
                ArduinoModel  = arduinoModel,
                PortName      = unambiguousPortName,
                AutoBootstrap = autoBootstrap
            });

            return(arduinoDriver);
        }
Example #5
0
 private void SelectPressureSensorColumn(ArduinoDriver.ArduinoDriver arduinoDriver, DigitalValue[] controlValues)
 {
     for (int i = 0; i < controlValues.Length; i++)
     {
         arduinoDriver.Send(new DigitalWriteRequest(controlPins[i], controlValues[i]));
     }
 }
        public void Start()
        {
            // Get model
            ArduinoDriver.ArduinoModel model;
            if (_device == "Mega2560")
            {
                model = ArduinoDriver.ArduinoModel.Mega2560;
            }
            else if (_device == "Micro")
            {
                model = ArduinoDriver.ArduinoModel.Micro;
            }
            else if (_device == "NanoR3")
            {
                model = ArduinoDriver.ArduinoModel.NanoR3;
            }
            else if (_device == "UnoR3")
            {
                model = ArduinoDriver.ArduinoModel.UnoR3;
            }
            else
            {
                throw new Exception("Arduino model unknown");
            }

            // Init driver
            _driver = new ArduinoDriver.ArduinoDriver(model, _port);
            //_driver = new ArduinoDriver.ArduinoDriver(model, false);
        }
 public static void SetOutput(ArduinoDriver.ArduinoDriver driver, byte PinNumber, Dispatcher MainDispatcher)
 {
     MainDispatcher.Invoke(new Action(() => { driver.Send(new PinModeRequest(PinNumber, PinMode.Output)); }));
     if (ConfigurationManager.AppSettings.Get("InvertPinPolarity") == "true")       //The V1.0 relay board is retarded and uses Low == On
     {
         driver.Send(new DigitalWriteRequest(PinNumber, DigitalValue.High));
     }                                                                              //so this is necessary in order to start up with everything off
 }
Example #8
0
        static void Main()
        {
            //Declare the arduino itself -- Note the COM Port and Model Specifications -- If no COM port is specified the program
            //searches for a single available COM Port. If there are multiple devices it must be specified
            var driver = new ArduinoDriver.ArduinoDriver(ArduinoModel.Mega2560, true);
            //var driver = new ArduinoDriver.ArduinoDriver(ArduinoModel.Leonardo, "COM6", true);
            //var driver = new ArduinoDriver.ArduinoDriver(ArduinoModel.NanoR3, "COM5", true);


            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //Declare all your things and assign each one a pin number (LEDS, Sensors, Relays etc)
            //Digital Outputs -- LEDS with positive lead connected to pins 22 and 23
            byte LED1 = 22;
            byte LED2 = 23;

            //Digital Inputs
            byte Switch = 24; //A switch connected from 5v or 3.3v to Pin 24

            //Analog Inputs
            byte TempSensor   = 54; //Temperature sensor
            byte VacuumSensor = 55; // Vacuum sensor (Or any resistance based sensor really)


            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //Setup the Arduino itself by setting the pinmodes
            //Digital outputs
            driver.Send(new PinModeRequest(LED1, PinMode.Output));
            driver.Send(new PinModeRequest(LED2, PinMode.Output));

            //Digial inputs
            driver.Send(new PinModeRequest(Switch, PinMode.Input));

            //Sensor Inputs
            driver.Send(new PinModeRequest(TempSensor, PinMode.Input));
            driver.Send(new PinModeRequest(VacuumSensor, PinMode.Input));


            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //Tell the arduino to read and write
            driver.Send(new DigitalWriteRequest(LED1, DigitalValue.High)); //Turn LED 1 and 2 On
            driver.Send(new DigitalWriteRequest(LED2, DigitalValue.High));

            //Read from the sensors and write the value to a variable
            string Temperature = driver.Send(new AnalogReadRequest(TempSensor)).PinValue.ToString();
            string Pressure    = driver.Send(new AnalogReadRequest(VacuumSensor)).PinValue.ToString();

            //Use a switch connected from 5v to Pin24 to turn off LED2
            while (driver.Send(new DigitalReadRequest(Switch)).PinValue.ToString() == "Low")
            {
                System.Threading.Thread.Sleep(1000);
            }
            driver.Send(new DigitalWriteRequest(LED2, DigitalValue.Low));

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Main());
        }
 public static void RelayOff(ArduinoDriver.ArduinoDriver driver, byte PinNumber)  //This simplifies turning periphrials on when switching from dev to production and shortens the syntax for calling "Off"
 {
     if (ConfigurationManager.AppSettings.Get("InvertPinPolarity") == "True")
     {
         driver.Send(new DigitalWriteRequest(PinNumber, DigitalValue.High));
     }
     else
     {
         driver.Send(new DigitalWriteRequest(PinNumber, DigitalValue.Low));
     }
 }
Example #10
0
 public static Int32 GetTemperature(ArduinoDriver.ArduinoDriver driver, byte PinNumber) //This is used just for simplyifying the syntax to read a temperature and assumes all thermocouples are K-Types, will add settings
 {                                                                                      //to the app config to allow this to be adjusted and incorporate metric imperial calculations as well.
     if (PinNumber > 1)
     {
         return(Convert.ToInt32((((Convert.ToDouble(driver.Send(new AnalogReadRequest(PinNumber)).PinValue.ToString()) * (5.0 / 1023.0)) - 1.25) / 0.005)));
     }
     else
     {
         return(0);
     }
 }
 public ArduinoWorker()
 {
     try
     {
         init();
     }
     catch (Exception ex)
     {
         driver = null;
     }
 }
Example #12
0
        private void InitializeDigitialOutputPins(ArduinoDriver.ArduinoDriver driver)
        {
            for (int i = 0; i < controlPins.Length; i++)
            {
                driver.Send(new PinModeRequest(controlPins[i], PinMode.Output));
            }

            for (int i = 0; i < 6; i++)
            {
                driver.Send(new PinModeRequest(ledPins[i], PinMode.Output));
            }
        }
Example #13
0
 private Stepper()
 {
     try
     {
         _driver = new ArduinoDriver.ArduinoDriver(ArduinoModel.UnoR3, "COM3", true);
     }
     catch (Exception e)
     {
         Logger.Error(e);
         throw;
     }
 }
        /// <summary>
        /// Creates a new ArduinoDriver instance for a specified portName.
        /// </summary>
        /// <param name="arduinoModel"></param>
        /// <param name="portName">The COM portname to create the ArduinoDriver instance for.</param>
        /// <param name="autoBootstrap">Determines if an listener is automatically deployed to the Arduino if required.</param>
        public static async Task <ArduinoDriver> CreateAsync(ArduinoModel arduinoModel, string portName, bool autoBootstrap = false)
        {
            var arduinoDriver = new ArduinoDriver();
            await arduinoDriver.InitializeAsync(new ArduinoDriverConfiguration
            {
                ArduinoModel  = arduinoModel,
                PortName      = portName,
                AutoBootstrap = autoBootstrap
            });

            return(arduinoDriver);
        }
Example #15
0
        public void Start()
        {
            try
            {
                _driver         = new ArduinoDriver.ArduinoDriver(ArduinoModel.UnoR3, "COM3", true);
                IsStepperReady  = true;
                CurrentDistance = MIN_DISTANCE;
            }
            catch (Exception e)
            {
                IsStepperReady = false;
                Logger.Error(e);

                //throw;
            }
            OnStatusChanged(IsStepperReady);
        }
 public void init()
 {
     try
     {
         lock (locker)
         {
             if (driver != null)
             {
                 driver = new ArduinoDriver.ArduinoDriver(ArduinoUploader.Hardware.ArduinoModel.NanoR3, autoBootstrap: true);
                 for (int i = 2; i <= 10; i++)
                 {
                     driver.Send(new ArduinoDriver.SerialProtocol.PinModeRequest((byte)i, ArduinoDriver.SerialProtocol.PinMode.Output));
                 }
                 driver.Send(new ArduinoDriver.SerialProtocol.DigitalWriteRequest((byte)(8), DigitalValue.High));
             }
         }
     }
     catch { }
 }
Example #17
0
        static void Main(string[] args)
        {
            var waef   = "";
            var driver = new ArduinoDriver.ArduinoDriver(ArduinoModel.Mega2560, "COM7", true);

            driver.Send(new PinModeRequest(52, PinMode.Output));
            driver.Send(new PinModeRequest(35, PinMode.Output));
            driver.Send(new PinModeRequest(26, PinMode.Input));
            driver.Send(new PinModeRequest(54, PinMode.Input));
            while (1 == 1)
            {
                driver.Send(new DigitalWriteRequest(52, DigitalValue.High));
                driver.Send(new DigitalWriteRequest(35, DigitalValue.High));
                driver.Send(new DigitalWriteRequest(52, DigitalValue.Low));
                waef = driver.Send(new DigitalReadRequest(26)).PinValue.ToString();
                //Console.WriteLine("Digital Value " + waef);
                Console.WriteLine(driver.Send(new AnalogReadRequest(54)).PinValue);
            }
        }
Example #18
0
        public static BackgroundWorker InitializePressureWorker(ArduinoDriver.ArduinoDriver driver, Dispatcher MainDispatcher)
        {
            PressureWorker = new BackgroundWorker();
            PressureWorker.WorkerSupportsCancellation = true;
            PressureWorker.DoWork += new DoWorkEventHandler((state, args) =>
            {
                //Make sure the pump is off
                MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.VacuumPump); }));
                Main.VacuumPumpOn = false;
                do
                {
                    try
                    {
                        if (Main.Run != true || PressureWorker.CancellationPending == true)
                        {
                            break;
                        }

                        System.Threading.Thread.Sleep(1000);
                        if (Convert.ToDouble(Main.Pressure) > SystemProperties.TargetPressure && Main.VacuumPumpOn == false)
                        {
                            //Turn the vacuum pump on
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOn(driver, SystemProperties.VacuumPump); }));
                            Main.VacuumPumpOn = true;

                            //Refresh the pressure has changed every second -- Note that the pressure is set in the still monitor background worker
                            do
                            {
                                System.Threading.Thread.Sleep(1000);
                            }while (Convert.ToDouble(Main.Pressure) > (SystemProperties.TargetPressure - SystemProperties.TgtPresHysteresisBuffer) && PressureWorker.CancellationPending == false);

                            //Once the pressure has reached its target turn the pump off
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.VacuumPump); }));
                            Main.VacuumPumpOn = false;
                        }
                    }
                    catch { MainDispatcher.Invoke(new Action(() => { driver = Periphrials.InitializeArduinoDriver(); })); }
                } while (true);
            });
            return(PressureWorker);
        }
Example #19
0
        // Make Delays adjustable

        public PressureSensorArduinoControl()
        {
            driver = new ArduinoDriver.ArduinoDriver(AttachedArduino, "COM24", true);
            InitializeDigitialOutputPins(driver);
        }
Example #20
0
 public static BackgroundWorker InitializeStillController(ArduinoDriver.ArduinoDriver driver, Dispatcher MainDispatcher)
 {
     return(StillController);
 }
Example #21
0
 public static Int32 GetAmperage(ArduinoDriver.ArduinoDriver driver, byte PinNumber) //This is used just for simplyifying the syntax, will need to incorporate voltage as well
 {
     return(Convert.ToInt32((((Convert.ToDouble(driver.Send(new AnalogReadRequest(PinNumber)).PinValue.ToString()) * (5.0 / 1023.0)) - 1.25) / 0.005)));
 }
Example #22
0
        private static BackgroundWorker FanController2;  //Turns the fan set for the condensor on, off, up and down depending on target temperature and distillation speed

        //Background worker to monitor all sensor valuess and switch states on the still and keep global variables and the UI updated
        //The idea here is to imtermittently check all variables and write to a local variable in memory to minimize commands sent to the arduino
        //This is also convienent as it minimizes the amount of long of code required to message the arduino in the control loop
        public static BackgroundWorker InitializeSystemMonitor(ArduinoDriver.ArduinoDriver driver, Dispatcher MainDispatcher)
        {
            SystemMonitor = new BackgroundWorker();
            SystemMonitor.WorkerSupportsCancellation = true;
            SystemMonitor.DoWork += new DoWorkEventHandler((state, args) =>

            {
                do
                {
                    if (Main.Run != true || driver == null) //The periphrials class returns null if no arduino is found on any of the com ports
                    {
                        break;
                    }
                    System.Threading.Thread.Sleep(1000);
                    //Check Temperature
                    bool success = false;
                    while (success == false)
                    {
                        try
                        {
                            MainDispatcher.Invoke(new Action(() =>
                            {
                                Main.ColumnTemp      = DriverFunctions.GetTemperature(driver, SystemProperties.SensorColumnTemp).ToString();
                                Main.RefluxTemp      = DriverFunctions.GetTemperature(driver, SystemProperties.SensorCoolantTemp1);
                                Main.CondensorTemp   = DriverFunctions.GetTemperature(driver, SystemProperties.SensorCoolantTemp2);
                                Main.ElementAmperage = DriverFunctions.GetAmperage(driver, SystemProperties.SensorColumnTemp);
                            }));
                            success = true;
                        }
                        catch
                        {
                            MainDispatcher.Invoke(new Action(() => {
                                driver.Dispose();
                                driver = Periphrials.InitializeArduinoDriver();
                            }));
                        }
                    }

                    //Check the low level switch -- a value of low means the lower still switch is open
                    MainDispatcher.Invoke(new Action(() => {
                        if (driver.Send(new DigitalReadRequest(SystemProperties.StillLowSwitch)).PinValue == DigitalValue.Low)
                        {
                            Main.StillEmpty = true;
                        }
                        else
                        {
                            Main.StillEmpty = false;
                        }
                    }));

                    //Check the high level switch -- a value of high means the upper still switch is closed
                    MainDispatcher.Invoke(new Action(() => {
                        if (driver.Send(new DigitalReadRequest(SystemProperties.StillHighSwitch)).PinValue == DigitalValue.High)
                        {
                            Main.StillFull = true;
                        }
                        else
                        {
                            Main.StillFull = false;
                        }
                    }));

                    //Check the recieving vessel low level switch -- a value of high means the upper rv switch is closed
                    MainDispatcher.Invoke(new Action(() => {
                        if (driver.Send(new DigitalReadRequest(SystemProperties.RVEmptySwitch)).PinValue == DigitalValue.High)
                        {
                            Main.RVEmpty = true;
                        }
                        else
                        {
                            Main.RVEmpty = false;
                        }
                    }));

                    //Check the recieving vessel high level switch -- a value of high means the upper rv switch is closed
                    MainDispatcher.Invoke(new Action(() => {
                        if (driver.Send(new DigitalReadRequest(SystemProperties.RVFullSwitch)).PinValue == DigitalValue.Low)
                        {
                            Main.RVFull = true;
                        }
                        else
                        {
                            Main.RVFull = false;
                        }
                    }));

                    //Check the pressure (1024 is the resolution of the ADC on the arduino, 45.1 is the approximate pressure range in PSI that the sensor is capable of reading, the -15 makes sure that STP = 0 PSI/kPa)
                    MainDispatcher.Invoke(new Action(() => { Main.Pressure = Math.Round((((Convert.ToDouble(driver.Send(new AnalogReadRequest(SystemProperties.SensorPressure)).PinValue.ToString()) / 1024) * 45.1) - 16.5) * ((SystemProperties.Units == "Metric") ? 6.895 : 1), 2).ToString(); }));

                    if (Main.Phase == -1)
                    {
                        Main.Phase = 0;
                    }
                } while (true);
            });
            return(SystemMonitor);
        }
Example #23
0
 public static void SetOutput(ArduinoDriver.ArduinoDriver driver, byte PinNumber)
 {
     driver.Send(new PinModeRequest(PinNumber, PinMode.Output));
 }
Example #24
0
 public static void TurnOff(ArduinoDriver.ArduinoDriver driver, byte PinNumber)  //This simplifies turning periphrials on when switching from dev to production and shortens the syntax for calling "Off"
 {
     driver.Send(new DigitalWriteRequest(PinNumber, DigitalValue.Low));
 }
Example #25
0
 private void stop_shooting(ArduinoDriver.ArduinoDriver driver)
 {
     //set relay to low
 }
Example #26
0
 public static void SetInput(ArduinoDriver.ArduinoDriver driver, byte PinNumber) //Used for setting an input synchronously
 {
     driver.Send(new PinModeRequest(PinNumber, PinMode.Input));
 }
Example #27
0
 public static void SetInput(ArduinoDriver.ArduinoDriver driver, byte PinNumber, Dispatcher MainDispatcher) //Used for setting an input asynchronously
 {
     MainDispatcher.Invoke(new Action(() => { driver.Send(new PinModeRequest(PinNumber, PinMode.Input)); }));
 }
Example #28
0
        public void StillLoop()
        {
            //Dispatcher to accept commands from the various background workers
            Dispatcher MainDispatcher = Dispatcher.CurrentDispatcher;

            //Instanciate the periphrial class and start up the arduino
            ArduinoDriver.ArduinoDriver driver = Periphrials.InitializeArduinoDriver();

            if (driver == null)
            {
                lblStatus.Text    = "No controller found";
                btnRescan.Visible = true;
            }
            else
            {
                btnRescan.Visible = false;
                lblStatus.Text    = "Starting";
            }

            //Declare the background workers
            SystemMonitor     = BackGroundWorkers.InitializeSystemMonitor(driver, MainDispatcher);
            PressureRegulator = BackGroundWorkers.InitializePressureWorker(driver, MainDispatcher);
            //StillController;
            FanController1 = BackGroundWorkers.InitializeFanController1(driver, MainDispatcher);
            FanController2 = BackGroundWorkers.InitializeFanController2(driver, MainDispatcher);

            //Datatable for statistics and calculating when to turn the element off
            DataTable StillStats = Statistics.InitializeTable();

            chartRun.DataSource = StillStats;


            StillController = new BackgroundWorker();
            StillController.WorkerSupportsCancellation = true;
            StillController.DoWork += new DoWorkEventHandler((state, args) =>

            {
                do
                {
                    try {
                        DateTime RunStart = DateTime.Now;
                        StillStats.Clear();
                        //Run unless a stop condition is hit
                        if (Run != true || driver == null)
                        {
                            break;
                        }

                        while (Phase == -1)//Wait for initial values to be collected before starting
                        {
                            System.Threading.Thread.Sleep(250);
                        }

                        //Check to see if the still is full, if not fill it. This ensures there is no product wasted if the previous batch was stopped half way
                        if (StillFull == false && Phase < 2)
                        {
                            {
                                //Open the inlet valve and turn the inlet pump on
                                MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOn(driver, SystemProperties.StillFillValve); }));
                                StillValveOpen = true;
                                //Wait 5 seconds for the valve to open
                                System.Threading.Thread.Sleep(3000);
                                MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOn(driver, SystemProperties.StillFluidPump); }));
                                MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Filling Still"; }));
                                StillPumpOn = true;


                                //Check once a second to see if the still is full now -- note that StillFull is updated by the monitor worker
                                while (StillFull == false)
                                {
                                    System.Threading.Thread.Sleep(1000);
                                }
                                //Close the valve and turn off the pump
                                MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.StillFillValve); }));
                                StillValveOpen = false;
                                MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.StillFluidPump); }));
                                MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Filling Complete"; }));

                                StillPumpOn = false;

                                //If this line is reached that means the still has liquid in it and is ready to start distilling
                                Phase = 1;
                            }
                        }

                        //Make sure the first loop was passed and the still didnt magically empty itself
                        if (Phase < 2 && StillFull == true)
                        {
                            //Turn on the element and vacuum pump
                            DriverFunctions.TurnOn(driver, SystemProperties.StillElement);
                            ElementOn = true;
                            PressureRegulator.RunWorkerAsync();
                            MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Heating"; }));



                            //Set up variables for calculating when to turn off the element
                            int CurrentTemp     = Convert.ToInt16(ColumnTemp);
                            int CurrentDelta    = 0;
                            int Counter         = 0;
                            PlateauTemp         = 0;
                            string StartTempRaw = null;
                            while (StartTempRaw == null)
                            {
                                try { StartTempRaw = driver.Send(new AnalogReadRequest(SystemProperties.SensorColumnTemp)).PinValue.ToString(); } catch { }
                            }
                            double StartTemp    = Convert.ToInt64((((Convert.ToDouble(StartTempRaw) * (5.0 / 1023.0)) - 1.25) / 0.005));
                            double Temp1        = 0.0;
                            double Temp2        = 0.0;
                            double AverageDelta = 0.0;
                            double TotalDelta   = 0.0;

                            DataRow row;

                            row                         = StillStats.NewRow();
                            row["Time"]                 = DateTime.Now;
                            row["Temperature"]          = CurrentTemp;
                            row["TemperatureDelta"]     = 0;
                            row["Pressure"]             = Convert.ToDecimal(Pressure);
                            row["Phase"]                = Phase;
                            row["Amperage"]             = ElementAmperage;
                            row["RefluxTemperature"]    = RefluxTemp;
                            row["CondensorTemperature"] = CondensorTemp;
                            StillStats.Rows.Add(row);

                            //Get the last written row for collecting temperature rise statistics
                            DataRow LastRow = StillStats.Rows[0];

                            //Get two rows from two points in time 2.5 minutes apart so an average temperature change can be obtained from the given time span
                            DataRow Delta1;
                            DataRow Delta2;

                            //Start both fan controllers to maintain the temperature of the coolant in Reflux column and the Condensor
                            //Note that these are started here because they are auto-regulating and will shut off by themselves when not necessary
                            //FanController1.RunWorkerAsync();
                            //FanController2.RunWorkerAsync();

                            //Keep the element on and keep collecting data every 10 seconds until the first plateau is reached then go to the next loop
                            //note thate the total delta is there incase it takes longer than 10 minutes to start seeing a temperature rise at the sensor
                            while ((StillEmpty == false && AverageDelta >= 0.02) || TotalDelta < 0.25)
                            {
                                //Change this back to 10 seconds
                                System.Threading.Thread.Sleep(250);
                                //Once the element has been on for 10 minutes start checking for the plateau
                                if (Counter < 60)
                                {
                                    Counter = Counter + 1;
                                }
                                else
                                {
                                    Delta1       = StillStats.Rows[StillStats.Rows.Count - 19];
                                    Delta2       = StillStats.Rows[StillStats.Rows.Count - 1];
                                    Temp1        = Delta1.Field <Int32>("Temperature");
                                    Temp2        = Delta2.Field <Int32>("Temperature");
                                    AverageDelta = Temp2 != 0 ? ((Temp2 - Temp1) / Temp2) : 0;
                                    if (Temp2 > Temp1)
                                    {
                                        TotalDelta = Temp2 != 0 ? ((Temp2 - StartTemp) / Temp2) : 0;
                                    }
                                }

                                CurrentTemp                 = Convert.ToInt32(ColumnTemp);
                                CurrentDelta                = CurrentTemp - LastRow.Field <Int32>("Temperature");
                                row                         = StillStats.NewRow();
                                row["Time"]                 = DateTime.Now;
                                row["Temperature"]          = CurrentTemp;
                                row["TemperatureDelta"]     = CurrentDelta;
                                row["Pressure"]             = Convert.ToDecimal(Pressure);
                                row["Phase"]                = Phase;
                                row["Amperage"]             = ElementAmperage;
                                row["RefluxTemperature"]    = RefluxTemp;
                                row["CondensorTemperature"] = CondensorTemp;
                                StillStats.Rows.Add(row);
                                LastRow = StillStats.Rows[StillStats.Rows.Count - 1];
                                MainDispatcher.Invoke(new Action(() => { chartRun.DataBind(); }));
                            }

                            //Prep variables related to the distillation phase and start the fan controller for the condensor
                            Phase        = 2;
                            AverageDelta = 0;
                            TotalDelta   = 0;
                            PlateauTemp  = LastRow.Field <Int32>("Temperature");
                            MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Distilling"; }));


                            //Once the first plateau is reached allowing for a 4 degree change at the most
                            //or end the batch if the saftey limit switch is triggered also reset the Delta counters so the next step is not skipped
                            while (StillEmpty == false && (Temp2 - PlateauTemp) < 5 && RVFull == false)
                            {
                                Delta1       = StillStats.Rows[StillStats.Rows.Count - 19];
                                Delta2       = StillStats.Rows[StillStats.Rows.Count - 1];
                                Temp1        = Delta1.Field <Int32>("Temperature");
                                Temp2        = Delta2.Field <Int32>("Temperature");
                                AverageDelta = Math.Abs(((Temp2 - Temp1) / Temp2));
                                System.Threading.Thread.Sleep(250); //Change this back to 10 seconds
                                CurrentTemp                 = Convert.ToInt32(ColumnTemp);
                                CurrentDelta                = CurrentTemp - LastRow.Field <Int32>("Temperature");
                                row                         = StillStats.NewRow();
                                row["Time"]                 = DateTime.Now;
                                row["Temperature"]          = CurrentTemp;
                                row["TemperatureDelta"]     = CurrentDelta;
                                row["Pressure"]             = Convert.ToDecimal(Pressure);
                                row["Phase"]                = Phase;
                                row["Amperage"]             = ElementAmperage;
                                row["RefluxTemperature"]    = RefluxTemp;
                                row["CondensorTemperature"] = CondensorTemp;
                                StillStats.Rows.Add(row);
                                LastRow = StillStats.Rows[StillStats.Rows.Count - 1];
                                MainDispatcher.Invoke(new Action(() => { chartRun.DataBind(); }));
                            }

                            //Batch complete!
                            MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Batch Complete, Saving Run Data"; }));
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.StillElement); }));
                            ElementOn = false;
                            Phase     = 3;
                        }
                        //If the run completed without issue then calculate the header info and write the data to a local sqldb
                        //Note that this must be done sequentially as the records must relate to a header record
                        //Once the table is succesfully written set the phase back to 0 and start another run
                        if (Phase == 3)
                        {
                            Statistics.CreateHeader(RunStart, DateTime.Now, true, SystemProperties.Units);
                            Statistics.SaveRun(StillStats, RunStart);

                            //Turn off the vacuum pump and fan controllers synchronously with the main thread
                            PressureRegulator.CancelAsync();
                            //FanController1.CancelAsync();
                            //FanController2.CancelAsync();
                            while (PressureRegulator.CancellationPending == true || FanController1.CancellationPending == true || FanController2.CancellationPending == true)
                            {
                                System.Threading.Thread.Sleep(100);
                            }


                            //Fill the system with air so it is at a neutral pressure before pumping any fluids -- note that the system will pull air from the drain valve
                            //since it eventually vents somewhere that is at atmospheric pressure
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOn(driver, SystemProperties.StillDrainValve); }));
                            MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Draining Still"; }));
                            while (StillEmpty == false || Convert.ToDouble(Pressure) <= -0.2)
                            {
                                System.Threading.Thread.Sleep(1500);
                            }
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.StillDrainValve); }));
                            System.Threading.Thread.Sleep(3000);


                            //Make sure that the switches are working then pump the Recieving vessels contents into a storage tank so the next run can begin
                            MainDispatcher.Invoke(new Action(() => { lblStatus.Text = "Draining Distillate"; }));
                            MainDispatcher.Invoke(new Action(() => { RVEmpty = (driver.Send(new DigitalReadRequest(SystemProperties.RVEmptySwitch)).PinValue == DigitalValue.Low) ? true : false; }));
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOn(driver, SystemProperties.RVDrainValve); }));
                            System.Threading.Thread.Sleep(3000); //3 second delay so the valve has time to open
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOn(driver, SystemProperties.RVFluidPump); }));
                            while (RVEmpty == false)
                            {
                                //MainDispatcher.Invoke(new Action(() => { RVEmpty = (driver.Send(new DigitalReadRequest(SystemProperties.RVEmptySwitch)).PinValue == DigitalValue.Low) ? true : false; }));
                                System.Threading.Thread.Sleep(1500);
                            }
                            //Turn off the pump and shut the valves and give them 3 seconds to close
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.RVFluidPump); }));
                            MainDispatcher.Invoke(new Action(() => { DriverFunctions.RelayOff(driver, SystemProperties.RVDrainValve); }));

                            Phase = 0;
                        }
                    }
                    //The arduino driver reference has a tendency to randomly throw null reference exceptions, for now I will handle it by just restarting the arduino
                    //the code is designed to pick up where it left off if it errors since the phase is still in memory
                    catch (NullReferenceException)
                    {
                        MainDispatcher.Invoke(new Action(() => { driver = Periphrials.InitializeArduinoDriver(); }));
                    }
                } while (true);
            });

            UIUpdater = new BackgroundWorker();
            UIUpdater.WorkerSupportsCancellation = true;
            UIUpdater.DoWork += new DoWorkEventHandler((state, args) =>
            {
                do
                {
                    System.Threading.Thread.Sleep(1000);
                    MainDispatcher.Invoke(new Action(() => { lblPressure.Text = Main.Pressure + ((SystemProperties.Units == "Metric") ? "kPa" : "PSI"); }));
                    MainDispatcher.Invoke(new Action(() => { lblTemp1.Text = Main.ColumnTemp + ((SystemProperties.Units == "Metric") ? "°C" : "°F"); }));
                }while (true);
            });

            //Start the workers and pause for 2 seconds to allow for initial values to be collected
            SystemMonitor.RunWorkerAsync();
            System.Threading.Thread.Sleep(2000);
            StillController.RunWorkerAsync();
            UIUpdater.RunWorkerAsync();
        }
Example #29
0
 private void start_shooting(ArduinoDriver.ArduinoDriver driver)
 {
     //set pin to high
 }