PORTx vs. digitalRead()

I have something that's mystifying me and I'm hoping someone can explain.

Background:
I'm using PORTB in this case.
I have DDRB = 0xFF; and PORTB = 0xFF;

I have an external chip that pulls down one of 6 pins on PORTB. Each one triggers a pin change interrupt. First thing I do in the ISR is check which was pulled low. Now when I just read in PORTB, they all appear high. When I use a for loop and use digitalRead(), it correctly tells me which one was low.

I could use the for loop method, but I'm wondering why just reading PORTB doesn't work.

I've looked at digitalRead, which after doing some checks returns this:

return (_SFR_IO8(port_to_input[digitalPinToPort(pin)]) >> digitalPinToBit(pin)) & 0x01;

Which I've managed to turn into this:

_SFR_IO8(port_to_input[2]); //PB is defined as 2 in pins_arduino.c

which successfully works as well.

SOO my question is can anyone explain why this SFR_IO8 trick works but simply reading PORTB does not?

Huh, strange; I don't have any ideas off of the top of my head. Can you post the full source for your sketch (or a simplified version that illustrates the problem)?

Yeah it is strange...here is the code:

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

/* 
Interupt-based QT300 1-WIRE driver
*/

#define TBR 200  //baud period in microseconds (110-200 allowed)
#define TWU 40  //wake up time
#define TSCK 40 //half period of clock (min 30)
#define TDS 80 //data spacing duration  (min 75)
#define TSAMP 15 

#define CHAN 1 // number of channels to be sampled (not used yet)

//Connectors and corresponding arudino pins
#define       J1      2
#define       J2      3
#define       J3      4
#define       J4      5
#define       J5      6
#define       J6      7
#define       J7      8
#define       J8      9
#define       J9      10
#define       J10      11
#define       J11      12
#define       J12      13


//macros to disable pin change interrupts and mask/unmask them
#define DISABLE_INT  PCICR &= !(0x05)
#define ENABLE_INT PCICR |= 0x05
#define MASK0 PCMSK0 |= 0x3F
#define MASK2 PCMSK2 |= 0xFC
#define UNMASK0 PCMSK0 &= !(0x3F)
#define UNMASK2 PCMSK2 &= !(0xFC)

//states
#define DEFAULT 0
#define PRINT 1
#define SEND 2

//which PIN to send/recieve from:
int req = J4;
 
volatile uint16_t qt_data = 0;

volatile uint8_t state;
volatile byte portreading = 0;


int ch = 0;
int i = 0;
int bl = 0;                 // used to count the time of the acquisition burst

int dec_reading = 0;

void setup() {

  
  //disable PCinterrupts
  DISABLE_INT;
  UNMASK0;
  UNMASK2;

  //set PORTB to outputs
  DDRB = 0xFF;
  PORTB = 0xFF;
  
  DDRD = 0xFF;
  PORTD = 0xFF;
  
  
  Serial.begin(115200);      
  delay(500);                

  
   ENABLE_INT;
   MASK0;
   MASK2;

   state = SEND;
 

}//setup()

void loop(){
    
    switch (state) {
      
    case SEND:
   
    
     //send acquisition request
     send_req(req);
     state = DEFAULT;
     break;
      
    
     case PRINT:

     Serial.print(qt_data);
     Serial.println("");
     Serial.print(portreading,BIN);
     Serial.println("");
   
     state = SEND;
    
     break;
    
    
    default:
    
    
    break; 
  
    }
 
}//loop()


uint16_t get_bytes(int pin) {
    
 
    static uint8_t qtMSB;
    static uint8_t qtLSB;
    
    qtMSB = 0;
    qtLSB = 0;
    
    //this delay needs to be determined by how long it takes to go through ISR
    delayMicroseconds(TBR);  //TBD
    delayMicroseconds(TBR/2);
    
    //first byte
    
    for (i = 0; i < 8; i++) {
    
     
      qtMSB |= (digitalRead(pin) << i);
      //qtMSB |= (PORTB1 << i);
      delayMicroseconds(TBR);
      
 
     }
  
    delayMicroseconds(85);
    
   
    while (digitalRead(pin)  != HIGH);
    while (digitalRead(pin) != LOW);
   
  
    delayMicroseconds(TBR);
    delayMicroseconds(TBR/2);
    
    //second byte
    for (i = 0; i < 8; i++) {
       
      qtLSB |= (digitalRead(pin) << i);
      //qtLSB |= PORTB1 << i;
      delayMicroseconds(TBR);
  
    }
  
   
   
   
   return qtLSB + (qtMSB << 8);

  
}

//send acquisition request to qt300 on selected pin
void send_req(int pin) {
  

    DISABLE_INT;
    UNMASK0;
    UNMASK2;
    
   
    DDRB |= 0xFF;
    DDRD |= 0xFF;
    
    //send wake up pulse
    digitalWrite(pin, LOW);
    delayMicroseconds(TWU); 
    
    //send baud rate pulse
    digitalWrite(pin, HIGH);
    delayMicroseconds(TBR);
    digitalWrite(pin, LOW);
    
    
    delayMicroseconds(TWU); //twu
    digitalWrite(pin, HIGH);
   
    DDRB &= 0x00;
    DDRD &= 0x00;
    delayMicroseconds(TBR);
    
    ENABLE_INT;
    MASK0;
    MASK2;    
    
  
}

ISR(__vector_default)
{
    Serial.println("DEFAULT");
    state = PRINT;
}



ISR (PCINT0_vect) {
   
   DISABLE_INT;
   UNMASK0;
   UNMASK2;
  
   //portreadin = PORTB; //doesn't work, always gives all HIGH
   portreading = _SFR_IO8(port_to_input[2]);
 
   qt_data = get_bytes(req);  
   
   state = PRINT;

   ENABLE_INT;
   MASK0;
   MASK2;
   
}//ISR(PCINT0_vect);


ISR (PCINT2_vect) {

   DISABLE_INT;
   UNMASK0;
   UNMASK2;
 
   //portreading = PORTD;
   portreading = _SFR_IO8(port_to_input[4]); 
   
   qt_data = get_bytes(req);  
   
   state = PRINT;

   ENABLE_INT;
   MASK0;
   MASK2;   
   
}//ISR(PCINT2_vect);

Use PINB to read the values of the pins. PORTB is used to write the values

ahh thanks, I'll give that a try.