//Author: LabJack
//July 18, 2007
//This example program makes 3 SingleIO calls.  One call sets DAC0 to
//2.500 V.  One call reads voltage from AIN0.  One call reads the 
//temperature from the internal temperature sensor.  Need control 
//firmware version 1.03 and above for the SingleIO function to work.

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

namespace u9SingleIO
{
	public class SingleIOUSBForm : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Label errorLabel;
		private System.Windows.Forms.TextBox errorBox;
		private System.Windows.Forms.Label singleIOVoltText;
		private System.Windows.Forms.Button singleIOButton;
		private System.Windows.Forms.TextBox AI0Box;
		private UE9 ue9Dev;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.Label idLabel;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label tempTest;
		private System.Windows.Forms.TextBox tempBox;
		private System.Windows.Forms.NumericUpDown idBox;
	
		public SingleIOUSBForm()
		{
			InitializeComponent();
		}
		/// <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.idLabel = new System.Windows.Forms.Label();
			this.errorLabel = new System.Windows.Forms.Label();
			this.errorBox = new System.Windows.Forms.TextBox();
			this.singleIOVoltText = new System.Windows.Forms.Label();
			this.singleIOButton = new System.Windows.Forms.Button();
			this.AI0Box = new System.Windows.Forms.TextBox();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.idBox = new System.Windows.Forms.NumericUpDown();
			this.label1 = new System.Windows.Forms.Label();
			this.tempTest = new System.Windows.Forms.Label();
			this.tempBox = new System.Windows.Forms.TextBox();
			// 
			// idLabel
			// 
			this.idLabel.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.idLabel.Location = new System.Drawing.Point(8, 200);
			this.idLabel.Size = new System.Drawing.Size(96, 16);
			this.idLabel.Text = "UE9 Local ID :";
			this.idLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// errorLabel
			// 
			this.errorLabel.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.errorLabel.Location = new System.Drawing.Point(0, 232);
			this.errorLabel.Size = new System.Drawing.Size(48, 20);
			this.errorLabel.Text = "Error :";
			this.errorLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// errorBox
			// 
			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.ReadOnly = true;
			this.errorBox.Size = new System.Drawing.Size(176, 21);
			this.errorBox.Text = "";
			// 
			// singleIOVoltText
			// 
			this.singleIOVoltText.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.singleIOVoltText.Location = new System.Drawing.Point(48, 40);
			this.singleIOVoltText.Size = new System.Drawing.Size(56, 20);
			this.singleIOVoltText.Text = "AIN0 :";
			this.singleIOVoltText.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// singleIOButton
			// 
			this.singleIOButton.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.singleIOButton.Location = new System.Drawing.Point(88, 160);
			this.singleIOButton.Size = new System.Drawing.Size(72, 24);
			this.singleIOButton.Text = "Run";
			this.singleIOButton.Click += new System.EventHandler(this.singleIOButton_Click);
			// 
			// AI0Box
			// 
			this.AI0Box.Location = new System.Drawing.Point(112, 40);
			this.AI0Box.ReadOnly = true;
			this.AI0Box.Text = "";
			// 
			// idBox
			// 
			this.idBox.Location = new System.Drawing.Point(112, 200);
			this.idBox.Maximum = new System.Decimal(new int[] {
																  255,
																  0,
																  0,
																  0});
			this.idBox.Minimum = new System.Decimal(new int[] {
																  1,
																  0,
																  0,
																  -2147483648});
			this.idBox.Size = new System.Drawing.Size(56, 20);
			this.idBox.Value = new System.Decimal(new int[] {
																1,
																0,
																0,
																-2147483648});
			// 
			// label1
			// 
			this.label1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.label1.Location = new System.Drawing.Point(32, 128);
			this.label1.Size = new System.Drawing.Size(176, 24);
			this.label1.Text = "DAC0 will be set to 2.5 V.";
			// 
			// tempTest
			// 
			this.tempTest.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
			this.tempTest.ForeColor = System.Drawing.SystemColors.ControlText;
			this.tempTest.Location = new System.Drawing.Point(8, 72);
			this.tempTest.Size = new System.Drawing.Size(96, 20);
			this.tempTest.Text = "Temperature :";
			this.tempTest.TextAlign = System.Drawing.ContentAlignment.TopRight;
			// 
			// tempBox
			// 
			this.tempBox.Location = new System.Drawing.Point(112, 72);
			this.tempBox.ReadOnly = true;
			this.tempBox.Text = "";
			// 
			// SingleIOUSBForm
			// 
			this.Controls.Add(this.tempTest);
			this.Controls.Add(this.tempBox);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.idBox);
			this.Controls.Add(this.singleIOVoltText);
			this.Controls.Add(this.singleIOButton);
			this.Controls.Add(this.AI0Box);
			this.Controls.Add(this.idLabel);
			this.Controls.Add(this.errorLabel);
			this.Controls.Add(this.errorBox);
			this.Menu = this.mainMenu1;
			this.MinimizeBox = false;
			this.Text = "ue9SingleIO USB";

		}
		#endregion

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

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

		private void singleIOButton_Click(object sender, System.EventArgs e)
		{
			int err = 0;
			Error errorText = new Error(); 
			ue9Dev = new UE9();
			errorBox.Text = "";
			AI0Box.Text = "";

			if( (err = ue9Dev.openUSBConnection(Convert.ToInt32(idBox.Value))) < 0)
			{
				errorBox.Text = errorText.getError(err);
				return;
			}

			if( (err = ue9Dev.getCalibrationInfo()) < 0)
			{
				errorBox.Text = errorText.getError(err);
				ue9Dev.closeUSBConnection();				
				return;
			}

			if( (err = singleIO_AV_example()) < 0)
			{
				errorBox.Text = errorText.getError(err);
				ue9Dev.closeUSBConnection();				
				return;
			}

			if( (err = ue9Dev.closeUSBConnection()) < 0)
			{
				errorBox.Text = errorText.getError(err);
			}
		}

		private int singleIO_AV_example()
		{
			byte []buff = new byte[8];
			double voltage = 0;
			double temperature = 0; //in Kelvins 
			ushort bytesVoltage = 0;
			ushort bytesTemperature = 0;
			int err = 0;


			//////////////////////////////////// 
			//set voltage of DAC0 to 2.500 V
			////////////////////////////////////
			//if(ue9Dev.analogToUncalibratedBinaryVoltage(2.500, ref bytesVoltage) < 0)  
			if( (err = ue9Dev.analogToCalibratedBinaryVoltage(0, 2.500, ref bytesVoltage)) < 0 ) 
				return err;

			buff[1] = (byte)(0xA3);  //command byte
			buff[2] = (byte)(0x05);  //IOType = 5 (analog out)
			buff[3] = (byte)(0x00);  //Channel = 0 (DAC0)
			buff[4] = (byte)( bytesVoltage & (0x00FF) );  //low bits of voltage
			buff[5] = (byte)(( bytesVoltage / 256 ) + 192);  //high bits of voltage 
							   						          //(bit 7 : Enable, bit 6: Update)
			buff[6] = (byte)(0x00);  //Settling time - does not apply to analog output
			buff[7] = (byte)(0x00);  //Reserved
			buff[0] = UE9.normalChecksum8(buff, 8);

			try
			{
				if(UE9.LJUSB_BulkWrite(ue9Dev.handle, UE9.UE9_PIPE_EP1_OUT, buff, 8) != 8)
					throw new Exception();
			}
			catch(System.Exception e)
			{
				errorBox.Text = e.ToString();
				return -14;
			}
  
			try
			{
				if(UE9.LJUSB_BulkRead(ue9Dev.handle, UE9.UE9_PIPE_EP1_IN, buff, 8) != 8)
					throw new Exception();
			}
			catch(System.Exception)
			{
				return -15;
			}

			if((byte)(UE9.normalChecksum8(buff, 8)) != buff[0])
				return -12;
			
			if(buff[1] != (byte)(0xA3))
				return -10;

			if(buff[2] != (byte)(0x05))
				return -13;


			///////////////////////////
			//read voltage from AIN0
			///////////////////////////
			buff[1] = (byte)(0xA3);  //command byte
			buff[2] = (byte)(0x04);  //IOType = 4 (analog in)
			buff[3] = (byte)(0x00);  //Channel = 0 (AIN0)
			buff[4] = (byte)(0x00);  //BipGain (Bip = unipolar, Gain = 1)
			buff[5] = (byte)(0x0C);  //Resolution = 12
			buff[6] = (byte)(0x00);  //SettlingTime = 0
			buff[7] = (byte)(0x00);  //Reserved
			buff[0] = UE9.normalChecksum8(buff, 8);

			try
			{
				if(UE9.LJUSB_BulkWrite(ue9Dev.handle, UE9.UE9_PIPE_EP1_OUT, buff, 8) != 8)
					throw new Exception();
			}
			catch(System.Exception e)
			{
				errorBox.Text = e.ToString();
				return -14;
			}
  
			try
			{
				if(UE9.LJUSB_BulkRead(ue9Dev.handle, UE9.UE9_PIPE_EP1_IN, buff, 8) != 8)
					throw new Exception();
			}
			catch(System.Exception)
			{
				return -15;
			}

			if((byte)(UE9.normalChecksum8(buff, 8)) != buff[0])
				return -12;
			
			if(buff[1] != (byte)(0xA3))
				return -10;

			if(buff[2] != (byte)(0x04))
				return -13;
			
			if(buff[3] != 0)
				return -19;

			bytesVoltage = (ushort)(buff[5] + buff[6]*256);

			//if(binaryToUncalibratedAnalogVoltage(sendBuff[4], bytesVoltage, ref voltage) < 0)
			if( (err = ue9Dev.binaryToCalibratedAnalogVoltage(buff[4], 12, bytesVoltage, ref voltage)) < 0) 
				return err;

			AI0Box.Text = string.Format("{0:f3}", voltage) + " V";


			///////////////////////////////////////////////////
			//read temperature from internal temperature sensor 
			///////////////////////////////////////////////////
			buff[1] = (byte)(0xA3);  //command byte
			buff[2] = (byte)(0x04);  //IOType = 4 (analog in)
			buff[3] = (byte)(0x85);  //Channel = 133 (tempSensor)
			buff[4] = (byte)(0x00);  //Gain = 1 (Bip does not apply)
			buff[5] = (byte)(0x0C);  //Resolution = 12
			buff[6] = (byte)(0x00);  //SettlingTime = 0
			buff[7] = (byte)(0x00);  //Reserved
			buff[0] = UE9.normalChecksum8(buff, 8);

			try
			{
				if(UE9.LJUSB_BulkWrite(ue9Dev.handle, UE9.UE9_PIPE_EP1_OUT, buff, 8) != 8)
					throw new Exception();
			}
			catch(System.Exception e)
			{
				errorBox.Text = e.ToString();
				return -14;
			}
  
			try
			{
				if(UE9.LJUSB_BulkRead(ue9Dev.handle, UE9.UE9_PIPE_EP1_IN, buff, 8) != 8)
					throw new Exception();
			}
			catch(System.Exception)
			{
				return -15;
			}

			if((byte)(UE9.normalChecksum8(buff, 8)) != buff[0])
				return -12;
			
			if(buff[1] != (byte)(0xA3))
				return -10;

			if(buff[2] != (byte)(0x04))
				return -13;
			
			if(buff[3] != (byte)(0x85))
				return -19;

			bytesTemperature = (ushort)(buff[5] + buff[6]*256);

			//assuming high power level
			if( (err = ue9Dev.binaryToCalibratedAnalogTemperature(0, bytesTemperature, ref temperature)) < 0 )
				return err;
  
			tempBox.Text = string.Format("{0:f3}", temperature) + " K";

			return 0;
		}
	}
}
