Compiler problem?

Excuse me if this has been mentioned before but I couldn’t think of a suitable search string to find out.

I have an old program of mine that is working as I want (compiled with VER 1.6.something) and in that program is a debounce routine. The program I’m currently working on also needed a debounce routine so I decided to borrow it from there rather than work the logic out again.

This is the code in question

bool lastansense[4] = {false, false, false, false};
// global variable declared at the beginning
void analogSensorStatus(byte sensor) {
  /* needs to be debounced or the srvo could go crazy if we have
   *  set the bit to drive the servo from the sensor
   */
  byte analogsensorpin[4] = {4, 5, 6, 7};
  byte av;
  bool ansense;
  byte hyst = 2;
  ansense = lastansense; //set a default
  av = map(analogRead(analogsensorpin[sensor]), 0, 1023, 0, 255);
  if (av > (CVtable.CV[sensor + 4]) + hyst) {
    ansense = true;
  }
  if (av < (CVtable.CV[sensor + 4]) - hyst) {
    ansense = false;
  }
  // now debounce
  if (ansense != lastansense[sensor]) {
    lastDebounceTime[sensor] = millis();
  }
  if ((millis() - lastDebounceTime[sensor]) > debounceDelay) {
    // it's been constant for the debounce time so accept it
    analogsensor[sensor] = ansense;
  }
  lastansense[sensor] = ansense;
}

While doing so I noticed that this line near the start

  ansense = lastansense; //set a default

Is referring to a variable ‘lastansense’ and that variable is not declared anywhere, I checked with the ‘find’ tool.

But it compiles without throwing up an ‘undefined variable’ error. (I’m now using VER 1.8.1)

Rechecking I find that it only comes up as a warning, and then only if verbose and MORE are set in preferences

C:\Users\Dave\AppData\Local\Temp\arduino_modified_sketch_616406\DEIServo1v2.ino:1251:11: warning: the address of ‘lastansense’ will always evaluate as ‘true’ [-Waddress]

ansense = lastansense; //set a default

This seems a bit odd that it is only considered as a warning.

Now when I included it in my new program it came out like this

void TestCalButton() {
  //test cal button with debounce
  calPressed = (digitalRead(calButton) == 0);
  // true if pressed, false if not;
  if (calPressed != lastCal) {
    //it's changed
    lastDebounceTime = millis;
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // been stable debounce delay time
    if (calPressed) {
      setOffsets();
    }
  }
  lastCal = calPressed;
}

Can you spot the mistake? It didn’t debounce at all. Eventually I spotted it
lastDebounceTime = millis; should have been lastDebounceTime = millis();

This time the compiler threw up a warning without verbose being needed

C:\Users\Dave\AppData\Local\Temp\arduino_modified_sketch_141935\halleffect4.ino:344:22: warning: invalid conversion from ‘long unsigned int (*)()’ to ‘long unsigned int’ [-fpermissive]

lastDebounceTime = millis;

but as ‘millis’ was nicely colored red in the code, and it was only listed as a warning I didn’t take much notice. But why again did it not get thrown up as an undeclared variable?

Regards
Dave

  1. lastansense Is declared! - it's the first line of your code.

  2. The name of an array gives the address of the first element in the array.

Mark

You are not calling millis(), you try to assign its address to a long unsigned int.

TrylastDebounceTime = millis();

holmes4: 1. lastansense Is declared! - it's the first line of your code.

  1. The name of an array gives the address of the first element in the array.

Mark

Thanks! Now I did wonder if that was the answer. So when I coded ansense = lastansense; It's the same as coding ansense = lastansense[0]; or not?

Any comments on the millis part of my post? regards Dave

No, it's the same as writeing ansense = &lastsense[0];

PS, if you formatVariablesLikeThis is easier to read PSS, if you want to reuse a part of your code it's useful to convert it into a library. (Which is not the same as a class, just files with the functions and variables you want the reuse.)

septillion: No, it's the same as writeing ansense = &lastsense[0];

PS, if you formatVariablesLikeThis is easier to read PSS, if you want to reuse a part of your code it's useful to convert it into a library. (Which is not the same as a class, just files with the functions and variables you want the reuse.)

I have never been able, in all the tens of years I've been coding, to get my head round what is a pointer and what is not a pointer. I can understand redirection, I used it a lot when I was coding 6502, but when a variable is a pointer and when it's not, I have never managed to really grasp it. So I don't use them, perhaps I should and the mist might clear.

I've often thought of putting a few of the routines I use frequently in a library but don't. Cut and paste with mods where needed works just fine for me and if I want to share my code I don't have to worry about sending the library as well.

Regards Dave

Its a pointer if you declare it as a pointer or an array or a function, or take the address of a variable. You can think of it as an array is implemented as a pointer to the 0'th element and a function is implemented as a pointer to the code. Other types like numbers and structs are just values without an address.

The more confusing part are reference types, which are pointers that are automatically dereferenced by the compiler to save you the effort (and which don't allow pointer-arithmetic).