interrupts on pins 13 & 14 doens't work

Status
Not open for further replies.

giliep

Active member
interrupts on pins 13 & 14 doens't work on teensy 3.5. + how to call 2 hat switches?

Hi,

I'm using 4 rotary encoders in my project on teensy 3.5, and i managed to get the first 2 encoders work great with interrupts. they are connected on pins 51,52,53,54.
I copied and pasted the same code to the other two encoders, but nothing happens.
I don't know how to even check if something happens with the interrupts.
Checked with a scope and the signals are working great.

i tried looking for an answer about the specific pins, but couldn't find any answer.
I know i can only use interrupt on digital pins so there shouldn't be any problem with firing the interrupts...
(just to mention - reading the pins with digitalread is working but the teensy is missing changes)

any help would be highly appreciated...

here is the code:

Code:
void setup() {
  pinMode (encoderF9A, INPUT); // pin 11
  pinMode (encoderF9B, INPUT);
  
  
  pinMode (encoderF14A, INPUT); // analog pin
  pinMode (encoderF14B, INPUT); // pin 13

   attachInterrupt(digitalPinToInterrupt(13), StateofF14B, RISING);
   attachInterrupt(digitalPinToInterrupt(11), StateofF9A, FALLING);

}

void StateofF14B() {

encF14BstateCurrent = digitalReadFast(encoderF14B); // encoderF14B - pin 13
 
 if ((encF14Bstatelast == LOW) && (encF14BstateCurrent == HIGH)){
        if (digitalReadFast(encoderF14A) == HIGH){
          Serial.println ("left");
          encF14btnleft = true;
        } else {
          Serial.println ("right");
          encF14btnright = true; 
        }
 }

encF14Bstatelast = encF14BstateCurrent; 

}// StateofF14A

//----stateofF9A

void StateofF9A(){

Serial.println("ISR F9A");// just to check if its even get into the ISR

encF9AstateCurrent = digitalReadFast(encoderF9A); // encoderF9A - pin 11

if ((encF9Astatelast == LOW) && (encF9AstateCurrent == HIGH)){
  if (digitalReadFast(encoderF9B) == HIGH){
    Serial.println("right");
    encF9btnright = true;
  } else {
    encF9btnleft = true;
    Serial.println("left");
  }
}
encF9Astatelast = encF9AstateCurrent;
}//  Stateof F9

i would also like to know what is the correct syntax to use with more then 1 hat switch? should i declare something?
That is when using the many axis joystick code.

Thanks.
 
Last edited:
I copied your code into Arduino, but it doesn't compile. Stuff is missing. See below....


any help would be highly appreciated...

Since you already have the hardware wired up, try opening File > Examples > Encoder > Basic and just change the pin numbers to 11 and 13. That can at least give you a quick confirmation whether your hardware is working and you should focus on the software side, or if you need to check your wiring.



Here's the errors I see when I tried to verify your program in Arduino

Code:
sketch_jan19a: In function 'void setup()':
sketch_jan19a:2: error: 'encoderF9A' was not declared in this scope
   pinMode (encoderF9A, INPUT); // pin 11
            ^
sketch_jan19a:3: error: 'encoderF9B' was not declared in this scope
   pinMode (encoderF9B, INPUT);
            ^
sketch_jan19a:6: error: 'encoderF14A' was not declared in this scope
   pinMode (encoderF14A, INPUT); // analog pin
            ^
sketch_jan19a:7: error: 'encoderF14B' was not declared in this scope
   pinMode (encoderF14B, INPUT); // pin 13
            ^
sketch_jan19a: In function 'void StateofF14B()':
sketch_jan19a:16: error: 'encF14BstateCurrent' was not declared in this scope
   encF14BstateCurrent = digitalReadFast(encoderF14B); // encoderF14B - pin 13
   ^
sketch_jan19a:16: error: 'encoderF14B' was not declared in this scope
   encF14BstateCurrent = digitalReadFast(encoderF14B); // encoderF14B - pin 13
                                         ^
sketch_jan19a:18: error: 'encF14Bstatelast' was not declared in this scope
   if ((encF14Bstatelast == LOW) && (encF14BstateCurrent == HIGH)) {
        ^
sketch_jan19a:19: error: 'encoderF14A' was not declared in this scope
     if (digitalReadFast(encoderF14A) == HIGH) {
                         ^
sketch_jan19a:21: error: 'encF14btnleft' was not declared in this scope
       encF14btnleft = true;
       ^
sketch_jan19a:24: error: 'encF14btnright' was not declared in this scope
       encF14btnright = true;
       ^
sketch_jan19a:28: error: 'encF14Bstatelast' was not declared in this scope
   encF14Bstatelast = encF14BstateCurrent;
   ^
sketch_jan19a: In function 'void StateofF9A()':
sketch_jan19a:38: error: 'encF9AstateCurrent' was not declared in this scope
   encF9AstateCurrent = digitalReadFast(encoderF9A); // encoderF9A - pin 11
   ^
sketch_jan19a:38: error: 'encoderF9A' was not declared in this scope
   encF9AstateCurrent = digitalReadFast(encoderF9A); // encoderF9A - pin 11
                                        ^
sketch_jan19a:40: error: 'encF9Astatelast' was not declared in this scope
   if ((encF9Astatelast == LOW) && (encF9AstateCurrent == HIGH)) {
        ^
sketch_jan19a:41: error: 'encoderF9B' was not declared in this scope
     if (digitalReadFast(encoderF9B) == HIGH) {
                         ^
sketch_jan19a:43: error: 'encF9btnright' was not declared in this scope
       encF9btnright = true;
       ^
sketch_jan19a:45: error: 'encF9btnleft' was not declared in this scope
       encF9btnleft = true;
       ^
sketch_jan19a:49: error: 'encF9Astatelast' was not declared in this scope
   encF9Astatelast = encF9AstateCurrent;
   ^
'encoderF9A' was not declared in this scope
 
Hi Paul,

Thanks a lot for the answer!
the code didn't compile because it is a snippet from a very long code... i didn't want to clutter the post.
I did found out what the problem was. I would be happy to understand the behavior.

Code:
//encoder 9
  pinMode (encoderF9A, INPUT);
  pinMode (encoderF9B, INPUT);
  
  //encoder 14
  pinMode (encoderF14A, INPUT);
  pinMode (encoderF14B, INPUT);

  //Encoder 17
  pinMode (enc17A, INPUT);
  pinMode (enc17B, INPUT);
  

  //Encoder 16
  pinMode (enc16A, INPUT);
  pinMode (enc16B, INPUT);
  
  attachInterrupt(digitalPinToInterrupt(enc16A), Stateof16A, CHANGE);
  attachInterrupt(digitalPinToInterrupt(enc17A), Stateof17A, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderF14B), StateofF14B, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderF9A), StateofF9A, CHANGE);
 

  //Fanky SW
  for (uint8_t i1 = 0; i1 <= 14; i1++){

    pinMode(i1, INPUT_PULLUP);
  }

the problem lies in the for loop, which configure the pins as INPUT_PULLUP. what i didn't notice (or thought of) was that the loop is overwriting the INPUT configuration for the encoder pins.
Once i understood that,and restricted the loop to go up to pin 9. i managed to get interrupts.

my questions are?
1. Why INPUT_PULLUP disable the interrupts?
2. pin encoderF14A = 14 - is there any way at all to get interrupts on this pin? (or at least mimic the behaivor of the interrupt?
3. un - related question - to address more then 1 hat switch in the many axis joystick would the syntax be:
joystick.hat(1,angle);
joystick.hat (2,angle);
joystick.hat (3,angle);

i'm asking becuase i get weird results.

Thanks!
 
Snippets are usually a distraction - better to have the whole code posted if it can't be cut down to a smaller sketch that effectively shows the problem - that's why this :: Forum Rule: Always post complete source code & details to reproduce any issue!

Many times the self examination of the code to reduce it will lead to the solution, other times the problem area is in a part not included in the snippet.

Reading the code in the browser can solve some issues on sight when it is all there - but often as Paul did, the code is copied to see in "viewer's editor of choice" and compiled to see it in action to observe and correct.

Can you post code showing pinMode( 14, INPUT_PULLUP ) failing to get a call to foo() with attachInterrupt( 14, foo, CHANGE) ? AFAIK on CHANGE to or from low that should be called.

If that pin 14 is always high or associated with any other library or use that would be a first guess. Also not sure what encoderF14B or the other named values has as a pin number, there can only be a single interrupt handler per pin, a subsequent call to attachInterrupt() with the same pin# will replace any existing func() with the new func2().
 
1. Why INPUT_PULLUP disable the interrupts?

Any use of pinMode will do this. It completely reconfigures the pin, overwriting the previously set interrupt config.

Maybe pinMode should check for this case? I'm also considering adding a pinModeFast function, which would omit some of the pinMode features.
 
Any use of pinMode will do this. It completely reconfigures the pin, overwriting the previously set interrupt config.

Maybe pinMode should check for this case? I'm also considering adding a pinModeFast function, which would omit some of the pinMode features.

So pinMode (pin#, INPUT) doesn't interfere with the interrupt config? it would be best practice to set the interrupt at the end of the setup?

I have problem which relates to the hat switches (which is why is asked about the hat switch command).

for some reason, the computer/joystick, thinks that the UP & RIGHT buttons on the hat switch are always on.

I couldn't understand how that's possible since i checked the pin status with the serial monitor and everything is in order.

I also found a post stating that there is a bug on the hat switch API. https://forum.pjrc.com/threads/60620-quot-Extreme-quot-Joystick-hat-bug?highlight=hat+switch

Could it be a bug?

I've also checked on my Mac (not trusting windows 10) and sure enough both buttons are turned on....

Here's the code (i've shortened the code to the relevant section).

Am i doing anything wrong?

Code:
#include <Arduino.h>


int Hat14Down = 0; // F14A
int Hat14Right = 1; // F14B
int Hat14Up = 2; // F14C
int Hat14Left = 3; // F14D
int Hat9Up = 5; // F9A
int Hat9Left = 6; // F9B
int Hat9Down = 7; // F9C
int Hat9Right = 8; // F9D
int hat14Switch = 0;
int hat9Switch = 0;
int angle = -1;
int angle2 = -1;

/*-------------setup-----------------*/

void setup() {
   
  //rotary encoder
  
  //Fanky9
  pinMode (encoderF9A, INPUT);
  pinMode (encoderF9B, INPUT);
  
  //Fanky14
  pinMode (encoderF14A, INPUT);
  pinMode (encoderF14B, INPUT);

  //Encoder 17
  pinMode (enc17A, INPUT);
  pinMode (enc17B, INPUT);
  

  //Encoder 16
  pinMode (enc16A, INPUT);
  pinMode (enc16B, INPUT);
  
  attachInterrupt(digitalPinToInterrupt(enc16A), Stateof16A, CHANGE);
  attachInterrupt(digitalPinToInterrupt(enc17A), Stateof17A, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderF14B), StateofF14B, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderF9A), StateofF9A, CHANGE);
 

  //Fanky SW
  for (uint8_t i1 = 0; i1 <= 9; i1++){

    pinMode(i1, INPUT_PULLUP);
  }

 Hat14Down = HIGH; // F14A
 Hat14Right = HIGH; // F14B
 Hat14Up = HIGH; // F14C
 Hat14Left = HIGH; // F14D
 Hat9Up = HIGH; // F9A
 Hat9Left = HIGH; // F9B
 Hat9Down = HIGH; // F9C
 Hat9Right = HIGH; // F9D 
 
Serial.begin(115200);
 
}

/*-----------------------------------------loop---------------------------------------*/

void loop() {
  
   
  // ---------------hat switch F14 


  // pin 0 - A - Up
  // pin 1 - B - Left
  // pin 2 - C - Down
  // pin 3 - D - Right
  // pin PB - [4]
  // Read pin values
  
  
     Hat14Up = !digitalRead(0); // A
     Hat14Left = !digitalRead(1); // B
     Hat14Down = !digitalRead(2); // C
     Hat14Right = !digitalRead(3); // D
     hat14Switch = digitalRead(4); // switch.

     
          if ((Hat14Down == 0)
            && (Hat14Right == 0)
            && (Hat14Up == 0)
            && (Hat14Left == 0)) {
              Joystick.hat(1,-1);
              if (hat14Switch )
                  {
                    Joystick.button(25, LOW);
                    Serial.println( "Button No No NO No :");
                    Serial.print ("14 up  ");Serial.print ("14 Left  ");Serial.print ("14 Down  ");Serial.print ("14 Right  "); Serial.print ("14 Switch  "); Serial.println ("");
                    /*Serial.print("\t");*/Serial.print ("  ");Serial.print (Hat14Up);Serial.print("\t"); Serial.print(" ");Serial.print (Hat14Left);Serial.print("\t"); Serial.print("  ");Serial.print (Hat14Down);Serial.print("\t"); Serial.print("   ");Serial.print (Hat14Right);Serial.print("\t\t"); /*Serial.print("  "); */Serial.print (hat14Switch); Serial.println ("");
                    Serial.println("");
                  }
                  else {
                    Joystick.button(25, HIGH);
                    Serial.println( "Button Pressed:");
                    Serial.print ("14 up  ");Serial.print ("14 Left  ");Serial.print ("14 Down  ");Serial.print ("14 Right  "); Serial.print ("14 Switch  "); Serial.println ("");
                    /*Serial.print("\t");*/Serial.print ("  ");Serial.print (Hat14Up);Serial.print("\t"); Serial.print(" ");Serial.print (Hat14Left);Serial.print("\t"); Serial.print("  ");Serial.print (Hat14Down);Serial.print("\t"); Serial.print("   ");Serial.print (Hat14Right);Serial.print("\t\t"); /*Serial.print("  "); */Serial.print (hat14Switch); Serial.println ("");
                    Serial.println("");

                  }
          }
      

      if (Hat14Up == 1 && Hat14Right == 0 && Hat14Left == 0 && Hat14Down == 0) {
        Joystick.hat(1,0);
        
        Serial.println( "Up Dir:");
        Serial.print ("14 up  ");Serial.print ("14 Left  ");Serial.print ("14 Down  ");Serial.print ("14 Right  "); Serial.print ("14 Switch  "); Serial.println ("");
        /*Serial.print("\t");*/Serial.print ("  ");Serial.print (Hat14Up);Serial.print("\t"); Serial.print(" ");Serial.print (Hat14Left);Serial.print("\t"); Serial.print("  ");Serial.print (Hat14Down);Serial.print("\t"); Serial.print("   ");Serial.print (Hat14Right);Serial.print("\t\t"); /*Serial.print("  "); */Serial.print (hat14Switch); Serial.println ("");
        Serial.println("");
      }

      //   if (Hat14Right == 1 && Hat14Up == 1 ) {
      //  Joystick.hat(1,45);
      // }

      if (Hat14Right == 1 && Hat14Down == 0 && Hat14Up == 0 && Hat14Left == 0) {
        Joystick.hat(1,90);
       Serial.println( "Right Dir:");
        Serial.print ("14 up  ");Serial.print ("14 Left  ");Serial.print ("14 Down  ");Serial.print ("14 Right  "); Serial.print ("14 Switch  "); Serial.println ("");
        /*Serial.print("\t");*/Serial.print ("  ");Serial.print (Hat14Up);Serial.print("\t"); Serial.print(" ");Serial.print (Hat14Left);Serial.print("\t"); Serial.print("  ");Serial.print (Hat14Down);Serial.print("\t"); Serial.print("   ");Serial.print (Hat14Right);Serial.print("\t\t"); /*Serial.print("  "); */Serial.print (hat14Switch); Serial.println ("");
        Serial.println("");
       }

      //  if (Hat14Down == 1 && Hat14Right == 1) {
      //   Joystick.hat(1,135);
      // }

      if (Hat14Down == 1 && Hat14Left == 0 && Hat14Right == 0 && Hat14Up ==0)  {
        Joystick.hat(1,180);
        Serial.println( "Down Dir:");
        Serial.print ("14 up  ");Serial.print ("14 Left  ");Serial.print ("14 Down  ");Serial.print ("14 Right  "); Serial.print ("14 Switch  "); Serial.println ("");
        /*Serial.print("\t");*/Serial.print ("  ");Serial.print (Hat14Up);Serial.print("\t"); Serial.print(" ");Serial.print (Hat14Left);Serial.print("\t"); Serial.print("  ");Serial.print (Hat14Down);Serial.print("\t"); Serial.print("   ");Serial.print (Hat14Right);Serial.print("\t\t"); /*Serial.print("  "); */Serial.print (hat14Switch); Serial.println ("");
        Serial.println("");
      }

      // if (Hat14Down == 1 && Hat14Left == 1) {
      //   Joystick.hat(1,225);
      // }

      if (Hat14Left == 1 && Hat14Down == 0 && Hat14Up == 0 && Hat14Right == 0) {
        Joystick.hat(1,270);
        Serial.println( "Left Dir:");
        Serial.print ("14 up  ");Serial.print ("14 Left  ");Serial.print ("14 Down  ");Serial.print ("14 Right  "); Serial.print ("14 Switch  "); Serial.println ("");
        /*Serial.print("\t");*/Serial.print ("  ");Serial.print (Hat14Up);Serial.print("\t"); Serial.print(" ");Serial.print (Hat14Left);Serial.print("\t"); Serial.print("  ");Serial.print (Hat14Down);Serial.print("\t"); Serial.print("   ");Serial.print (Hat14Right);Serial.print("\t\t"); /*Serial.print("  "); */Serial.print (hat14Switch); Serial.println ("");
        Serial.println("");
      }

      // if (Hat14Left == 1 && Hat14Up == 1) {
      //   Joystick.hat(1,315);
      // }


// ---------------hat switch F9 


  // pin 0 - A - [5] Up 
  // pin 1 - B - [6] Left
  // pin 2 - C - [7] Down
  // pin 3 - D - [8] Right
  // pin PB - [9]
  // Read pin values

  
    Hat9Up = !digitalRead(5); // A
    Hat9Right = !digitalRead(6); // B
    Hat9Down = !digitalRead(7); // C
    Hat9Left = !digitalRead(8); // D

          if ((Hat9Up == 0)
            && (Hat9Left == 0)
            && (Hat9Down == 0)
            && (Hat9Right == 0)) {
              Joystick.hat(2,-1);
              if (digitalRead(9) )
                  {
                    Joystick.button(26, LOW);
                  }
                  else Joystick.button(26, HIGH);
          }
      

      if (Hat9Up == 1 && Hat9Left == 0 && Hat9Right == 0) {
        Joystick.hat(2,0);
      }

      //   if (Hat9Left == 1 && Hat9Up == 1 ) {
      //  Joystick.hat(2,45);
      // }

      if (Hat9Left == 1 && Hat9Up == 0 && Hat9Down == 0) {
        Joystick.hat(2,90);
       }

      //  if (Hat9Down == 1 && Hat9Left == 1) {
      //   Joystick.hat(2,135);
      // }

      if (Hat9Down == 1 && Hat9Right == 0 && Hat9Left == 0)  {
        Joystick.hat(2,180);
      }

      // if (Hat9Down == 1 && Hat9Right == 1) {
      //   Joystick.hat(2,225);
      // }

      if (Hat9Right == 1 && Hat9Up == 0 && Hat9Down == 0) {
        Joystick.hat(2,270);
      }

      // if (Hat9Right == 1 && Hat9Up == 1) {
      //   Joystick.hat(2,315);
      // }


}// loop
 
Paul said, pinMode completely reconfigures the pin.
This includes interrupts.

I understand that, I'm not sure why INPUT allows interrupts while INPUT_PULLUP isn't, so i wanted to understand that better

If i was more familiar with the ARM architecture i would go with direct pin/register method, but it is more complicated then the AVR 8 bit...

anyway, learned something new, so that's good!.

Now i want to solve the 2 hat switches problem
 
BTW. this is what i mean by wrong Hat...

The red one is Windows default i guess and the green one is my Hat Switch, when nothing is pressed

Hat Switchs .png
 
Last edited:
It Looks like this post did solve the problem...

@pual - Can you confirm ?

I dont really understand the issue or the solution to be honest...

I will check on my Mac and update.


Update: the controller test program on the mac showed the hat switches correctly. So i guess there was a bug in the joystick hat...

I would be happy if someone more knowledgeable then me can confirm this.

Also, is there any chance to get read of the red arrow in the hat joy.cpl window?

Thankss
 
Last edited:
Status
Not open for further replies.
Back
Top