public void importedCurrentProfile(double[] ampArrayD) { plotDisplay tempChart = new plotDisplay(); if (checkBox3.Checked == true) tempChart.Show(); Hardware basicSetup = new Hardware(); Ke37XX DMM = basicSetup.InitializeDMM(timeStep, channelNumber, nplc); FormattedIO488 pS1 = basicSetup.InitializeAgilent6032(); FormattedIO488 pS2 = basicSetup.InitializeAgilent6760(); int iscanCount = ampArrayD.Length + 100; int ibufferSize = iscanCount; double amps = constantA; double currentProgress; double[] dTdt = new double[ampArrayD.Length + 1]; double[] time = new double[ampArrayD.Length + 1]; double[] temp = new double[ampArrayD.Length + 1]; double[] temp2 = new double[ampArrayD.Length + 1]; double[] timeDiff = new double[ampArrayD.Length + 1]; double[] data = new double[ampArrayD.Length + 1]; double[] readings = new double[ampArrayD.Length + 1]; double[] ampstoWrite = new double[ampArrayD.Length + 1]; string sbufferName = "Mybuffer"; DMM.Display.Clear(); DMM.Display.Text = "Scanning..."; DMM.Scan.ScanCount = 1; DMM.Measurement.Buffer.Create(sbufferName, ibufferSize); DMM.System.DirectIO.IO.Timeout = 10000; DMM.Timer.Reset(); tempChart.InitializePlotDisplay(ListPlot); for (int i = 0; i <= ampArrayD.Length - 1; i++) { pS1.IO.WriteString("ISET " + ampArrayD[i] + "\n"); time[i] = DMM.Timer.Measure(); DMM.Scan.Execute(sbufferName); ampstoWrite[i] = ampArrayD[i]; readings = DMM.Measurement.Buffer.ReadingData.GetAllFormattedReadings(sbufferName); temp[i] = getTemp(readings[0]); //temp2[i] = getTemp(readings[1]); if (i > 5) { int j = i - 2; timeDiff[i] = time[i] - time[i - 1]; dTdt[i] = (8 * (temp[j + 1] - temp[j - 1]) + (temp[j - 2] - temp[j + 2])) / (12 * (timeDiff[i])); } if (relayFlag == false & readRelayArray[i] == 1) { relayFlag = switchRelay(pS2, relayFlag); } if (relayFlag == true & readRelayArray[i] == 0) { relayFlag = switchRelay(pS2, relayFlag); } if (checkBox3.Checked == true) { if (checkBoxTemp.Checked == true) tempChart.plotData(time[i], temp[i], "Temperature"); if (checkBoxDtdt.Checked == true) tempChart.plotData(time[i], temp2[i], "dTdt"); currentProgress = (i * (Math.Pow((double)iscanCount, -1))) * 100;//(double)((i/iscanCount) * 100); currentProgress = (double)Math.Round((decimal)currentProgress, 2); tempChart.updateChart(currentProgress); tempChart.updateValues(time[i], temp[i], temp2[i], amps); } toWriteAmp[i] = ampArrayD[i]; toWriteRelay[i] = readRelayArray[i]; toWriteTemp[i] = temp[i]; toWriteTime[i] = time[i]; toWriteTemp2[i] = temp2[i]; } pS1.IO.WriteString("ISET 0.0\n"); //switchRelay(pS2, relayFlag); // Turns relay back off DMM.Display.Clear(); DMM.Display.Text = "Finished!"; //writeFile(temp, time, dTdt, iscanCount, ampstoWrite); // Writes data to .csv file newWriteFile(); Cleanup(); switchRelay(pS2, relayFlag); }
// ********************************************************************************************** // ****************************** LINEAR COOLING PROFILE **************************************** // ********************************************************************************************** public void LinearCooling(double[] ampArrayD) { // Generates an instance object of the custom-class plotDisplay() called tempChart; plotDisplay tempChart = new plotDisplay(); // This forces the plot window to show immediately if (checkBox3.Checked == true) tempChart.Show(); Stopwatch pscom = new Stopwatch(); // Generates an instance object of the custom-class Hardware, and names is LinearCoolingSetup Hardware LinearCoolingSetup = new Hardware(); // Generates an instance object of type Ke37xx (Keithley .dll), naming it DMM for further commands Ke37XX DMM = LinearCoolingSetup.InitializeDMM(timeStep, channelNumber, nplc); // Instances two FormattedIO488 objects for both power supplies and sets their value equal to two different outputs // These outputs are determined by the initialize routines that are called in the Hardware class FormattedIO488 ps1 = LinearCoolingSetup.InitializeAgilent6032(); FormattedIO488 ps2 = LinearCoolingSetup.InitializeAgilent6760(); // ibufferSize is used to set the reading buffer within the Keithley (dependent upon how many measurements are taken) int ibufferSize = SampleNumber; // Sets the number of measurements taken per scan (per loop iteration) DMM.Scan.ScanCount = 1; // String containing name of buffer (used as a reference when sending commands to Keithley) string sbufferName = "Mybuffer"; // Creates buffer named sbufferName with a size of ibufferSize DMM.Measurement.Buffer.Create(sbufferName, ibufferSize); // Sets IO timeout in ms DMM.System.DirectIO.IO.Timeout = 10000; // Used to hold value of experiment progress to user via PlotDisplay double currentProgress; // Holds readings from Keithley's Buffer double[] readings = new double[SampleNumber + 25000]; // Value of derivative of temperature with respect to time double[] dTdt = new double[SampleNumber + 25000]; // Value of time read from Keithley double[] time = new double[SampleNumber + 25000]; // Value of temperature, passed back from getTemp() Function double[] temp = new double[SampleNumber + 25000]; // Value of temperature for second thermocouple, passed back from getTemp() Function (mostly unused) double[] temp2 = new double[SampleNumber + 25000]; // Holds value of time differential for numerical derivative calculation double[] timeDiff = new double[SampleNumber + 25000]; // double[] data = new double[SampleNumber + 25000]; // Holds value of the error in what the derivative is vs. what it should be for a linear cooling profile double[] dERR = new double[SampleNumber + 25000]; // Holds the value of the current set by the control system double[] ampArrayToWrite = new double[SampleNumber + 25000]; // Holds the value in the error in the derivative (proportional) double[] dTdterr = new double[SampleNumber + 25000]; // Holds the value of the error in the derivative (integral) double[] dTdtint = new double[SampleNumber + 25000]; // Holds the value of the AVERAGE of the past 10 derivative errors to help smooth the numerical derivative error double[] dtdtTEST = new double[SampleNumber + 25000]; // Holds the value of a constant current to be set double aSet; // Holds the value of the reference cooling rate double dTdtref = dtdtCoolRef; // Holds the value of the reference warming rate double aWarmSet; // Initializes the plot display (by setting the plot type) for each plot label [string] in ListPlot tempChart.InitializePlotDisplay(ListPlot); // Resets the internal timer in the DMM for reporting accurate time measurements // Clears the display on the Keithley and sets it to "Scanning..." DMM.Display.Clear(); DMM.Display.Text = "Scanning..."; // Three different counters utilized in measurement loop for derivative calculation int p = 0; int l = 0; int kk = 0; // Initially the relay is set to make the TE module warm the bridge (to eliminate water/ice formation) while (warmFlag == true) { // Reads the time from the DMM if (p == 0) DMM.Timer.Reset(); time[p] = DMM.Timer.Measure(); // Executes the Scan, storing the measurement taken in the buffer named by sbufferName[string] DMM.Scan.Execute(sbufferName); // Gets the readings from the measurement buffer on the DMM and assigns the value(s) to readings [double array] readings = DMM.Measurement.Buffer.ReadingData.GetAllFormattedReadings(sbufferName); // Converts the thermocouple voltage into a temperature, and stores it in temp[p] temp[p] = getTemp(readings[0]); // Placeholder incase two thermocouples are utilized // temp2[p] = getTemp(readings[1]); if (p > 9) { kk = p - 2; // Calculates the time difference used in the numerical derivative calculation timeDiff[p] = time[p] - time[p - 1]; // Calculates the derivative dTdt[p] = (8 * (temp[kk + 1] - temp[kk - 1]) + (temp[kk - 2] - temp[kk + 2])) / (12 * (timeDiff[p])); // Calculates the current error in the derivative dTdterr[p] = dTdtref - dTdt[p]; // Calculates the derivative of the error in the derivative... yeah dERR[p] = (8 * (dTdterr[p + 1] - dTdterr[p - 1]) + (dTdterr[p - 2] - dTdterr[p + 2])) / (12 * (timeDiff[p])); // Integrates the error of the derivative dTdtint[p] = dTdtint[p - 1] + dTdterr[p]; } if (checkBox3.Checked == true) { // First checks to see if the 'temperature' plot box is checked, and if it is, it plots the data calculated prior if (checkBoxTemp.Checked == true) tempChart.plotData(time[p], temp[p], "Temperature"); // First checks to see if the 'dtdt' plot box is checked, and if it is, it plots the data calculated prior if (checkBoxDtdt.Checked == true) tempChart.plotData(time[p], temp2[p], "dTdt"); } // Apply new current -- Might need to change this to subtract an amount of current based on it's current value; // Debug.WriteLine("Iter: " + p.ToString() + " Error in derivative: " + dTdterr[p].ToString() + " Derivative^2 of error: " + dERR[p].ToString() + " Integral Error: " + dTdtint[p].ToString()); //Debug.WriteLine("Iter: " + p.ToString() + " Error in derivative[n]: " + (0.08 * dTdterr[p]).ToString() + " Derivative^2 of error[n]: " + (0.02 * dERR[p]).ToString() + " Integral Error[n]: " + (0.0035 * dTdtint[p]).ToString()); aWarmSet = 1.9 - Math.Abs((0.2 * dTdterr[p] + 0.02 * dERR[p] + 0.004*dTdtint[p])); // Sets safety range for current going to the TE module if (aWarmSet >= 2.5) aWarmSet = 2.5; if (aWarmSet <= 0) aWarmSet = 0; // Increments array size toWriteArraySize++; // Sets the current on ps1 to aWarmSet ps1.IO.WriteString("ISET " + aWarmSet.ToString() + "\n"); // if the temperature has went below -20 (Typically ambient), kick off heating and go to cooling if (temp[p] <= -20) warmFlag = false; // Updates numerical values located on the plot display if (checkBox3.Checked == true) tempChart.updateValues(time[p], temp[p], temp2[p], aWarmSet); // Writes values to their respective global double arrays toWriteTemp[toWriteArraySize] = temp[p]; toWriteTemp2[toWriteArraySize] = temp2[p]; toWriteTime[toWriteArraySize] = time[p]; toWriteAmp[toWriteArraySize] = aWarmSet; toWriteRelay[toWriteArraySize] = 0; // Increments p p++; // If calculated set current is equal to 0 then l is incremented 1. Once l reaches 50 it breaks the warming loop if (aWarmSet == 0) l++; if (l > 45) // If the current has been set to 0 or less than 0 for 50 times then break the while/loop warmFlag = false; } // relayFlag initialized as false (since it WAS in the warming state) relayFlag = false; // relayFlag then passed through switchRelay(and switched to TRUE), which switches to cooling mode relayFlag = switchRelay(ps2, relayFlag); // Linear Cooling loop for (int i = p; i <= SampleNumber - 1 + p; i++) { time[i] = DMM.Timer.Measure(); DMM.Scan.Execute(sbufferName); readings = DMM.Measurement.Buffer.ReadingData.GetAllFormattedReadings(sbufferName); temp[i] = getTemp(readings[0]); //temp2[i] = getTemp(readings[1]); int j = i - 2; timeDiff[i] = time[i] - time[i - 1]; dTdt[i] = (8 * (temp[j + 1] - temp[j - 1]) + (temp[j - 2] - temp[j + 2])) / (12 * (timeDiff[j])); dtdtTEST[i] = (dTdt[i] + dTdt[i - 1] + dTdt[i - 2] + dTdt[i - 3] + dTdt[i - 4] + dTdt[i - 5] + dTdt[i - 6] + dTdt[i - 7] + dTdt[i - 8]) / 9; dTdterr[i] = dTdtref + dtdtTEST[i]; dERR[i] = (8 * (dTdterr[j + 1] - dTdterr[j - 1]) + (dTdterr[j - 2] - dTdterr[j + 2])) / (12 * (timeDiff[i])); dTdtint[i] = dTdtint[i - 1] + dTdterr[i]; // MONITOR THIS // if (time[i] < 50) // { // Checks to see if the integral error has gotten out of hand (accumulates large errors early on), and resets accordingly) // if ((dTdtint[i] * ki) >= 12 | (dTdtint[i] * ki) <= -12) // { // dTdtint[i] = 0; // } // Calcualtes new current based on passed through values of the derivative error, integral error, and the derivative of the error of the derivative aSet = ControlSysCR(dTdterr[i], dTdtint[i], dERR[i]); // Empirical relationship between Current and desired cooling rate [--------------------------------- NEEWWWW ----------------------------------] double i_aSet = dTdtref * (1.4682 / 2); // 1.4682 int h = 0; if (i - p < 45) // 75 is a good value, well--decent { aSet = i_aSet; } else { //aSet = i_aSet + aSet * 1.4 + 0.01 * (i - p); aSet = aSet; //if (h == 0) //{ // dTdtint[i] = 0; // h++; //} } //if (temp[i] < -19) //{ // dTdterr[i] *= 11; //} //int h = 0; //if (temp[i] < -19 && h == 0) //{ // kp *= 1.3; // ki *= 1.25; // kd *= 2.0; // h++; //} //if (i < 200) // dTdterr[i] *= 3; if (aSet >= 5.5) aSet = 5.5; if (aSet <= 0) aSet = 0; toWriteArraySize++; toWriteTemp[toWriteArraySize] = temp[i]; toWriteTime[toWriteArraySize] = time[i]; toWriteAmp[toWriteArraySize] = aSet; toWriteTemp2[toWriteArraySize] = temp2[i]; toWriteRelay[toWriteArraySize] = 1; // This checks to see if the current profile being used is imported or not, if so, it assigns the current based on the iteration # // otherwise it assigns the calculated current if (chkboxImport.Checked == true && i <= ampArrayD.Length) { ps1.IO.WriteString("ISET " + ampArrayD[i].ToString() + "\n"); toWriteAmp[i] = ampArrayD[i]; } else { ps1.IO.WriteString("ISET " + aSet.ToString() + "\n"); } pscom.Start(); if (checkBox3.Checked == true) { if (checkBoxTemp.Checked == true) tempChart.plotData(time[i], temp[i], "Temperature"); if (checkBoxDtdt.Checked == true) tempChart.plotData(time[i], temp2[i], "dTdt"); // Calculates and posts the current progress of the experiment based on the current iteration currentProgress = (i * (Math.Pow((double)SampleNumber - 1, -1))) * 100;//(double)((i/iscanCount) * 100); currentProgress = (double)Math.Round((decimal)currentProgress, 2); // Changes display to indicate whether or not TE module is warming or cooling to the user tempChart.CoolingorWarming(relayFlag); // Updates the calculated progress on the chart display tempChart.updateChart(currentProgress); // Updates numerical values listed on the chart display tempChart.updateValues(time[i], temp[i], dTdt[i], aSet); } } // End of cooling loop // Start of Warming Profile int m = SampleNumber - 1 + p; if (checkBox2.Checked == true) // If Warming Profile is enabled { while (temp[m - 5] < 15) { } } // Sets current to TE module to 0 ps1.IO.WriteString("ISET 2.0\n"); switchRelay(ps2, relayFlag); // Turns relay back off // Clears display on DMM DMM.Display.Clear(); // Sets display on DMM to Finished! DMM.Display.Text = "Finished!"; // Writes write arrays to a .csv file newWriteFile(); // Clears DMM measurement buffer DMM.Measurement.Buffer.Clear(sbufferName); Cleanup(); }
public void BasicMeasurement() { try { plotDisplay tempChart = new plotDisplay(); if (checkBox3.Checked == true) tempChart.Show(); Hardware basicSetup = new Hardware(); Ke37XX DMM = basicSetup.InitializeDMM(timeStep, channelNumber, nplc); FormattedIO488 pS1 = basicSetup.InitializeAgilent6032(); FormattedIO488 pS2 = basicSetup.InitializeAgilent6760(); int numberofChannels = 2; int iscanCount = SampleNumber; int ibufferSize = iscanCount * numberofChannels; List<double> dataList = new List<double>(); double tempValue; double amps = constantA; double currentProgress; double[] dTdt = new double[iscanCount + 1]; double[] time = new double[iscanCount + 1]; double[] temp = new double[iscanCount + 1]; double[] temp2 = new double[iscanCount + 1]; double[] timeDiff = new double[iscanCount + 1]; double[] data = new double[iscanCount + 1]; double[] readings = new double[iscanCount + 1]; double[] ampstoWrite = new double[iscanCount + 1]; double AmbTemp = double.Parse(txtSensorTC.Text); string sbufferName = "Mybuffer"; DMM.Display.Clear(); DMM.Display.Text = "Scanning..."; DMM.Scan.ScanCount = 1; DMM.Measurement.Buffer.Create(sbufferName, ibufferSize); DMM.System.DirectIO.IO.Timeout = 10000; DMM.Timer.Reset(); relayFlag = switchRelay(pS2, relayFlag); tempChart.InitializePlotDisplay(ListPlot); for (int i = 0; i <= iscanCount; i++) { Stopwatch debugTimer = new Stopwatch(); debugTimer.Start(); ampstoWrite[i] = amps; pS1.IO.WriteString("ISET " + constantA.ToString() + "\n"); time[i] = DMM.Timer.Measure(); DMM.Scan.Execute(sbufferName); // readings = DMM.Measurement.Buffer.ReadingData.GetFormattedReadings(sbufferName,1,2); readings = DMM.Measurement.Buffer.ReadingData.GetAllFormattedReadings(sbufferName); //foreach (double reading in readings) //{ // if (checkboxSensorRead.Checked == true) // { // //temp[i] = -1 * (0.9237 - 0.0041 * AmbTemp + 0.00004 * Math.Pow(AmbTemp, 2) - reading) / (0.0305 + 0.000044 * AmbTemp - 1.1 * Math.Pow(10, -6) * Math.Pow(AmbTemp, 2)); // tempValue = -1 * (161.29 * (-reading + 0.16 * 4.5)) / 4.5; // temp[i] = tempValue / (1.0546 - 0.00216 * AmbTemp); // } // else // { // temp[i] = getTemp(reading); // } //} //foreach (double reading in readings) //{ // Debug.WriteLine(reading); // dataList.Add(reading); //} if (checkboxSensorRead.Checked == true) { tempValue = -1 * (161.29 * (-readings[0] + 0.16 * 5.0)) / 5.0; temp[i] = tempValue / (1.0546 - 0.00216 * AmbTemp); } else { temp[i] = getTemp(readings[0]); } //temp[i] = getTemp(readings[0]); // temp2[i] = getTemp(readings[1]); dataList.Clear(); if (i > 5) { int j = i - 2; timeDiff[i] = time[i] - time[i - 1]; dTdt[i] = (8 * (temp[j + 1] - temp[j - 1]) + (temp[j - 2] - temp[j + 2])) / (12 * (timeDiff[i])); } if (checkBox3.Checked == true) { if (checkBoxTemp.Checked == true) tempChart.plotData(time[i], temp[i], "Temperature"); if (checkBoxDtdt.Checked == true) tempChart.plotData(time[i], dTdt[i], "dTdt"); currentProgress = (i * (Math.Pow((double)iscanCount, -1))) * 100;//(double)((i/iscanCount) * 100); currentProgress = (double)Math.Round((decimal)currentProgress, 2); tempChart.updateChart(currentProgress); tempChart.updateValues(time[i], temp[i], temp2[i], amps); } } pS1.IO.WriteString("ISET 1.5\n"); switchRelay(pS2, relayFlag); // Turns relay back off DMM.Display.Clear(); DMM.Display.Text = "Finished!"; writeFile(temp, time, dTdt, iscanCount, ampstoWrite); // Writes data to .csv file Cleanup(); } catch { MessageBox.Show("General Measurement Error, Terminating", "Error!", MessageBoxButtons.OK); } }