XRAD'S Issue with FADE or BLINK teensy 4.0

XRAD

Well-known member
I have tried many variations of FADE and BLINK non blocking code (not just what is here below), but the same issue persists. Either will work fine without the other in the loop. The FADE and BLINK functions do not work together in the loop, and the FADE seems to block the LED display. I'm confused and not sure how to correct the issue. I have reviewed in depth the libraries and there does not seem to be anything obvious that is causing this issue. I am getting accurate distance reads. I can flag the distance and that works fine. Maybe it's an internal timer conflict?? Any help much appreciated!!

Hardware: Teensy 4.0, standard 5v LEDs with 200 ohm resistors. HC-SR04 ultrasoud detector.

Code:
#include <LEDFader.h>
#include <Ultrasonic.h>

Ultrasonic ultrasonic(2, 20);//trig, output
int distance;
unsigned long US_Distance_Ping_Timer = 0;

unsigned long LED_BLINK_Timer = 0;

const int LED_RIGHT_EYE = 4;
const int LED_LEFT_EYE = 3;

int ledState = LOW;

#define LED_NUM 2

LEDFader leds[LED_NUM] = {
  LEDFader(LED_RIGHT_EYE),
  LEDFader(LED_LEFT_EYE)
};

 
unsigned long currentMillis = 0;

//array of subjective milli run times
int MillisRunLengthTime[7] = { 20, 200, 800, 1000, 1500, 2000, 2500 };

//this is the key timer function, can use for MANY functions
boolean RunForThisAmountOfTime(unsigned long &startNowTimer, int runLengthTime) {
  currentMillis = millis();
  if (currentMillis - startNowTimer >= runLengthTime) {
    startNowTimer = currentMillis;
    return true;
  } else return false;
}


void setup() {
  pinMode(LED_RIGHT_EYE, OUTPUT);
  pinMode(LED_LEFT_EYE, OUTPUT);
}

void loop() {

  if (RunForThisAmountOfTime(US_Distance_Ping_Timer, MillisRunLengthTime[1])) {
    distance = ultrasonic.read();
    Serial.print("Distance in CM: ");
    Serial.println(distance);
  }

  if (distance <= 25) {
    BLINK();
  } else {
    FADER();
  }
}

void BLINK() {
  if (RunForThisAmountOfTime(LED_BLINK_Timer, MillisRunLengthTime[3])) {
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(LED_RIGHT_EYE, ledState);
    digitalWrite(LED_LEFT_EYE, ledState);
  }
}


void FADER() {
  for (byte i = 0; i < LED_NUM; i++) {
    LEDFader *led = &leds[i];
    if (distance <= 25) {
      BLINK();
    } else {
      led->update();
    }
    if (led->is_fading() == false) {
      if (led->get_value() == 0) {
        led->fade(255, 1000);
      } else {
        led->fade(0, 1000);
      }
    }
  }
}
 
updated code, but no change to initial issue.... any help MUCH appreciated!

Code:
#include <LEDFader.h>
#include <Ultrasonic.h>

Ultrasonic ultrasonic(2, 20);
int distance;
unsigned long US_Distance_Ping_Timer = 0;

unsigned long LED_BLINK_Timer = 0;

const int LED_RIGHT_EYE = 4;
const int LED_LEFT_EYE = 3;

int ledState  = LOW;

#define LED_NUM 2

LEDFader leds[LED_NUM] = {
  LEDFader(LED_RIGHT_EYE),
  LEDFader(LED_LEFT_EYE)
};

 
unsigned long currentMillis = 0;

//array of subjective milli run times
int MillisRunLengthTime[7] = { 20, 200, 800, 1000, 1500, 2000, 2500 };

//this is the key timer function, can use for MANY functions
boolean RunForThisAmountOfTime(unsigned long &startNowTimer, int runLengthTime) {
  currentMillis = millis();
  if (currentMillis - startNowTimer >= runLengthTime) {
    startNowTimer = currentMillis;
    return true;
  } else return false;
}


void setup() {
  pinMode(LED_RIGHT_EYE, OUTPUT);
  pinMode(LED_LEFT_EYE, OUTPUT);
}

void loop() {

  if (RunForThisAmountOfTime(US_Distance_Ping_Timer, MillisRunLengthTime[1])) {
    distance = ultrasonic.read();
    Serial.print("Distance in CM: ");
    Serial.println(distance);
  }

  if (distance <= 25) {
    BLINK();
  } else {
    FADER();
  }
}

void BLINK() {
  if (RunForThisAmountOfTime(LED_BLINK_Timer, MillisRunLengthTime[3])) {
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(LED_RIGHT_EYE, ledState);
    digitalWrite(LED_LEFT_EYE, ledState);
  }
}


void FADER() {
  for (byte i = 0; i < LED_NUM; i++) {
    LEDFader *led = &leds[i];
      led->update();
    if (led->is_fading() == false) {
      if (led->get_value() == 0) {
        led->fade(255, 1000);
      } else {
        led->fade(0, 1000);
      }
    }
  }
}
 
even with a simple button press, same issue. Maybe has to do with not updating LED state when I switch functions... maybe I need a global updateLED(); function...

Code:
#include <LEDFader.h>


unsigned long LED_BLINK_Timer = 0;
//unsigned long LED_FADE_Timer = 0;
int value = 0;

int brightness = 0;   // how bright the LED is
int fadeAmount = 10;  // how many points to fade the LED by
unsigned long Fade_Timer = 0;

const int LED_RIGHT_EYE = 4;
const int LED_LEFT_EYE = 3;

int ledState = LOW;


#define LED_NUM 2

LEDFader leds[LED_NUM] = {
  LEDFader(LED_RIGHT_EYE),
  LEDFader(LED_LEFT_EYE)
};


unsigned long currentMillis = 0;

//array of subjective milli run times
int MillisRunLengthTime[7] = { 20, 200, 800, 1000, 1500, 2000, 2500 };

//this is the key timer function, can use for MANY functions
boolean RunForThisAmountOfTime(unsigned long &startNowTimer, int runLengthTime) {
  currentMillis = millis();
  if (currentMillis - startNowTimer >= runLengthTime) {
    startNowTimer = currentMillis;
    return true;
  } else return false;
}

const int buttonPin = 23;
const int ledPin = 13;
int buttonState = 0;


void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLDOWN);
  pinMode(LED_RIGHT_EYE, OUTPUT);
  pinMode(LED_LEFT_EYE, OUTPUT);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
    BLINK();
  } else {
    digitalWrite(ledPin, LOW);
    //FADER();
  }
}


void BLINK() {
  if (RunForThisAmountOfTime(LED_BLINK_Timer, MillisRunLengthTime[3])) {
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(LED_RIGHT_EYE, ledState);
    digitalWrite(LED_LEFT_EYE, ledState);
  }
}


void FADER() {
  for (byte i = 0; i < LED_NUM; i++) {
    LEDFader *led = &leds[i];
    // led->update();
    if (led->is_fading() == false) {
      if (led->get_value() == 0) {
        led->fade(255, 1000);
      } else {
        led->fade(0, 1000);
      }
    }
    led->update();
  }
}
 
I presume the fader uses PWM output (analogWrite), which is not compatible with digitalWrite on the Teensy if I remember right - on the ARM digitalWrite has the pin mapped to GPIO, analogWrite has it mapped to some timer internally.
 
Hi Mark, thank you for reply! I figured it out late last night..... this code works in case anyone wants to use it:
harware: Teensy 4.0 and x2 one color 5v LEDs with 200ohm resistors

Code:
unsigned long CLEAR_LED_Timer = 0;
unsigned long LED_BLINK_Timer = 0;
unsigned long LED_FADE_Timer = 0;

int value = 0;
int brightness = 0;
int fadeAmount = 5;

const int LED_RIGHT_EYE = 4;
const int LED_LEFT_EYE = 3;

int ledState = LOW;
bool eyeStateClear = true;

unsigned long currentMillis = 0;

//array of subjective milli run times
int MillisRunLengthTime[8] = { 20, 100, 200, 800, 1000, 1500, 2000, 2500 };

//this is the key timer function, can use for MANY functions
boolean RunForThisAmountOfTime(unsigned long &startNowTimer, int runLengthTime) {
  currentMillis = millis();
  if (currentMillis - startNowTimer >= runLengthTime) {
    startNowTimer = currentMillis;
    return true;
  } else return false;
}

const int buttonPin = 23;
const int ledPin = 13;
int buttonState = 0;

enum eyeStates {
  BLINK_BOTH_EYES,  // blink both eyes
  FADE_BOTH_EYES,   // fade both eyes
  CLEAR_EYES,       // clear eye variables
  BLINK_RIGHT_EYE,  //
  BLINK_LEFT_EYE,
  BOTH_EYES_ON,
  BOTH_EYES_OFF
};

enum eyeStates EYE_FUNCTIONS();


void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLDOWN);
  pinMode(LED_RIGHT_EYE, OUTPUT);
  pinMode(LED_LEFT_EYE, OUTPUT);
}



void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
    //digitalWrite(ledPin, HIGH);//for debugging
    eyeStateClear = true;
    EYE_FUNCTIONS(BLINK_BOTH_EYES);
  } else {
    //digitalWrite(ledPin, LOW);
    if (eyeStateClear == true) {
      eyeStateClear = false;
      EYE_FUNCTIONS(CLEAR_EYES);//need to clear FADE variables
    }
    EYE_FUNCTIONS(FADE_BOTH_EYES);
  }
}


void EYE_FUNCTIONS(int var) {
  switch (var) {
    case 0:  //blink LEDs
      if (RunForThisAmountOfTime(LED_BLINK_Timer, MillisRunLengthTime[2])) {
        if (ledState == LOW) {
          ledState = HIGH;
          if (ledState == HIGH) {
            brightness = 255;
          }
        } else {
          ledState = LOW;
          if (ledState == LOW) {
            brightness = 0;
          }
        }
        analogWrite(LED_RIGHT_EYE, brightness);
        analogWrite(LED_LEFT_EYE, brightness);
      }
      break;
    case 1:  //fade LEDs
      if (RunForThisAmountOfTime(LED_FADE_Timer, MillisRunLengthTime[0])) {
        brightness = brightness + fadeAmount;
        if (brightness <= 0 || brightness >= 255) {
          fadeAmount = -fadeAmount;
        }
      }
      analogWrite(LED_RIGHT_EYE, brightness);
      analogWrite(LED_LEFT_EYE, brightness);
      break;

    case 2:  //clear LEDs
      fadeAmount = 0;
      brightness = 0;
      LED_FADE_Timer = 0; 
      analogWrite(LED_RIGHT_EYE, 0);
      analogWrite(LED_LEFT_EYE, 0);
      fadeAmount = 5;
      break;

    case 3:  //blink RIGHT eye
      if (RunForThisAmountOfTime(LED_BLINK_Timer, MillisRunLengthTime[2])) {
        if (ledState == LOW) {
          ledState = HIGH;
          if (ledState == HIGH) {
            brightness = 255;
          }
        } else {
          ledState = LOW;
          if (ledState == LOW) {
            brightness = 0;
          }
        }
        analogWrite(LED_RIGHT_EYE, brightness);
        analogWrite(LED_LEFT_EYE, 0);
      }
      break;

    case 4:  //blink LEFT eye
      if (RunForThisAmountOfTime(LED_BLINK_Timer, MillisRunLengthTime[1])) {
        if (ledState == LOW) {
          ledState = HIGH;
          if (ledState == HIGH) {
            brightness = 255;
          }
        } else {
          ledState = LOW;
          if (ledState == LOW) {
            brightness = 0;
          }
        }
        analogWrite(LED_RIGHT_EYE, 0);
        analogWrite(LED_LEFT_EYE, brightness);
      }
      break;

    case 5:  //both eyes ON
      analogWrite(LED_RIGHT_EYE, 255);
      analogWrite(LED_LEFT_EYE, 255);
      break;

    case 6:  //both eyes OFF
      analogWrite(LED_RIGHT_EYE, 0);
      analogWrite(LED_LEFT_EYE, 0);
      break;
  }
}

//========end============
 
Last edited:
Back
Top