Input pins adress regisiters (PINC)

Hi. I have a push button switch connected to PC1 that uses PCINT to toggle PB5 (I'm using arduino UNO), so far so good. The next step was to add a condition that PB5 only toggles when the button is released, I was told to use the following code:

ISR(PCINT1_vect)
{
if ((PINC & (1<<PC1))) //problem here
{
PORTB ^= (1<<PB5);
}

This works... some of the time. The IF condition behaves erratically, seemingly without any clear pattern. I wrote a bunch of code to try to use Serial to diagnose the problem but the results only made me more confused. Could someone explain in leyman's terms what PINC is and how the values on it change?

I wrote a bunch of code to try to use Serial to diagnose the problem

Please share the code and results with us

The button is "bouncing" and that causes the erratic behaviour, debouncing is needed in the code.

Here is the code:

ISR(PCINT1_vect)
{
  i = digitalRead(PC1);
  j = digitalRead(PB5);
  a = digitalRead(PINC0);
  b = digitalRead(PINC1);
  c = digitalRead(PINC2);
  d = digitalRead(PINC3);
  e = digitalRead(PINC4);
  f = digitalRead(PINC5);
  g = digitalRead(PINC6);
  k = digitalRead(PINC);
  Serial.print("PC1(button)=");
  Serial.print(i);
  Serial.print(", PB5(diode)=");
  Serial.print(j);
  Serial.print(", PINC=");
  Serial.print(g);
  Serial.print(f);
  Serial.print(e);
  Serial.print(d);
  Serial.print(c);
  Serial.print(b);
  Serial.print(a);
  Serial.print(", Overall=");
  Serial.println(k);
  
  if ((PINC & (1<<PC1))) //if (PINC and button is on)=1
  {
    PORTB ^= (1<<PB5);
  }
}

To paraphrase each time the button is pressed Serial displays the status of the button, PB5, the values in the PINC register and the overall value of PINC.
And some results:

PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=0, PB5(diode)=0, PINC=0011001, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=1
PC1(button)=0, PB5(diode)=0, PINC=0011001, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011111, Overall=1
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0
PC1(button)=1, PB5(diode)=0, PINC=0011011, Overall=0

CluelessEngineer:
Here is the code:

No, around here we call that a snippet.

Do not use serial communication in an interrupt handler, if the buffer gets filled up inside the ISR, the Arduino will hang until it is reset.

Okay, was trying not to post too much code. Here is the full program:

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

int i=0;
int j=0;
int k=0;
int a=0;
int b=0;
int c=0;
int d=0;
int e=0;
int f=0;
int g=0;

ISR(PCINT1_vect)
{
  i = digitalRead(PC1);
  j = digitalRead(PB5);
  a = digitalRead(PINC0);
  b = digitalRead(PINC1);
  c = digitalRead(PINC2);
  d = digitalRead(PINC3);
  e = digitalRead(PINC4);
  f = digitalRead(PINC5);
  g = digitalRead(PINC6);
  k = digitalRead(PINC);
  Serial.print("PC1(button)=");
  Serial.print(i);
  Serial.print(", PB5(diode)=");
  Serial.print(j);
  Serial.print(", PINC=");
  Serial.print(g);
  Serial.print(f);
  Serial.print(e);
  Serial.print(d);
  Serial.print(c);
  Serial.print(b);
  Serial.print(a);
  Serial.print(", Overall=");
  Serial.println(k);
  
  if ((PINC & (1<<PC1))) //if (PINC and button is on)=1
  {
    PORTB ^= (1<<PB5);
  }
}
  
int main(void)
{
  DDRB |= (1<<PB5);
  //PORTB &= (0<<PB5);

  DDRC &= (0<<PC1);
  PCMSK1 |= (1<<PCINT9);
  PCICR |= (1<<PCIE1);
  sei();

  Serial.begin(9600); 
  
  while(1)
  {
    /*k = digitalRead(PINC);
    Serial.println(k);
    //delay(1000);*/
  }
}

@CluelessEngineer, it appears you somehow missed this extremely obvious thread at the top of every forum page: Read this before posting a programming question ....

Please read it now. Pay particular attention to Item #6 that describes how to properly post your (complete) code using CODE TAGS.

You problem is related to hardware. Switch bouncing, as already mentioned, for the first and you may also need a pullup or pulldown resistor to prevent the pin from floating.

You forgot to call "init()" in your main(). If you want to use ANY Arduino library code (like Serial or digitslRead()) you have to initialize the Arduino run-time library. That is done for you if you use setup() and loop() but not if you declare your own main().

WARNING! 'digitalRead()' uses Arduino pin numbers, not AVR register pin names. The AVR declarations define 'PC1 as 1 and 'PB5' as 5. Are you using Pin 1 and Pin 5 on the Arduino? I don't know how 'PINC0' through 'PINC6' are defined but I would not expect them to match the Arduino pin numbers.

johnwasser:
WARNING! 'digitalRead()' uses Arduino pin numbers, not AVR register pin names. The AVR declarations define 'PC1 as 1 and 'PB5' as 5. Are you using Pin 1 and Pin 5 on the Arduino? I don't know how 'PINC0' through 'PINC6' are defined but I would not expect them to match the Arduino pin numbers.

An AVR (say: ATmega328P) has external physical pins, and these pins have serial numbers wrt to notch mark.
An AVR has internal registers, and these registers have names and serial numbers (0 to 7) for their bits.

So, what does it mean: "AVR register pin names" in the above quote?