Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Threading;
- using System.Windows.Forms;
- using System.Globalization;
- using MeasurementComputing.DAQFlex;
- namespace ConsoleApplication1
- {
- class Program
- {
- static DaqDevice device;
- static System.IO.StreamWriter file;
- const int period = 150;
- static void Main()
- {
- string[] deviceNames = DaqDeviceManager.GetDeviceNames(DeviceNameFormat.NameAndSerno);
- int deviceNumber = 0;
- string deviceName = deviceNames[deviceNumber];
- Thread th = new Thread(BackFunc);
- file = new System.IO.StreamWriter("voltage.txt");
- //find the device and clear the console
- device = DaqDeviceManager.CreateDevice(deviceName);
- Console.Clear();
- //analog input section (to log pressure)
- Console.SetCursorPosition(0, 0);
- Console.Write("-----------------------------------------------------------------------------\n");
- device.SendMessage("AI:CHMODE=SE");
- Console.WriteLine("Device Info:");
- Console.WriteLine(device.SendMessage("?AI: VALIDCHANS/CHMODE"));
- device.SendMessage("AI:SCALE=ENABLE");
- device.SendMessage("AI{0}:RANGE=BIP10V");
- //analog output section (use this to set temperature in the future)
- device.SendMessage("AO:SCALE=ENABLE");
- device.SendMessage("AO{0}:VALUE=1.21");
- //digital io section (to control solenoids)
- device.SendMessage("DIO{0}:DIR=OUT");
- device.SendMessage("DIO{1}:DIR=OUT");
- Console.WriteLine("Ports Available: " + device.SendMessage("?DIO"));
- Console.WriteLine("Bits on Port 0: " + device.SendMessage("?DIO{0}"));
- Console.WriteLine("Bits on Port 1: " + device.SendMessage("?DIO{1}"));
- Console.Write("-----------------------------------------------------------------------------\n");
- //start polling the device for data
- th.Start();
- Console.ReadLine();
- //clean up and ensure solenoids are off
- th.Abort();
- Console.Clear();
- file.Close();
- device.SendMessage("DIO{1/0}:VALUE=0");
- device.SendMessage("DIO{1/1}:VALUE=0");
- DaqDeviceManager.ReleaseDevice(device);
- }
- static void BackFunc() {
- int i = 0;
- const double gain = 0.076;
- DaqResponse responsePress, responseTemp;
- double pressVoltF, pressVolt, pressF, press, tempVolt, temp;
- double error = 0, lError = 0, cError = 0, slope = 0;
- double iCorr = 0, pCorr = 0, dCorr = 0, correction = 0;
- int intCorrection = 0;
- TimeSpan currTime;
- bool flag = false;
- //set initial values
- double kP = 6;
- double kI = 0.000;
- double kD = 0;
- double setP = 2;
- //get a value to start with for the low pass filter
- responsePress = device.SendMessage("?AI{0}:VALUE");
- pressVoltF = responsePress.ToValue();
- Thread.Sleep(period);
- t = 0
- last_t = DateTime.Now blah blah blah
- while(true) {
- delta_t = last_t - DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
- t += delta_t
- if t < 2
- setP = t
- else
- setP = 2
- //get pressue transducer voltage & calibrate
- responsePress = device.SendMessage("?AI{0}:VALUE");
- pressVolt = responsePress.ToValue(); //convert to a decimal number
- pressVoltF += (pressVolt-pressVoltF)*gain; //use a low pass filter on pressure voltage
- press = (12.5*pressVolt)-6.25; //calibrate according to P=12.5V-6.25
- pressF = (12.5*pressVoltF)-6.25; //pressure based on filtered pressure voltage
- //get temperature voltage & calibrate
- tempVolt = 0;
- temp = 0;
- //PID
- error = setP - pressF;
- //proporitonal section (distance between curve and 0)
- pCorr = kP * error;
- //integral section (accumulation of error --- area under curve)
- cError += error;
- iCorr = kI * cError;
- //derivative section (rate of change of error --- slope of curve)
- slope = error - lError;
- dCorr = kD * slope;
- lError = error;
- correction = 1000*(pCorr + iCorr + dCorr);
- intCorrection = Convert.ToInt32(Math.Round(correction));
- //decision making for correction
- if(intCorrection >= period) {
- intCorrection = period;
- Console.SetCursorPosition(0, 25);
- Console.Write("Limiting max correction to {0}ms\n", period);
- } else if(intCorrection <= (-1*period)) {
- intCorrection = -1*period;
- Console.SetCursorPosition(0, 25);
- Console.Write("Limiting min correction to -{0}ms\n", period);
- }
- //display temperature and voltage
- Console.SetCursorPosition(0, 8);
- Console.Write("-----------------------\n");
- Console.Write("Sample #: {0}\n", i++);
- Console.Write("Pressure (V): {0:0.00}\n", pressVolt);
- Console.Write("Pressure Filtered (V): {0:0.00}\n", pressVoltF);
- Console.Write("Pressure (psi): {0:0.00}\n", press);
- Console.Write("Pressure Filtered (psi): {0:0.00}\n", pressF);
- Console.Write("Temperature (V): {0:0.0}\n", tempVolt);
- Console.Write("Temperature (\u00b0C): {0:0.0}\n", temp);
- Console.Write("Time (s): {0}\n", currTime.TotalSeconds);
- Console.Write("Solenoid Duration Period (ms): {0}\n", intCorrection);
- Console.Write("Pressure Setpoint (psi): {0}\n", setP);
- Console.Write("-----------------------\n");
- Console.Write("\n\nPress any key to exit.....");
- //log the data
- file.Write(currTime.TotalSeconds+"\t"+press+"\t"+pressF+"\n");
- //command the corrected value
- //if(Math.Abs(error) > 0.5) { //sets deadband and chooses solenoid for correction
- if(Math.Abs(intCorrection) >= 50) { //ensures that no modulation happens below 50ms range
- if(correction >= 0) {
- //solenoid 1;
- Console.SetCursorPosition(0, 26);
- Console.Write("Letting pressure in (Solenoid 1 active)\n");
- device.SendMessage("DIO{1/1}:VALUE=1"); //turn on
- Thread.Sleep(Math.Abs(intCorrection)); //wait the correction amount
- device.SendMessage("DIO{1/1}:VALUE=0"); //turn off
- flag = true;
- } else if (correction <0) {
- //solenoid 2;
- Console.SetCursorPosition(0, 26);
- Console.Write("Letting pressure out (Solenoid 2 active)\n");
- device.SendMessage("DIO{1/0}:VALUE=1"); //turn on
- Thread.Sleep(Math.Abs(intCorrection)); //wait the correction amount
- device.SendMessage("DIO{1/0}:VALUE=0"); //turn off
- flag = true;
- }
- }
- //}
- //ensure the base period remains the same
- if(flag == true) {
- Thread.Sleep(period-Math.Abs(intCorrection));
- flag = false;
- } else {
- Thread.Sleep(period);
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement