Hello, I have an issue and can't figure out a solution. This is a code that I'm writing for a hybrid system, when the gas engine goes below a given range (545-550) nothing happens until the RPM are lower or equal to 530, in that case I would need the electric motor to run until RPM are back to the lowest value of the range (545) but cant go higher than the second value (550), so it would need to stop spinning the electric motor at 545
N.B. In the final code the 2 values for the range are given by a potentiometer where:
545 = pot_val - 5
550 = pot_val (pot val are obtained trought the map function since the max val can be 550)
530 = pot_val2 (another potentiometer for the RPM value where the electric motor activates)
the variables are these:
Kelly_PWR = relay activating to make electric motor spin
em_led = Emergency LED showing the electric motor is spinning
loosing_rpm_led = LED that shows that RPM are decreasing from 545 to 530
I can't manage to code the part where if RPM <= 530; Kelly_PWR = HIGH until the RPM are back in the 545 - 550 range.
The problem with my code is that it activates the electric motor (Kelly_PWR) only until RPM are = 530 , and when that condition is true, the electric motor turns off without bringing the RPM back to 545 which is what I would need
this is the code:
if (RPM >= 545 && RPM <= 550) {
Serial.println("RPM ARE OKAY");
digitalWrite(kelly_PWR, LOW);
digitalWrite(em_led, LOW);
digitalWrite(loosing_rpm_led, LOW);
Serial.println(soglia1);
Serial.println(soglia2);
}
else if (RPM <= 530) {
digitalWrite(kelly_PWR, HIGH);
delay(100);
digitalWrite(em_led, HIGH);
digitalWrite(loosing_rpm_led, LOW);
delay(100);
Serial.println(RPM);
Serial.println("LOW RPM DETECTED, EM. MOTOR ACTIVATION");
Serial.println(map_pot_value);
}
else {
Serial.println("\tLOOSING RPM:");
Serial.println(RPM);
while this one here is the full code:
//Konner Helicopters
//Konner S.r.l.
// Calibration:
const byte PulsesPerRevolution = 1; //# of pulses per revolution
const unsigned long ZeroTimeout = 500000; // to work with low RPM higher #
const byte numReadings = 2; //# of samples per smoothing: HIGHER = SMOOTHER = SLOWER (1: no smoothing / 2: default)
volatile unsigned long LastTimeWeMeasured;
volatile unsigned long PeriodBetweenPulses = ZeroTimeout + 1000;
volatile unsigned long PeriodAverage = ZeroTimeout + 1000;
unsigned long FrequencyRaw;
unsigned long FrequencyReal;
unsigned long RPM;
unsigned int PulseCounter = 1;
unsigned long PeriodSum;
unsigned long LastTimeCycleMeasure = LastTimeWeMeasured;
unsigned long CurrentMicros = micros();
unsigned int AmountOfReadings = 1;
unsigned int ZeroDebouncingExtra;
unsigned long ramp_value;
unsigned long buttonState;
unsigned long readings[numReadings];
unsigned long readIndex;
unsigned long total;
unsigned long average;
int em_led = 13; //emergency led pin
int loosing_rpm_led = 12;
int kelly_PWR = 11; //5v to kelly pin (rele)
int pot = A0; //pot1 MIN VALUE RPM
int pot2 = A1; //pot2 RANGE VALUE RPM to reach
int BTT = 7; //emulator button for testing
void setup() // Start of setup:
{
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(2), Pulse_Event, RISING); // Enable interruption pin 2 when going from LOW to HIGH.
pinMode(kelly_PWR, OUTPUT);
pinMode(em_led, OUTPUT);
pinMode(loosing_rpm_led, OUTPUT);
pinMode(pot, INPUT);
pinMode(pot2, INPUT);
pinMode(BTT, INPUT);
delay(1000);
} // End of setup.
void loop() // Start of loop:
{
LastTimeCycleMeasure = LastTimeWeMeasured;
CurrentMicros = micros(); // Store the micros() in a variable.
if (CurrentMicros < LastTimeCycleMeasure)
{
LastTimeCycleMeasure = CurrentMicros;
}
// Calculate the frequency:
FrequencyRaw = 10000000000 / PeriodAverage;
if (PeriodBetweenPulses > ZeroTimeout - ZeroDebouncingExtra || CurrentMicros - LastTimeCycleMeasure > ZeroTimeout - ZeroDebouncingExtra)
{
FrequencyRaw = 0;
ZeroDebouncingExtra = 2000;
}
else
{
ZeroDebouncingExtra = 0;
}
FrequencyReal = FrequencyRaw / 10000; // Get frequency without decimals.
//Calculate the RPM: --> !!Must bypass to test with button. Find RPM in "if" statement below
RPM = FrequencyRaw / PulsesPerRevolution * 60;
RPM = RPM / 10000;
// Smoothing RPM:
total = total - readings[readIndex];
readings[readIndex] = RPM;
total = total + readings[readIndex];
readIndex = readIndex + 1;
if (readIndex >= numReadings)
{
readIndex = 0;
}
// Calculate the average:
average = total / numReadings;
// buttonState = digitalRead(BTT); if (buttonState == LOW) { RPM = 550;} else { RPM= 530; } //BUTTON RPM SIMULATOR
Serial.print("Period: ");
Serial.print(PeriodBetweenPulses);
Serial.print("\tReadings: ");
Serial.print(AmountOfReadings);
Serial.print("\tFrequency: ");
Serial.print(FrequencyReal);
Serial.print("\tRPM: ");
Serial.print(RPM);
Serial.print("\tTachometer: ");
Serial.println(average);
int pot_value = analogRead(pot);
int pot_value2 = analogRead(pot2);
int map_pot_value = map(pot_value, 0, 1028, 0, 550); //MIN RPM
int map_pot_value2 = map(pot_value2, 0, 1028, 250, 540); //RANGE RPM
int soglia1 = map_pot_value2 - 5;
int soglia2 = map_pot_value2;
Serial.println(map_pot_value);
Serial.println(map_pot_value2);
Serial.println(soglia1);
Serial.println(soglia2);
delay(100);
if (RPM >= soglia1 && RPM <= soglia2) {
Serial.println("RPM ARE OKAY");
digitalWrite(kelly_PWR, LOW);
digitalWrite(em_led, LOW);
digitalWrite(loosing_rpm_led, LOW);
Serial.println(soglia1);
Serial.println(soglia2);
}
else if (RPM <= map_pot_value) {
digitalWrite(kelly_PWR, HIGH);
delay(100);
digitalWrite(em_led, HIGH);
digitalWrite(loosing_rpm_led, LOW);
delay(100);
Serial.println(RPM);
Serial.println("LOW RPM DETECTED, EM. MOTOR ACTIVATION");
Serial.println(map_pot_value);
}
else {
Serial.println("\tLOOSING RPM:");
Serial.println(RPM);
}
} //voidloop end
void Pulse_Event() // The interrupt runs this to calculate the period between pulses:
{
PeriodBetweenPulses = micros() - LastTimeWeMeasured;
LastTimeWeMeasured = micros();
if (PulseCounter >= AmountOfReadings)
{
PeriodAverage = PeriodSum / AmountOfReadings;
PulseCounter = 1;
PeriodSum = PeriodBetweenPulses;
int RemapedAmountOfReadings = map(PeriodBetweenPulses, 40000, 5000, 1, 10);
RemapedAmountOfReadings = constrain(RemapedAmountOfReadings, 1, 10);
AmountOfReadings = RemapedAmountOfReadings;
}
else
{
PulseCounter++;
PeriodSum = PeriodSum + PeriodBetweenPulses;
}
} // End of Pulse_Event.
//Konner s.r.l -- Hybrid Fligh Assistant H.F.A.