예제 #1
0
//Display the Temperature on the LCD
void displayTemp(void* args) 
{	
	//String constants
	const uint8_t LCDTemp[5] = "TEMP\0";
	
	//LCD locations
	const uint8_t T_FOOD_REF_LOC = 0;
	const uint8_t T_FOOD = 5;
	
	uint8_t tempRefLen;
	uint8_t tempLen;
	float localTemp;
	float localTempRef;
	
	//String buffers
	uint8_t LCDTempRef[4];
	uint8_t LCDTempMeas[5];
	
	//flags indicating whether a variable needs to be updated
	uint8_t updateTempRefRef;
	
	//make local copies of the system parametes
	trtWait(SEM_T_REF);
	localTempRef = waterTempRef;
	trtSignal(SEM_T_REF);
	
	trtWait(SEM_T);
	localTemp = waterTemp;
	trtSignal(SEM_T);
	
	trtWait(SEM_THICKNESS);
	float localThickness = thickness;
	trtSignal(SEM_THICKNESS);
	
	trtWait(SEM_MAT_PROP);
	float localK = k;
	trtSignal(SEM_MAT_PROP);
	
	LCDGotoXY(0,0);
	LCDstring(LCDTemp, 4);
	
	uint32_t rel, dead;
	while(1){
		//trtWait(SEM_T_WATER);
		//trtSignal(SEM_T_WATER);

		
		sprintf(LCDTempMeas, "%f", localTemp);
		LCDGotoXY(0, 0);
		LCDstring(LCDTempMeas, 5);
		
		rel = trtCurrentTime() + SECONDS2TICKS(0.2);
		dead = trtCurrentTime() + SECONDS2TICKS(0.225);
		trtSleepUntil(rel, dead);
	}
}
예제 #2
0
파일: segBot.c 프로젝트: avh34/ECE-4760
void serialTask(void* args)
{
	char  cmd[4];
	float num = 0;

	while(1)
	{
		fscanf(stdin, "%s %f", cmd, &num);

		if (cmd[0] == 's') {
			/* Set desired motor speed */
			trtWait  (SEM_S);
			s = num;
			trtSignal(SEM_S);

			/* Statment confirming the new speed is printed. */
			fprintf(stdout, "\n\rDesired motor speed is now %.2f\n\r\n\r", (double) num);
		}
		else if (cmd[0] == 'p') {
			/* Set proportional gain */
			trtWait  (SEM_P);
			p = num;
			trtSignal(SEM_P);

			/* Statment confirming the new proportional gain is printed. */
			fprintf(stdout, "\n\rProportional gain is now %.2f\n\r\n\r", (double) num);
		}
		else if (cmd[0] == 'i') {
			/* Set integral gain */
			trtWait  (SEM_I);
			i = num;
			trtSignal(SEM_I);

			/* Statment confirming the new integral gain is printed. */
			fprintf(stdout, "\n\rIntegral gain is now %.2f\n\r\n\r", (double) num);
		}
		else if (cmd[0] == 'd') {
			/* Set differential gain */
			trtWait  (SEM_D);
			d = num;
			trtSignal(SEM_D);

			/*Statment confirming the new differential gain is printed.*/
			fprintf(stdout, "\n\rDifferential gain is now %.2f\n\r\n\r", (double) num);
		}

	}

}
예제 #3
0
파일: code.c 프로젝트: shanesoh/pulso
// Read the right sonar
void readSonar2(void* args) 
{
	uint32_t rel, dead ;
	uint8_t sonar_adc2;

	while(1)
	{
		if (firstRun == 0) // not the first run of this task
		{
			trtWait(SEM_RANGE);

			//turn on RX of sonar2
			PORTC = PORTC ^ 0x04;
			_delay_ms(50);	

			// read ADC1 and convert to meters
			sonar_adc2 = adc_read(1); 
			sonarR_range = (float)sonar_adc2 * 0.0508;// (5/256)*(512/5)*.0254 * adc reading

			//turn off RX
			PORTC = PORTC ^ 0x04;
			_delay_ms(20);
		
			trtSignal(SEM_RANGE);

			// Save ranges
			rangeR[((iR++)%windowSize)] = sonarR_range;
		} // end of -- if (firstRun == 0)

		// Sleep
		rel = trtCurrentTime() + SECONDS2TICKS(sonarFreq);
		dead = trtCurrentTime() + SECONDS2TICKS(sonarFreq);
		trtSleepUntil(rel, dead);
	} // end of -- while(1)
} 
예제 #4
0
//==============================================================
// trtLockMutex
// LOCK and record owner 
// If already LOCKED, force a context switch
void trtLockMutex(uint8_t mutex_number){
	cli();
	// if not locked
	if (mutex[mutex_number].state == UNLOCKED){
		mutex[mutex_number].state = LOCKED ;
		mutex[mutex_number].owner = kernel.running ;
	}//if (tmutex[mutex_number].state = UNLOCKED)
	else if (mutex[mutex_number].owner != kernel.running){
	 	trtWait(mutex_number) ;
	}
	sei();
} //void trtLockMutex(uint8_t mutex_number)
예제 #5
0
파일: code.c 프로젝트: shanesoh/pulso
// Read Sonar3, i.e. fwd sonar
void readSonar3(void* args) 
{
	uint32_t rel, dead ;
	uint8_t sonar_adc3;

	while(1)
	{
		if (firstRun) // not the first run of this task
		{
			// Calibrate front sensor
			calibrateFront();
			firstRun = 0;
		}

		if (firstRun == 0) // not the first run of this task
		{
			trtWait(SEM_RANGE);

			//turn on RX of sonar1
			PORTC = PORTC ^ 0x08;
			_delay_ms(50);	

			// read ADC0 and convert to meters
			sonar_adc3 = adc_read(2); 
			sonarF_range = (float)sonar_adc3 * 0.0508; // (5/256)*(512/5)*.0254 * adc reading

			//turn off RX
			PORTC = PORTC ^ 0x08;
			_delay_ms(20);
			
			trtSignal(SEM_RANGE);
	
			// Save ranges 
			rangeF[((iF++) % windowSize)] = sonarF_range;
		} // end of -- if (fristRun == 0)

		// Sleep
		rel = trtCurrentTime() + SECONDS2TICKS(sonarFreq);
		dead = trtCurrentTime() + SECONDS2TICKS(sonarFreq);
		trtSleepUntil(rel, dead);
	} // end of -- while(1)
}
예제 #6
0
//get input from the keypad
void keypadComm(void* args) {
	//uint8_t cmd0, cmd1, cmd2, cmd3;
	//float val0, val1, val2, val3;
	//uint8_t numParams;
	uint8_t key = getCurKey();
	uint8_t valBuffer[16];	// Input parameter buffer
	uint32_t valInt = 0;			// Input parameter - before the decimal place
	uint32_t valDec = 0;		// Input parameter after the decimal place
	uint32_t numAfterDecimal = 1; 
	uint8_t valLoc = 0;
	float val;				//The actual input value
	
	uint8_t beforeDecimal = 1;		//flag indicating whether or not the current
	//key comes before or after the decimal point
	
	while(1)
	{
		//If we aren't debouncing, scan the keypad and begin debouncing the signal
		if (!debouncing){
			debounce();
		}
		
		//Otherwise, finish debouncing the signal
		else {
			debounce();
		}
		
		if (waitingForInput) {
			switch (key){
				case 0x01:
				valBuffer[valLoc] = '1';
				if (beforeDecimal){
					valInt = valInt * 10 + 1;
				}
				else {
					valDec = valDec * 10 + 1;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x02:
				valBuffer[valLoc] = '2';
				if (beforeDecimal) {
					valInt = valInt * 10 + 2;
				}
				else {
					valDec = valDec * 10 + 2;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x03:
				valBuffer[valLoc] = '3';
				if (beforeDecimal) {
					valInt = valInt * 10 + 3;
				}
				else{
					valDec = valDec * 10 + 3;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x04:
				valBuffer[valLoc] = '4';
				if (beforeDecimal) {
					valInt = valInt * 10 + 4;
				}
				else{
					valDec = valDec * 10 + 4;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x05:
				valBuffer[valLoc] = '5';
				if (beforeDecimal) {
					valInt = valInt * 10 + 5;
				}
				else{
					valDec = valDec * 10 + 5;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x06:
				valBuffer[valLoc] = '6';
				if (beforeDecimal) {
					valInt = valInt * 10 + 6;
				}
				else{
					valDec = valDec * 10 + 6;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x07:
				valBuffer[valLoc] = '7';
				if (beforeDecimal) {
					valInt = valInt * 10 + 7;
				}
				else{
					valDec = valDec * 10 + 7;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x08:
				valBuffer[valLoc] = '8';
				if (beforeDecimal) {
					valInt = valInt * 10 + 8;
				}
				else{
					valDec = valDec * 10 + 8;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x09:
				valBuffer[valLoc] = '9';
				if (beforeDecimal) {
					valInt = valInt * 10 + 9;
				}
				else{
					valDec = valDec * 10 + 9;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x10:
				valBuffer[valLoc] = '0';
				if (beforeDecimal) {
					valInt = valInt * 10;
				}
				else{
					valDec = valDec * 10;
					numAfterDecimal *= 10;
				}
				valLoc++;
				break;
				case 0x0E:		//E ==> decimal
				valBuffer[valLoc] = '.';
				valLoc++;
				beforeDecimal = 0;
				case 0x0F:		//F ==> backspace
				valLoc--;
				if (beforeDecimal){
					valInt = valInt / 10;
				}
				else {
					if (valBuffer[valLoc] == '.'){
						valInt = valInt / 10;
						beforeDecimal = 1;
						numAfterDecimal = 1;
					}
					else {
						valDec = valDec / 10;
						numAfterDecimal /= 10;
					}
				}
				case 0x0D:		//D ==> enter
				waitingForInput = 0;
				val = valInt + (float)valDec / (float)numAfterDecimal;
				
				switch (mode){
					case INPUT_T_REF:
					trtWait(SEM_T_WATER_REF);
					waterTempRef = val;
					trtSignal(SEM_T_WATER_REF);
					break;
					
					case INPUT_THICKNESS:
					trtWait(SEM_THICKNESS);
					thickness = val;
					trtSignal(SEM_THICKNESS);
					break;
					
					case INPUT_MAT_PROP:
					trtWait(SEM_MAT_PROP);
					k = val;
					trtSignal(SEM_MAT_PROP);
					break;
				} 
				break;
			}
		}							
	}
}
예제 #7
0
//Actual tasks to complete
//PID Control Stuff...worry about this silt later
// --- define task 1  ----------------------------------------
void pidControl(void* args) 
{	
  	uint32_t rel, dead ; //relase and deadline times
	float error = 0;		//Calculated error
	float prevError = 0;	//previously calculated error
	float prevWaterTemp = 0; //previously measured motor frequency
	int8_t prevSign = 0;	//previously calculated sign of the error
	
	//Local copies of shared system parameters
	uint16_t localWaterTemp;	
	uint16_t localWaterTempRef;
	
	//PID parameters
	float k_p = 1.0, k_i = 0.0, k_d = 0.0;
	
	//Declarations for calculated values.
	int8_t sign = 0;
	int16_t derivative;
	int16_t output;
	int16_t integral = 0;
	
	uint8_t first = 1;
	
	//transduction constant for the LM34
	const float transductionConstant = 0.01; // V/degF	
	
	while(1)
	{
		//update the previous measuremtns
		if (!first){
			prevWaterTemp = localWaterTemp;
			prevSign = sign;
			prevError = error;
		}
		
		//poll the ADC and convert the voltage to a temperature
		Ain = ADCH;
		ADCSRA |= (1<<ADSC); //start another conversion
		voltage = (float)Ain;
		voltage = (voltage/256.0) * Vref;
		localWaterTemp = voltage * transductionConstant;
		
		//copy to global waterTemp
		trtWait(SEM_T_WATER);
		waterTemp = localWaterTemp; 
		trtSignal(SEM_T_WATER);
		
		//make local copies of the system parameters
		trtWait(SEM_T_WATER_REF);
		localWaterTempRef = waterTempRef;
		trtSignal(SEM_T_WATER_REF);
		
		//Proportional Error
		error = localWaterTempRef - localWaterTemp;
		
		//Integral Error
		
		//Get the current sign of the error
		if (!first) {
			if (error - prevError > 0){
				sign = 1;
			}
			else if (error - prevError < 0) {
				sign = -1;
			}
			else {
				sign = 0;
			}
		}
		
		//Update the integral of the error
		if (!first){
			if (sign == prevSign){
				integral += error;
			}
			else{
				integral = 0.8 * error;
			}
		}
		
		//Derivative Error
		if (!first) {
			derivative = error - prevError;
		}
		
		//determine what the output should be
		if (!first){
			output = k_p * error + k_i * integral + k_d * derivative;
		}
		else{
			output = k_p * error;
			first = 0;
		}
		
		//clamp the output between 0 and 255 so we can directly set OCR0A
		if (output < 0){
			OCR0A = 0;
		}
		else if (output > 255) {
			OCR0A = 255; //saturated the controller, turn the integrator off
			integral = 0;
		}
		else {
			OCR0A = output;
		}
		
		if (error > 0){
			//Turn the heating thing on
			PORTA |= 0x08; //Pin 3...???
		}
		else{
			//Turn the heating thing off
			PORTA &= ~0x08;
		}
		
		ADCSRA |= (1<<ADSC);
		//Set the task to execute again in 0.02 seconds.
		rel = trtCurrentTime() + SECONDS2TICKS(0.19);
	    dead = trtCurrentTime() + SECONDS2TICKS(0.21);
	    trtSleepUntil(rel, dead);
	}
}
예제 #8
0
파일: trtUart.c 프로젝트: HarrisonW/ECE4760
int
uart_getchar(FILE *stream)
{
  uint8_t c;
  char *cp, *cp2;
  static char b[RX_BUFSIZE];
  static char *rxp;

  if (rxp == 0)
    for (cp = b;;)
      {
	// --- trtWait added instead of loop_until wait
	trtWait(SEM_RX_ISR_SIGNAL) ; //loop_until_bit_is_set(UCSR0A, RXC0)
	if (UCSR0A & _BV(FE0))
	  return _FDEV_EOF;
	if (UCSR0A & _BV(DOR0))
	  return _FDEV_ERR;
	// -- added to take char from ISR ---
	  c = trt_rx_c ; //c = UDR0; -- CHANGED

	/* behaviour similar to Unix stty ICRNL */
	if (c == '\r')
	  c = '\n';
	if (c == '\n')
	  {
	    *cp = c;
	    uart_putchar(c, stream);
	    rxp = b;
		// --- added for TRT to signal string-end
		trtSignal(SEM_STRING_DONE); //added--to signal end of string
	    break;
	  }
	else if (c == '\t')
	  c = ' ';

	if ((c >= (uint8_t)' ' && c <= (uint8_t)'\x7e') ||
	    c >= (uint8_t)'\xa0')
	  {
	    if (cp == b + RX_BUFSIZE - 1)
	      uart_putchar('\a', stream);
	    else
	      {
		*cp++ = c;
		uart_putchar(c, stream);
	      }
	    continue;
	  }

	switch (c)
	  {
	  case 'c' & 0x1f:
	    return -1;

	  case '\b':
	  case '\x7f':
	    if (cp > b)
	      {
		uart_putchar('\b', stream);
		uart_putchar(' ', stream);
		uart_putchar('\b', stream);
		cp--;
	      }
	    break;

	  case 'r' & 0x1f:
	    uart_putchar('\r', stream);
	    for (cp2 = b; cp2 < cp; cp2++)
	      uart_putchar(*cp2, stream);
	    break;

	  case 'u' & 0x1f:
	    while (cp > b)
	      {
		uart_putchar('\b', stream);
		uart_putchar(' ', stream);
		uart_putchar('\b', stream);
		cp--;
	      }
	    break;

	  case 'w' & 0x1f:
	    while (cp > b && cp[-1] != ' ')
	      {
		uart_putchar('\b', stream);
		uart_putchar(' ', stream);
		uart_putchar('\b', stream);
		cp--;
	      }
	    break;
	  }
      }

  c = *rxp++;
  if (c == '\n')
    rxp = 0;

  return c;
}
예제 #9
0
//PID Control Stuff keep the water temperature constant
// --- define task 1  ----------------------------------------
void pidControl(void* args)
{
    uint32_t rel, dead ; //relase and deadline times
    int16_t error = 0;		//Calculated error
    int16_t prevError = 0;	//previously calculated error
    uint16_t prevTemp; //previously measured motor frequency
    int8_t prevSign =0 ;	//previously calculated sign of the error

    //Local copies of shared system parameters
    uint8_t localTemp = 0;
    uint8_t localTempRef;
    uint8_t localWaterTemp;
    uint8_t localWaterTempRef;
    float k_p = 7.1;
    float k_i = 0.11;
    float k_d = 0.68;

    //transduction constant for LM35
    float transductionConstant = 0.1;

    //Declarations for calculated values.
    int8_t sign = 0;
    int16_t derivative;
    int16_t output;
    int16_t integral = 0;

    uint8_t first = 1;

    DDRB = 0xff;
    PORTB = 0;
    while(1)
    {

        while (!startHeating) {
            trtWait(SEM_START_HEATING);
        }


        Ain = ADCH;
        voltage = (float)Ain;
        voltage = (voltage/256.0) * Vref;
        localWaterTemp = voltage * transductionConstant
                         //update the previous measuremtns
        if (!first) {
            prevTemp = localTemp;
            prevSign = sign;
            prevError = error;
        }



        localWaterTemp = 0;
        //make local copies of the system parameters
        trtWait(SEM_TEMP);
        waterTemp = localWaterTemp;
        trtSignal(SEM_TEMP);

        trtWait(SEM_TEMP_REF);
        localWaterTempRef = waterTempRef;
        trtSignal(SEM_TEMP_REF);

        //Proportional Error
        error = localWaterTempRef - localWaterTemp;

        //Integral Error

        //Get the current sign of the error
        if (!first) {
            if (error - prevError > 0) {
                sign = 1;
            }
            else if (error - prevError < 0) {
                sign = -1;
            }
            else {
                sign = 0;
            }
        }

        //Update the integral of the error
        if (!first) {
            if (sign == prevSign) {
                integral += error;
            }
            else {
                integral = 0;
            }
        }

        //Derivative Error
        if (!first) {
            derivative = error - prevError;
        }

        //determine what the output should be
        if (!first) {
            output = k_p * error + k_i * integral + k_d * derivative;
        }
        else {
            output = k_p * error;
            first = 0;
        }

        //clamp the output between 0 and 255 so we can directly set OCR0A
        if (output < 0) {
            OCR0A = 0;
        }
        else if (output > 255) {
            OCR0A = 255;
        }
        else {
            OCR0A = output;
        }

        ADCSRA |= (1<<ADSC); //start another converstion
        //Set the task to execute again in 0.02 seconds.
        rel = trtCurrentTime() + SECONDS2TICKS(0.02);
        dead = trtCurrentTime() + SECONDS2TICKS(0.025);
        trtSleepUntil(rel, dead);
    }
}
예제 #10
0
// --- define a task for making sonar measurements
void sonar(void* args) {
    uint32_t rel, dead ; //relase and deadline times
    uint8_t threshold = 5;	//cm, If a new value differs by this much, assume the
    //food was put in

    uint8_t refHeight = 0; 		//cm, the (final) height of the water without food
    uint8_t newHeight = 0;		//cm, new height of the bath after adding food
    uint8_t heightAvg = 0;		//cm, average height of the water. without food

    uint8_t newHeightSet = 0; 	//Flag indicating that the thickness of the food
    //has been calculated
    uint8_t refHeightSet = 0;	//Flag indicating that we have measured
    //the reference distance from the sonar
    //to the water's surface

    //Boundaries so we don't measure the top or bottom of the bath
    uint8_t minDist = 3;	//cm
    uint8_t maxDist = 30; //cm

    uint8_t numSamples = 0;	//he number of samples currently taken in the set
    uint8_t desiredNumSamples = 64; //the number of samples to take in a set.

    uint8_t prevDistance = 0; //cm, the previous measurement

    //Ratio of the area of the bath and cooking bags
    uint8_t areaRatio = 2;

    uint8_t firstMeasurementTaken = 0;	//flag indicating that the very first measurement has not been taken
    uint8_t firstSample = 0;	//cm, first measurement out of 64 in a set of samples

    //flags inicating which distance we are measuring
    uint8_t measuringRefHeight = 1;
    uint8_t measuringNewHeight = 0;

    while(1) {

        PORTA |= 0x01;	//Set the trigger pin high to start the pulse
        _delay_us(10);	//Give the ultrasonic 10 us to send the pulse
        PORTA &= ~0x01;	//Set the trigger pin low to stop transmitting
        sonarFinished = 0;
        //Use TRTAccept to read the sonarFinishedSemaphor
        while (!sonarFinished) {
            trtWait(SEM_SONAR);
        }
        numSamples++;

        //if this is the first sample, just record the distance
        //as the height, previous measurement, and first sample.
        if (!firstMeasurementTaken) {
            prevDistance = distance;
            heightAvg = distance;
            firstMeasurementTaken = 1;
            firstSample = distance;
        }

        //Otherwise determine what we wanted to measure
        //and whether or not the state ofthe cooker has changed
        else {
            //check if the measurement is valid.
            if  (distance < maxDist and distance > minDist) {

                //check if the depth increased by more than 5cm (corresponds to
                // adding or removing food).
                if (distance - prevDistance > threshold or prevDistance - distance > 5) {
                    numSamples = 1;
                    firstSample = distance;
                    newHeight = distance;
                    measuringNewHeight = 1;
                    measuringRefHeight = 0;
                }

                else {
                    if (!measuringNewHeight) {
                        if (!numSamples) {
                            firstSample = distance;
                            heightAvg = 0;
                        }
                        heightAvg += distance;
                    }
                    else {
                        newHeight += distance;
                    }
                    numSamples++;
                }
                //check if we are done sampling
                if (numSamples == desiredNumSamples) {
                    //check if we are setting the reference height
                    //or the new height
                    if (!measuringNewHeight) {
                        heightAvg <<= 6;
                        //check if the measurement has increased substantially
                        //since taking the first sample. If so, the water level
                        //is rising and we should start sampling again
                        if (heightAvg - firstSample > threshold or firstSample - heightAvg > threshold) {
                            measuringRefHeight = 1;
                            numSamples = 0;
                        }

                        //the water level has settled. Set the reference height flag
                        //and clear the measuring reference height flag
                        else {
                            if (measuringRefHeight) {
                                refHeight = heightAvg;
                                refHeightSet = 1;
                                measuringRefHeight = 0;
                            }
                            numSamples = 0;
                        }
                    }

                    //We finished taking measurements for the new height
                    //of the bath
                    else {
                        //set the new height of the bath, calculate the thickness
                        //of the food, and signal the heating task to start heating
                        //the water
                        newHeight <<= 6;
                        newHeightSet = 1;
                        measuringNewHeight = 0;
                        trtWait(SEM_THICKNESS);
                        thickness = areaRatio * (newHeight - refHeight);
                        trtSignal(SEM_THICKNESS);
                        trtSignal(SEM_START_HEATING);
                        numSamples =0 ;
                    }
                }
            }
            else if (distance <= minDist) {
                overflow = 1;
            }
            else {
                firstMeasurementTaken = 0;
                measuringNewHeight = 0;
                measuringRefHeight = 1;
                numSamples = 0;
            }

            prevDistance = distance;
        }

        rel = trtCurrentTime() + SECONDS2TICKS(0.015625);
        dead = trtCurrentTime() + SECONDS2TICKS(0.02);
        trtSleepUntil(rel, dead);
    }

}