cancel
Showing results for 
Search instead for 
Did you mean: 

How to wait for Interruption to continue code execution ? Or better non CPU blocking solution for my code.

ADesp.1
Associate II

Hey,

I'm basicly filling a tank with liquid and I have 2 level sensors in this tank.

These level sensors are connected to GPIO_EXTI of my MCU so when the water reached the sensor level, an interrupt occure.

If the tank is filling or emptying, I must disable the water input regarding to which level the water is (low if emptying or high if filling).

The interruption routine :

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin){
	/* Sensor 1 (lower level) interrupt */
	if(GPIO_Pin == WATER_SENSOR_LOW_Pin){
		if(isEmptying){
		        StopWaterInput();
		}
	}
	/* Sensor 2 (upper level) interrupt */
	else if(GPIO_Pin == WATER_SENSOR_HIGH_Pin){
		if(isFilling){
		        StopWaterOutput();
 
		}
	}
}

I need to code a cycle like this :

void Process(){
   //Start Fillling the tank
   isFilling = 1;
   isEmptying = 0;
   StartWaterFlowing();
 
   //Water reach low sensor, do nothing
   //Water reach high sensor and so the water input is closed (IR callback)
 
   //NEED TO HAVE CLOSED THE WATER INPUT TO CONTINUE
   
   HAL_Delay(5000);
 
   //Start emptying the tank
   isFilling = 0;
   isEmptying = 1;
   StartTankEmptying();
 
   //Water reach high sensor, do nothing
   //Water reach low sensor and so the water output is closed (IR callback)
 
  //NEED TO HAVE CLOSED THE WATER OUTPUT TO CONTINUE
}

0693W00000aI9YHQA0.pngI don't know how to do for the code to not start emptying the tank until the water reached the high level and reciprocally not start the cycle again until the water reached the low level.

I've read a bit about WFI but I'm not sure that's what I need. I'm also new to thread programming so maybe I need to build the code differently to use thread.

Do you have any suggestion how to acheive this ?

Thanks for your help.

Adrien

12 REPLIES 12

Hey, I'm strugggling with my code, if you can help ...

/* Create different states for the dosing cell state machine */
enum statesCell {
   ReadyForDosing,
   Flowing,
   PausePriorFilling,
   Filling,
   WaitForHighSensorFlag,
   CloseFilling,
   PausePriorEmptying,
   Emptying,
   WaitForLowSensorFlag,
   CloseEmptying,
   PauseAfterEmptying
};
 
/* Structure to handle one dosing cell */
struct dosingCell {
   /* PIN LAYOUT */
   GPIO_TypeDef* InPort;
   uint16_t InPin;
 
   GPIO_TypeDef* OutPort;
   uint16_t OutPin;
 
   GPIO_TypeDef* EvacPort;
   uint16_t EvacPin;
 
   /* VARIABLES */
   int lowSensorFlag;
   int highSensorFlag;
   enum statesCell state;
 
   /* TIMER */
   TIM_HandleTypeDef timer;
};
 
struct dosingCell Cell1;
struct dosingCell *Cell1Ptr;
 
Cell1Ptr = &Cell1;
 
Cell1Ptr->InPort = VANNE_ENTREE_GPIO_Port;
Cell1Ptr->InPin = VANNE_ENTREE_Pin;
Cell1Ptr->OutPort = VANNE_SORTIE_GPIO_Port;
Cell1Ptr->OutPin = VANNE_SORTIE_Pin;
Cell1Ptr->EvacPort = VANNE_EVAC_GPIO_Port;
Cell1Ptr->EvacPin = VANNE_EVAC_Pin;
Cell1Ptr->timer = htim16;
Cell1Ptr->lowSensorFlag = 0;
Cell1Ptr->highSensorFlag = 0;
Cell1Ptr->state = 0;

I have these errors and I can't solve them :

warning: data definition has no type or storage class
  108 | Cell1Ptr = &Cell1;
      | ^~~~~~~~
warning: type defaults to 'int' in declaration of 'Cell1Ptr' [-Wimplicit-int]
 
error: conflicting types for 'Cell1Ptr'
 
warning: initialization of 'int' from 'struct dosingCell *' makes integer from pointer without a cast [-Wint-conversion]
  108 | Cell1Ptr = &Cell1;
      |            ^
 
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  110 | Cell1Ptr->InPort = VANNE_ENTREE_GPIO_Port;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  111 | Cell1Ptr->InPin = VANNE_ENTREE_Pin;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  112 | Cell1Ptr->OutPort = VANNE_SORTIE_GPIO_Port;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  113 | Cell1Ptr->OutPin = VANNE_SORTIE_Pin;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  114 | Cell1Ptr->EvacPort = VANNE_EVAC_GPIO_Port;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  115 | Cell1Ptr->EvacPin = VANNE_EVAC_Pin;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  116 | Cell1Ptr->timer = htim16;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  117 | Cell1Ptr->lowSensorFlag = 0;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  118 | Cell1Ptr->highSensorFlag = 0;
      |         ^~
error: expected '=', ',', ';', 'asm' or '__attribute__' before '->' token
  119 | Cell1Ptr->state = 0;

I guess I'm handling the structure badly but I don't know why.

Here are my other functions prototype :

void ValveFlowing(struct dosingCell *cell);
void ValveFilling(struct dosingCell *cell);
void ValveEmptying(struct dosingCell *cell);
void ValveClose(struct dosingCell *cell);
void dosingCellControl(struct dosingCell *cell);
uint16_t TimerGetValue(TIM_HandleTypeDef timer);
void ResetTimer(TIM_HandleTypeDef timer);

And the callback and it's errors :

/* Handling the GPIO EXTI Interrupt */
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin){
	/* Photo-sensor 1 (lower) interrupt */
	if(GPIO_Pin == PHOTO_SENSOR_LOW_Pin){
		HAL_UART_Transmit(&hlpuart1, (uint8_t*)msgSensor1, strlen(msgSensor1), 100);
		Cell1Ptr->lowSensorFlag = 1;
	}
	/* Photo-sensor 2 (upper) interrupt */
	else if(GPIO_Pin == PHOTO_SENSOR_HIGH_Pin){
		HAL_UART_Transmit(&hlpuart1, (uint8_t*)msgSensor2, strlen(msgSensor2), 100);
		Cell1Ptr->highSensorFlag = 1;
	}
 
}
error: invalid type argument of '->' (have 'int')
  618 |   Cell1Ptr->lowSensorFlag = 1;
      |           ^~
error: invalid type argument of '->' (have 'int')
  623 |   Cell1Ptr->highSensorFlag = 1;

Nevermind I found my mistake. I had to put this part in the main function.

Cell1Ptr = &Cell1;
 
Cell1Ptr->InPort = VANNE_ENTREE_GPIO_Port;
Cell1Ptr->InPin = VANNE_ENTREE_Pin;
Cell1Ptr->OutPort = VANNE_SORTIE_GPIO_Port;
Cell1Ptr->OutPin = VANNE_SORTIE_Pin;
Cell1Ptr->EvacPort = VANNE_EVAC_GPIO_Port;
Cell1Ptr->EvacPin = VANNE_EVAC_Pin;
Cell1Ptr->timer = htim16;
Cell1Ptr->lowSensorFlag = 0;
Cell1Ptr->highSensorFlag = 0;
Cell1Ptr->state = 0;

Why can't you initialize your structure outside of the main function ?

Piranha
Chief II

The open/close "states", which execute only for a single iteration, are not actual states. Those are "transitions" and are typically implemented as a separate switch-case selection, which is called from a state machine when the state needs to be changed. That makes code more clear and better performance.