**Problem**

In essence, attachInterrupt uses a macro called `ISR` (stands for Interrupt Service Routine) to register a user provided function to handle an external interrupt event. 

The issue you are encountering is that `ISR` also wraps the call to your function with special instructions to clear the global interrupt flag of your microcontroller, and  set it again after your function returns. This is a good idea, and almost always what you want, because it prevents the possibility of infinitely recursive interrupts.

However, this behaviour will prevent `Serial` from working correctly, since it relies on interrupts being enabled to do its thing.

**Solution**

Although this is the default behaviour, there is nothing stopping you from enabling interrupts again inside your `c1_rise` function, as in:

    void c1_rise() {
        val_c1 ++;
        interrupts();
        Serial.print("C1:");
        Serial.print(val_c1);
        Serial.print("\n");
    }

Alternatively, but perhaps more involved, you can use the `ISR` macro directly by including `avr/interrupt.h`, and use `ISR(vect, NO_BLOCK)` to override the default behaviour.

Of course, you should be careful when overriding the default behaviour --- its there for a reason!

For more details about working with interrupts, I recommend reading [this documentation][1].


  [1]: https://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html