External Interrupt Pin putting out 5V?

I am trying to set up 4 pushbuttons to enable 4 of the external interrupts. I have set up the interrupts using the following:

  SREG |= 0x80; // enable interrupts
  EICRA |= 0xFF; // set interrupts to detect rising edges
  EIMSK |= 0x0F; // enable external interrupts on INT3:0

And have set up the pins as follows (PD3:0 are used for INT3:0):

  // set PD3:0 to inputs
  DDRD &= ~_BV(PD0);
  DDRD &= ~_BV(PD1);
  DDRD &= ~_BV(PD2);
  DDRD &= ~_BV(PD3);
  
  PORTD &= ~_BV(PD0);
  PORTD &= ~_BV(PD1);
  PORTD &= ~_BV(PD2);
  PORTD &= ~_BV(PD3);

For some reason, pins 18, 19, 20, and 21 (PD0 through PD3) are putting out 5V. Any ideas why this is happening?

Thanks.

Board?

Actually, only pins 21 and 20 are putting out 5V. Pins 19 and 18 are low. The interrupts still aren't working, though.

Mega2560

Is there a reason you're not using attachInterrupt?

I eventually want to use just the atmega2560 for the project and am trying not to use any of the built-in Arduino functions. I am really just using the Arduino to be able get to the pins and create a prototype.

The problem is not in the code you posted.

Okay, here’s the code that I’m using (I cleaned it up a little by deleting some code that was commented out, but that shouldn’t have an effect):

#include <avr/interrupt.h>
#include <inttypes.h>

#define LCD_COMMAND 0x00
#define LCD_DATA    0x01

#define LCD_X     84
#define LCD_Y     48

uint8_t display_x;
uint8_t display_y;

static const byte ASCII[][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20  
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j 
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ?
,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f ?
};

SIGNAL(SIG_INT2){
  display_y++;
}

void setup() {
  
  // set PA4:0 to outputs
  DDRA |= _BV(PA0);
  DDRA |= _BV(PA1);
  DDRA |= _BV(PA2);
  DDRA |= _BV(PA3);
  DDRA |= _BV(PA4);
  
  // set PD3:0 to inputs
  DDRD &= ~_BV(PD0);
  DDRD &= ~_BV(PD1);
  DDRD &= ~_BV(PD2);
  DDRD &= ~_BV(PD3);
  
  PORTD &= ~_BV(PD0);
  PORTD &= ~_BV(PD1);
  PORTD &= ~_BV(PD2);
  PORTD &= ~_BV(PD3);
  
  
  // set PA4:0 to low values
  PORTA &= ~_BV(PA0);
  PORTA &= ~_BV(PA1);
  PORTA &= ~_BV(PA2);
  PORTA &= ~_BV(PA3);
  PORTA &= ~_BV(PA4);
  // PA0 == PIN 22 == SCE
  // PA1 == PIN 23 == RST
  // PA2 == PIN 24 == D/C
  // PA3 == PIN 25 == DN
  // PA4 == PIN 26 == SCLK
  
  SREG |= 0x80; // enable interrupts
  EICRA |= 0xFF; // set interrupts to detect rising edges
  EIMSK |= 0x0F; // enable external interrupts on INT3:0
  
  initialize_display(); // initialize the display
  
  display_x = 42;
  display_y = 3;
  
}

void loop() {
  LcdClear();
  gotoXY( display_x, display_y );
  
  send_info(LCD_DATA, 0xFF);
  send_info(LCD_DATA, 0xFF);
  send_info(LCD_DATA, 0xFF);
  send_info(LCD_DATA, 0xFF);
  send_info(LCD_DATA, 0xFF);
  
}




void send_info(uint8_t select, uint8_t byte_send){
  // select either command or data to be sent
  if(select == 0x00){
     PORTA &= ~_BV(PA2); 
  }else{
     PORTA |= _BV(PA2); 
  }
  
  PORTA &= ~_BV(PA4); // SET SCLK TO LOW
  PORTA &= ~_BV(PA0); // SET SCE TO LOW (ENABLE)
  //shiftOut(25, 26, MSBFIRST, byte_send);
  
  uint8_t temp = 0;
  uint8_t i = 0;
  for(i = 0; i < 8 ; i++){
    temp = byte_send & (0x01 << (7 - i)); // mask the current bit
    temp = temp >> (7 - i); // move the current bit to bit 0
    temp = temp & 0x01; // make sure only the LSB is included
                      
    // send current bit through DN (IF LOW FOR DN BITWISE AND WITH REGISTER, IF HIGH FOR DN BITWISE OR WITH REGISTER)
    if(temp == 0x01){
      PORTA |= _BV(PA3);    
    }else{
      PORTA &= ~_BV(PA3); 
    }
    
    // PULSE THE SCLK
    PORTA |= _BV(PA4);
    //delay(1);
    PORTA &= ~_BV(PA4);
    //delay(1);
    
  }
  
  
  PORTA |= _BV(PA0); // SET SCE TO HIGH (DISABLE)
}

void initialize_display(void){
  PORTA &=  ~_BV(PA1);
  // delay(1);
  PORTA |= _BV(PA1);
  
  send_info(LCD_COMMAND, 0x21); // LCD Extended Commands
  send_info(LCD_COMMAND, 0xBF); // Set LCD Vop (Contrast)
  send_info(LCD_COMMAND, 0x04); // Set Temp coefficient
  send_info(LCD_COMMAND, 0x14); // LCD bias mode 1:48
  send_info(LCD_COMMAND, 0x0C); // LCD in normal mode
  send_info(LCD_COMMAND, 0x20);
  send_info(LCD_COMMAND, 0x0C);
  
}

void gotoXY(uint8_t x, uint8_t y){
   send_info(LCD_COMMAND, 0x80 | x);
   send_info(LCD_COMMAND, 0x40 | y); 
}

void LcdCharacter(char character)
{
  send_info(LCD_DATA, 0x00);
  uint8_t index = 0;
  for (index = 0; index < 5; index++)
  {
    send_info(LCD_DATA, ASCII[character - 0x20][index]);
  }
  send_info(LCD_DATA, 0x00);
}

void LcdClear(void)
{
  uint16_t index = 0;
  for (index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    send_info(LCD_DATA, 0x00);
  }
}

Actually, only pins 21 and 20 are putting out 5V

How did you determine this?

I used a multimeter with jumpers attached to the respective pins.

The problem is not in the code.

Am I correct that those pins line up with those ports? (i.e. Pins 21, 20, 19, 18 line up with PD0, PD1, PD2 and PD3)?

From the schematics seems like you are right: http://arduino.cc/en/uploads/Main/arduino-mega-schematic.pdf

Might this be a case of measurement of floating inputs or inputs with internal pull-ups enabled?

Another reason to utilize Arduino type statements is that it is clear to us more software challenge types to see what you are trying to do, as I didn't see any comments in the PORTD code section.

What is the purpose of:

  PORTD &= ~_BV(PD0);
  PORTD &= ~_BV(PD1);
  PORTD &= ~_BV(PD2);
  PORTD &= ~_BV(PD3);

That part of the code is disabling the pull up resistors. If you set the value of an input to zero, it disables the pull ups and if you set the input to one it enables the pull ups.

This is how they do it in the Arduino (021) core:

   switch (interruptNum) {
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    case 2:
      EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
      EIMSK |= (1 << INT0);
      break;
    case 3:
      EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
      EIMSK |= (1 << INT1);
      break;
    case 4:
      EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
      EIMSK |= (1 << INT2);
      break;
    case 5:
      EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
      EIMSK |= (1 << INT3);
      break;
    case 0:
      EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
      EIMSK |= (1 << INT4);
      break;
    case 1:
      EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
      EIMSK |= (1 << INT5);
      break;
    case 6:
      EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
      EIMSK |= (1 << INT6);
      break;
    case 7:
      EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
      EIMSK |= (1 << INT7);
      break;

They obviously set EICRB to something, which I cannot see in your code. On the other hand I don’t see them setting EICRA to anything and you set it to 0xFF.

On the other hand I don’t see them setting EICRA to anything and you set it to 0xFF.

EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);

EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);

EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);

:slight_smile:

My bad! (I was looking at the end of the case)
But here:

EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);

This (EICRA & ~((1 << ISC00) | (1 << ISC01))) means that the bits ISC00 and ISC01 are 0 in EICRA (and then modified by setting the mode).

This (EICRA & ~((1 << ISC00) | (1 << ISC01))) means that the bits ISC00 and ISC01 are 0 in EICRA (and then modified by setting the mode).

If you expand the equation for all four interrupts to fire on a rising edge and then reduce the equation it becomes this…

EICRA |= 0xFF; // set interrupts to detect rising edges

Which can be further reduced to this…

EICRA = 0xFF;

EICRB is used to control the way that interrupts are sensed on INT4, INT5, INT6, and INT7. Because I'm not using these, I just left them alone. Thanks for the responses! I would like to get this figured out.

I think I am going to use the serial commands to debug to absolutely make sure the interrupts aren't working.