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); }
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); }
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); }
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 }
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)); } }
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; } }
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)); } }
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); }
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 { } }
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); } }
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); }
// Make Delays adjustable public PressureSensorArduinoControl() { driver = new ArduinoDriver.ArduinoDriver(AttachedArduino, "COM24", true); InitializeDigitialOutputPins(driver); }
public static BackgroundWorker InitializeStillController(ArduinoDriver.ArduinoDriver driver, Dispatcher MainDispatcher) { return(StillController); }
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))); }
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); }
public static void SetOutput(ArduinoDriver.ArduinoDriver driver, byte PinNumber) { driver.Send(new PinModeRequest(PinNumber, PinMode.Output)); }
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)); }
private void stop_shooting(ArduinoDriver.ArduinoDriver driver) { //set relay to low }
public static void SetInput(ArduinoDriver.ArduinoDriver driver, byte PinNumber) //Used for setting an input synchronously { driver.Send(new PinModeRequest(PinNumber, PinMode.Input)); }
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)); })); }
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(); }
private void start_shooting(ArduinoDriver.ArduinoDriver driver) { //set pin to high }