void TaskSensores(void *pdata)
{    
#if OS_CRITICAL_METHOD == 3 
    OS_CPU_SR  cpu_sr;
#endif
    struct AdcMsg *m;
    INT16U value = 0;
    INT16U ValorTeclado = 0;
	INT8U err;
	for(;;)
	{
        
        m = (struct AdcMsg *) OSMemGet(dMemory,&err);
        if(err == OS_NO_ERR){
            OSSemPend(STeclado,0,&err);
            ValorTeclado = NumeroSensores;
            OSSemPost(STeclado);       
            m->adc0 = 0;
            m->adc1 = 0;
            m->adc2 = 0;
            switch(ValorTeclado){
                case 3:
                    Delay10TCYx(100);
                    SetChanADC(ADC_CH2);
                    ConvertADC();
                    while( BusyADC() );
                    value = ReadADC();
                    m->adc2 = Temp(value);
                case 2:
                    Delay10TCYx(100);
                    SetChanADC(ADC_CH1);
                    ConvertADC();
                    while( BusyADC() );
                    value = ReadADC();
                    m->adc1 = Temp(value);                    
                case 1:
                    Delay10TCYx(100);
                    SetChanADC(ADC_CH0);
                    ConvertADC();
                    while( BusyADC() );
                    value = ReadADC();
                    m->adc0 = Temp(value);
                default:
                    break;
            }

            err = OSQPost(QueueADC0,m);
            if(err == OS_Q_FULL){
                OSMemPut(dMemory,m);
                OSSemPost(STaskTxSerial);
            }
        }else{
            OSSemPost(STaskTxSerial);
        }
		//OSSemPost(STask2);
		OSTimeDly(1);
	}
}
Exemple #2
0
/* switch to ADC chan 8 (shorted to ground) to reset ADC measurement cap to zero before next measurement */
void ADC_zero(void)
{
	ClrWdt(); // reset the WDT timer
	SetChanADC(ADC_CH8); // F3 grounded input
	Delay10TCYx(ADC_CHAN_DELAY);
	ConvertADC();
	while (BusyADC());
}
Exemple #3
0
void main (void)
{
  int count = 0;
  int analogTemp = 0;  	// A temporary place holder is needed
						// since ADC will screw with the number
						// you are assigning to, and we could
						// switch threads during that time.
  TRISB = 0;  // Output for relay
  TRISD = 0;  // Output for seven segment display
  TRISC = 0;  // More output for seven segment display
  TRISAbits.TRISA0 = 1; // Analog input
  writeNum(0);

  // Enable timer interrupt
  Flags.Byte = 0;
  INTCON = 0x20;                //disable global and enable TMR0 interrupt
  INTCON2 = 0x84;               //TMR0 high priority
  RCONbits.IPEN = 1;            //enable priority levels
  TMR0H = 0;                    //clear timer
  TMR0L = 0;                    //clear timer
  T0CON = 0x84;                 //set up timer0 - prescaler 1:8
  INTCONbits.GIEH = 1;          //enable interrupts
		
  while(1){
    OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_0_TAD,
       ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,
	   0b1011);
    SetChanADC(ADC_CH0);
    ConvertADC(); // Start conversion
    while( BusyADC() ); // Wait for ADC conversion
    analogTemp = ReadADC(); // Read result and put in temp
    CloseADC();
    analogInput = analogTemp >> 6; // Get only the most significant bits

	// If we didn't change values since last time, we are in a holding state
	if( analogPrevious == analogInput && !hold) hold = 1;
    else if (analogPrevious != analogInput){
 	    acceptedNum = 0;
		hold = 0;
    }
	
	// Turn off potential for activating the relay if we aren't on 0
    if(analogInput) PORTB = 0;


	// If we are allowing the second relay activation and we are on 0
    if(secondRun && !analogInput) {
      PORTB = 0xFF;
      secondRun = 0;
	  passDigit = 0;
	}

    analogPrevious = analogInput;
    writeNum(analogInput);
  }
}
Exemple #4
0
unsigned int ADC_read(unsigned char ADC_channel)
 {
  unsigned int ad_res;
	   
  SetChanADC(ADC_channel);
  Delay10TCYx(5);
  ConvertADC();
  while(BusyADC());
  ad_res = ReadADC();
  return ad_res;
}
int readADC(BYTE address) {
  int data;

  // Choosing ADC channel (override ADC_CH0)
  switch(address) {
    case 0: SetChanADC(ADCCHAN(0)); break;
    case 1: SetChanADC(ADCCHAN(1)); break;
    case 2: SetChanADC(ADCCHAN(2)); break;
    case 3: SetChanADC(ADCCHAN(3)); break;
    case 4: SetChanADC(ADCCHAN(4)); break;
    default: return -1;  // non existing channel
  }

  delay_us(125);       // wait until channel selection is stable
  ConvertADC();        // Start conversion
  while (BusyADC());   // Wait for ADC conversion
  data = ReadADC();    // Read result

  return data;
}
Exemple #6
0
void measureCarbon()
{

	//Perform Measurement and convert to correct format
	//Choose a channel adc channel AN1
//    OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_8ANA_0REF , ADC_CH1 & ADC_INT_OFF);
    SetChanADC(ADC_CH1);
    Delay10KTCYx(5);
    ConvertADC();
    while(BusyADC());
    carbon = ReadADC(); //take value read and divide by 204.8 to get voltage read
}
Exemple #7
0
void adc_int_handler(){

    // adcbuffer[0] stores the count
    if(adcbuffer[0] < 3)                 // increment counter
        adcbuffer[0] = adcbuffer[0] + 1;
    else
        adcbuffer[0] = 1;

    // Converts ADRESH to a voltage
    int k = (int)ADRESH;
    float voltage = 3.4*k/256;
    int roundDist;

    // If the voltage is larger than .5 V this runs it through a simplifed equation to return the approximate distance
    // WARNING:  This equation is not completely accurate so results may vary until it is improved
    if (voltage > .5) {
        float dist = 24/(voltage - 0.1);
        roundDist = (int)(dist + 0.5);
    }
    // If the voltage is too small then the object is assumed to be too far away so we send back 0xFF
    else
        roundDist = 0xFF;

    // Reads the current channel from the count of the adcbuffer[0]
    // Puts the current distance of the respective sensor in the adcbuffer then changes to the next channel
    int channel = (int)adcbuffer[0] % 3;
    if (channel == 0) {
        adcbuffer[3] = roundDist;
        SetChanADC(ADC_CH1);
    }
    else if (channel == 1) {
        adcbuffer[1] = roundDist;
        SetChanADC(ADC_CH2);
    }
    else {
        adcbuffer[2] = roundDist;
        SetChanADC(ADC_CH3);
    }
}
Exemple #8
0
void measureTemperature()
{
    int i;
    for(i=0;i<5;i++){
            // perform measurement on AN5 note that AN3 is the +Vref signal and is 7 volts
        //OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_8ANA_0REF , ADC_CH5 & ADC_INT_OFF);
        SetChanADC(ADC_CH5);
        Delay10KTCYx(5);
        ConvertADC();
        while(BusyADC());
        temp[i] = ReadADC();
    }
}
/*****************************************************************
* Function:			readIRSensor
* Input Variables:	none
* Output Return:	1 if there is IR
*					0 if there is no IR
* Overview:			Reads the valus for the IR and determs if there is IR
******************************************************************/
int readIRSensor()
{
    int ra0 = 0;
    SetChanADC(ADC_CH0);
    ConvertADC();
    while(BusyADC());
    ra0 = ReadADC();
    
    if(ra0 >= 500){
    	return 0;
    }else{
    	return 1;
    }	
}	
Exemple #10
0
unsigned int GetCO()
{
    unsigned int CORaw=0;

    SetChanADC(ADC_CH0);

    ConvertADC();

    while(BusyADC());
    CORaw = ReadADC();

    //CloseADC();

    return CORaw;

}
Exemple #11
0
/* getArrayCurrent -- Major Function
 * Gather and convert the current provided
 * by the solar array, in mA
 */
int getArrayCurrent(void){
    int i;
    int average = 0;

    SetChanADC(PWR_I_AN_CH);

    for (i = 0; i < POWER_FILT; ++i){
        ConvertADC();
        while(BusyADC());
        average += ReadADC();
    }
    
    average /= POWER_FILT;
    average =(int)(average * POWER_BIT_MA);
    return average;
}
Exemple #12
0
/* getArrayVoltage -- Major Function
 * gathers and scales the voltage from
 * the output of the solar array, in mV
 */
int getArrayVoltage(void){
    int i;
    int average = 0;

    SetChanADC(PWR_V_AN_CH);

    for (i = 0; i < POWER_FILT; ++i){
        ConvertADC();
        while(BusyADC());
        average += ReadADC();
    }
    
    average /= POWER_FILT;
    average *= POWER_BIT_MV;
    return average;
}
Exemple #13
0
void measureSalinity()
{
	// send power on to measure circuit
	measureOn = 1;

	//Perform Measurement and convert to correct format  on AN0
   // OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_8ANA_0REF , ADC_CH0 & ADC_INT_OFF);
    SetChanADC(ADC_CH0);
    Delay10KTCYx(5);
    ConvertADC();
    while(BusyADC());
    salinity = ReadADC(); //take value read and divide by 204.8 to get voltage read

	// power off measureing circuit
	measureOn = 0;
}
Exemple #14
0
void Button_init(button_callback_func_ptr_t pfnCallback)
{
	unsigned char i = 0;
	for (i = 0; i < 16; i++)
	{
		m_astcButtonCtrl[i].currState = StateLow;
		m_astcButtonCtrl[i].saveState = 0; 
		m_astcButtonCtrl[i].light = 1; 				
	}
	m_astcButtonCtrl[4].light = 0;
	m_astcButtonCtrl[5].light = 0;	
	m_astcButtonCtrl[6].light = 0;
	m_astcButtonCtrl[7].light = 0;
	Init74hc595();
	SetChanADC(ADC_CH0);
	m_pfnCallback = pfnCallback;	
}
Exemple #15
0
int GetVOC()
{
    unsigned int VOC_Raw=0;

    SetChanADC(ADC_CH1);

    ConvertADC();

    while(BusyADC());
    VOC_Raw = ReadADC();

    //CloseADC();
    

    return VOC_Raw;


}
/* **********************************************************************
 * Function: readTempx2(void)
 *
 * Include: ADC.h
 *
 * Description: Reads the temperature from the Temp sensor
 *
 * Arguments: None
 *
 * Returns: temp x 2 (in deg celsius) as an unsigned char
 *************************************************************************/
unsigned char readTempx2(void)
{
    int ad_result;
    unsigned char tempx2;

    //Sets the ADC channel to read the temperature
    SetChanADC(ADC_TEMP_READ);

    //Performs the conversion
    ConvertADC();
    while(BusyADC());
    ad_result = ReadADC();

    //10mV per deg C, which 0V at 0deg, with the ADC res ~5mV
    tempx2 = ad_result;

    lastTempx2 = tempx2;
    
    return tempx2 + calibration_offset;
}
Exemple #17
0
unsigned int MPX6115_uiGetPression(void)
{
	int iResult; 
	unsigned long ulPression;
	OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_12_TAD, ADC_CH0 & ADC_INT_OFF, 0); //open adc port for reading
	ADCON1 =0x00; //set VREF+ to VDD and VREF- to GND (VSS)
	SetChanADC(ADC_CH5); //Set ADC to Pin 5
	Delay1KTCYx(5);
	ConvertADC();
	while( BusyADC() );
	iResult = ReadADC();
	CloseADC();
	ulPression=((unsigned long)iResult*5000/1024 + 475)*10 /45;
#ifdef DEBUG
	printf("Pression %ld %x\n\r",ulPression,iResult);
#endif
	
	ADCON1=0b00001111;			// Digital Channel Allocation 
	return (unsigned int)ulPression;
}
Exemple #18
0
Fichier : hax.c Projet : ellbur/hax
uint16_t analog_get(AnalogInIndex ain) {
	if ( ain > kAnalogSplit ) {
		/* get oi data */
		/* we may not want to trust "ain" */
		return rxdata.oi_analog[ ain - kAnalogSplit ];
	}
	/* kNumAnalogInputs should be checked somewhere else... preferably at
	 * compile time.
	 */
	else if ( ain < kNumAnalogInputs && NUM_ANALOG_VALID(kNumAnalogInputs)  ) {
		/* read ADC */
		SetChanADC(ain);
		Delay10TCYx( 5 ); /* Wait for capacitor to charge */
		ConvertADC();
		while( BusyADC() );
		return ReadADC();
	}
	else {
		return 0xFFFF;
	}
}
Exemple #19
0
void InitApp(void){
    /* TODO Initialize User Ports/Peripherals/Project here */
    TRISA = 0x00000001; //RA0 Input
    TRISB = 0b00000001; //RB0 Input
    TRISC = 0x00;
    TRISD = 0x00;
    TRISE = 0x00;
    /* Setup analog functionality and port direction */
    ADCON1 = 0x0F; //For Digital
    CMCON = 0x07;
    /* Initialize peripherals */
    PORTA = 0X00;
    PORTB = 0X00; //RB0 Input
    PORTC = 0X00;
    PORTD = 0X00;
    PORTE = 0X00;
    /* Configure the IPEN bit (1=on) in RCON to turn on/off int priorities */
    INTCON2bits.INTEDG0 = 0;
    INTCON2bits.RBIP = 1;
    /* Enable interrupts */
    INTCONbits.INT0IF = 0;
    INTCONbits.INT0IE = 1;

    RCONbits.IPEN = 1;
    INTCONbits.GIEH = 1;
    INTCONbits.GIEL = 0;

    /* ADC Config */
    OpenADC(ADC_FOSC_16 & ADC_RIGHT_JUST & ADC_2_TAD,
            ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,
            ADC_1ANA);
    SetChanADC(ADC_CH0);
    __delay_ms(1);

    //Com PORT -> 19200bps 8Bit 1Stop / fosc = 48Mhz / BRGH = 155
    TRISCbits.RC6 = 0;
    TRISCbits.RC7 = 1;
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & 
            USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH, 155);
}
Exemple #20
0
void isr(void)
{

	// === Eine PPM-Flanke vom Fernbedienungsempfänger wurde erkannt ===
	if(PIR1bits.CCP1IF)
	{
		current_edge_time = CCPR1;
		if ( current_edge_time < last_edge_time ) // Timer übergelaufen
			last_edge_time -= 0x00ffff;

		pulse_width = current_edge_time - last_edge_time;
		last_edge_time = current_edge_time;

		if (pulse_width > 6250) // 6250 Timertakte * 0,8µs Timertaktlänge = 5 ms
		{
			current_rc_channel = 1;
			current_rc_frame_ok = true;
		}
		else
		{
			if (pulse_width >= 1250 && pulse_width <= 2500) // zwischen 1 und 2 ms
				raw_rc_data[current_rc_channel] = pulse_width - 1250;
			else
				current_rc_frame_ok = false;

			if (current_rc_channel == sizeof(raw_rc_data)/sizeof(raw_rc_data[0]) - 1) // Letzter Kanal
			{
				if (current_rc_frame_ok)
				{
					new_rc_values_available = true;
					last_valid_rc_frame = ms_clock;
					signal = true;
				}
			}

			current_rc_channel++;
		}

		CCP1CONbits.CCP1M0 ^= 1; // Als nächstes auf die umgekehrte Flanke warten

		PIR1bits.CCP1IF = false;
	}

	// === Der ADC hat ne Wandlung fertig ===
	if (PIR1bits.ADIF)
	{
		if (*curr_chan == ADC_CH0)
			adc_values.batt = ReadADC();
		if (*curr_chan == ADC_CH1)
			adc_values.roll = ReadADC();
		if (*curr_chan == ADC_CH2)
			adc_values.pitch = ReadADC();
		if (*curr_chan == ADC_CH5)
			adc_values.yaw = ReadADC();

		curr_chan++;

		if (curr_chan == (channel_sequence + chan_count))
		{
			curr_chan = &channel_sequence[0];
			SetChanADC(*curr_chan);
			new_gyro_values_available = true;
		}
		else
		{
			SetChanADC(*curr_chan);
			ConvertADC();
		}

		PIR1bits.ADIF = false;
	}
	
	// === Interrupt Timer 1 ===
	if (INTCONbits.T0IF)
	{
		i16u temp;
		
		// Timer vorwärtsschieben, somit dauerts bis zum nächsten Überlauf nur 625 Timertakte * 1,6µs Timertaktlänge = 1ms
		temp.b0 = TMR0L;
		temp.b1 = TMR0H;
		temp.u16 += (65536 - 625);
		TMR0H = temp.b1;
		TMR0L = temp.b0;

		if (out_messages.waiting_for_ack_timer)
			out_messages.waiting_for_ack_timer--;

		PIE1bits.ADIE = true; // Das kann hier weg, oder?

		ms_clock++;

		if (signal && ms_clock - last_valid_rc_frame > 200)
			signal = false;

		if (!(ms_clock % 5))
			ConvertADC();

		// if (!(ms_clock % 5)) // erstmal einfach so, hab mir nichts dabei gedacht
		//	motors_need_updating = true;

		// if (!(ms_clock % 5000))
		//	motor_debug_needs_processing = true;
		
		if (lifesaver_timeout)
			lifesaver_timeout--;

		INTCONbits.T0IF = false;
	}

	// === Ein Byte ist per SPI eingegangen ===
	if (PIR1bits.SSPIF)
	{
		// Da wir nur beim ersten Byte frisch in diesen Block kommen und danach hier bleiben, wissen wir, daß dies das
		// erste Byte einer neuen Nachricht ist -> Puffer leeren
		spi_rec_buffer.read_cursor = 0;
		spi_rec_buffer.write_cursor = 0;

		while (!PORTAbits.NOT_SS && spi_rec_buffer.write_cursor < spi_rec_buffer.size) // den Ausgangspuffer brauchen wir nicht zu prüfen, von dem wird nur gelesen
		{
			spi_rec_buffer.data[spi_rec_buffer.write_cursor] = SSPBUF;
			SSPBUF = spi_out_msg_buffer.data[spi_out_msg_buffer.read_cursor];
			PIR1bits.SSPIF = 0;

			if (LATAbits.LATA4)
			{
				if (spi_out_msg_buffer.read_cursor == spi_out_msg_buffer.write_cursor)
				{
					spi_sending_state = SPI_SENDING_IDLE;
					LATAbits.LATA4 = 0; // IRQ-Leitung dauerhaft low, dann wird der Secondary das /CS gleich abschalten und das
					                    // Byte im Puffer nicht mehr abholen

					if (spi_out_msg_buffer.data[0] != 0 || spi_out_msg_buffer.data[1] != 0 || spi_out_msg_buffer.data[2] != 1)
					{
						// Wenns keine ACK-Nachricht war, war es wohl eine normale, wir warten also auf ein ACK

						// Und zwar 0.68 Sekunden lang, laut Data ist das "für einen Androiden fast eine Ewigkeit":
						out_messages.waiting_for_ack_timer = 664;
					}
				}
				else
				{
					// Ansonsten nur ein kurzer Low-Puls, damit er weiß, daß er weitere Bytes abholen kann
					LATAbits.LATA4 = 0;
					LATAbits.LATA4 = 0;
					LATAbits.LATA4 = 0;
					LATAbits.LATA4 = 0; // Um das zu erkennen, braucht er mindestens vier Zyklen
					LATAbits.LATA4 = 0;
					LATAbits.LATA4 = 1;
					spi_out_msg_buffer.read_cursor++;
				}
			}
			else
			{
				// Durch kurzes Wechseln der IRQ-Leitung teilen wir dem Secondary mit, daß er jetzt weitere Bytes schicken kann
				LATAbits.LATA4 = 1;
				LATAbits.LATA4 = 1;
				LATAbits.LATA4 = 1;
				LATAbits.LATA4 = 1; // Um das zu erkennen, braucht er mindestens vier Zyklen
				LATAbits.LATA4 = 1;
				LATAbits.LATA4 = 0;
			}

			spi_rec_buffer.write_cursor++;
			while (!PORTAbits.NOT_SS && !PIR1bits.SSPIF); // Wir warten, daß ein weiteres Byte kommt oder die Nachricht zu Ende ist
		}

		spi_message_received = true;

	}

}
Exemple #21
0
void ADC_read(void) // update all voltage/current readings and set load current in 'currentload' variable
{ // ADC is opened and config'd in main
	static uint16_t i, z, change = 0; // used for fast and slow sample loops >256
	static int32_t a10_x_t, a10_y_t, a10_z_t;

	ClrWdt(); // reset the WDT timer
	ADC_zero();
	SetChanADC(ADC_CH0); // A0 system
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	vbatol_t = Vin * (ADC0_MV - ADC_NULL + adc_cal[0]); //      voltage correction factor
	vbatol_t = vbatol_t / 100;


	ADC_zero();
	SetChanADC(ADC_CH1); // A1 motor
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	solar_t = Vin * (ADC1_MV - ADC_NULL + adc_cal[1]);
	solar_t = solar_t / 100;


	ADC_zero();
	SetChanADC(ADC_CH2); // A2 current_x
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_S; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_S;
	a10_x = Vin; // raw ADC value

	Vin = Vin - (AMP10_ZERO - ADC_NULL + adc_cal[11]); // set zero NULL0 point
	a10_x_t = (long) Vin * (long) (ADC2_MV - ADC_NULL + adc_cal[2]);
	if (ABSL(a10_x_t) < AMPZ)
		a10_x_t = 0; // zero bit noise
	a10_x_t = (long) ((float) a10_x_t / (float) AMP10_SEN_H);
	a10_x_t = (long) lp_filter((float) a10_x_t, LP_CURRENT_X, FALSE); // use digital filter
	if ((a10_x == NULL0) || (a10_x_t < 0.0)) a10_x_t = 0; // if sensor disconnected read zero

	ADC_zero();
	SetChanADC(ADC_CH11); // A11 current_y, switch from 3 so we can use external VREF
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_S; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_S; //
	a10_y = Vin; // raw ADC value

	Vin = Vin - (AMP10_ZERO - ADC_NULL + adc_cal[12]);
	a10_y_t = (long) Vin * (long) (ADC3_MV - ADC_NULL + adc_cal[3]);
	if (ABSL(a10_y_t) < AMPZ)
		a10_y_t = 0; // zero bit noise
	a10_y_t = (long) ((float) a10_y_t) / ((float) AMP10_SEN_L);
	a10_y_t = (long) lp_filter((float) a10_y_t, LP_CURRENT_Y, FALSE); //      use digital filter
	if ((a10_y == NULL0) || (a10_y_t < 0.0)) a10_y_t = 0; // if sensor disconnected (zero) read zero current

	ADC_zero();
	SetChanADC(ADC_CH4); // A5 current_z
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_S; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_S;
	a10_z = Vin;
	Vin = Vin - (AMP10_ZERO - ADC_NULL + adc_cal[13]); // set zero NULL0 point
	a10_z_t = (long) Vin * (long) (ADC4_MV - ADC_NULL + adc_cal[4]);
	if (ABSL(a10_z_t) < AMPZ)
		a10_z_t = 0; // zero bit noise
	a10_z_t = (long) ((float) a10_z_t / (float) AMP10_SEN_L);
	a10_z_t = (long) lp_filter((float) a10_z_t, LP_CURRENT_Z, FALSE);
	if ((a10_z == NULL0) || (a10_z_t < 0.0)) a10_z_t = 0; // if sensor disconnected read zero

	ADC_zero();
	SetChanADC(ADC_CH5); // F0 pot x
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	rawp[0] = Vin;

	ADC_zero();
	SetChanADC(ADC_CH6); // F1 pot y
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	rawp[1] = Vin;

	ADC_zero();
	SetChanADC(ADC_CH7); // F2 pot z
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	rawp[2] = Vin;

	ADC_zero();
	SetChanADC(ADC_CH8); // F0 pot max
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	rawa[0] = Vin;

	ADC_zero();
	SetChanADC(ADC_CH9); // F1 pot max
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	rawa[1] = Vin;

	ADC_zero();
	SetChanADC(ADC_CH10); // F2 pot max
	Delay10TCYx(ADC_CHAN_DELAY);
	Vin = 0;
	for (i = 0; i < ADC_SAMP_F; i++) {
		ConvertADC();
		while (BusyADC());
		Vin += (uint16_t) ReadADC();
	}
	Vin /= ADC_SAMP_F;
	rawa[2] = Vin;

	R.motorvoltage = solar_t;
	R.systemvoltage = vbatol_t;

	if (SYSTEM_STABLE) {
		s_crit(HL);
		R.current_z = a10_z_t;
		R.current_y = a10_y_t;
		R.current_x = a10_x_t;
		R.pos_x = rawp[XAXIS];
		R.pos_y = rawp[YAXIS];
		R.pos_z = rawp[ZAXIS];
		R.max_x = rawa[XAXIS];
		R.max_y = rawa[YAXIS];
		R.max_z = rawa[ZAXIS];
		e_crit();
		for (z = 0; z < MAX_POT; z++) {
			motordata[z].pot.pos_actual = rawp[z];
			if (ABSI(motordata[z].pot.pos_actual - motordata[z].pot.pos_actual_prev) > motordata[z].pot.pos_change) {
				motordata[z].pot.pos_change = ABSI(motordata[z].pot.pos_actual - motordata[z].pot.pos_actual_prev);
			}
			if (motordata[z].active && (motordata[z].pot.pos_change > motordata[z].pot.limit_change)) {
				if (mode.change) {
					term_time();
					sprintf(bootstr2, " Pot %i Change too high %i\r\n", z, motordata[z].pot.pos_change);
					puts2USART(bootstr2);
					motordata[z].pot.pos_change = motordata[z].pot.limit_change; // after one message stop and set it to the limit.
				} else {
					motordata[z].pot.pos_actual = rawp[z]; // set to current pot reading
					motordata[z].pot.pos_actual_prev = rawp[z];
					motordata[z].pot.pos_change = 0; // pot position change mag
				}
			}
			// Check for POT Dead-Spot readings
			if ((motordata[z].pot.pos_change >= POT_MAX_CHANGE) && !mode.qei) motordata[z].pot.cal_failed = TRUE;
			if (!motordata[z].active) motordata[z].pot.cal_failed = FALSE; // don't fail inactive motors

			motordata[z].pot.pos_actual_prev = motordata[z].pot.pos_actual;
			if (motordata[z].pot.pos_actual > motordata[z].pot.high) motordata[z].pot.high = motordata[z].pot.pos_actual; // set adc limits of values X,Y,Z
			if (motordata[z].pot.pos_actual < motordata[z].pot.low) motordata[z].pot.low = motordata[z].pot.pos_actual;
			if (mode.operate == VIISION_MS) { // use the preset o-100 resistance limits for scaling
				motordata[z].pot.high = VIISION_MS_RES_HIGH;
				motordata[z].pot.low = VIISION_MS_RES_LOW;
			}
			motordata[z].pot.offset = motordata[z].pot.low;
			motordata[z].pot.span = motordata[z].pot.high - motordata[z].pot.low;
			if (motordata[z].pot.span < 0) motordata[z].pot.span = 0;
			motordata[z].pot.scale_out = SCALED_FLOAT / motordata[z].pot.span;
			motordata[z].pot.scale_in = motordata[z].pot.span / SCALED_FLOAT;
			motordata[z].pot.scaled_actual = (int) ((float) (motordata[z].pot.pos_actual - motordata[z].pot.offset) * motordata[z].pot.scale_out);
			if (motordata[z].pot.scaled_actual > SCALED) motordata[z].pot.scaled_actual = SCALED;
			motordata[z].pot.pos_set = (int) (((float) motordata[z].pot.scaled_set * motordata[z].pot.scale_in) + motordata[z].pot.offset);
		}
		if (mode.emo) {
			term_time();
			sprintf(bootstr2, " EMO flag tripped, possible short circuit in the assy wiring.\r\n");
			puts2USART(bootstr2);
			term_time();
			sprintf(bootstr2, " EMO DUMP Current %li, %li, %li : Position %li, %li, %li\r\n", emodump.emo[0], emodump.emo[1], emodump.emo[2], emodump.emo[3], emodump.emo[4], emodump.emo[5]);
			puts2USART(bootstr2);
			voice2_ticks(40);
			while (TRUE) {
				emo_display();
				buzzer_ticks(200);
				ClrWdt(); // reset the WDT timer
			}
		}
	}

	ADC_zero(); // ground ADC input
	ClrWdt(); // reset the WDT timer
}
//reads and returns the current
long checkcurrent()
{
	/*//code for original current sensor
	int currentCH0 = 0, currentCH1 = 0, current = 0;
	unsigned char interruptstatus;
	/////////CURRENT///////////
	//get the channel 0 current
	//ensure that interrupts are disabled while doing the conversion
	interruptstatus = GLOBALINTERRUPTS;
	GLOBALINTERRUPTS = INTERRUPTDISABLE;
	SetChanADC(ADC_CH0);
	
	//From dale's code for the shunt current sensor
	currentCH0 = ((float) (read15bitOversample()  - 7.3284) * 0.001515656734 )* 100;      // Calculated new gains on 1/4/2012
	
	SetChanADC(ADC_CH1);
	currentCH1 = ((float) (read15bitOversample()  - 7.3284) * 0.001515656734 )* 100;      // Calculated new gains on 1/4/2012
	//enable interrupts until next conversion
	GLOBALINTERRUPTS = interruptstatus;
		
	//determine which value to use
	currentCH0 = currentCH0 - channelZeroInitial;
	currentCH1 = currentCH1 - channelOneInitial; //I am considering channel 1 to be the negative current direction
	if(currentCH0 >= 0 && currentCH1 >= 0)
	{
		//if both are positive we will just use the higher value (for now)
		if(currentCH0 > currentCH1)
			current = currentCH0;
		else
			current = -currentCH1;
	}
	else if(currentCH0 <= 0 && currentCH1 <= 0) current = 0;
	else if(currentCH0 <= 0 && currentCH1 >= 0) current = -currentCH1; //go with the positive value
	else if(currentCH0 >= 0 && currentCH1 <= 0) current = currentCH0;
	else current = 0;//just a default case
	
	
	return current;//*/

/////////////////////////////////////////////////////////////////////////////////////
	//*//The following code works for the HAIS 50 P hall effect current sensor.
    //On current sensor: yellow wire is voltage reference of 2.5, and white wire is Vout
	// Code written on the 2012 race by Jimmy Frilling
	// Inserted into this master BPS code on 29-Apr-2013
	//Edited by Daniel Cambron on 1-May-2013
	//int currentCH0 = 0, currentCH1 = 0;
	unsigned char interruptstatus;
	int k = 0;
	long result = 0;	//return the final answer
	signed long int adcval = 0;	//need a long to store the value (long is 32 bits)
	signed long int ref = 0;
	long average = 0;
	
	//Calibration 1-May-2013 Daniel Cambron
	//tests show that Vout-Vref = 0.00001253*current in mA 
	//current in mA = (4.5/1024)*(average adc value)/.00001253 + 470
	// or approximately 348.477*(average adc value) + 470
	// instead of dividing to get the average adc value, we just run the loop 1024 times and find the sum, 
    // and then multiply the number down to 348.48.    348.48 = 1024 * 0.3403095, 
	//so run the loop 1024 times and multiply by 0.3403095 at the end 
	interruptstatus = GLOBALINTERRUPTS;
	GLOBALINTERRUPTS = INTERRUPTDISABLE;
	for(k=0;k<1024;++k){
		SetChanADC(ADC_CH1);	//channel has the voltage reference for the current sensor
      	ConvertADC();			//tell the ADC to run once
       	while(BusyADC());		//wait until the conversion is finished
       	ref = ReadADC();	//store the value that was converted into result
		SetChanADC(ADC_CH0);	//channel has the current sensor value
      	ConvertADC();			//tell the ADC to run once
       	while(BusyADC());		//wait until the conversion is finished
       	adcval = ReadADC();	//store the value that was converted into result
		average += adcval - ref;
	}
	GLOBALINTERRUPTS = interruptstatus;
	result = average;
	//a calibration offset of 470 mA, and a factor of 0.3403095197
	result = ( (float)result * 0.3403) + 470;

	if(result > CUTOFF_CURRENT_HIGH || result < CUTOFF_CURRENT_LOW){
		failure(CURRENTERR, 0xFF, result, 0x00);
	}
	return result;	
}
Exemple #23
0
void main(void) {
    char c;
    signed char length;
    unsigned char msgtype;
    unsigned char last_reg_recvd;
    uart_comm uc;
    i2c_comm ic;
    unsigned char msgbuffer[MSGLEN + 1];
    unsigned char i;
    uart_thread_struct uthread_data; // info for uart_lthread
    timer1_thread_struct t1thread_data; // info for timer1_lthread
    timer0_thread_struct t0thread_data; // info for timer0_lthread

#ifdef __USE18F2680
    OSCCON = 0xFC; // see datasheet
    // We have enough room below the Max Freq to enable the PLL for this chip
    OSCTUNEbits.PLLEN = 1; // 4x the clock speed in the previous line
#else
#ifdef __USE18F45J10
    OSCCON = 0x82; // see datasheeet
    OSCTUNEbits.PLLEN = 1; // Makes the clock exceed the PIC's rated speed if the PLL is on
#else
#ifdef __USE18F26J50
    OSCCON = 0xE0; // see datasheeet
    OSCTUNEbits.PLLEN = 1;
#else
#ifdef __USE18F46J50
    OSCCON = 0xE0; //see datasheet
    OSCTUNEbits.PLLEN = 1;
#else
    Something is messed up.
    The PIC selected is not supported or the preprocessor directives are wrong.
#endif
#endif
#endif
#endif

    // initialize my uart recv handling code
    init_uart_recv(&uc);

    // initialize the i2c code
    init_i2c(&ic);

    // init the timer1 lthread
    init_timer1_lthread(&t1thread_data);

    // initialize message queues before enabling any interrupts
    init_queues();

#ifndef __USE18F26J50
    // set direction for PORTB to output
    LATB = 0x0;
    TRISB = 0x07;

    PORTA = 0x0;
    LATA = 0x0;
    TRISA = 0x0F;
//
//    PORTE = 0x0;
//    LATE = 0x0;
//    TRISE = 0x0F;
//
//    PSPMODE = 0x0;
#endif

    // how to set up PORTA for input (for the V4 board with the PIC2680)
    /*
            PORTA = 0x0;	// clear the port
            LATA = 0x0;		// clear the output latch
            ADCON1 = 0x0F;	// turn off the A2D function on these pins
            // Only for 40-pin version of this chip
            CMCON = 0x07;	// turn the comparator off
            TRISA = 0x0F;	// set RA3-RA0 to inputs
     */

    // initialize Timers
    OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_64);

#ifdef __USE18F26J50
    // MTJ added second argument for OpenTimer1()
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
#ifdef __USE18F46J50
    OpenTimer1(TIMER_INT_ON & T1_SOURCE_FOSC_4 & T1_PS_1_8 & T1_16BIT_RW & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF,0x0);
#else
    OpenTimer1(TIMER_INT_ON & T1_8BIT_RW & T1_PS_1_1 & T1_SOURCE_INT & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF);
#endif
#endif

    // Decide on the priority of the enabled peripheral interrupts
    // 0 is low, 1 is high

    // ADC interrupt
    IPR1bits.ADIP = 0;
    PIE1bits.ADIE = 1;
    // Timer1 interrupt
    IPR1bits.TMR1IP = 0;
    // USART RX interrupt
    IPR1bits.RCIP = 0;
    // I2C interrupt
    IPR1bits.SSPIP = 1;

    // configure the hardware i2c device as a slave (0x9E -> 0x4F) or (0x9A -> 0x4D)
#if 1
    // Note that the temperature sensor Address bits (A0, A1, A2) are also the
    // least significant bits of LATB -- take care when changing them
    // They *are* changed in the timer interrupt handlers if those timers are
    //   enabled.  They are just there to make the lights blink and can be
    //   disabled.
    i2c_configure_slave(0x9E);
#else
    // If I want to test the temperature sensor from the ARM, I just make
    // sure this PIC does not have the same address and configure the
    // temperature sensor address bits and then just stay in an infinite loop
    i2c_configure_slave(0x9A);
#ifdef __USE18F2680
    LATBbits.LATB1 = 1;
    LATBbits.LATB0 = 1;
    LATBbits.LATB2 = 1;
#endif
    for (;;);
#endif

    // must specifically enable the I2C interrupts
    PIE1bits.SSPIE = 1;

    // configure the hardware USART device
#ifdef __USE18F26J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
               USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else
#ifdef __USE18F46J50
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
               USART_CONT_RX & USART_BRGH_LOW, 0x19);
#else/*
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
        USART_CONT_RX & USART_BRGH_LOW, 0x19);
    TRISCbits.RC6 = 1; //TX pin set as output
    TRISCbits.RC7 = 1; //RX pin set as input
    WriteUSART(0x00);
    WriteUSART(0x01);
    WriteUSART(0x02);
    WriteUSART(0x03);*/
#endif
#endif

    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT &
              USART_CONT_RX & USART_BRGH_LOW, 38);
    TRISCbits.RC6 = 0; //TX pin set as output
    TRISCbits.RC7 = 1; //RX pin set as input
    //char data = 0x05;
    //WriteUSART(data);
    //while(BusyUSART());
    //WriteUSART(data);
    //WriteUSART(0x05);
    //WriteUSART(0x05);
    //putsUSART(0x00);
//    while(BusyUSART());
//    putsUSART(0x05);
//    while(BusyUSART());
//    putsUSART(0x05);
//    while(BusyUSART());
//    putsUSART(0x05);
    // Peripheral interrupts can have their priority set to high or low
    // enable high-priority interrupts and low-priority interrupts
    enable_interrupts();

    /* Junk to force an I2C interrupt in the simulator (if you wanted to)
    PIR1bits.SSPIF = 1;
    _asm
    goto 0x08
    _endasm;
     */

    // printf() is available, but is not advisable.  It goes to the UART pin
    // on the PIC and then you must hook something up to that to view it.
    // It is also slow and is blocking, so it will perturb your code's operation
    // Here is how it looks: printf("Hello\r\n");

    OpenADC(ADC_FOSC_16 & ADC_LEFT_JUST & ADC_2_TAD,
            ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,
            0b1011);
    SetChanADC(ADC_CH0);



    // ADC_CALIB();

    // loop forever
    // This loop is responsible for "handing off" messages to the subroutines
    // that should get them.  Although the subroutines are not threads, but
    // they can be equated with the tasks in your task diagram if you
    // structure them properly.
    while (1) {
        // Call a routine that blocks until either on the incoming
        // messages queues has a message (this may put the processor into
        // an idle mode)
        block_on_To_msgqueues();

        // At this point, one or both of the queues has a message.  It
        // makes sense to check the high-priority messages first -- in fact,
        // you may only want to check the low-priority messages when there
        // is not a high priority message.  That is a design decision and
        // I haven't done it here.
        length = ToMainHigh_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // This case be handled by your code.
            }
        } else {
            switch (msgtype) {
            case MSGT_TIMER0:
            {
                timer0_lthread(&t0thread_data, msgtype, length, msgbuffer);
                break;
            };
            case MSGT_I2C_DATA:
            case MSGT_I2C_DBG:
            {
                // Here is where you could handle debugging, if you wanted
                // keep track of the first byte received for later use (if desired)
                last_reg_recvd = msgbuffer[0];
                break;
            };
            case MSGT_I2C_RQST:
            {
                // Generally, this is *NOT* how I recommend you handle an I2C slave request
                // I recommend that you handle it completely inside the i2c interrupt handler
                // by reading the data from a queue (i.e., you would not send a message, as is done
                // now, from the i2c interrupt handler to main to ask for data).
                //
                // The last byte received is the "register" that is trying to be read
                // The response is dependent on the register.
                switch (last_reg_recvd) {
                case 0xaa:
                {
                    length = 2;
                    ConvertADC();
                    while( BusyADC()) {
                        //LATBbits.LATB0 = 1;
                    }
                    msgbuffer[0] = ADRESH;
                    msgbuffer[1] = 0xAA;
                    break;
                }
                case 0xa8:
                {
                    length = 1;
                    msgbuffer[0] = 0x3A;
                    break;
                }
                case 0xa9:
                {
                    length = 1;
                    msgbuffer[0] = 0xA3;
                    break;
                }
                };
                start_i2c_slave_reply(length, msgbuffer);
                break;
            };
            default:
            {
                break;
            };
            };
        }

        // Check the low priority queue
        length = ToMainLow_recvmsg(MSGLEN, &msgtype, (void *) msgbuffer);
        if (length < 0) {
            // no message, check the error code to see if it is concern
            if (length != MSGQUEUE_EMPTY) {
                // Your code should handle this situation
            }
        } else {
            switch (msgtype) {
            case MSGT_TIMER1:
            {
                timer1_lthread(&t1thread_data, msgtype, length, msgbuffer);
                break;
            };
            case MSGT_OVERRUN:
            case MSGT_UART_DATA:
            {
                uart_lthread(&uthread_data, msgtype, length, msgbuffer);
                break;
            };
            default:
            {
                // Your code should handle this error
                break;
            };
            };
        }
    }

}
void main (void)
{
	/*
		Define Variables ---------------------------------------------------------------------
	*/
	// I2C/MSG Q variables
	char c;		// Is this used?
	signed char	length;
	unsigned char	msgtype;
	unsigned char last_reg_recvd;
	i2c_comm ic;
	//unsigned char msgbuffer[MSGLEN+1];
	unsigned char msgbuffer[12];
	unsigned char i;
	int I2C_buffer[];
	int index = 0;
	int ITR = 0;
	int I2C_RX_MSG_COUNT = 0;
	int I2C_RX_MSG_PRECOUNT = 0;
	int I2C_TX_MSG_COUNT = 1;

	// Timer variables
	timer1_thread_struct t1thread_data; 	// info for timer1_lthread
	timer0_thread_struct t0thread_data; 	// info for timer0_lthread
	int timer_on = 1;
	int timer2Count0 = 0, timer2Count1 = 0;

	// UART variables
	uart_comm uc;
	//uart_thread_struct	uthread_data; 		// info for uart_lthread


	// ADC variables
	int ADCVALUE = 0;
	int adc_counter = 0;
	int adc_chan_num = 0;
	int adcValue = 0;
	int count = 0;

	// MIDI variable
	char notePlayed;

	/*
		Initialization ------------------------------------------------------------------------
	*/
	

	// Clock initialization
	OSCCON = 0x7C; // 16 MHz	// Use for internal oscillator	
	OSCTUNEbits.PLLEN = 1; 		// 4x the clock speed in the previous line
	
	
	// UART initialization
	init_uart_recv(&uc);		// initialize my uart recv handling code
	// configure the hardware USART device
  	Open2USART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT   & 
		USART_CONT_RX & USART_BRGH_LOW, 31);
	Open1USART( USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT   & 
		USART_CONT_RX & USART_BRGH_LOW, 51);

	//RCSTA1bits.CREN = 1;
	//RCSTA1bits.SPEN = 1;
	//TXSTA1bits.SYNC = 0;
	//PIE1bits.RC1IE = 1;
	IPR1bits.RC1IP = 0;
	
	// I2C/MSG Q initialization
	init_i2c(&ic);				// initialize the i2c code
	init_queues();				// initialize message queues before enabling any interrupts
	i2c_configure_slave(0x9E);	// configure the hardware i2c device as a slave

	// Timer initialization
	init_timer1_lthread(&t1thread_data);	// init the timer1 lthread
	OpenTimer0( TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_8);
	OpenTimer2( TIMER_INT_ON & T2_PS_1_16 /*& T2_8BIT_RW & T2_SOURCE_INT & T2_OSC1EN_OFF & T2_SYNC_EXT_OFF*/); // Turn Off
// ADC initialization
	// set up PORTA for input
	PORTA = 0x0;	// clear the port
	LATA = 0x0;		// clear the output latch
	TRISA = 0xFF;	// set RA3-RA0 to inputs
	ANSELA = 0xFF;	
	initADC();

	// Interrupt initialization
	// Peripheral interrupts can have their priority set to high or low
	// enable high-priority interrupts and low-priority interrupts
	enable_interrupts();
	// Decide on the priority of the enabled peripheral interrupts, 0 is low 1 is high
	IPR1bits.TMR1IP = 0;		// Timer1 interrupt
	//IPR1bits.RCIP = 0;			// USART RX interrupt
	IPR1bits.SSP1IP = 1;			// I2C interrupt
	PIE1bits.SSP1IE = 1;			// must specifically enable the I2C interrupts
	IPR1bits.ADIP = 1;			// ADC interrupt WE ADDED THIS

	
	// set direction for PORTB to output
	TRISB = 0x0;
	TRISD = 0xFF;
	LATB = 0x0;
	ANSELC = 0x00;


	/*
		Hand off messages to subroutines -----------------------------------------------------------
	*/
	// This loop is responsible for "handing off" messages to the subroutines
	// that should get them.  Although the subroutines are not threads, but
	// they can be equated with the tasks in your task diagram if you 
	// structure them properly.
  	while (1) {
		// Call a routine that blocks until either on the incoming
		// messages queues has a message (this may put the processor into
		// an idle mode
		block_on_To_msgqueues();
		/*
			High Priority MSGQ ----------------------------------------------------------------------
		*/
		
		// At this point, one or both of the queues has a message.  It 
		// makes sense to check the high-priority messages first -- in fact,
		// you may only want to check the low-priority messages when there
		// is not a high priority message.  That is a design decision and
		// I haven't done it here.
		length = ToMainHigh_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
				//printf("Error: Bad high priority receive, code = %x\r\n", length);
			}
		} else {
			switch (msgtype) {
				case MSGT_ADC:	{				
					// Format I2C msg
					msgbuffer[6] = (timer2Count0 & 0x00FF);
					msgbuffer[5] = (timer2Count0 & 0xFF00) >> 8;
					msgbuffer[4] = (timer2Count1 & 0x00FF);
					msgbuffer[3] = (timer2Count1 & 0xFF00) >> 8;

					msgbuffer[8] = 0x00;
					msgbuffer[10] = adc_chan_num;
					msgbuffer[11] = 0xaa;			// ADC MSG opcode
					
					// Send I2C msg
					FromMainHigh_sendmsg(12, msgtype, msgbuffer);	// Send ADC msg to FromMainHigh MQ, which I2C
																	// int hdlr later Reads

					
					// Increment I2C message count from 1 to 100
					if(I2C_TX_MSG_COUNT < 100)	{
						I2C_TX_MSG_COUNT = I2C_TX_MSG_COUNT + 1;
					}
					else	{
						I2C_TX_MSG_COUNT = 1;
					}

					// Increment the channel number
					if(adc_chan_num <= 4)	adc_chan_num++;
					else	adc_chan_num = 0;
					// Set ADC channel based off of channel number
					if(adc_chan_num == 0)	SetChanADC(ADC_CH0);
					else if(adc_chan_num == 1)	SetChanADC(ADC_CH1);
					else if(adc_chan_num == 2)	SetChanADC(ADC_CH2);
					else if(adc_chan_num == 3)	SetChanADC(ADC_CH3);
					else if(adc_chan_num == 4)	SetChanADC(ADC_CH4);
					else	SetChanADC(ADC_CH5);
				};
				case MSGT_TIMER0: {
					timer0_lthread(&t0thread_data,msgtype,length,msgbuffer);

					break;
				};
				case MSGT_TIMER2:	{
					timer2Count0++;
					if(timer2Count0 >= 0xFFFF)	{	
						timer2Count1++;
						timer2Count0 = 0;
					}

					break;
				}

				case MSGT_I2C_DATA: { //this data still needs to be put in a buffer
;

						if(msgbuffer[0] == 0xaf)	{
						//FromMainLow_sendmsg(5, msgtype, msgbuffer);
						// The code below checks message 'counts' to see if any I2C messages were dropped
						//I2C_RX_MSG_COUNT = msgbuffer[4];
						
							FromMainLow_sendmsg(9, msgtype, msgbuffer);						
							TXSTA2bits.TXEN = 1;
	/*
							// Send note data to the MIDI device
							//while(Busy2USART());
							putc2USART(msgbuffer[1]);
							//while(Busy2USART());
							Delay1KTCYx(8);
							putc2USART(msgbuffer[2]);
							//while(Busy2USART());
							Delay1KTCYx(8);		
							putc2USART(msgbuffer[3]);
	*/
	
							if(I2C_RX_MSG_COUNT - I2C_RX_MSG_PRECOUNT == 1)	{
								if(I2C_RX_MSG_PRECOUNT < 99)	{
									I2C_RX_MSG_PRECOUNT++;
								}
								else	{
									I2C_RX_MSG_PRECOUNT = 0;
								}
							}
							else	{
								I2C_RX_MSG_PRECOUNT = I2C_RX_MSG_COUNT;
							}
						}
				};
				
	`			
				case MSGT_I2C_DBG: {
					//printf("I2C Interrupt received %x: ",msgtype);
					for (i=0;i<length;i++) {
						//printf(" %x",msgbuffer[i]);
					}
					//printf("\r\n");
					// keep track of the first byte received for later use
					last_reg_recvd = msgbuffer[0];
					break;
				};
				case MSGT_I2C_RQST: {
					//printf("I2C Slave Req\r\n");
					// The last byte received is the "register" that is trying to be read
					// The response is dependent on the register.
					switch (last_reg_recvd) {
						case 0xaa: {
							break;
						}
						/*
						case 0xa8: {
							length = 1;
							msgbuffer[0] = 0x3A;
							break;
						}					
						case 0xa9: {
							length = 1;
							msgbuffer[0] = 0xA3;
							break;
						}*/
					};
					//start_i2c_slave_reply(length,msgbuffer);
					break;
				};
				default: {
					//printf("Error: Unexpected msg in queue, type = %x\r\n", msgtype);
					break;
				};
			};
		}

		/*
			Low Priority MSGQ -----------------------------------------------------------------------
		*/
		
		length = ToMainLow_recvmsg(MSGLEN,&msgtype,(void *) msgbuffer);
		if (length < 0) {
			// no message, check the error code to see if it is concern
			if (length != MSGQUEUE_EMPTY) {
			
			}
		} else {
			switch (msgtype) {
				
				case MSGT_TIMER1: {
					timer1_lthread(&t1thread_data,msgtype,length,msgbuffer);
					break;
				};
				case MSGT_OVERRUN:
				case MSGT_UART_DATA: 
				{
					LATB = 0xFF;
					msgbuffer[11] = 0xBB;
					FromMainHigh_sendmsg(12, msgtype, msgbuffer);
					
					break;
				};
				default: {
					
					break;
				};
			};
		}
 	 }
void adc_int_handler(unsigned char *adcbuffer){
    // adcbuffer[0] stores the count
    if(adcbuffer[0] < 30)                 // increment counter
        adcbuffer[0] = adcbuffer[0] + 1;
    else
        adcbuffer[0] = 0;
    // ADRESL less significant, but is more accurate than our resolution

    int voltage = (int)ADRESH;




//    float voltage = 3.4*k/256;
//    int roundDist;
//    if (voltage > .7) {
//        float dist = 24/(voltage - 0.1);
//        roundDist = (int)(dist + 0.5);
//    }
//    else
//        roundDist = 0xFF;

/*
    if (adcbuffer[0] == 1){
        adcbuffer[3] = roundDist;
        SetChanADC(ADC_CH1);
    }
    else if (adcbuffer[0] == 2){
        adcbuffer[1] = roundDist;
        SetChanADC(ADC_CH2);
    }
    else if (adcbuffer[0] == 3){
        adcbuffer[2] = roundDist;
        SetChanADC(ADC_CH3);
    }
    */


    ////////Low///////////
    // > 48 too close for front
    // 00 is an error code
    // 1 is too close < 28 cm > 4C for channel 2      > 4C for channel 3
    // 3 is too far, ignore for front > 32 cm  < 45 for channel       2 < 46 for channel 3
    // 2 is correct

    //////////High////////
    // > 5C too close for front
    // 00 is an error code
    // 1 is too close < 28 cm > 5D for channel 2      > 5F for channel 3
    // 3 is too far, ignore for front > 32 cm  < 58 for channel 2    < 59 for channel 3
    // 2 is correct

    // Greater than 4.2 volts for on the ground
    ///////////////////////////////////////////////////////////////////////////

    int channel = (int)adcbuffer[0];
    int line = (int)adcbuffer[0] % 3;
    unsigned char output;

    if (channel == 0) {
            LATBbits.LATB3 = 0x01;
        if (voltage < 0x4F) {
            adcbuffer[4] = 0x01;
        }
        else
            adcbuffer[4] = 0x00;
        SetChanADC(ADC_CH0);
    }
    else if (channel == 1) {
        if (ADRESH > 0x68) //if (ADRESH > 0x55)
            output = 0x01;
        else
            output = 0x02;
        if (output != adcbuffer[1]) {
            if (output == adcbuffer[8]) {
                adcbuffer[1] = output;
                adcbuffer[8] = 0xFF;
            }
            else
                adcbuffer[8] = output;
        }
        else {
            adcbuffer[8] = 0xFF;
            adcbuffer[1] = output;
        }
        SetChanADC(ADC_CH10);
    }
    else if (channel == 10) {
            LATBbits.LATB3 = 0x01;
        if (voltage < 0x4F) {
            adcbuffer[4] = 0x01;
        }
        else
            adcbuffer[4] = 0x00;
        SetChanADC(ADC_CH1);
    }
    else if (channel == 11) {
        if (ADRESH - 4 > adcbuffer[2] || ADRESH + 4 < adcbuffer[2]) {
            if (ADRESH - 2 < adcbuffer[9] && ADRESH + 2 > adcbuffer[9]) {
                adcbuffer[2] = ADRESH;
                adcbuffer[9] = 0xFF;
            }
            else
                adcbuffer[9] = ADRESH;
        }
        else {
            adcbuffer[9] = 0xFF;
            adcbuffer[2] = ADRESH;
        }
        SetChanADC(ADC_CH12);
    }
    else if (channel == 20) {
            LATBbits.LATB3 = 0x01;
        if (voltage < 0x4F) {
            adcbuffer[4] = 0x01;
        }
        else
            adcbuffer[4] = 0x00;
        SetChanADC(ADC_CH2);
    }
    else if (channel == 21) {
        if (ADRESH - 4 > adcbuffer[3] || ADRESH + 4 < adcbuffer[3]) {
            if (ADRESH - 2 < adcbuffer[10] && ADRESH + 2 > adcbuffer[10]) {
                adcbuffer[3] = ADRESH;
                adcbuffer[10] = 0xFF;
            }
            else
                adcbuffer[10] = ADRESH;
        }
        else {
            adcbuffer[10] = 0xFF;
            adcbuffer[3] = ADRESH;
        }
        SetChanADC(ADC_CH8);
    }
    else {
        TXREG = voltage;
        if (line == 0) {
            LATBbits.LATB3 = 0x01;
            if (voltage < 0x4F) {
                adcbuffer[4] = 0x01;
            }
            else
                adcbuffer[4] = 0x00;
            SetChanADC(ADC_CH8);
        }
        else if (line == 1) {
            LATBbits.LATB4 = 0x01;
            if (voltage < 0x4F) {
                adcbuffer[5] = 0x01;
            }
            else
                adcbuffer[5] = 0x00;
            SetChanADC(ADC_CH10);
        }
        else{
            LATBbits.LATB5 = 0x01;
            if (voltage < 0x4F) {
                adcbuffer[6] = 0x01;
            }
            else
                adcbuffer[6] = 0x00;
            SetChanADC(ADC_CH12);
        }
    }
    if((adcbuffer[4] == 0x01) && (adcbuffer[5] == 0x01) && (adcbuffer[6] == 0x01)) {
        adcbuffer[7] = 0x01;
    }
    LATBbits.LATB3 = 0x00;
    LATBbits.LATB4 = 0x00;
    LATBbits.LATB5 = 0x00;
    ///////////////////////////////////////////////////////////////////////////

    /*
    if (channel == 0) {
        if (voltage < 3)
            adcbuffer[4] = 0x01;
        else
            adcbuffer[4] = 0x00;
        SetChanADC(ADC_CH1);
    }
    else if (channel == 1) {
    if (((int)roundDist - 4 > (int)adcbuffer[1]) || ((int)roundDist + 4 < (int)adcbuffer[1])) {
        if (((int)roundDist - 4 > (int)adcbuffer[8]) || ((int)roundDist + 4 < (int)adcbuffer[8])) {
            adcbuffer[1] = roundDist;
            adcbuffer[8] = 0xFF;
        }
        else
            adcbuffer[8] = 0xFF;
    }
    else {
        adcbuffer[8] = 0xFF;
        adcbuffer[1] = roundDist;
    }
        //adcbuffer[1] = roundDist;
        TXREG = adcbuffer[1];
        SetChanADC(ADC_CH6);
    }
    else if (channel == 10) {
        if (voltage < 3)
            adcbuffer[4] = 0x01;
        else
            adcbuffer[4] = 0x00;
        SetChanADC(ADC_CH2);
    }
    else if (channel == 11) {
        if (((int)roundDist - 4 > (int)adcbuffer[2]) || ((int)roundDist + 4 < (int)adcbuffer[2])) {
            if (((int)roundDist - 4 > (int)adcbuffer[9]) || ((int)roundDist + 4 < (int)adcbuffer[9])) {
                adcbuffer[2] = roundDist;
                adcbuffer[9] = 0xFF;
            }
            else
                adcbuffer[9] = 0xFF;
        }
        else {
            adcbuffer[9] = 0xFF;
            adcbuffer[2] = roundDist;
        }
        //adcbuffer[2] = roundDist;
        SetChanADC(ADC_CH7);
    }
    else if (channel == 20) {
        if (voltage < 3)
            adcbuffer[4] = 0x01;
        else
            adcbuffer[4] = 0x00;
        SetChanADC(ADC_CH3);
    }
    else if (channel == 21) {
        if (((int)roundDist - 4 > (int)adcbuffer[1]) || ((int)roundDist + 4 < (int)adcbuffer[1])) {
            if (((int)roundDist - 4 > (int)adcbuffer[8]) || ((int)roundDist + 4  (int)adcbuffer[8])) {
                adcbuffer[3] = roundDist;
                adcbuffer[10] = 0xFF;
            }
            else
                adcbuffer[10] = 0xFF;
        }
        else {
            adcbuffer[10] = 0xFF;
            adcbuffer[3] = roundDist;
        }

        //adcbuffer[3] = roundDist;
        SetChanADC(ADC_CH5);
    }
    else {
        if (line == 0) {
            if (voltage < 3)
                adcbuffer[4] = 0x01;
            else
                adcbuffer[4] = 0x00;
            SetChanADC(ADC_CH5);
        }
        else if (line == 1) {
            if (voltage < 3)
                adcbuffer[5] = 0x01;
            else
                adcbuffer[5] = 0x00;
            SetChanADC(ADC_CH6);
        }
        else{
            if (voltage < 3)
                adcbuffer[6] = 0x01;
            else
                adcbuffer[6] = 0x00;
            SetChanADC(ADC_CH7);
        }
    }*/
}