ESP32-MINI-1 "if" statements not triggering "digitalWrite"

Hi all,

I am at a loss and cannot figure this out.

I am working on a script that operates FastLED, two Mosfets, and an OLED, it is controlled via IRremote and Bluetooth via two Switchcase's. One of the "if" (first) statements controlling a mosfet is not triggering digitalWrite (digitalWrite(LEFTTAP, HIGH);). The hardware works when tested with nearly the exact timing code but without the other 2000+ lines of code. I have searched the rest of the code for any other mentions of "lefttap" without finding any. The mosfet pins can be reversed in the code - the second if statements always work, the first if statements work but do not appear to trigger the digitalwrite - the pin does not output with a measurable period using a good meter to test or the mosfet itself. I know the "if" statements are somewhat convoluted, but they do work, had I considered at the beginning how convoluted they would become, I probably would have used a switchcase or goto set.

I am using an Arduino framework on PlatformIO.

Serial output from the entire script:

Mode:
2    

    BUZZZ LEFT ON

19527

19527

    BUZZZ LEFT OFF
end

currentMillis
19727

lastExecutedMillisLeft
19527

    BUZZZ RIGHT ON

21103

21103

    BUZZZ RIGHT OFF
end

currentMillis
21303

lastExecutedMillisLeft
19527

Pertinent portions of script (reduced for readability):

//In preamble:
#define RIGHTTAP 5

#define LEFTTAP 18

unsigned long lastExecutedMillis = 0;
unsigned long lastExecutedMillisRight;
unsigned long lastExecutedMillisLeft;

int m = 1;

int left_tap_state = LOW;
int right_tap_state = LOW;
int tap_side = LOW;

//In setup:
pinMode(RIGHTTAP, OUTPUT);
pinMode(LEFTTAP, OUTPUT);

//In loop:
unsigned long currentMillis = millis();

//Left Tapper (1) (Far End) Pin not going HIGH
if ((m >= 2) && (lead_dot == travel_distanceint-1) && (left_tap_state == LOW) && (right_tap_state == LOW) &&
    (tap_side == LOW)){
              lastExecutedMillisLeft = currentMillis;
              left_tap_state = HIGH;
              digitalWrite(LEFTTAP, HIGH);                //Does not go HIGH
              digitalWrite(LED_BUILTIN, HIGH);
              Serial.println ("    BUZZZ LEFT ON");
              Serial.println("");
              Serial.println(lastExecutedMillisLeft);
              Serial.println("");
              }
if ((left_tap_state == HIGH) && (right_tap_state == LOW) && (tap_side == LOW) && 
    (currentMillis - lastExecutedMillisLeft >= 200)){ 
              Serial.println(lastExecutedMillisLeft);
              Serial.println("");
              left_tap_state = LOW;
              right_tap_state = LOW;
              tap_side = HIGH;
              digitalWrite(LEFTTAP, LOW);                 //?
              digitalWrite(LED_BUILTIN, LOW);
              Serial.println ("    BUZZZ LEFT OFF");
              Serial.println("end");
              Serial.println("");
              Serial.println ("currentMillis");
              Serial.println(currentMillis);
              Serial.println("");
              Serial.println ("lastExecutedMillisLeft");
              Serial.println(lastExecutedMillisLeft);
              Serial.println("");
              digitalWrite(LEFTTAP, LOW);
              }        

    //Right Tapper (2) (closer to controller)
if ((m >= 2) && (lead_dot == 0) && (right_tap_state == LOW) &&
    (left_tap_state == LOW) && (tap_side == HIGH)){                  
              lastExecutedMillisRight = currentMillis;
              right_tap_state = HIGH;
              digitalWrite(RIGHTTAP, HIGH);          //works
              digitalWrite(LED_BUILTIN, HIGH);
              Serial.println ("    BUZZZ RIGHT ON");
              Serial.println("");
              Serial.println(lastExecutedMillisRight);
              Serial.println("");
              }
if ((right_tap_state == HIGH) && (left_tap_state == LOW) && (tap_side == HIGH) && 
    (currentMillis - lastExecutedMillisRight >= 200)){
              Serial.println(lastExecutedMillisRight);
              Serial.println("");
              right_tap_state = LOW;
              tap_side = LOW;
              digitalWrite(RIGHTTAP, LOW);          //works
              digitalWrite(LED_BUILTIN, LOW);
              Serial.println ("    BUZZZ RIGHT OFF");
              Serial.println("end");
              Serial.println("");
              Serial.println ("currentMillis");
              Serial.println(currentMillis);
              Serial.println("");
              Serial.println ("lastExecutedMillisLeft");
              Serial.println(lastExecutedMillisLeft);
              Serial.println("");
               }

      if (( m < 2) || (pausestate == 1)){
        digitalWrite(LEFTTAP, LOW);
        digitalWrite(RIGHTTAP, LOW);
        left_tap_state = LOW;
        right_tap_state = LOW;
        digitalWrite(LED_BUILTIN, LOW);
        }

Functional Test:

#include <Arduino.h>

#define LED_BUILTIN 27

#define RIGHTTAP 5

#define LEFTTAP 18

unsigned long lastExecutedMillis = 0;
unsigned long lastExecutedMillisRight;
unsigned long lastExecutedMillisLeft;

int left_tap_state = LOW;
int right_tap_state = LOW;
int tap_side = LOW;

void setup() {

    pinMode(RIGHTTAP, OUTPUT);
    pinMode(LEFTTAP, OUTPUT);

  Serial.begin(115200);
}

void loop() {


  unsigned long currentMillis = millis();

        //Left Tapper
        if ((left_tap_state == LOW) && (right_tap_state == LOW) && (tap_side == LOW)){
              left_tap_state = HIGH;
              lastExecutedMillisLeft = currentMillis;
              digitalWrite(LEFTTAP, HIGH);          
              digitalWrite(LED_BUILTIN, HIGH);
              Serial.println ("    BUZZZ LEFT ON");
              Serial.println("");
              Serial.println(lastExecutedMillisLeft);
              Serial.println("");
              }
        else if ((left_tap_state == HIGH) && (right_tap_state == LOW) && (tap_side == LOW) && 
        (currentMillis - lastExecutedMillisLeft >= 250)){
          Serial.println(lastExecutedMillisLeft);
          Serial.println("");
              left_tap_state = LOW;
              right_tap_state = LOW;
              tap_side = HIGH;
              digitalWrite(LEFTTAP, LOW);
              digitalWrite(LED_BUILTIN, LOW);
              Serial.println ("    BUZZZ LEFT OFF");
              Serial.println("end");
              Serial.println("");
              digitalWrite(LEFTTAP, LOW);

     }
          

        if ((right_tap_state == LOW) && (left_tap_state == LOW) && (tap_side == HIGH)){                  //Right Tapper (closer to controller)
              lastExecutedMillisRight = currentMillis;
              right_tap_state = HIGH;
              digitalWrite(RIGHTTAP, HIGH);          //works
              digitalWrite(LED_BUILTIN, HIGH);
              Serial.println ("    BUZZZ RIGHT ON");
              Serial.println("");
              Serial.println(lastExecutedMillisRight);
              Serial.println("");
              }
        else if ((right_tap_state == HIGH) && (left_tap_state == LOW) && (tap_side == HIGH) && 
        (currentMillis - lastExecutedMillisRight >= 250)){
              Serial.println(lastExecutedMillisRight);
              Serial.println("");
              right_tap_state = LOW;
              tap_side = LOW;
              digitalWrite(RIGHTTAP, LOW);
              digitalWrite(LED_BUILTIN, LOW);
              Serial.println ("    BUZZZ RIGHT OFF");
              Serial.println("end");
              Serial.println("");
     }
        Serial.println("LED Travel");
        Serial.println("");
          }

Thanks for reading this far:)

The first "if" always false because one of conditions (m>=2) and m =1;

Thanks for catching that Hopper, I should have caught that and explained in my description of the script. (Mode) m = 1 is in the preamble so as not to trigger the mosfets until m is updated via the ir remote from a switchcase in the loop, my testing is all done with m = 2 or 3. Sorry for not noticing and explaining this.

If the if-condition evaluates to true
all, each and every command inside the opening and closing curly braces belonging to the if-condition are executed.

If you could not rely on this
the modern IT-based world would have broken down 40 years ago

All lines of code or zero lines of code but nothing inbetween!
You could analyse this by adding a serial print right in front of the digitalWrite and behind it

This means you measured with a digital multimeter?
How about connecting a resistor and a LED to the IO-pin to see if the LED is flashing?

What MOS-FET are you using? Is the gate-voltage high enough for proper switching to real good conducting of the MOS-FET?

what?

lots of lines of code.
Does this mean you have around 2000 lines of code all inside loop?
This can work. But it will be very awful to maintain such a code-structure

You should organise your code into functions.

And if your code is well organised in function your code could be 4000 lines long
posting the complete code with some hints where you assume the bug might be every experienced used would be happy to have the complete 4000 lines of code instead of beeing forced to guess what the bug might be.

Thanks for your reply StefanL38,

I did test the pin directly at the module with a digital multimeter. Additionally, the mosfet and a corresponding motor are connected to it, I know these to work because they work in the provided test code.

The digitalwrite command in question is being proven active by the serial output "Serial.println (" BUZZZ LEFT ON");" being displayed in the provided serial output.

Yes, my current code is about 2800 lines. I am unfortunately not able to organize it into functions because the resulting interrupts would prevent FastLED from running. The current period for the loop to process is less then 4ms, so although it is very challenging to work with, it is fast enough for my purposes.

The many if comparison conditions are avoidable using other methods, but I had started with a simpler script from a previous version and did not consider that I could have used a simpler switchcase instead. It works other then the first digitalwrite - so I left it instead of rewriting the section.

If your code needs to run so fast I would change to a faster microcontroller that can be programmed with the arduino-IDE too.

A Teensy 4.0 or Teensy 4.1 runs on 600 MHz.

Why would using functions invoke interrupts? A function-call would cause a short delay for pushing / pulling values to / from the stack and jumping to another memory-adress to execute the code inside the function, but won't invoke interrupts.

If you don't mind posting your code it would be interesting to find out the looping-time of your code on a teensy 4.0

best regards Stefan

Thanks for the thought and offer Stefan. I am stuck with this - the ESP32-MINI-1 is running on a custom PCB. I spec'd the MINI because of space constraints, $, Wifi and bluetooth, it was supposed to be dual core but I was not aware that my assembler purchased Espressif's first version's that were undocumented to actually be single core. I needed dual core so that FastLED could run uninterrupted on one core and everything else on the other core. I have ALOT of these sitting, waiting for my approval to be assembled, so I am trying to prove that it can function well enough to work reliably until I run out of this version and re-design it with a dual core.

I think the function call would cause a long enough delay for FastLED to skip - but I could be wrong. FastLED is operating at a maximum of 2Hz.

I am sorry but I am not comfortable posting the full code. I was hoping this would be enough, I do understand how frustrating it must be to try and help without the full code, no worries, if the error does not pop-out to someone, I will just keep working on it.

The overhead of a function call (vs inline inside loop) is on the order of a microsecond. And if you mark your functions static, the compiler will likely inline the code from the functions (especially "small" functions) into where they're called anyway, completely removing the function call overhead.

Awesome, thanks for that Christop, I will likely give that a try.

Problem solved! It seems that SPI.h has a library conflict. Commenting it out solved the issue (I should have tried this a week ago). SPI.h was only included for a past version of my code and for testing, so I don't think I am going to need to find the actual conflict.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.