Exemple #1
0
void mean_readings(void)
{
	//Calculate mean of cell adc readings
	float temp;
	for (uint8_t x = 0; x < cellNumber; x++) temp += adcConvert(adcReadings[x], cellReading);
	adcReadingsMean = temp / cellNumber;
}
Exemple #2
0
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the ADC1 driver.
   */
  adcStart(&ADCD1, &adccfg1);

  while (1) {
    /*
     * ADC linear conversion.
     */
    adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH);

    chThdSleepMilliseconds(500);
  }
}
static THD_FUNCTION(m3pyro_continuity_thd, arg)
{
    (void)arg;

    while(true) {
        adcsample_t sampbuf[5];
        adcStart(&ADCD1, NULL);
        msg_t result = adcConvert(&ADCD1, &adc_grp, sampbuf, 1);
        adcStop(&ADCD1);

        if(result != MSG_OK) {
            m3status_set_error(M3PYRO_COMPONENT_CONTINUITY, M3PYRO_ERROR_ADC);
            chThdSleepMilliseconds(500);
            continue;
        }

        uint8_t continuities[4];
        continuities[0] = adc_to_resistance(sampbuf[0]);
        continuities[1] = adc_to_resistance(sampbuf[1]);
        continuities[2] = adc_to_resistance(sampbuf[2]);
        continuities[3] = adc_to_resistance(sampbuf[3]);
        can_send(CAN_MSG_ID_M3PYRO_CONTINUITY, false,
                 continuities, sizeof(continuities));

        uint8_t supply;
        supply = adc_to_voltage(sampbuf[4]);
        can_send(CAN_MSG_ID_M3PYRO_SUPPLY_STATUS, false,
                 &supply, 1);

        m3status_set_ok(M3PYRO_COMPONENT_CONTINUITY);
        chThdSleepMilliseconds(500);
    }
}
void readADC(void)
{
	uint32_t i;
	char Result2[6];

	adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH);
	  ADC2status = 0;
	  sum=0;
	  for (i=0;i<=ADC_GRP1_BUF_DEPTH;i++){
	      //chprintf(chp, "%d  ", samples1[i]);
	      sum += samples1[i];
	  }

	  sum = ((uint64_t)sum)*VREFINT/(ADC_GRP1_BUF_DEPTH/16*VREFMeasured/100);

	  sprintf ( Result, "%i", (uint16_t)sum/10000 ); // megadja a feszültség egész részét
	  sprintf ( Result2, ".%iV", (uint16_t)sum%10000 );
	  strncat(Result, Result2, 6);

	  gwinSetText(ADCvalue, Result, TRUE);
	  //prints the averaged value with 4 digits precision
	  chprintf((BaseSequentialStream *)&SD2, "\r\nMeasured: %U.%04UV", sum/10000, sum%10000);
	/*
	i = avg;
	sprintf ( Result, "%i", i ); // %d makes the result be a decimal integer

	  for (i=0; i<=4; i++)
	  {
		  chprintf( (BaseSequentialStream *)&SD2, "%c", Result[i] );
	  }
	  chprintf( (BaseSequentialStream *)&SD2, "\r\n", NULL);
	*/
}
Exemple #5
0
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the serial driver 1 using the driver default configuration.
   */
  
  palSetPadMode(IOPORT2, 0, PAL_MODE_OUTPUT_PUSHPULL);
  
  sdStart(&SD1, NULL);

  #define ADC_GRP1_NUM_CHANNELS   3
  #define ADC_GRP1_BUF_DEPTH      10
    DDRD |= _BV(DDD5);  
    
  static adcsample_t samples[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
  static const ADCConversionGroup adcgrpcfg = {
    FALSE,
    ADC_GRP1_NUM_CHANNELS,
    NULL,
    0b00000111                        /*   enabled channels                */
  };

  ADCConfig adccfg = {
    ANALOG_REFERENCE_AVCC /* use the AVCC pin as the ADC reference voltage */
  };

  adcStart(&ADCD1, &adccfg);
  
  palSetGroupMode(IOPORTADC, 0b00000111, 0, PAL_MODE_INPUT_PULLUP);
  

  while(TRUE)
  {
	int i;
    adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH);
      
    chprintf((BaseSequentialStream *) &SD1,"Result:\r\n");
    for(i=0; i < (ADC_GRP1_BUF_DEPTH * ADC_GRP1_NUM_CHANNELS); i++) {
      if((i % ADC_GRP1_NUM_CHANNELS) == 0) chprintf((BaseSequentialStream *) &SD1,"\r\n");
      chprintf((BaseSequentialStream *) &SD1," %d", samples[i]);
    }
     
    chprintf((BaseSequentialStream *) &SD1,"\r\n");
    chThdSleepMilliseconds(500);
	palTogglePad(IOPORT2, PORTB_LED1);
  }
}
Exemple #6
0
uint16_t analog_read(uint8_t index)
{
	msg_t result;
	
	result = adcConvert (&ADCD1, &adcgrpcfg, samples, ADC_GRP1_BUF_DEPTH);
	
	//TODO
	return samples[index];
}
Exemple #7
0
int main(void) { 

  halInit(); 
  chSysInit();
    
/*
  * ADC init
  */
  palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG);
  adcStart(&ADCD1, NULL); 

  /* 
   * Activates the serial driver 2 using the driver default configuration: 
   * 38400 bauds, 8bits, 1 stop-bit, no parity 
   */ 
    sdStart(&SD2, NULL);
  palSetPadMode(GPIOC, 5, PAL_MODE_ALTERNATE(7));
  palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(7));
    
  /* 
   * Normal main() thread activity, in this demo it does nothing except 
   * sleeping in a loop and check the button state. 
   */ 
  while (TRUE) 
   { 

/*
* single analog conversion
* converts ADC_GRP1_BUF_DEPTH samples and averages them
* with ADC_GRP1_BUF_DEPTH==2048 this gives around 14 bit precision
* even though the ADC hardware has only 12 bits internal precision
* also at 2048 samples the 14 bit are nearly noise free, while
* each sample is very noisy.
* WARNING: If you average to many samples, the variable containing
*  the sum may overflow. That means that your readings will be wrong.
* However: With the ADC delivering a max value of 2^12, with uint32_t
*  you can average 2^20 = 1048576 samples.
*/

  uint32_t sum=0;
  unsigned int i;

  adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH);

  //prints the first measured value
  chprintf((BaseSequentialStream *)&SD2, "Measured: %d  ", samples1[0]*16);
  sum=0;
  for (i=0;i<ADC_GRP1_BUF_DEPTH;i++){
      sum += samples1[i];
  }
  //prints the averaged value with two digits precision
  chprintf((BaseSequentialStream *)&SD2, "%U\r\n", sum/(ADC_GRP1_BUF_DEPTH/16));

  chThdSleepMilliseconds(500);
}
}
Exemple #8
0
float
board_get_core_temp()
{
  adcsample_t sample;

  adcAcquireBus(&ADCD1);
  adcConvert(&ADCD1, &core_temp_conv_grp, &sample, 1);
  adcReleaseBus(&ADCD1);

  return (float)((((float)sample - TS_CAL1_CNT) / TS_AVG_SLOPE) + TS_CAL1_TMP);
}
Exemple #9
0
void uart_out(void)
{
	char adcDisplay[4];
	char cellDisplay;
	//Outputs BMS information and measurements to computer
	uart_puts("Start");
	uart_putc('\n');
	uart_putc(*utoa(cellNumber, &cellDisplay, 10));
	uart_putc('\n');
	for (uint8_t x = 0; x < cellNumber; x++)
	{
		uart_puts(dtostrf(adcConvert(adcReadings[x], cellReading), 4, 2, adcDisplay));
		uart_putc('\n');
		uart_putc(*utoa(balanceByte[x], &cellDisplay, 10));
		uart_putc('\n');
	}
	uart_puts(dtostrf(adcConvert(adcReadings_I, mainReading), 4, 2, adcDisplay));
	uart_putc('\n');
	uart_putc(*utoa(charger, &cellDisplay, 10));
	uart_putc('\n');
}
Exemple #10
0
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Setting up analog inputs used by the demo.
   */
  palSetGroupMode(GPIOC, PAL_PORT_BIT(1) | PAL_PORT_BIT(2),
                  0, PAL_MODE_INPUT_ANALOG);

  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

  /*
   * Activates the ADC1 driver and the temperature sensor.
   */
  adcStart(&ADCD1, NULL);
  adcSTM32EnableTS(&ADCD1);
  adcSTM32EnableVBAT(&ADCD1);

  /*
   * Linear conversion.
   */
  adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH);
  chThdSleepMilliseconds(1000);

  /*
   * Starts an ADC continuous conversion.
   */
  adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH);

  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (true) {
    if (palReadPad(GPIOA, GPIOA_BUTTON)) {
      adcStopConversion(&ADCD1);
    }
    chThdSleepMilliseconds(500);
  }
}
/**
 * @brief   Reads out the X direction.
 *
 * @note    The samples are median filtered for greater noise reduction
 *
 * @notapi
 */
uint16_t ts_lld_read_x(void) {
	uint16_t val1, val2;
	adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];

    palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_INPUT_ANALOG);
    palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_INPUT_ANALOG);
    palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_OUTPUT_PUSHPULL);
    palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_OUTPUT_PUSHPULL);
    
    palSetPad(ts->xl_port, ts->xl_pin);
    palClearPad(ts->xr_port, ts->xr_pin);
    chThdSleepMilliseconds(1);
    adcConvert(ts->adc_driver, &adc_x_config, samples, ADC_BUF_DEPTH);  
    val1 = ((samples[0] + samples[1])/2);

    palClearPad(ts->xl_port, ts->xl_pin);
    palSetPad(ts->xr_port, ts->xr_pin);
    chThdSleepMilliseconds(1);
    adcConvert(ts->adc_driver, &adc_x_config, samples, ADC_BUF_DEPTH);
    val2 = ((samples[0] + samples[1])/2);
    
	return ((val1+((1<<12)-val2))/4);
}
Exemple #12
0
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

  /*
   * Activates the ADC1 driver, the temperature sensor and the VBat
   * measurement.
   */
  adcStart(&ADCD1, NULL);
  adcSTM32Calibrate(&ADCD1);
  adcSTM32EnableTSVREFE();
  adcSTM32EnableVBATE();

  /*
   * Linear conversion.
   */
  adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH);
  chThdSleepMilliseconds(1000);

  /*
   * Starts an ADC continuous conversion.
   */
  adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH);

  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (TRUE) {
    if (palReadPad(GPIOA, GPIOA_WKUP_BUTTON)) {
      adcStopConversion(&ADCD1);
    }
    chThdSleepMilliseconds(500);
  }
}
Exemple #13
0
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
	int i = 0, j = 0;
	int addr;

	//usb atjungimo kintamasis
	bool usbDisabled = true;

	//adc variables
	float *result;
	char mockResult[600];
	char UARTTxPacket[100];
	static short ultrasoundPacketTxMultiplier = 0;
    static int ULTRASOUND_PACKET_COUNT = 100;

	//usart state machine switch
	uartSwitch = 'r';

	//USB buffer variables
    uint8_t buf[255],outstrg[100],inchar;
    uint8_t len;

    //dac variables
    uint16_t waveform[32];
    uint8_t continueReading = 1;
    uint8_t intCount = 0;
    uint8_t charCount = 0;
    bool bufferReadSuccessful = false;
	char tempString[4];

    int cs;
    volatile float a,b,elapsedtime,angle,radius,angleinc;

    RCC_ClocksTypeDef RCC_Clocks;

	// Initialize System and Setup clocks.
	SystemInit();
	SystemCoreClockUpdate();

	//ini ADC
	adcConfigure();

	//init USART
	USARTInit();

	USART_puts(USART2, "P_Cmd\n\n");
	//USARTSendByte();
	//USARTReadByte();

	/* SysTick end of count event each 40ms */
	RCC_GetClocksFreq(&RCC_Clocks);
	//SysTick_Config(RCC_Clocks.HCLK_Frequency /100);

	// Initialize FPU
	*((volatile unsigned long*)0xE000ED88) = 0xF << 20;

	// Initialize LEDs and User_Button on STM32F4-Discovery
    STM_EVAL_LEDInit(LED4);
    STM_EVAL_LEDInit(LED3);
    STM_EVAL_LEDInit(LED5);
    STM_EVAL_LEDInit(LED6);

    if(!usbDisabled){
		// USB Device Initialize
		USBD_Init(&USB_OTG_dev,
				USB_OTG_FS_CORE_ID,
				&USR_desc,
				&USBD_CDC_cb,
				&USR_cb);

		// Wait for USB connection goes live
		while (!gbUsbDeviceReady);

		// Clean USB RX buffer
		while(VCP_get_string(&buf[0]) == 0);

		// Output signon
		printf("USB serial DEMO\r\n");
		printf("test\n\r>");
    }
    //  Main loop
    while(1) {
    	//SPI (WITH MSP) STATE MACHINE
    	if(uartSwitchGet() != 'r')
    		switch(uartSwitchGet()){
    		case 't': //cmd tx packet
    			for (i=0;i<600;i++)
    				mockResult[i] = i;
    			for(i=0;i<100;i++)
    				UARTTxPacket[i] = mockResult[i+ultrasoundPacketTxMultiplier];
    			txDataArrayToMsp(UARTTxPacket);
    			uartSwitchSet('r');
    			break;
    		case 'e':
    			//Delay(1000);
    			USART_puts(USART2, "P_End\n\n");
    			ultrasoundPacketTxMultiplier = 0;
    			uartSwitchSet('r');
    			break;
    		case 'c': //cmd_packet_received_msg.
    			ultrasoundPacketTxMultiplier++;
    			if (ultrasoundPacketTxMultiplier >= 10)
    				uartSwitchSet('e'); //finish transmission, or...
    			else
    				uartSwitchSet('r'); // prepare for the next packet
    			break;
    		default:
    			break;
    		}
    	if(!usbDisabled){
			//USB COMM STATE MACHINE
			inchar = GetCharnw();

			if(inchar) {
				switch (inchar){
					case 'a':
						result = adcConvert();
						float* k;
						uint16_t j;
						//for (j=0;j<250;j++){
							for(k=result;k<result+10/*28000*/;k++){
								printf("%f \n",*k);
							}
					//	}
						break;
					case 'd':
						  intCount = charCount = bufferReadSuccessful = 0;
						  while(continueReading){
							for(i=0;i<rxbuflen;i++){
							  if(inbuf[i]!='d' && inbuf[i]!='e' && inbuf[i]!=' ' && continueReading == true){
								tempString[charCount]=inbuf[i];
								charCount++;
								if(charCount==4){
								  waveform[intCount] = 0;
								  for(j=0;j<4;j++)
								  waveform[intCount] += (int)(tempString[j]-'0')*pow(10,3-j);
								  intCount++;
								  charCount = 0;
								}
							  }
							  if(inbuf[i]=='e'||intCount == 32) { continueReading = 0; bufferReadSuccessful = true;}
							}
						  rxbuflen = 0;
						  char inchar = GetCharnw();
						  }
						if(bufferReadSuccessful)DAC_SignalsGenerate(&waveform);
						break;

					case 's':
						printf("\n\rF4 Discovery Test V0.55\n\r>");
						break;
					case 't':
						printf("\n\rDo 10000 circular interpolation calculations\n\r");
						TimingDelay4 = 10000;
						angle = 0.125;
						radius = 2.56;
						angleinc = 0.0001;
						for(i=0; i<100000; i++) {
							a = radius * sinf(angle);
							b = radius * cosf(angle);
							angle += angleinc;
							}
						elapsedtime = ((float)(10000 - TimingDelay4))/25.0;
						printf("timing delay=%d\n\r",TimingDelay4);
						printf("Single precision finished in %f seconds or %f usec/loop\n\r",elapsedtime,elapsedtime*10.0);
						TimingDelay4 = 10000;
						angle = 0.125;
						radius = 2.56;
						angleinc = 0.0001;
						for(i=0; i<100000; i++) {
							a = radius * sinfp(angle);
							b = radius * cosfp(angle);
							angle += angleinc;
							}
						elapsedtime = ((float)(10000 - TimingDelay4))/25.0;
						printf("timing delay=%d\n\r",TimingDelay4);
						printf("Single prec fp finished in %f seconds or %f usec/loop\n\r",elapsedtime,elapsedtime*10.0);
						TimingDelay4 = 10000;
						angle = 0.125;
						radius = 2.56;
						angleinc = 0.0001;
						printf("angle=%f radius=%f angleinc=%f\n\r",angle,radius,angleinc);
						for(i=0; i<100000; i++) {
							a = radius * sin(angle);
							b = radius * cos(angle);
							angle += angleinc;
							}
						printf("timing delay=%d\n\r",TimingDelay4);
						elapsedtime = ((float)(10000 - TimingDelay4))/25.0;
						printf("Double precision finished in %f seconds or %f usec/loop\n\r>",elapsedtime,elapsedtime*10.0);
						break;
					case 'f':
						printf("f\n\rTry float output: 1.234\n\r");
						a = 1.234;
						printf("a = %f\n\r",a);
						i = 35;
						printf("i = %d\n\r",i);
						a = 35.45;
						printf("a = %f\n\r",a);
						printf("a = %f\n\r",12.345);
						printf("a = %f\n\r",-12.345);
						printf("i = %d\n\r",i);
						break;
					case 'g':
						printf("d\n\rRCC_Clocks.HCLK_Frequency=%ld",RCC_Clocks.HCLK_Frequency);
						printf("\n\rDelay 2 second\n\r");
						Delay(200);
						printf("finished\n\r>");
						break;
					case CR:
						printf("\n\r>");
						break;
					default:
						printf("%c\n\r>",inchar);
						break;
					}
				}
    	}

        if (i == 0x100000) {
            STM_EVAL_LEDOff(LED4);
            STM_EVAL_LEDOff(LED3);
            STM_EVAL_LEDOff(LED5);
            STM_EVAL_LEDOff(LED6);
        	}
        if (i++ == 0x200000) {
        	i = 0;
            STM_EVAL_LEDOn(LED4);
            STM_EVAL_LEDOn(LED3);
            STM_EVAL_LEDOn(LED5);
            STM_EVAL_LEDOn(LED6);
        	}
    	}
}
/**
  * @brief  This is the pressure control thread
  * @param  void* to a PID Loops configuration
  * @retval msg_t status
  */
msg_t Pressure_Thread(void *This_Config) {
	/* This thread is passed a pointer to a PID loop configuration */
	PID_State Pressure_PID_Controllers[((Pressure_Config_Type*)This_Config)->Number_Setpoints];
	memset(Pressure_PID_Controllers,0,((Pressure_Config_Type*)This_Config)->Number_Setpoints*sizeof(PID_State));/* Initialise as zeros */
	float* Last_PID_Out=(float*)chHeapAlloc(NULL,sizeof(float)*((Pressure_Config_Type*)This_Config)->Number_Setpoints);/* PID output for interpol */
	adcsample_t Pressure_Samples[PRESSURE_SAMPLES],Pressure_Sample;/* Use multiple pressure samples to drive down the noise */
	float PID_Out,Pressure;//,step=0.01,sawtooth=0.7;
	uint32_t Setpoint=0;
	uint8_t Old_Setpoint=0, Previous_Setpoint;
	chRegSetThreadName("PID_Pressure");
	//palSetGroupMode(GPIOC, PAL_PORT_BIT(5) | PAL_PORT_BIT(4), 0, PAL_MODE_INPUT_ANALOG);
	palSetPadMode(GPIOE, 9, PAL_MODE_ALTERNATE(1));		/* Only set the pin as AF output here, so as to avoid solenoid getting driven earlier*/
	palSetPadMode(GPIOE, 11, PAL_MODE_ALTERNATE(1));	/* Experimental servo output here */
	#ifndef USE_SERVO
	/*
	* Activates the PWM driver
	*/
	pwmStart(&PWM_Driver_Solenoid, &PWM_Config_Solenoid);	/* Have to define the timer to use for PWM_Driver in hardware config */
	/*
	* Set the solenoid PWM to off
	*/
	pwmEnableChannel(&PWM_Driver_Solenoid, (pwmchannel_t)PWM_CHANNEL_SOLENOID, (pwmcnt_t)0);
	#else
	/*
	* Activates the experimental servo driver
	*/
	pwmStart(&PWM_Driver_Servo, &PWM_Config_Servo);		/* Have to define the timer to use for PWM_Driver in hardware config */
	#endif
	/*
	* Activates the ADC2 driver *and the thermal sensor*.
	*/
	adcStart(&ADCD2, NULL);
	//adcSTM32EnableTSVREFE();
	/*
	/ Now we run the sensor offset calibration loop
	*/
	do {
		adcConvert(&ADCD2, &adcgrpcfg1, &Pressure_Sample, 1);/* This function blocks until it has one sample*/
	} while(Calibrate_Sensor((uint16_t)Pressure_Sample));
	systime_t time = chTimeNow();				/* T0 */
	systime_t Interpolation_Timeout = time;			/* Set to T0 to show there is no current interpolation */
	/* Loop for the pressure control thread */
	while(TRUE) {
		/*
		* Linear conversion.
		*/
		adcConvert(&ADCD2, &adcgrpcfg1, Pressure_Samples, PRESSURE_SAMPLES);/* This function blocks until it has the samples via DMA*/
		/*
		/ Now we process the data and apply the PID controller - we use a median filter to take out the non guassian noise
		*/
		Pressure_Sample = quick_select(Pressure_Samples, PRESSURE_SAMPLES);
		Pressure = Convert_Pressure((uint16_t)Pressure_Sample);/* Converts to PSI as a float */
		/* Retrieve a new setpoint from the setpoint mailbox, only continue if we get it*/
		if(chMBFetch(&Pressures_Setpoint, (msg_t*)&Setpoint, TIME_IMMEDIATE) == RDY_OK) {
			//Pressure=Run_Pressure_Filter(Pressure);/* Square root raised cosine filter for low pass with minimal lag */
			Pressure = Pressure<0?0.0:Pressure;	/* A negative pressure is impossible with current hardware setup - disregard*/
			Setpoint &= 0x000000FF;
			/* The controller is built around an interpolated array of independant PID controllers with seperate setpoints */
			if(Setpoint != Old_Setpoint) {		/* The setpoint has changed */
				Previous_Setpoint = Old_Setpoint;/* This is for use by the interpolator */
				Old_Setpoint = Setpoint;	/* Store the setpoint */
				/* Store the time at which the interpolation to new setpoint completes*/
				Interpolation_Timeout = time + (systime_t)( 4.0 / ((Pressure_Config_Type*)This_Config)->Interpolation_Base );
			}
			if(Interpolation_Timeout > time) {	/* If we have an ongoing interpolation  - note, operates in tick units */
				/* Value goes from 1 to -1 */
				float interpol = erff( (float)(Interpolation_Timeout - time) *\
						 ((Pressure_Config_Type*)This_Config)->Interpolation_Base - 2.0 );/* erf function interpolator */
				interpol = ( (-interpol + 1.0) / 2.0);/* Interpolation value goes from 0 to 1 */
				PID_Out = ( Last_PID_Out[Previous_Setpoint] * (1.0 - interpol) ) + ( Last_PID_Out[Setpoint] * interpol );
				Pressure_PID_Controllers[Setpoint].Last_Input = Pressure;/* Make sure the input to next PID controller is continuous */
			}
			else {
				PID_Out = Run_PID_Loop( ((Pressure_Config_Type*)This_Config)->PID_Loop_Config, &Pressure_PID_Controllers[Setpoint],\
						 (((Pressure_Config_Type*)This_Config)->Setpoints)[Setpoint], \
						 Pressure, (float)PRESSURE_TIME_INTERVAL/1000.0);/* Run PID */
				Last_PID_Out[Setpoint] = PID_Out;/* Store for use by the interpolator */
			}
		}
		else
			PID_Out=0;				/* So we can turn off the solenoid simply by failing to send Setpoints */
		PID_Out=PID_Out>1.0?1.0:PID_Out;
		PID_Out=PID_Out<0.0?0.0:PID_Out;		/* Enforce range limits on the PID output */
		//sawtooth+=step;				/* Test code for debugging mechanics with a sawtooth */
		//if(sawtooth>=1 || sawtooth<=0.65)
		//	step=-step;
		//PID_Out=sawtooth;
		#ifndef USE_SERVO
		/*
		/ Now we apply the PID output to the PWM based solenoid controller, and feed data into the mailbox output - Note fractional input
		*/
		pwmEnableChannel(&PWM_Driver_Solenoid, (pwmchannel_t)PWM_CHANNEL_SOLENOID, (pwmcnt_t)PWM_FRACTION_TO_WIDTH(&PWM_Driver_Solenoid, 1000\
														, (uint32_t)(1000.0*PID_Out)));	
		#else
		pwmEnableChannel(&PWM_Driver_Servo, (pwmchannel_t)PWM_CHANNEL_SERVO, (pwmcnt_t)PWM_FRACTION_TO_WIDTH(&PWM_Driver_Servo, 10000\
														, (uint32_t)(1000.0*(PID_Out+1.0))));	
		#endif
		chMBPost(&Pressures_Reported, *((msg_t*)&Pressure), TIME_IMMEDIATE);/* Non blocking write attempt to the Reported Pressure mailbox FIFO */
		/*
		/ The Thread is syncronised to system time
		*/	
		time += MS2ST(PRESSURE_TIME_INTERVAL);		/* Next deadline */
		chThdSleepUntil(time);				/* Gives us a thread with regular timing */
	}
}
Exemple #15
0
THD_FUNCTION(Thread1, arg) {

  (void)arg;

  /*
   * Activate the serial driver 0 using the driver default configuration.
   */
  sdStart(&SD1, NULL);

  /* Activate the ADC driver 1 using its config */
  adcStart(&ADCD1, &config);

  while (chnGetTimeout(&SD1, TIME_INFINITE)) {
    print(start_msg);
    chThdSleepMilliseconds(2000);

    /* Test 1 - 1ch1d, no circular */
    run_test(test_1_msg, 1, 1, false);
    
    /* Test 2 - 1ch8d, no circular */
    run_test(test_2_msg, 1, 8, false);
    
    /* Test 3 - 4chd1, no circular */
    run_test(test_3_msg, 4, 1, false);
    
    /* Test 4 - 4ch8d, no circular */
    run_test(test_4_msg, 4, 8, false);
    
    /* Test 5 - 1ch1d, circular */
    run_test(test_5_msg, 1, 1, true);
    
    /* Test 6 - 1ch8d, circular */
    run_test(test_6_msg, 1, 8, true);
    
    /* Test 7 - 4ch1d, circular */
    run_test(test_7_msg, 4, 1, true);
    
    /* Test 8 - 4ch8d, circular */
    run_test(test_8_msg, 4, 8, true);
    
    /* Test 9 - 1ch1d, synchronous */
    print(test_9_msg);
    cb_arg = 0;
    
    group.num_channels = 1;
    group.circular = false;
    group.end_cb = adc_callback;
    
    cb_expect = 1;
    
    adcConvert(&ADCD1, &group, buffer, 1);
    
    while (ADCD1.state == ADC_ACTIVE) ;
    
    sniprintf(out_string, 128, chn_fmt_string, group.channels[0]);
    print(out_string);
    
    sniprintf(out_string, 128, raw_fmt_string, buffer[0]); 
    print(out_string);
    
    buffer[0] = adcMSP430XAdjustTemp(&group, buffer[0]);
    
    sniprintf(out_string, 128, cooked_fmt_string, buffer[0]); 
    print(out_string);
    
    if (cb_arg == cb_expect) {
      print(success_string);
    }
    else {
      print(fail_string);
    }
  }
}