I have some complex conditions in my if statements and I was wondering if there is a way to output what condition passed when using OR in if statements?
at a basic level, this is what I am trying to achieve.
if (condition_1 || condition_2 || condition_3){
Serial.println( the condition that passed the if statement );
}
At the moment I am just printing out all the variables belonging to the if statement and tracing back from there to see what condition passed but this is time-consuming and as my code gets bigger and more complex if or statements get added it will become very difficult to keep track.
bool c_1 = condition_1;
bool c_2 = condition_2;
bool c_3 = condition_3;
if (c_1 || c_2 || c_3){
if (c_1) Serial.println("1st condition that passed the if statement");
if (c_2) Serial.println("2nd condition that passed the if statement");
if (c_3) Serial.println("3rd condition that passed the if statement");
}
@PaulRB not quite, as C/C++ has short circuit evaluation.
If c_1 triggers the execution of the body, c_2 may well be true but did not pass the if statement.
bool c_1 = condition_1;
bool c_2 = condition_2;
bool c_3 = condition_3;
if (c_1 || c_2 || c_3){
if (c_1) Serial.println("1st condition passed the if statement");
else if (c_2) Serial.println("2nd condition passed the if statement");
else if (c_3) Serial.println("3rd condition passed the if statement");
}
@alto777 quite true, but even your refinement does not make the code behave exactly as the original in all circumstances. In the original, if condition_1 is true, condition_2 and _3 are not evaluated. In both our versions, all 3 are always evaluated, and any side-effects of those evaluations will always occur, unlike in the original. For example the conditions might compare one variable to another and apply ++ or -- to one variable.
But judging by the question, I think short circuit evaluation and side-effecting are a little beyond @staroflaw 's experience at this point. They need to build up their basic coding skills at the moment, and the effects we are discussing will make more sense when they encounter them for the first time in their own code.
What I meant was: both our codes evaluate all 3 "conditions" in advance, and assign the results to 3 bool variables. I agree that the if() should not check the second or third bool variables if the first bool variable is true. But at that point, all 3 "conditions" have been previously evaluated.
No. I think we agree that the if/else will not go further in evaluating the conditions than it has to.
As for time/efficiency, there is nothing to worry about, either way of expressing a short circuit in the sequential evaluations will take about the same time.
Writing it out if/else might be more clear explicit. But most ppl do know about short circuit logic.
Was that >> supposed to be > ? (>> means bit-shift-right!)
Correct, in theory. The code I and @alto777 posted might waste cycles that could have been avoided. From your original question, it did not sound like you were experienced enough to be aware of such things! The solution you are now proposing could prevent those wasted cycles.
In practice, in your example above, the second and third criteria are so trivial to evaluate that it will probably make no difference. But in an example where the second and third criteria are more complex, your method could definitely save some cycles.
(>> means bit-shift-right!) - Never even thought of that. The IDE was happy so I just accepted it but thanks for pointing that out as I need to be more aware.
@PaulRB No the comma wasn't supposed to be there it was a typo. Well spotted tho, you all have keen eyes
Still a huge amount to learn and I didn't want to come across as more experienced than I was so I tried to keep it simple, just didn't really give enough information for the help I needed. But I got there in the end.....
My objective is to test various gauges of nichrome/other wire to see how long and what current it takes to blow. This is a stripped-down function I have so far. The ADC takes about 65uS to complete each cycle and for now that's fine as I can play with that once my code runs as expected. Once the wire has blown (detected by trip_threshold) it should go into (if (pass_code > 0){) and output various information and depending on the pass_code eventually pass to other functions for more testing.
void runTest(){
// Setup
unsigned long timeout_t = 10000; // 10,000uS - 10mS
int a_pin = ADC_1, f_pin = debug_pin;
int loop_count, low_count, high_count, trip_count = 0;
int low_threshold = 250, high_threshold = 251, trip_threshold = 3;
int buffer[160]; // buffer to store ADC readings
int pass_code = 0;
// Enable FET pin
digitalWrite(f_pin, HIGH);
// set start time
unsigned long start_t = micros();
// Start loop
int x=0; while (x==0){
// read ADC
int adc_val = analogRead(a_pin);
if (adc_val >= high_threshold) {high_count++; trip_count = 0;}
if (adc_val <= low_threshold) {low_count++; trip_count++;}
// save to buffer
buffer[loop_count] = adc_val;
if (micros() - start_t >= timeout_t) {
pass_code = 1;
} else if (trip_count >= trip_threshold) {
pass_code = 2;
} else if (high_count >= 15){
pass_code = 3;
} else if (low_count >= 15){
pass_code = 4;
}
if (pass_code > 0){
// Disable FET pin
digitalWrite(f_pin, LOW);
// Debug - Print out pass_code
Serial.println(pass_code);
// print buffer content
for (int i=0; i<=loop_count; i++){
Serial.printf("%d, ", buffer[i]);
if (i==loop_count) {Serial.println("\n");}
}
// end while loop
x=1;
}
// increase loop count
loop_count++;
}
}
I will test what I have so far when I get home and see how it behaves. As always I really appreciate all the help and time you have all taken to help me.
The while loop keeps polling the ADC and checking the results against the if statements until one of the conditions is met or a timeout is reached. Then x=1 stops the while loop and allows the function to end. The while loop runs approx 150 times before timeout is reached or less if one of the other conditions is met.
If/when the time comes that you need non-blocking code, runTest can (easily?) be changed into a routine that is meant to be called very frequently.
To do its job (or nothing) one step at a time and perhaps return a value that indicates whether pass_code did in fact end up letting something else happen and maybe even why.