# ATtiny84 with internal pull-ups

Hi,
In my current project I have come across a rather weird situation. I am using an ATtiny84 programmed using the Arduino IDE and the core from: https://code.google.com/p/arduino-tiny/
I have 6 inputs connected to PB0, PB1, PA1, PA2, PA3 and PA4. I have activated internal pull-ups and set the pins as inputs using:

void setup() {
DDRA |= (0<<DDA4)|(0<<DDA3)|(0<<DDA2)|(0<<DDA1); // Define directions for port pins
DDRB |= (0<<DDB1)|(0<<DDB0);
PORTA |= (1<<PA4)|(1<<PA3)|(1<<PA2)|(1<<PA1);  // Define pull-ups and set outputs high
PORTB |= (1<<PB1)|(1<<PB0);
}

This is all well and good. I program the micro and apply power and measure the voltage on the pins and its ~5V as expected. In the main loop I have the following code to detect when the pin goes low and then do something (removed the actual code for debugging purposes, but its only 1 line so braces are not required):

void loop() {
if(!(PINA & (1<<PA4)))
// do something
if(!(PINA & (1<<PA3)))
// do something
if(!(PINA & (1<<PA2)))
// do something
if(!(PINA & (1<<PA1)))
// do something
if(!(PINB & (1<<PB1)))
// do something
if(!(PINB & (1<<PB0)))
// do something
}

Now here’s the problem, when I connect power to the chip and apply 0v to PA1, PA2 drops from ~5V to ~0.2V, hence rendering that if statement true and executing code that should have been executed. The same happens the other way round, apply 0V to PA2 and PA1 drops to ~0.2V. This also happens with the pins PB0 and PB1. PA3 and PA4 don’t do this and work as you’d expect.
There are no shorts between the pins.
I cannot change the pins the inputs are on because all the other pins are occupied on the PCB I designed for this. I have also tried multiple chips, and they all behave the same. Its running using its 8MHz internal clock.
I simply can’t work it out so any help would be greatly appreciated
Cheers
Michael

MichaelKavanagh:
Hi,
In my current project I have come across a rather weird situation. I am using an ATtiny84 programmed using the Arduino IDE and the core from: https://code.google.com/p/arduino-tiny/
I have 6 inputs connected to PB0, PB1, PA1, PA2, PA3 and PA4. I have activated internal pull-ups and set the pins as inputs using:

DDRA |= (0<<DDA4)|(0<<DDA3)|(0<<DDA2)|(0<<DDA1); // Define directions for port pins

DDRB |= (0<<DDB1)|(0<<DDB0);

Nope.

You just ORed a port with 0 - that code will have no effect. None!

Maybe you meant:

DDRA &= ~((1<<DDA4)|(1<<DDA3)|(1<<DDA2)|(1<<DDA1)); // Define directions for port pins

Oh.. :astonished: Kinda new to the whole bit manipulation thing and using bitwise operators and masks etc.. Anyway, changed it to the code you suggested and the problem still exists :(

Maybe you need to post more complete code…

What I posted is literally it as it stands at the moment… I removed everything else to eliminate it during debugging.

void setup() {
DDRA &= ~((1<<DDA4)|(1<<DDA3)|(1<<DDA2)|(1<<DDA1)); // Define directions for port pins
DDRB &= ~((1<<DDB1)|(1<<DDB0));
PORTA |= (1<<PA4)|(1<<PA3)|(1<<PA2)|(1<<PA1);  // Define pull-ups and set outputs high
PORTB |= (1<<PB1)|(1<<PB0);
}
void loop() {
if(!(PINA & (1<<PA4)))
// do something
if(!(PINA & (1<<PA3)))
// do something
if(!(PINA & (1<<PA2)))
// do something
if(!(PINA & (1<<PA1)))
// do something
if(!(PINB & (1<<PB1)))
// do something
if(!(PINB & (1<<PB0)))
// do something
}

So how do you know if it's working or not?

By connecting GND to each of the pins in turn and probing adjacent pins with multimeter, and going through and measuring the voltage at each pin. I should also say that the same thing happened when I used pinMode(x, INPUT_PULLUP)

MichaelKavanagh:
By connecting GND to each of the pins in turn and probing adjacent pins with multimeter, and going through and measuring the voltage at each pin.

?? How does that tell you if it’s working/not?

if (!(PINA & (1<<PA4))) {
turnOnMyLED();
}
else {
turnOffMyLED();
}

Because say for instance when I pull PA2 down to gnd, the measured voltage on the adjacent pin PA1, which should be around VCC, is instead around 0.2v which is obviously below the 1/2 VCC threshold and is therefore detected as low as well, triggering that code block. When none of the pins are pulled low, the voltage measured is around VCC, as it should be. As I said in my original post, this happens with PA1&2 and PB0&1, in those pairs. PA3&4 do not show this behaviour. Anyway I have done the LED thing you suggested and it shows the same behaviour, pulling one pin low lights up the LED associated with that pin and the adjacent one.

If an adjacent pin changes that suggests the pins are OUTPUT_HIGH and short-circuiting them.

I think you have bigger problems somewhere. Maybe you've damaged the chip.

I have tried >10 brand new chips straight out of the tube, so that cannot be the reason unless I literally got 2 tubes of bad chips from farnell... And the current from each io pin to ground is 2.89mA, so I am not overloading the io pins

It makes no sense that adjacent pins should change.

I know, I have puzzled over this for several days, and read through the datasheet a multiple times as well. I hope someone will be able to help me :blush:

MichaelKavanagh: And the current from each io pin to ground is 2.89mA, so I am not overloading the io pins

If the pin is OUTPUT_HIGH you normally see about 75mA when you short it to GND.

If the pin is INPUT_PULLUP you should see about 0.1mA.

What is the ground connected to... and is it the same place as the Arduino ground really is? and is it possible that there is a power supply issue...Measure the Vcc in the failed condition IE PA1 and PA2...

Doc

MichaelKavanagh: And the current from each io pin to ground is 2.89mA, so I am not overloading the io pins

Agree with fungus, 2.89mA is definitely too high. How about a picture?

Yep. This is the clue. 2.89mA is just wrong.

The problem isn’t the code, it’s the power supply, the breadboard, something like that.