PROJECT NAME: HIGH PERFORMANCE LIQUID CHROMATOGRAPHY

High Performance Liquid Chromatography (HPLC) is one mode of chromatography; the most widely used analytical technique. HPLC utilizes a liquid mobile phase to separate the components of a mixture. These components (or analytes) are first dissolved in a solvent, and then forced to flow through a chromatographic column under a high pressure. In the column, the mixture is resolved into its components. The interaction of the solute with mobile and stationary phases can be manipulated through different choices of both solvents and stationary phases. As a result, HPLC acquires a high degree of versatility not found in other chromatographic systems and it has the ability to easily separate a wide variety of chemical mixtures.

There are two elution types: isocratic and gradient. In the first type constant eluent composition is pumped through the column during the whole analysis. This is ISOCRATIC ELUTION. In the second type, eluent composition (and strength) is steadily changed during the run. This is GRADIENT ELUTION. DAS FLOW FOR UV – VIS DETECTOR FOR HPLC

Initial Software flow: 1.Check communication synchronization 2.Send function code to micro controller 3.Send integration time to micro controller (2 bytes) 4.Wait for conversion to complete 5.Get the readings from controller 6.Convert the values to bipolar 7.Convert ADC count to float 8.Multiply the count with resolution (mV = Count *2.4420) 9.Calculate absorbance (Log (ref/smp)) 10.Display absorbance on LCD 11.Send the absorbance value to PC Disad: Overhead of 80 mSec Modified software flow: Micro processor: 1.Check communication synchronization 2.Send function code to micro controller 3.Send integration time to micro controller (2 bytes) 4.Wait for RST7.5 interrupt from controller Micro controller: 1.Check for communication synchronization 2.Receive function code 3.Receive integration time 4.Initiate ADC 5.Acquire ADC readings for the given integration time – 10 mSec 6.Interrupt Micro Processor after completion of ADC acquisition The tasks of microprocessor and micro controller are done in parallel. Hence the overhead time of 80 mSec has been overcome.


ADC Acquisition: Initially, set DG508 to reference path


Bank 0 – Reference Bank 1 – Sample

Only 2 regions – Ref and sample


DAS Flow:


Configure Timer 2 to 2 msec








Timer 2 Routine: It interrupts for every 2 msec.



Yes




Detailed hardware flow: 1.Switch on the system. 2.System initialization is done i.e, lamp, grating and filter homing 3.Enter the required wavelength and integration time. 4.Move the grating and filter to the desired positions. 5.Initially set DG508 to reference path 6.Output of DG 508 is given to CA3140 op amp. Output of Op Amp is fed to ADC and readings are taken. The buffering is done to avoid loading. 7.Accumulate the readings in Bank 0 8.Now switch DG 508 to sample path and take the readings from ADC. 9.Accumulate these readings in Bank1 10.Continue till the completion of integration time – 10 msec. 11.Calculate mV and absorbance 12.Display absorbance on LCD and send it to PC. 13.Continue till scan has been stopped.


Observations: a) With initial software flow: S.No. Integration time (sec) Data acquisition time (sec) Display calc. (mSec) Time taken (sec) 1 1 1.010 130 1.140 2 2 2.010 130 2.140 3 3 3.010 130 3.140




Individual times


S.No Task Time taken


1 Data Acquisition Int. time + 10 mSec


2 Absorbance calculation 60 mSec


3 Displaying on LCD 60 mSec


4 Sending to PC 12 mSec


5 Total time taken for one data point Int. time +142 mSec


b) With new software flow: S.No. Integration time (sec) Data acquisition time (sec) Display calc. (mSec) Time taken (sec) 1 1 1.0 130 1.0 2 2 2.0 130 2.0 3 3 3.0 130 3.0 Since the two tasks are done in parallel with each other, there’s no overhead of 130 mSec

Individual times


S.No Task Time taken


1 Data Acquisition Int. time - 10 mSec


2 Absorbance calculation 60 mSec


3 Displaying on LCD 60 mSec


4 Sending to PC 12 mSec


5 Total time taken for one data point Int. time




/*------------------------------------------------------------------------------ AD8Input.C: MSC 1210 A/D Conversion for 8 single ended channels.

            Uses 0-5V on inputs AIN0 to AIN7 and AINCOM = 2.5V.

date : 02-06-07 sign on , sign off, time scan and channel select commands functionality is achieved. external trigger input is enabled.


*/

  1. include <REG1210.H>
  2. include <stdio.h>
  3. define XTAL 11059200 // XTAL frequency

// defines for UART BAUDRATE

  1. define BAUDRATE 9600 // 9600bps communication baudrate
  2. define T2RELOAD (65536-(XTAL/32/BAUDRATE))

// defines for A/D Converter setup

  1. define A_CLK 10 // about 1MHz Analog Clock
  2. define ANA_CLK 1000000 // precise Analog Clock
  3. define DECIMATION 1562 // 10 Hz Decimation

/******* defines for commands *************/

  1. define STX 0x02
  2. define ETX 0x03
  3. define NAK 0x0F
  4. define ACK 0x06

/*********** USB definitions **************/

  1. define TXE P1_5
  2. define RXF P1_4
  3. define USB_RD P1_7
  4. define USB_WR P1_6
  5. define TRG P3_2
  6. define ENB P3_4

sbit P1_4 = P1^4; sbit P1_5 = P1^5; sbit P1_6 = P1^6; sbit P1_7 = P1^7; sbit P1_2 = P1^2; sbit P3_2 = P3^2; sbit P3_4 = P3^4; sbit P3_3 = P3^3; sbit P3_5 = P3^5; sbit P3_7 = P3^7; sbit P3_6 = P3^6;

void Delay (void); void Delay1(void);

unsigned char read; unsigned char abort;


/******** Writes character into transmit buffer ******************/ void USB_send_char( char dat) {

while(1)
{
 while (!TXE)
 {
  	USB_WR = 1;           	//pull WR line high
	Delay(); 				// put some delay

P2 = dat; //write P2 USB_WR = 0; return;

 }
}

}

/*************Reads character from the receive buffer ***********/ unsigned char USB_read_char() {

while(1)
{
 while (!RXF)
 {
    unsigned char bBYTE;

P2 = 0xFF;

  	 P2DDRH = 0x00;             //port2 all inputs

P2DDRL = 0x00; USB_RD = 0; //pull RD line low

    Delay1();			     	//put some delay

bBYTE = P2; //read P2 USB_RD = 1; //pull RD line high

    return bBYTE;
 }
}

}

/****************** Flushes the USB recieve buffer *************/ void Purge_USBFIFO( void) {

//P2 = 0xFF;
P2DDRH = 0x00;    // set P2 for input
P2DDRL = 0x00;
P2 = 0xFF;
if (!RXF)
{
 USB_RD = 0; 		//  Delay1();             
 USB_RD = 1;
}

}

/*****************timer interrupt routine *********************/ static unsigned long ovf_cnt = 0;

void timer0_ISR( void) interrupt 1 {

 //  TR0 = 0;        // stop timer 0 
 	TL0 = 0xFE;     //reload value for 50msec    
 	TH0 = 0x4B;   
 //  TR0 = 1;        // start timer 0 */  
  ovf_cnt++ ;

}


void timer1_ISR( void) interrupt 3 { TR1 = 0;

  	TL1 = 0xFE;	//0x32;     	        //reload value for 3msec    
 	TH1 = 0x4B;	//0xF5;   

while(!RXF) { P2 = 0xFF;

  	P2DDRH = 0x00;              //port2 all inputs

P2DDRL = 0x00; USB_RD = 0; //pull RD line low

   Delay1();			     	//put some delay

read = P2; //read P2 USB_RD = 1; //pull RD line high if(read == 0X04) abort = 1; } TR1 = 1; }


/***********************Initializes ADC **********************/ void init_ADC( void) {

 ADMUX  = 0x08;                    // (AIN+ = AIN0),(AIN- = AINCOM) Voltage from DAC
 ACLK   = A_CLK;                   // set ACLK factor for about 1MHz
 ADCON0 = 0x10; 					// disable internal vref //0x30; // Vref On, Vref Hi, Buff off, BOD off, PGA=1
 ADCON2 = DECIMATION & 0xFF;       // LSB of decimation
 ADCON3 =(DECIMATION>>8) & 0x07;   // MSB of decimation
 ADCON1 =  0x01;                   // bipolar, auto, self calibration (offset, gain) 

}

/****************Initializes serial**************************/ void init_UART( void) {

 T2CON   = 0x34;                   // Use Timer 2 as baudrate generator  */
 RCAP2H  = (T2RELOAD >> 8);        // baudrate reload factor
 RCAP2L  = T2RELOAD;
 SCON0   = 0x53;                   // enable serial uart & receiver
 P3DDRL &= 0xF0;                   // set port pins of UART to input/strong drive output
 P3DDRL |= 0x07;                   // set port pins of UART to input/strong drive output

}

/****************Timer Initialize **********************/ void timer0_initialize( void) {

  EA = 0;             // disable all interrupts 
  TR0 = 0;            // stop timer 0
  TMOD = (TMOD & 0xF0) | 0x01;
  TL0 = 0xFE;
  TH0 = 0x4B;
  ET0 = 1;            // enable timer 0 interrupt
  TR0 = 0;            // start timer 0
  EA = 1;             // enable interrupts */

}

void timer1_initialize( void) {

  TR1 = 0;
  EA = 0;              // disable all interrupts 
  TR1 = 0;             // stop timer 1
  TMOD = (TMOD & 0x0F) | 0x10;
  TL1 = 0x32;
  TH1 = 0xF5;			// timer 1 interrupt is set for 3 msec
  ET1 = 1;             // enable timer1 interrupt
  EA = 1;              // enable interrupts */

// TR1 = 1; }

/*******Ext. Interrupt init********/ void ex0_isr_init(void) {

 IT0 = 1;
 EX0 = 1;
 EA = 1;

}


/********External interrupt routine********/ //unsigned char ex0_isr_counter = 0;

void ex0_isr (void) interrupt 0 { //ex0_isr_counter++; // Increment the count }


/*****Helper structure to read in ADC values*****/ union {

 unsigned char  c[4];              // bytes
 unsigned long  l;                 // unsigned long

} res;

/***********Main Function*****************/ void main(void) { unsigned char chk_sum1,chk_sum2,fcode_stat = 0xFF,c2,j1,c,time_scan,count,chan_ID = 0x00; unsigned char chan_sel=0x34,k; unsigned int xdata size = 0 ; unsigned int i,j,sum2, sum3, timer_cnt, scan_cnt, cnt =0,sum,sum1,interval; unsigned int a[10], temp[10]; unsigned long tot;

CKCON = 0; // 0 MOVX cycle stretch make movx machine cycle = 2

 	PDCON = 0x14;                     	// turn on ADC-Vref, SPI and Systimers make power down mode and 

// watchdog timer in powerdown mode

  	init_UART();						// Setup Serial Interface
  	P1DDRH = 0x5F;  					// set port pins  
 	init_ADC();							// Setup ADC
 	USB_RD = 1;   						// init usb WR
 	USB_WR = 1;   						// init usb RD
   timer0_initialize();				// init timer0

timer1_initialize(); // init timer1

ex0_isr_init(); // initialize external interrupt

	Purge_USBFIFO();					// flush usb buffer
   for (i=0;i<10;i++)							// dump 3 conversions

{ while(!(AIE&0x20)) {} j1=ADRESL; }

while (1) { while (!RXF) { c = USB_read_char(); //reading STX 0x02

if(c == STX) //else { c = USB_read_char(); //reading first byte of length 0x00

c = USB_read_char(); //reading second byte of length can be 0x00 or 0x05

if(c == 0x02) //connect,disconnect or channel select cmd { c = USB_read_char(); //reading function code fcode_stat = c; } else if( c == 0x05) { if(TRG != 0 ) USB_send_char(NAK);

else { c = USB_read_char(); //READING FUNCTION CODE time_scan = c;

c = USB_read_char(); //reading first byte of scan count sum1 = 0; sum1 += (int)c; scan_cnt = 0; c2 = c;

c = USB_read_char(); //reading second byte of scan count

sum1 += (int)c; scan_cnt += (int)((c2 << 8) | c); if( scan_cnt <= 0) USB_send_char(NAK);

c = USB_read_char(); //reading first byte of time interval

sum1 += (int)c; timer_cnt = 0; c2 = c;

c = USB_read_char(); //reading second byte of time interval sum1 += (int)c; sum1 += 2; timer_cnt = (int) ((c2 << 8) | c); interval = timer_cnt * 4;

if( timer_cnt <= 0) USB_send_char(NAK);

sum = sum1/256; // mod256 sum = sum1 - (256 * sum); chk_sum1 = (char) (sum & 0xFF); chk_sum1 = (~(chk_sum1) + 1); //calculating check sum

if((c = USB_read_char()) != chk_sum1) {

USB_send_char(NAK); } if((c = USB_read_char()) != ETX) USB_send_char(NAK);

else { USB_send_char(ACK); TR0 = 1; TR1 = 1; } cnt = 0; ovf_cnt = 0; } } //end of time scan cmd } //end of else

if(fcode_stat != 0xFF) { switch(fcode_stat) { case 0x00: //SIGNON command c = USB_read_char(); //reading data block sum = c; sum1 = sum/256; sum1 = sum - (256*sum1); chk_sum1 = (char) (sum1 & 0xFF); chk_sum1 = (~(chk_sum1)+1); if((c = USB_read_char())!= chk_sum1) USB_send_char(NAK); if((c = USB_read_char())!= ETX) USB_send_char(NAK); else USB_send_char(ACK); fcode_stat = 0xFF; break;

case 0x01: //CHANNEL SELECT command sum = fcode_stat; chan_sel = USB_read_char(); //reading the selected channels

sum += (int)chan_sel; for(i=0;i<8;i++) { a[i] = chan_sel % 2; chan_sel = chan_sel/2; } count = 0; j = 0;

for(i=0;i<8;i++) { if(a[i] == 1) { count++; temp[j] = i; j++; } } i = 0; sum1 = sum/256; sum1 = sum - (256*sum1); chk_sum1 = (char) (sum1 & 0xFF); chk_sum1 = (~(chk_sum1)+1);

if((c = USB_read_char())!= chk_sum1) USB_send_char(NAK);

if((c = USB_read_char())!= ETX) USB_send_char(NAK);

else USB_send_char(ACK);

fcode_stat = 0xFF; // printf("channel ID : %d ", temp[i]); break;

case 0x03: //SIGNOFF command // printf("SIGN OFF CMD RECEIVED \n"); c = USB_read_char(); //reading data block sum = c + fcode_stat; sum1 = sum/256; sum1 = sum - (256*sum1); chk_sum1 = (char) (sum1 & 0xFF); chk_sum1 = (~(chk_sum1)+1); if((c = USB_read_char())!= chk_sum1) USB_send_char(NAK); if((c = USB_read_char())!= ETX) USB_send_char(NAK);

else USB_send_char(ACK); fcode_stat = 0xFF; break;

default:

break; } // end of switch } } // end of while(!RXF)

while( time_scan == 0x02) //time scan mode { chan_ID = temp[i];

ADMUX = (temp[i]<<4) | 1;

while( (cnt <= scan_cnt && ovf_cnt == timer_cnt/50)|(ovf_cnt == 0&&cnt == 0) ) { // AINP = chan, AINN = AINCOM if(cnt == 0) { for (k=0;k<3;k++) // dump 3 conversions { while(!(AIE&0x20)) {} j1=ADRESL; } } USB_send_char(STX); USB_send_char(0x00); USB_send_char(0x05);

while (!(AIE & 0x20)); // Read Input Voltage Wait for data ready

res.c[0] = ADRESH ^ 0x80; // Invert the Most significant bit (only positive inputs) res.c[1] = ADRESM; res.c[2] = ADRESL; res.c[3] = 0;

tot = 0x00;

tot = res.c[0];

tot = tot << 8; tot += res.c[1];

tot = tot << 8; tot += res.c[2];

				if(tot >= 0x00208D)

tot += 0x00208D;

res.c[2] = tot % 256; tot = tot/256; res.c[1] = tot % 256; tot = tot/256; res.c[0] = tot % 256;

USB_send_char(chan_ID); //channel ID USB_send_char(0x00); //byte to check data sent is valid data or an error

USB_send_char(res.c[0]);

sum2 = 0; sum2 += (int) res.c[0];

USB_send_char(res.c[1]);

sum2 += (int) res.c[1];

USB_send_char(res.c[2]);

sum2 += (int) res.c[2];

sum3 = 0; sum3 = sum2/256;

               sum3 = sum2 - (256 * sum3);  


               chk_sum2 = (char) (sum3 & 0xFF);

chk_sum2 = (~(chk_sum2) + 1);


USB_send_char(chk_sum2); USB_send_char(ETX);

ovf_cnt = 0; cnt++; i++;

if(i == count) i = 0; if(abort == 1) { abort = 0; TR0 = 0; TR1 = 0; time_scan = 0x00; Purge_USBFIFO(); // flush usb buffer }

  		   		if(cnt == scan_cnt)
          		{	

TR0 = 0; TR1 = 0; time_scan = 0x00; Purge_USBFIFO(); // flush usb buffer } } //end of outer while } // end of if condition

 }		// end of while(1)

} // end of main

void Delay(void) {

// unsigned int i, j;
 //for(i=0; i<20/*100*/; i++)
 //     for(j=0; j<10; j++)
 //             i = i + 0;

}

void Delay1(void) { // unsigned int i, j;

// for(i=0; i<50/*500*/; i++)

//      for(j=0; j<10/*50*/; j++)
//            i = i + 0;

}