PWM using port manipulation

Hi guys,
I'm new to port manipulation so I studied the datasheet of ATmega 328p and I understood that for Arduino Nano We've got 3 ports PORTB PORTD PORTC and all of them have DDR and PIN.
I'm trying to read pwm using interrupts on digital pins 4 5 6 7 of Arduino Nano, so first of all I enabled PCICR bit named PCIE2 to activate PCMSK2.
Then I setted to 1 PCINT20 (D4 on Arduino),PCINT21 (D5 on Arduino),PCINT22 (D6 on Arduino),PCINT23 (D7 on Arduino) to trigger pin change interrupts on these pins.
At least I have ISR(PCINT2_vect) that should call the interrupt routine service every time that a pin of PORTD (digital pins form 0 to 7) changes its state from HIGH to LOW or from LOW to HIGH.

Once loaded the code I can see at least 1 or 2 channels pwm value on the serial monitor; the other are always at 0 also if i change stick position.
This is my code if someone could help me it would be great because I spend 2 day checking for error but at least I can't find them

volatile unsigned long counter_1, counter_2, counter_3, counter_4, current_count;
volatile byte CH1_LS, CH2_LS,CH3_LS,CH4_LS;
volatile int radioCh[4];

void setup(){
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT20);
PCMSK2 |= (1 << PCINT21);
PCMSK2 |= (1 << PCINT22);
PCMSK2 |= (1 << PCINT23);
Serial.begin(115200);
}

void loop() {
Serial.print("CH1 " + String(radioCh[0]) + " CH2 " + String(radioCh[1]) );
Serial.print("CH3 " + String(radioCh[2]) + " CH4 " + String(radioCh[3]) );
Serial.print("\n");
}

ISR(PCINT2_vect){
current_count = micros();

//CH 1
if(PIND & B00100000 ){
if(CH1_LS == 0){
CH1_LS = 1;
counter_1 = current_count;
}
}
else if(CH1_LS == 1){
CH1_LS = 0;
radioChannelCommands[0] = current_count - counter_1;
}

//CH 2
if(PIND & B00010000){
if(CH2_LS == 0){
CH1_LS = 2;
counter_2 = current_count;
}
}
else if(CH2_LS == 1){
CH2_LS = 0;
radioChannelCommands[1] = current_count - counter_2;
}

//CH 3
if(PIND & B10000000 ){
if(CH3_LS == 0){
CH3_LS = 1;
counter_3 = current_count;
}
}
else if(CH3_LS == 1){
CH3_LS = 0;
radioChannelCommands[2] = current_count - counter_3;

}

//CH 4
if(PIND & B01000000 ){
if(CH4_LS == 0){
CH4_LS = 1;
counter_4 = current_count;
}
}
else if(CH4_LS == 1){
CH4_LS = 0;
radioChannelCommands[3] = current_count - counter_4;
}

}

I have no idea what your problem is, but this caught my attention:

  current_count = micros();

What, exactly, is the relationship between now (as returned by micros()) and current_count? Looks to me like you REALLY should be using a better name.

I presume that this

radioChannelCommands[0] = current_count - counter_1;

should be
radioCh[0] = current_count - counter_1;

You can't simply print multi-byte values that are updated by an ISR. The values in the variables can change while they are being printed.

Also you are printing far too frequently which will probably screw up the ISR as well as the printing.

Try gathering the values once per second and then printing them - like this

if (millis() - prevPrintMillis >= 1000) {
     prevPrintMillis += 1000;
     noInterrupts();  // prevent values changing while being read
        for (byte n = 0; n < numChans; n++) {
           latestWidth[n] = radioCh[n];
        }
      interrupts();
      // code to print latestWidth[] values
}

...R

Every if statement in your ISR reads PIND which may have changed from when the interrupt was triggered. To better understand what triggered the interrupt, you need to copy PIND to a variable upon entering the ISR and then make your decisions based on that.

thank you all for your advice ... the interrupt now works properly