Sensor not working

I have the following code that is supposed to turn on a led (Port D, pin 5) whenever a digital distance sensor is triggered. Double checked the pinout and the sensor is working.

Is there a problem in the snippet?

#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>

void init()
{
DDRD |=  _BV(PIN5) | _BV(PIN6); //enable the pins
//    PORTD |= _BV(PD3); //playing here
}

int main(void)
{
init();

while(1){
if ((PIND & _BV(PD3)) == 0) {
_delay_ms(100);

if ((PIND & _BV(PD3)) == 0) {
PORTD |= _BV(PIN5);
} else {
PORTD &= ~_BV(PIN5);
}
}
}
}

• Guesses: Pullup/down necessary? How does the signal look like (timing issue)? Common ground? What is the numerical value of PD3 (I think this is not part of io.h)? If the problem persists, please provide a minimal schematic and some more details about the sensor. – jp-jee Feb 28 '16 at 19:25
• I tried to play with pullups, no results there. Yes, PD3 is a part of the iom8.h library. Definition here: #define PD3 3 – sitilge Feb 28 '16 at 19:31
• Did you look at the disassembly listing? I would personally change DDRD |= _BV(PIN5) | _BV(PIN6); to DDRD |= _BV(PD5) | _BV(PD6); – jippie Feb 28 '16 at 19:31
• Are you passing a -Os (optimize size) option to the compiler (I'm guessing avr-gcc)? If not, _delay_ms does not work as expected. – Vicente Cunha Feb 28 '16 at 19:38
• @VicenteCunha not really, however, a warning should be thrown upon that. Nothing in the build messages. The only flag I am using (using CMake) is -mmcu=atmega8 – sitilge Feb 28 '16 at 19:42

EDIT4:

so I would expect the code to input a active low signal to drive a LED high output to look similar to:

//#include <avr/io.h>
#define F_CPU 1000000
#include <util/delay.h>

void init()
{
DDRD |=  (1<<5); // output on port D, pin 5
DDRD &=  ~(1<<6); // input on port D, pin 6
}

int main(void)
{
init();

while(1)
{
//if ((PIND & _BV(PD3)) == 0)
if( !(PIND & (1<<6)) )
{ // then sensor input is 'active' low
_delay_ms(100);

// perform some debounce
// if ((PIND & _BV(PD3)) == 0)
if ( !(PIND & (1<<6)) )
{ // then input definitely low
// set output pin for LED high
PORTD |= (1<<5); // (LED ON)
}

else
{
PORTD &= ~(1<<5); // (LED OFF)
}
}

else
{
PORTD &= ~(1<<5); // (LED OFF)
}
}
}


however, this only leaves the LED ON for the duration of the input signal being low.

A description of the sensor is not posted, With out that detail, I would try having a delay before checking if the input is still low.

I.E.

           if ( !(PIND & (1<<6) ) )
{ // then input definitely low
// set output pin for LED high
PORTD |= (1<<5);
delay_sec(1);
}


I would put the 1 second delay in, or several reasons, including a LED that is being pulsed for short durations will not really be easily visible to the naked eye.

Suggest connecting a dual trace 'scope to the two pins of interest and seeing if the code is actually working.

• You don't need io.h, it's in the Atmel Datasheets: PORTx -> Output & Pull-Up; PINx -> Input&Read-Back. You can't use PIN to output. Apart from that there's a missing bracket (or one too many) on the first DDRD and a missing Tilde on the second. – Asmyldof Feb 29 '16 at 8:02
• @Asmyldof, Thanks for catching those syntax problems. Of course this means you should write an answer, then I can delete my answer. – user3629249 Feb 29 '16 at 23:03