//Author: LabJack
//July 18, 2007
//This example program calls the Feedback function in a continuous loop. 
//It will read the voltages from AIN0-AIN3, set and read the states  
//and directions from FIO0 - FIO3,  and set DAC0 and DAC1.  The first 
//UE9 found is used in this example. 

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using LabJack;

namespace ue9Feedback
{
	public class FeedbackUSBForm : System.Windows.Forms.Form
	{
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.Label errorLabel;
		private System.Windows.Forms.TextBox errorBox;
		private System.Windows.Forms.Label fio3;
		private System.Windows.Forms.Label fio2;
		private System.Windows.Forms.Label fio1;
		private System.Windows.Forms.Label fioDirText;
		private System.Windows.Forms.Label fioStateText;
		private System.Windows.Forms.Label fioText;
		private System.Windows.Forms.Label dac0Text;
		private System.Windows.Forms.CheckBox dir0Check;
		private System.Windows.Forms.Label dac1Text;
		private System.Windows.Forms.CheckBox state3Check;
		private System.Windows.Forms.CheckBox state2Check;
		private System.Windows.Forms.CheckBox state1Check;
		private System.Windows.Forms.CheckBox state0Check;
		private System.Windows.Forms.CheckBox dir1Check;
		private System.Windows.Forms.CheckBox dir3Check;
		private System.Windows.Forms.CheckBox dir2Check;
		private System.Windows.Forms.TextBox dac0Box;
		private System.Windows.Forms.TextBox dac1Box;
		private System.Windows.Forms.Button decDAC0Button;
		private System.Windows.Forms.Button incDAC0Button;
		private System.Windows.Forms.Button incDAC1Button;
		private System.Windows.Forms.Button decDAC1Button;
		private System.Windows.Forms.Label ain3;
		private System.Windows.Forms.Label ain2;
		private System.Windows.Forms.Label ain1;
		private System.Windows.Forms.Label ain0;
		private System.Windows.Forms.Label ainVoltageText;
		private System.Windows.Forms.Label ainText;
		private System.Windows.Forms.Label fio0;
		private System.Windows.Forms.TextBox ain3V;
		private System.Windows.Forms.TextBox ain2V;
		private System.Windows.Forms.TextBox ain1V;
		private System.Windows.Forms.TextBox ain0V;
		private System.Windows.Forms.Panel dacPanel;
		private System.Windows.Forms.Panel ainPanel;
		private System.Windows.Forms.Panel fioPanel;
		private System.Windows.Forms.Timer updateTimer;
		
		private Mutex dac0Mut = new Mutex();
		private Mutex dac1Mut = new Mutex();
		private UE9 ue9Dev;
		private bool openDevice;	//open UE9 device?
		private bool state0Value;
		private bool state1Value;
		private bool state2Value;
		private bool state3Value;
		private double dac0Value = 0;
		private double dac1Value = 0;
		private string errorBoxText;
		private double ain0Value;
		private double ain1Value;
		private double ain2Value;
		private double ain3Value;
		private bool useUpdateTimer; //can use update timer? (false if busy or closing
		private bool exitApp;		 //exit application?

		
		public FeedbackUSBForm()
		{
			InitializeComponent();

			exitApp = false;
			useUpdateTimer = true;
			ue9Dev = new UE9();

			myInit();
		}
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			base.Dispose( disposing );
		}
		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.errorLabel = new System.Windows.Forms.Label();
			this.errorBox = new System.Windows.Forms.TextBox();
			this.fio3 = new System.Windows.Forms.Label();
			this.fio2 = new System.Windows.Forms.Label();
			this.fio1 = new System.Windows.Forms.Label();
			this.fio0 = new System.Windows.Forms.Label();
			this.fioDirText = new System.Windows.Forms.Label();
			this.fioStateText = new System.Windows.Forms.Label();
			this.fioText = new System.Windows.Forms.Label();
			this.ain3 = new System.Windows.Forms.Label();
			this.ain2 = new System.Windows.Forms.Label();
			this.ain1 = new System.Windows.Forms.Label();
			this.ain0 = new System.Windows.Forms.Label();
			this.ain3V = new System.Windows.Forms.TextBox();
			this.ain2V = new System.Windows.Forms.TextBox();
			this.ain1V = new System.Windows.Forms.TextBox();
			this.ain0V = new System.Windows.Forms.TextBox();
			this.ainVoltageText = new System.Windows.Forms.Label();
			this.ainText = new System.Windows.Forms.Label();
			this.dac0Text = new System.Windows.Forms.Label();
			this.dac1Text = new System.Windows.Forms.Label();
			this.dir0Check = new System.Windows.Forms.CheckBox();
			this.dir1Check = new System.Windows.Forms.CheckBox();
			this.dir3Check = new System.Windows.Forms.CheckBox();
			this.dir2Check = new System.Windows.Forms.CheckBox();
			this.state3Check = new System.Windows.Forms.CheckBox();
			this.state2Check = new System.Windows.Forms.CheckBox();
			this.state1Check = new System.Windows.Forms.CheckBox();
			this.state0Check = new System.Windows.Forms.CheckBox();
			this.dac0Box = new System.Windows.Forms.TextBox();
			this.dac1Box = new System.Windows.Forms.TextBox();
			this.decDAC0Button = new System.Windows.Forms.Button();
			this.incDAC0Button = new System.Windows.Forms.Button();
			this.incDAC1Button = new System.Windows.Forms.Button();
			this.decDAC1Button = new System.Windows.Forms.Button();
			this.dacPanel = new System.Windows.Forms.Panel();
			this.ainPanel = new System.Windows.Forms.Panel();
			this.fioPanel = new System.Windows.Forms.Panel();
			this.updateTimer = new System.Windows.Forms.Timer();
			// 
			// errorLabel
			// 
			this.errorLabel.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.errorLabel.Location = new System.Drawing.Point(8, 232);
			this.errorLabel.Size = new System.Drawing.Size(40, 20);
			this.errorLabel.Text = "Error:";
			// 
			// errorBox
			// 
			this.errorBox.BackColor = System.Drawing.Color.Silver;
			this.errorBox.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold);
			this.errorBox.Location = new System.Drawing.Point(56, 232);
			this.errorBox.Size = new System.Drawing.Size(176, 21);
			this.errorBox.Text = "";
			// 
			// fio3
			// 
			this.fio3.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.fio3.Location = new System.Drawing.Point(16, 104);
			this.fio3.Size = new System.Drawing.Size(16, 16);
			this.fio3.Text = "3";
			// 
			// fio2
			// 
			this.fio2.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.fio2.Location = new System.Drawing.Point(16, 80);
			this.fio2.Size = new System.Drawing.Size(16, 16);
			this.fio2.Text = "2";
			// 
			// fio1
			// 
			this.fio1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.fio1.Location = new System.Drawing.Point(16, 56);
			this.fio1.Size = new System.Drawing.Size(16, 16);
			this.fio1.Text = "1";
			// 
			// fio0
			// 
			this.fio0.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.fio0.Location = new System.Drawing.Point(16, 32);
			this.fio0.Size = new System.Drawing.Size(16, 16);
			this.fio0.Text = "0";
			// 
			// fioDirText
			// 
			this.fioDirText.Font = new System.Drawing.Font("Tahoma", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))));
			this.fioDirText.Location = new System.Drawing.Point(32, 8);
			this.fioDirText.Size = new System.Drawing.Size(24, 16);
			this.fioDirText.Text = "Dir";
			this.fioDirText.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// fioStateText
			// 
			this.fioStateText.Font = new System.Drawing.Font("Tahoma", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))));
			this.fioStateText.Location = new System.Drawing.Point(56, 8);
			this.fioStateText.Size = new System.Drawing.Size(40, 16);
			this.fioStateText.Text = "State";
			this.fioStateText.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// fioText
			// 
			this.fioText.Font = new System.Drawing.Font("Tahoma", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))));
			this.fioText.Location = new System.Drawing.Point(8, 8);
			this.fioText.Size = new System.Drawing.Size(28, 16);
			this.fioText.Text = "FIO";
			// 
			// ain3
			// 
			this.ain3.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.ain3.Location = new System.Drawing.Point(16, 104);
			this.ain3.Size = new System.Drawing.Size(16, 16);
			this.ain3.Text = "3";
			// 
			// ain2
			// 
			this.ain2.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.ain2.Location = new System.Drawing.Point(16, 80);
			this.ain2.Size = new System.Drawing.Size(16, 16);
			this.ain2.Text = "2";
			// 
			// ain1
			// 
			this.ain1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.ain1.Location = new System.Drawing.Point(16, 56);
			this.ain1.Size = new System.Drawing.Size(16, 16);
			this.ain1.Text = "1";
			// 
			// ain0
			// 
			this.ain0.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.ain0.Location = new System.Drawing.Point(16, 32);
			this.ain0.Size = new System.Drawing.Size(16, 16);
			this.ain0.Text = "0";
			// 
			// ain3V
			// 
			this.ain3V.Location = new System.Drawing.Point(40, 104);
			this.ain3V.Size = new System.Drawing.Size(64, 22);
			this.ain3V.Text = "";
			// 
			// ain2V
			// 
			this.ain2V.Location = new System.Drawing.Point(40, 80);
			this.ain2V.Size = new System.Drawing.Size(64, 22);
			this.ain2V.Text = "";
			// 
			// ain1V
			// 
			this.ain1V.Location = new System.Drawing.Point(40, 56);
			this.ain1V.Size = new System.Drawing.Size(64, 22);
			this.ain1V.Text = "";
			// 
			// ain0V
			// 
			this.ain0V.Location = new System.Drawing.Point(40, 32);
			this.ain0V.Size = new System.Drawing.Size(64, 22);
			this.ain0V.Text = "";
			// 
			// ainVoltageText
			// 
			this.ainVoltageText.Font = new System.Drawing.Font("Tahoma", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))));
			this.ainVoltageText.Location = new System.Drawing.Point(32, 8);
			this.ainVoltageText.Size = new System.Drawing.Size(78, 16);
			this.ainVoltageText.Text = "Voltage";
			this.ainVoltageText.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// ainText
			// 
			this.ainText.Font = new System.Drawing.Font("Tahoma", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))));
			this.ainText.Location = new System.Drawing.Point(8, 8);
			this.ainText.Size = new System.Drawing.Size(28, 16);
			this.ainText.Text = "AIN";
			this.ainText.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// dac0Text
			// 
			this.dac0Text.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.dac0Text.Location = new System.Drawing.Point(8, 8);
			this.dac0Text.Size = new System.Drawing.Size(72, 16);
			this.dac0Text.Text = "DAC0 (V): ";
			// 
			// dac1Text
			// 
			this.dac1Text.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.dac1Text.Location = new System.Drawing.Point(8, 40);
			this.dac1Text.Size = new System.Drawing.Size(72, 16);
			this.dac1Text.Text = "DAC1 (V): ";
			// 
			// dir0Check
			// 
			this.dir0Check.Location = new System.Drawing.Point(40, 32);
			this.dir0Check.Size = new System.Drawing.Size(16, 20);
			// 
			// dir1Check
			// 
			this.dir1Check.Location = new System.Drawing.Point(40, 56);
			this.dir1Check.Size = new System.Drawing.Size(16, 20);
			// 
			// dir3Check
			// 
			this.dir3Check.Location = new System.Drawing.Point(40, 104);
			this.dir3Check.Size = new System.Drawing.Size(16, 20);
			// 
			// dir2Check
			// 
			this.dir2Check.Location = new System.Drawing.Point(40, 80);
			this.dir2Check.Size = new System.Drawing.Size(16, 20);
			// 
			// state3Check
			// 
			this.state3Check.Location = new System.Drawing.Point(72, 104);
			this.state3Check.Size = new System.Drawing.Size(16, 20);
			// 
			// state2Check
			// 
			this.state2Check.Location = new System.Drawing.Point(72, 80);
			this.state2Check.Size = new System.Drawing.Size(16, 20);
			// 
			// state1Check
			// 
			this.state1Check.Location = new System.Drawing.Point(72, 56);
			this.state1Check.Size = new System.Drawing.Size(16, 20);
			// 
			// state0Check
			// 
			this.state0Check.Location = new System.Drawing.Point(72, 32);
			this.state0Check.Size = new System.Drawing.Size(16, 20);
			// 
			// dac0Box
			// 
			this.dac0Box.AcceptsReturn = true;
			this.dac0Box.Location = new System.Drawing.Point(80, 8);
			this.dac0Box.Size = new System.Drawing.Size(64, 22);
			this.dac0Box.Text = "0.000";
			this.dac0Box.Validating += new System.ComponentModel.CancelEventHandler(this.dac0Box_Validating);
			// 
			// dac1Box
			// 
			this.dac1Box.AcceptsReturn = true;
			this.dac1Box.Location = new System.Drawing.Point(80, 40);
			this.dac1Box.Size = new System.Drawing.Size(64, 22);
			this.dac1Box.Text = "0.000";
			this.dac1Box.Validating += new System.ComponentModel.CancelEventHandler(this.dac1Box_Validating);
			// 
			// decDAC0Button
			// 
			this.decDAC0Button.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold);
			this.decDAC0Button.Location = new System.Drawing.Point(184, 8);
			this.decDAC0Button.Size = new System.Drawing.Size(24, 24);
			this.decDAC0Button.Text = "-";
			this.decDAC0Button.Click += new System.EventHandler(this.decDAC0Button_Click);
			// 
			// incDAC0Button
			// 
			this.incDAC0Button.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold);
			this.incDAC0Button.Location = new System.Drawing.Point(152, 8);
			this.incDAC0Button.Size = new System.Drawing.Size(24, 24);
			this.incDAC0Button.Text = "+";
			this.incDAC0Button.Click += new System.EventHandler(this.incDAC0Button_Click);
			// 
			// incDAC1Button
			// 
			this.incDAC1Button.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold);
			this.incDAC1Button.Location = new System.Drawing.Point(152, 40);
			this.incDAC1Button.Size = new System.Drawing.Size(24, 24);
			this.incDAC1Button.Text = "+";
			this.incDAC1Button.Click += new System.EventHandler(this.incDAC1Button_Click);
			// 
			// decDAC1Button
			// 
			this.decDAC1Button.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold);
			this.decDAC1Button.Location = new System.Drawing.Point(184, 40);
			this.decDAC1Button.Size = new System.Drawing.Size(24, 24);
			this.decDAC1Button.Text = "-";
			this.decDAC1Button.Click += new System.EventHandler(this.decDAC1Button_Click);
			// 
			// dacPanel
			// 
			this.dacPanel.BackColor = System.Drawing.Color.White;
			this.dacPanel.Controls.Add(this.dac0Text);
			this.dacPanel.Controls.Add(this.dac1Text);
			this.dacPanel.Controls.Add(this.decDAC1Button);
			this.dacPanel.Controls.Add(this.incDAC1Button);
			this.dacPanel.Controls.Add(this.incDAC0Button);
			this.dacPanel.Controls.Add(this.decDAC0Button);
			this.dacPanel.Controls.Add(this.dac1Box);
			this.dacPanel.Controls.Add(this.dac0Box);
			this.dacPanel.Location = new System.Drawing.Point(8, 8);
			this.dacPanel.Size = new System.Drawing.Size(224, 72);
			// 
			// ainPanel
			// 
			this.ainPanel.BackColor = System.Drawing.Color.White;
			this.ainPanel.Controls.Add(this.ainText);
			this.ainPanel.Controls.Add(this.ainVoltageText);
			this.ainPanel.Controls.Add(this.ain2);
			this.ainPanel.Controls.Add(this.ain1V);
			this.ainPanel.Controls.Add(this.ain2V);
			this.ainPanel.Controls.Add(this.ain3V);
			this.ainPanel.Controls.Add(this.ain0);
			this.ainPanel.Controls.Add(this.ain1);
			this.ainPanel.Controls.Add(this.ain0V);
			this.ainPanel.Controls.Add(this.ain3);
			this.ainPanel.Location = new System.Drawing.Point(120, 88);
			this.ainPanel.Size = new System.Drawing.Size(112, 136);
			// 
			// fioPanel
			// 
			this.fioPanel.BackColor = System.Drawing.Color.White;
			this.fioPanel.Controls.Add(this.dir2Check);
			this.fioPanel.Controls.Add(this.dir0Check);
			this.fioPanel.Controls.Add(this.fio2);
			this.fioPanel.Controls.Add(this.fio1);
			this.fioPanel.Controls.Add(this.fio0);
			this.fioPanel.Controls.Add(this.dir3Check);
			this.fioPanel.Controls.Add(this.state1Check);
			this.fioPanel.Controls.Add(this.fioText);
			this.fioPanel.Controls.Add(this.fioStateText);
			this.fioPanel.Controls.Add(this.fioDirText);
			this.fioPanel.Controls.Add(this.dir1Check);
			this.fioPanel.Controls.Add(this.state0Check);
			this.fioPanel.Controls.Add(this.fio3);
			this.fioPanel.Controls.Add(this.state2Check);
			this.fioPanel.Controls.Add(this.state3Check);
			this.fioPanel.Location = new System.Drawing.Point(8, 88);
			this.fioPanel.Size = new System.Drawing.Size(104, 136);
			// 
			// updateTimer
			// 
			this.updateTimer.Enabled = true;
			this.updateTimer.Interval = 1000;
			this.updateTimer.Tick += new System.EventHandler(this.updateTimer_Tick);
			// 
			// FeedbackUSBForm
			// 
			this.BackColor = System.Drawing.Color.Silver;
			this.Controls.Add(this.fioPanel);
			this.Controls.Add(this.ainPanel);
			this.Controls.Add(this.dacPanel);
			this.Controls.Add(this.errorLabel);
			this.Controls.Add(this.errorBox);
			this.Menu = this.mainMenu1;
			this.MinimizeBox = false;
			this.Text = "ue9Feedback USB";
			this.Closing += new System.ComponentModel.CancelEventHandler(this.FeedbackUSBForm_Closing);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>

		static void Main() 
		{
			Application.Run(new FeedbackUSBForm());
		}

		private void myInit()
		{
			ain0Value = 99999.999;
			ain1Value = 99999.999;
			ain2Value = 99999.999;
			ain3Value = 99999.999;			
			openDevice = true;			
			this.Invoke(new EventHandler(this.UpdateAINVoltBoxText));
		}

		private void updateTimer_Tick(object sender, System.EventArgs e)
		{
			if(exitApp == false && useUpdateTimer == true)
			{
				Thread updateThread = new Thread(new ThreadStart(update));
				updateThread.Start();
			}
			
			if(exitApp == true )
			{
				if(openDevice == false)
					ue9Dev.closeUSBConnection();
				updateTimer.Enabled = false;
				this.Close();
			}
		}
		
		private void update()
		{
			int err = 0;
			Error errorText = new Error(); 
			useUpdateTimer = false;
			errorBoxText = "";
			this.Invoke(new EventHandler(UpdateErrorBoxText));

			try
			{
				if(openDevice == true)
				{
					if((err = ue9Dev.openUSBConnection(-1)) < 0)
						throw new Exception();

					if((err = ue9Dev.getCalibrationInfo()) < 0)
						throw new Exception();
				}

				if( (err = feedback_example()) < 0)
					throw new Exception();
			}
			catch
			{
				errorBoxText = errorText.getError(err);
				this.Invoke(new EventHandler(UpdateErrorBoxText));
				if(openDevice == false)
					ue9Dev.closeUSBConnection();	
				myInit();
			}
				
			useUpdateTimer = true;
		}
		
		
		private int feedback_example()
		{
			byte []sendBuff = new byte[34];
			byte []recBuff = new byte[64];
			ushort checksumTotal = 0;
			ushort voltageBitsS = 0;
			byte resolution = 17;

			sendBuff[1] = (byte)(0xF8);  //command byte
			sendBuff[2] = (byte)(0x0E);  //number of data words
			sendBuff[3] = (byte)(0x00);  //extended command number
			
			sendBuff[6] = (byte)(0x0f);  //FIOMask - enabling mask for FIO0-4

			//FIODir - setting directions of FIO0-4
			sendBuff[7] = Convert.ToByte(
				Convert.ToByte(dir0Check.Checked) + 
				(Convert.ToByte(dir1Check.Checked) * 2) + 
				(Convert.ToByte(dir2Check.Checked) * 4) + 
				(Convert.ToByte(dir3Check.Checked) * 8));
			
			//FIOState - setting states of FIO0-4
			sendBuff[8] = Convert.ToByte(
				Convert.ToByte(state0Check.Checked) + 
				(Convert.ToByte(state1Check.Checked) * 2) + 
				(Convert.ToByte(state2Check.Checked) * 4) + 
				(Convert.ToByte(state3Check.Checked) * 8));
			
			//Not enabling masks and not setting direction and state values
			//for EIOs, CIOs and MIOs
			for(int i = 9; i <= 15; i++)
				sendBuff[i] = (byte)(0x00);

			//Enabling, updating and setting the voltage for DAC0
			dac0Mut.WaitOne();
			ue9Dev.analogToCalibratedBinaryVoltage(0, dac0Value, ref voltageBitsS);
			sendBuff[16] = (byte)(voltageBitsS & 0xff);          //DAC0 (low bits)
			sendBuff[17] = (byte)((voltageBitsS / 256) + 0xc0);  //DAC0 (high bits)
			dac0Mut.ReleaseMutex();

			//Enabling, updating and setting the voltage for DAC1
			dac1Mut.WaitOne();
			ue9Dev.analogToCalibratedBinaryVoltage(1, dac1Value, ref voltageBitsS);
			sendBuff[18] = (byte)(voltageBitsS & 0xff);          //DAC1 (low bits)
			sendBuff[19] = (byte)((voltageBitsS / 256) + 0xc0);  //DAC1 (high bits)
			dac1Mut.ReleaseMutex();

			sendBuff[20] = (byte)(0x0f);  //AINMask (low bits) - enabling mask of AIN0-4
			sendBuff[21] = (byte)(0x00);  //AINMask (high bits)
			sendBuff[22] = (byte)(0x00);  //AIN14ChannelNumber
			sendBuff[23] = (byte)(0x00);  //AIN15ChannelNumber
			sendBuff[24] = resolution;	  //Resolution : setting to 17 (default)
			sendBuff[25] = (byte)(0x00);  //SettlingTime : 0
			sendBuff[26] = (byte)(0x88);  //AIN1_0_BipGain : setting AIN0-1 as bipolar
			sendBuff[27] = (byte)(0x88);  //AIN3_2_BipGain : setting AIN2-3 as bipolar

			//AIN5_4_BipGain - AIN15_14_BipGain
			for(int i = 28; i < 34; i++)
				sendBuff[i] = (byte)(0x00);

			UE9.extendedChecksum(ref sendBuff, 34);
  
			try
			{
				if(UE9.LJUSB_BulkWrite(ue9Dev.handle, UE9.UE9_PIPE_EP1_OUT, sendBuff, 34) != 34)
					throw new Exception();
			}
			catch(System.Exception)
			{
				return -14;
			}

			try
			{
				if(UE9.LJUSB_BulkRead(ue9Dev.handle, UE9.UE9_PIPE_EP1_IN, recBuff, 64) != 64)
					throw new Exception();
			}
			catch(System.Exception)
			{
				return -15;
			}

			checksumTotal = UE9.extendedChecksum16(recBuff, 64);
			
			if( (byte)((checksumTotal / 256) & 0xff) != recBuff[5])
				return -16;

			if( (byte)(checksumTotal & 0xff) != recBuff[4])
				return -16;

			if( UE9.extendedChecksum8(recBuff) != recBuff[0])
				return -17;

			if(recBuff[1] != (byte)(0xF8) || recBuff[2] != (byte)(0x1D) || recBuff[3] != (byte)(0x00))
				return -10;
		
			state0Value = Convert.ToBoolean( recBuff[7] & (0x01));
			state1Value = Convert.ToBoolean( (recBuff[7] / 2) & (0x01));
			state2Value = Convert.ToBoolean( (recBuff[7] / 4) & (0x01));
			state3Value = Convert.ToBoolean( (recBuff[7] / 8) & (0x01));

			this.Invoke(new EventHandler(this.UpdateStateValues));

			ue9Dev.binaryToCalibratedAnalogVoltage(8, resolution, (ushort)(recBuff[12] + (recBuff[13] * 256)), ref ain0Value);
			ue9Dev.binaryToCalibratedAnalogVoltage(8, resolution, (ushort)(recBuff[14] + (recBuff[15] * 256)), ref ain1Value);
			ue9Dev.binaryToCalibratedAnalogVoltage(8, resolution, (ushort)(recBuff[16] + (recBuff[17] * 256)), ref ain2Value);
			ue9Dev.binaryToCalibratedAnalogVoltage(8, resolution, (ushort)(recBuff[18] + (recBuff[19] * 256)), ref ain3Value);
			
			this.Invoke(new EventHandler(this.UpdateAINVoltBoxText));

			return 0;
		}

		private void incDAC0Button_Click(object sender, System.EventArgs e)
		{			
			try
			{
				if(dac0Value == 5)
				{}
				else if(dac0Value + 0.2 > 5.0)
				{
					dac0Value = 5.0;
					dac0Box.Text = string.Format("{0:f3}", dac0Value);
					dac0Box.Update();
				}
				else
				{
					dac0Value += 0.2;
					dac0Box.Text = string.Format("{0:f3}", dac0Value);
					dac0Box.Update();
				}
			}
			catch
			{}
		}

		private void decDAC0Button_Click(object sender, System.EventArgs e)
		{
			try
			{
				if(dac0Value == 0)
				{}
				else if(dac0Value - 0.2 < 0.0)
				{
					dac0Value = 0.0;
					dac0Box.Text = string.Format("{0:f3}", dac0Value);
					dac0Box.Update();
				}
				else
				{
					dac0Value -= 0.2;
					dac0Box.Text = string.Format("{0:f3}", dac0Value);
					dac0Box.Update();
				}
			}
			catch {}
		}

		private void incDAC1Button_Click(object sender, System.EventArgs e)
		{
			try
			{
				if(dac1Value == 5)
				{}
				else if(dac1Value + 0.2 > 5.0)
				{
					dac1Value = 5.0;
					dac1Box.Text = string.Format("{0:f3}", dac1Value);
					dac1Box.Update();
				}
				else
				{
					dac1Value += 0.2;
					dac1Box.Text = string.Format("{0:f3}", dac1Value);
					dac1Box.Update();
				}
			}
			catch{}
		}

		private void decDAC1Button_Click(object sender, System.EventArgs e)
		{
			try
			{
				if(dac1Value == 0)
				{
					return;
				}
				else if(dac1Value - 0.2 < 0.0)
				{
					dac1Value = 0.0;
					dac1Box.Text = string.Format("{0:f3}", dac1Value);
					dac1Box.Update();
				}
				else
				{
					dac1Value -= 0.2;
					dac1Box.Text = string.Format("{0:f3}", dac1Value);
					dac1Box.Update();
				}
			}
			catch{}
		}

		private void dac0Box_Validating(object sender, System.ComponentModel.CancelEventArgs e)
		{
			double dac0Conv = 0;
			dac0Mut.WaitOne();
			try
			{
				if((dac0Conv = Convert.ToDouble(dac0Box.Text)) != dac0Value)
				{
					if(dac0Conv > 5.0 || dac0Conv < 0.0)
						throw new Exception();

					dac0Value = dac0Conv;
					dac0Box.Text = string.Format("{0:f3}", dac0Value);
				}
			}
			catch
			{
				dac0Box.Text = string.Format("{0:f3}", dac0Value);
			}
			dac0Mut.ReleaseMutex();
		}

		private void dac1Box_Validating(object sender, System.ComponentModel.CancelEventArgs e)
		{
			double dac1Conv = 0;
		
			dac1Mut.WaitOne();
			try
			{
				if((dac1Conv = Convert.ToDouble(dac1Box.Text)) != dac1Value)
				{
					if(dac1Conv > 5.0 || dac1Conv < 0.0)
						throw new Exception();

					dac1Value = dac1Conv;
					dac1Box.Text = string.Format("{0:f3}", dac1Value);
				}
			}
			catch
			{
				dac1Box.Text = string.Format("{0:f3}", dac1Value);
			}
			dac1Mut.ReleaseMutex();		
		}	
	
		private void UpdateErrorBoxText(object sender, System.EventArgs e)
		{
			errorBox.Text = errorBoxText;
			errorBox.Update();
		}

		private void UpdateAINVoltBoxText(object sender, System.EventArgs e)
		{
			ain0V.Text = string.Format("{0:f3}", ain0Value);
			ain1V.Text = string.Format("{0:f3}", ain1Value);
			ain2V.Text = string.Format("{0:f3}", ain2Value);
			ain3V.Text = string.Format("{0:f3}", ain3Value);
		}

		private void UpdateStateValues(object sender, System.EventArgs e)
		{
			state0Check.Checked = state0Value;
			state1Check.Checked = state1Value;
			state2Check.Checked = state2Value;
			state3Check.Checked = state3Value;
		}

		private void FeedbackUSBForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			useUpdateTimer = false;
			exitApp = true;
		}
	}
}
