0
\$\begingroup\$

I have simplified the listing to bare minimum where I can still observe this behaviour.
When this program is running, it works as expected. Button press causes LED to show up.

The problem exist on first run: when I run it first time (powering up) or resetting the processor the body of if (!(PINC & (1<<PC0))) is executed despite that the condition is not met (button not pressed).
Code:

#include <avr/io.h>
#include <util/delay.h>

int main(void) {
  DDRB |= (1<<PB5); // pin for LED as output 
  DDRC &= ~(1<<PC0); // to ensure PC0 is input - btn here, shorts to gnd when pressed 
  DDRD |= (1<<PD0)|(1<<PD1); // debug LED1 and LED2

  while(1) {
    PORTC |= (1<<PC0); // pull-up
    asm( "nop " ); 
    asm( "nop " ); 

    if (!(PINC & (1<<PC0))) {  //btn pressed? shorts to gnd
      PORTB |= (1<<PB5); // LED on <-- executed after RESET!
      // here comes extra code to move stepper motor
    }
    else {
      PORTD |= (1<<PD1); // dbg LED on
    }
    _delay_ms(2000);
    PORTB &= ~(1<<PB5);
    PORTD &= ~(1<<PD1);
  }
}

Is here something I am not aware of?
Extra info: this would be a small nuisance if comes as LEDs only, but I want some step motor movement (or rather - NO movement). This execution is undesired just after powering the processor up.

EDIT
More info: The hardware is Arduino UNO SMD.
Arduino Uno SMD
Code is written and compiled with Arduino IDE.

Wires connected between pushbutton switch and the PC0 (or A0, using Arduino description) with about 15cm long wires. This pushbutton shorts PC0 to gnd.
No external (hardware) pullup/pulldown.

\$\endgroup\$
7
  • 5
    \$\begingroup\$ How does your button circuit look like? Do you have some capacitor connected there? You have 2 s delay in your loop :-o (is this intentional?), but first check is two cycles after enabling the pull-up. Likely not enough time to charge whatever capacitance is connected to the PC0. \$\endgroup\$
    – Martin
    Commented Mar 17 at 20:37
  • \$\begingroup\$ I think you have to add a short delay at the beginning of the if and else. \$\endgroup\$
    – liaifat85
    Commented Mar 17 at 20:46
  • 2
    \$\begingroup\$ You need to show the schematics for an explanation. Also if there is any wiring or cabling between button and IO pin, add that info as well. I bet it shows a logical explanation. Do you want a hardware fix or software fix, or just want to know why it behaves the way it does? \$\endgroup\$
    – Justme
    Commented Mar 17 at 21:09
  • 1
    \$\begingroup\$ What ATmega328P board are you using ? If it is an Arduino Uno etc. then PB5 is the built in led pin and is used by the boot loader to signal it is active. \$\endgroup\$
    – 6v6gt
    Commented Mar 17 at 22:08
  • \$\begingroup\$ @Martin 2sec delay to debug, it is not to stay there. I will try to extend the time before checking the state of PC0. \$\endgroup\$
    – smajli
    Commented Mar 18 at 13:01

2 Answers 2

3
\$\begingroup\$

As there is no external pull-up, the internal pull-up of the AVR is so weak that the voltage on the pushbutton pin rises slowly.

The two NOP delay is only to compensate the delay caused by the synchronizer, so you get data there was on pin 2 clock cycles ago, right after the moment the pull-up was activated.

But the voltage was still rising and below the threshold of logic 1 level.

It is best to use initialize the pull-up at startup, maybe have an explicit delay of few microseconds to wait that the voltage has risen to supply voltage, before reading the pin state for the first time.

\$\endgroup\$
0
\$\begingroup\$

The unwanted led activity on PB5 is caused by the bootloader on that Uno clone. Possible solutions: Chose a pin other than PB5 to avoid spurious switching at start up or eliminate the bootloader.

\$\endgroup\$
4
  • \$\begingroup\$ This answer explains only LED blinking at the start. Execution of the conditional block is caused by something else. \$\endgroup\$
    – smajli
    Commented Mar 18 at 15:25
  • \$\begingroup\$ But isn't your assumption that there is an unwanted execution of the conditional block based on the blinking of the led or have I missed something? \$\endgroup\$
    – 6v6gt
    Commented Mar 18 at 15:39
  • \$\begingroup\$ Your understanding is not incorrect per se, and this is why your comment helped (thanks for that!) anyway in 'extra info' I mention that there would be stepper motor control in this block where your explanation is not solving my issue. \$\endgroup\$
    – smajli
    Commented Mar 18 at 16:33
  • 1
    \$\begingroup\$ In principle, for an Arduino, pin 13 (PB5) should be avoided. If you connect say a relay or similar to it, it will chatter during the execution of the boot loader. The solution is very simple. Use another pin since only PB5 is written to by the boot loader. You also have the option of deleting the boot loader but then you have to load your code using an ICSP programmer and also, because you have used the Arduino boot loader, clean the fuses (e.g. BOOTRST) \$\endgroup\$
    – 6v6gt
    Commented Mar 18 at 20:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.