Problems with static variable

I was experimenting with a multitasking library (cth from CopyThreads), when I got a mystic behavior of the program - a static int variable would not work ???

I use IDE version 1.8.10, and run it on an Uno.

I tried to quit the library, but I still get the same behavior, with the following relatively simple code:

// Output
int grnPin = 3;  // Green LED, connected to digital pin 3
int yelPin = 4;  // Yellow LED,  connected to digital pin 4
int redPin = 5;  // Red LED,   connected to digital pin 5
int kontLED = 6; // LED for indicationg LED state
int kontakt = 8; // Contact input from switch

void setup() {
  pinMode(redPin, OUTPUT);   // sets the pins as output
  pinMode(grnPin, OUTPUT);
  pinMode(yelPin, OUTPUT);

  Serial.begin(9600);  // ...set up the serial ouput

}

boolean redState = false;
boolean grnState = false;
boolean yelState = false;

void loop() {
  blinkRed();
  blinkGrn();
  blinkYel();
}

unsigned long nextTimeRed = 0;
unsigned long nextTimeGrn = 0;
unsigned long nextTimeYel = 0;

void blinkRed(void)
{
  static int val = analogRead(A0);
  val = map(val, 0, 1023, 100, 1000);
  if (millis() - nextTimeRed >= val) {
    nextTimeRed += val;
    digitalWrite(redPin, redState);
    redState = ! redState;
    Serial.print(val);
    Serial.println(" Red");
  }
}

void blinkGrn(void)
{
  if (millis() - nextTimeGrn >= 2000) {
    nextTimeGrn += 2000;
    digitalWrite(grnPin, grnState);
    grnState = ! grnState;
    Serial.print(millis());
    Serial.println("  Grn");
  }
}

void blinkYel(void)
{
  if (millis() - nextTimeYel >= 500) {
    nextTimeYel += 500;
    digitalWrite(yelPin, yelState);
    yelState = ! yelState;
    Serial.print(millis());
    Serial.println("  Yel");
  }
}

The variable that fails is at line 33, and converted with map() it is stuck at 824, and not changeing although the input at A0 changes.

If I change the code to use a simple local variable it works.

If I move the variable out as a global variable it works.

I am confused

It's working as expected. A static variable can be initialized, which is what you're doing with the analogRead. But it only happens once for the life of the program. It's as if you made it global and initialized it and never did another analogRead in your blinkRed function.

So that was my mistake :slight_smile:

Thank you very much for clarifying the way it works.

if (millis() - nextTimeRed >= val) {

This mixes unsigned long integers and signed integers in a comparison. Why not make val an unsigned int? You can still map to it the same range? Also, move the following line outside the conditional to better understand why the conditional is no longer true.

Serial.print(val);

wildbill:
It's working as expected. A static variable can be initialized, which is what you're doing with the analogRead. But it only happens once for the life of the program. It's as if you made it global and initialized it and never did another analogRead in your blinkRed function.

I totally missed that as well.

static unsigned long mappedValue;
int val = analogRead(A0);
mappedValue = map(val, 0, 1023, 100, 1000);
if (millis() - nextTimeRed >= mappedValue) {
  nextTimeRed += mappedValue;

Also, why does it need to be static? Each time you enter the loop, you update it based on analogRead, so couldn't it be local?