Hi everyone
I am developing a project that runs a BLDC motor, using an ESC that takes in input a PWM signal, and, based on thresholds in temperature and pressure, can go in stand- by mode or in overheating mode.
Other loads are connected to the board (SV1,SV2 and a fan)
the project has a momentary push button embedding a LED and a resistor for the LED.
IF the threshold of temperature is reached, the system goes in overheating mode. the motor stops, the fan is ON and LED start blinking.
the same happens if the pressure threshold is reached, so the system goes in stand-by mode, and the led blinks at a different frequency.
if I am in run mode, so P and T are below thresholds, the motor runs, and if the push button is pressed again, everything turn off. If I play with the code and sensors, using hot water to simulate the increasing of T and P, the states are reached correctly, the fan and the other loads are enabled correctly and when I am in run mode again, I can switch off the unit.
I have got problems in switching off the system when it is in overheating mode or stand-by mode. The variable “counter” I set, seems to be bypassed, so if I press the push button, while in stand-by or overheating mode, nothing happens.
I fear there is a loop where I am stuck in, but I don’t find which one…
If anybody could help…I attach here the code. Thank you very much.
#include <Servo.h>
Servo ESC;
// macro for detection of rising edge and debouncing
/*the state argument (which must be a variable) records the current
and the last 7 reads by shifting one bit to the left at each read.
If the value is 15(=0b00001111) we have one rising edge followed by
4 consecutive 1's. That would qualify as a debounced rising edge*/
#define DRE(signal, state) (state=(state<<1)|signal)==B00001111
// Rising state variables for each button
byte button1RisingState;
// macro for detection of falling edge and debouncing
/*the state argument (which must be a variable) records the current
and the last 7 reads by shifting one bit to the left at each read.
If the value is 240(=0b11110000) we have one falling edge followed by
4 consecutive 0's. That would qualify as a debounced falling edge*/
#define DFE(signal, state) (state=(state<<1)|signal)==B11110000
// Falling state variables for each button
byte button1FallingState;
static unsigned long Delay_sv1 = 3000;
static unsigned long Delay_esc = 1000;
int counter = 0; /* counts if the push button has been clicked and even or odd number of times*/
int flag = 0; /*defines if the temperature already went above T_max*/
int flag2 = 0; /*defines if the pressure rose above P_max*/
int pres; /* Pressure */
int temp; /* Temperature */
int T_deg;
int P_bar;
int P_max = 14;
int P_min = 11;
int P_air_on = 10;
int P_air_off = 9;
int T_max = 65;
int T_reset = 40;
int T_fan_on = 55;
int T_fan_off = 40;
#define sv1 4/* Oil electrovalve in relay 1 (PIN4)*/
#define sv2 5/* Air electrovalve in relay 2 (PIN5)*/
#define fan 7 /* Fan of heat exchanger in relay 4 (PIN7)*/
#define button 0/* momentary push button NO contact wired in IO1 [PIN0] with internal pull-up resistor in the micro ATmega enabled, and external 4K7 ohm pull-up resistor enabled. Contact "C" of the push button is wired in GND */
#define led 9/* LED+ in IO3 [PIN9] with embedded resistor in series to the anode, and LED- in GND. */
void setup() {
// Serial.begin(9600);
pinMode(button, INPUT); /* On the board place the jumper to enable the 4K7 ohm pull-up resistor at this input.*/
pinMode(led, OUTPUT); /* remove the jumper in correspondence of IO3, not required pull-up resistor for outputs */
pinMode(sv1, OUTPUT);
pinMode(sv2, OUTPUT);
pinMode(fan, OUTPUT);
ESC.attach(13);
}
boolean readButtons() {
// Read button states every 5 ms (debounce time):
static unsigned long lastDebounce;
if (millis() - lastDebounce >= 5) {
lastDebounce = millis();
// Rising edge (if switch is released)
if (DRE(digitalRead(button), button1RisingState)) {
int x = 1;
}
// Falling edge (if switch is pressed)
if (DFE(digitalRead(button), button1FallingState)) {
digitalWrite(led, !digitalRead(led)); // switch LED on or off
counter = counter + 1;
int x = 0;
}
}
}
void Inputs(){
/*Check the pressure. Pressure in AIN1 [A0]*/
pres = analogRead(A0);
P_bar = 0.030*(pres+0.75)-6.25; /*bar g*/
/* Check the temperature: Temperature in AIN2 [A1].*/
temp = analogRead(A1);
T_deg = 0.244*(temp+0.75)-100; /*deg °C*/
}
boolean FanOn(){
if(T_deg >= T_fan_on){
digitalWrite(fan, HIGH);
}
if(T_deg <= T_fan_off){
digitalWrite(fan, LOW);
}
}
boolean Flag(){
if(T_deg >= T_max && flag == 0){
flag = 1;
}
if(T_deg < T_reset && flag == 1){
flag = 0;
}
}
boolean Flag2(){
if(P_bar >= P_max && flag2 == 0){
flag2 = 1;
}
if(P_bar < P_min && flag2 == 1){
flag2 = 0;
}
}
boolean LED(){
/* LED blinks each 600ms when in STAND-BY mode, due to pressure reaching the threshold P_max (temperature below T_max)*/
if(P_bar >= P_min && flag2 == 1 && T_deg < T_max && flag == 0){
digitalWrite(led, HIGH);
delay(600);
digitalWrite(led, LOW);
delay(600);
}
/*LED blinks each 300ms when in OVERHEATING mode, due to temperature reaching the threshold */
if(T_deg >= T_reset && flag == 1){
digitalWrite(led, HIGH);
delay(300);
digitalWrite(led, LOW);
delay(300);
}
if(P_bar < P_max && flag2 == 0 && T_deg < T_max && flag == 0){
digitalWrite(led, HIGH);
}
}
boolean SV2On(){
/*if pressure >= 10bar, and the unit is NOT in the OVERHEATING state, sv2 opens*/
if(P_bar >= P_air_on && T_deg < T_max && flag == 0){
digitalWrite(sv2, HIGH);
}
/* if pressure <= 9bar, or the unit is in the OVERHEATING state, sv2 closes*/
if(P_bar <= P_air_off || T_deg >= T_max || flag == 1){
digitalWrite(sv2, LOW);
}
}
boolean SV1On(){
/*if the unit is in OVERHEATING MODE or in STAND-BY MODE, the sv1 closes*/
if(T_deg >= T_max || flag == 1 || P_bar >= P_max || flag2 == 1){
digitalWrite(sv1, LOW);
}
/*if the unit is with temperature below the T_max, and is not in OVERHEATING mode, and the Pressure is below the P_max threshold, and the unit is not in STAND-BY mode, sv1 is open*/
if(T_deg < T_max && flag == 0 && P_bar < P_max && flag2 == 0){
if (millis() >= Delay_sv1){
digitalWrite(sv1, HIGH);
}
}
}
boolean Motor_Controller_On(){
/*if the unit is with temperature below the T_max, and is not in OVERHEATING mode, and the Pressure is below the P_max threshold, and the unit is not in STAND-BY mode, the ESC spins the motor clockwise (2ms period square wave signal)*/
if(T_deg < T_max && flag == 0 && flag2 == 0 && P_bar < P_max){
if (millis() >= Delay_esc){
ESC.writeMicroseconds(2000);
}
}
/* if the unit is with temperature over threshold, or pressure over threshold, or the unit is in STAND-BY mode or in OVERHEATING mode, the ESC stops (1ms period square wave signal)*/
if(T_deg >= T_max || flag == 1 || flag2 == 1 || P_bar >= P_max){
if (millis() >= Delay_esc){
ESC.writeMicroseconds(1000);
}
}
}
boolean ShutDown(){
if(counter%2 == 0){
digitalWrite(fan, LOW);
digitalWrite(sv2, LOW);
digitalWrite(sv1, LOW);
if (millis() >= Delay_esc){
ESC.writeMicroseconds(1000);
}
}
}
void loop(){
/*Read Buttons*/
readButtons();
Serial.print("counter = ");
Serial.println(counter);
/*if the counter is odd, then the button went from OFF to ON*/
if(counter%2 == 1){
Inputs();
Serial.print ("temp = ");
Serial.println (T_deg);
Serial.print ("pres = ");
Serial.println (P_bar);
FanOn();
Flag();
// Serial.print("flag = ");
// Serial.println(flag);
Flag2();
// Serial.print("flag2 = ");
// Serial.println(flag2);
LED();
SV2On();
SV1On();
Motor_Controller_On();
}
else{
ShutDown();
}
}