Invalid use of void expression when attaching interrupt

Hello, all! I am working on a Christmas gift for my mother (procrastination, I know. School has been tough, though!), and I recently ran into this issue. I have a working knowledge of Wiring language, but I don’t have a strong understanding of C++, so I hope I may be doing something that is so obvious to the particle community that it’ll be easily fixed.

So, the problem: I’m using a rotary encoder to scroll some junk on an LCD which I’m operating over I2C. I’ve set up an interrupt on one of the encoder pins to catch the rising edge of the encoder signal, and this seems to be where the issue is arising. When compiling, I get an error code which says, “Error: invalid use of void expression.” The program worked successfully for a long while using the interrupt, but I must have changed something in the code recently, causing it to break. I have added use of the HTU21D library today, but after commenting all HTU-related lines out and compiling again, I have determined that that is most likely not the issue. The code is as follows:

#include "HTU21D/HTU21D.h"
#include "LiquidCrystal_I2C_Spark/LiquidCrystal_I2C_Spark.h"

LiquidCrystal_I2C *lcd;
//HTU21D htu = HTU21D();

int encoderA=3;
int encoderB=4;
int encoderButton=5;
int floatSwitch=7;
int moistureL=A1;
int moistureR=A2;
int pumpL=A3;
int pumpR=A4;

int volatile pos=0;

void setup(void)

  lcd = new LiquidCrystal_I2C(0x27, 20, 4);
  pinMode(encoderA, INPUT);
  attachInterrupt(encoderA, encoder(), RISING);
  pinMode(encoderB, INPUT);
  pinMode(encoderButton, INPUT);
  pinMode(floatSwitch, INPUT);
  pinMode(moistureL, INPUT);
  pinMode(moistureR, INPUT);
  pinMode(pumpL, OUTPUT);
  pinMode(pumpR, OUTPUT);


void loop(void){
    //Serial.print("Temp: "); Serial.println(htu.readTemperature());
    //Serial.print("Hum: "); Serial.println(htu.readHumidity());

void encoder(void){
    if (digitalRead(D3) == digitalRead(D4)){
    else if(digitalRead(D3) != digitalRead(D4)){


Also peculiar, the error reports that the issue is occurring multiple lines above where the actual problematic code. This is confirmed by commenting out the attachInterrupt statement and re-compiling (or attempting to, anyway). Any ideas on this? I’ll appreciate any help I can get.

You should do it this way

  pinMode(encoderA, INPUT_PULLDOWN); 
  attachInterrupt(encoderA, encoder, RISING);  // just the function name, not a function call with ()

With switches of any sort that have only one descrete state and an open/floating state otherwise, you’d need to change INPUT to either INPUT_PULLUP or INPUT_PULLDOWN opposite to the one descrete state your switch provides, to avoid floating pins to give your wrong readings.

You also don’t need the else if() in your encoder() function, since if the two pins are not equal t(==) hey definetly have to be not-equal (!=). So just use else (without if()).

Further more, please stick with the more explicit pin naming D3, D4, D5 and D7 instead of only number literals and keep using your pin-variables (which should be declared const int encoderA=D3;) all over your code, otherwise, if you happen to change the declaration for some reason, your code would break (e.g. inside encoder()).


I should have known the issue. It was the brackets on the encoder function, like you mentioned. I renamed from the generic “ISR” I’ve been seeing in examples and added “()” on at the end by habit. Per your advice, I’ll be going back through to add more explicit naming later today.

As far as the INPUT_PULLUP or …_PULL_DOWN, I have an external pullup and smoothing capacitor on both of the signal pins from the encoder, so I think that should take care of the floating values. I get consistent, accurate incrementation of my pos variable from turning the encoder, anyway.

Thank you, ScruffR, for the quick response! I knew it had to be something simple. Hope the holidays treat you well!

1 Like