2023-03-03 07:45 AM
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
}
I 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
2023-03-07 06:23 AM
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;
2023-03-07 06:46 AM
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 ?
2023-03-11 12:00 PM
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.