NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Detecting high/ low pins

March 25, 2011
by dgikuljot
dgikuljot's Avatar

Hi, I am working on a small mini project to detect the push of a button and to turn on an led if ground input is detected. I messed around alot with my code but the compiler keeps giving me errors.

// led_blink.c
// for NerdKits with ATmega168
// hevans@nerdkits.edu

#define F_CPU 14745600

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

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// PIN DEFINITIONS:
//
// PC4 -- LED anode

int main() {
  // LED as output
  DDRC |= (1<<2);
  DDRC &= ~(1<<PC3);

  DDRC &= ~(1<<PC3); // set PC3 as input
while(1) {
if(PINC & (1<<PC3)) {
// do something if PC3 is high
PORTC |= (1<<PC2);} else {
return 0:
}

return 1;
}

Basically i want to detect a low on pc3 and if it is detected set pc2 and low output. For some reason it wont work, can someone pelase help me.

March 26, 2011
by Ralphxyz
Ralphxyz's Avatar

Since you are working (struggling) on this you ought to also be looking at pin change interrupts.

There are multiple ways of doing what you are looking to do.

Oh now is also as good of time as any to to look in to switch debouncing, it will not have any effect on lighting a led but you are gong to have to deal with switch debouncing in the future.

In other words search the Nerdkit you will find lots of examples doing what you want to do.

Look for pin change interrupt, see if you cannot find your answer, and really advance your learning.

Ralph

March 26, 2011
by dgikuljot
dgikuljot's Avatar

Hey Ralph, Thanks for the suggestion i will look into pin interrupts. But right now i would like it if we could get it to work the way i was trying to, because i am just trying to make a q1uick demo for a friend. Can you guys please help me diagnose my mistake in the code?. Basically i want to detect a low on pc3 and then output a low on pc2

March 26, 2011
by leedawg
leedawg's Avatar

well if all you want to do is detect a low on PC3 and then ouput a low on PC2 that is fairly easy to do.

Just write something like this.

int main(){

DDRC |= (1<<PC2); //define your output as PC2

DDRC &= ~(1<<PC3); //Define input on PC3
PORTC |= (1<<PC3); // set pull up resistor

while(1){

if(!(PINC & (1<<PC3))) {

PORTC &= ~(1<<PC2);
}
else {
PORTC |= (1<<PC2);
}

}
}

Thats how I would do it short and simple. Good luck hope that helps.

Lee

March 27, 2011
by dgikuljot
dgikuljot's Avatar

Hey Leedawg, Thank You so much, that is exactly what i was trying to do. I was close to the code, but my syntax was messed up. Actually i am used to basic programming so right now c seems a little weird. My next goal is to implement a timer for this circuit, so after the button is pressed it will count down by ten seconds before lighting the led. Can anyone give me a general idea of how this would work in "C". Thanks Kuljot Dhami

March 27, 2011
by leedawg
leedawg's Avatar

No problem. I did not know anything about programming three months ago, ive just been teaching myself as I read and trial and error things and look at other examples of code and tutorials. Its been a fun and challenging adventure so far and I there is tons I still dont know and want to learn.

As far as a delay that should be fairly simple to do as well. I would look at the code for the real time clock tutorial in the nerdkits video that gives a good idea of how to set up a timer. I would then use that timer to increment a variable and then set a statement that will keep the LED off for x count on some variable you define that is being incremented by the timer.

Good luck keep reading and posting thats what I do.

Lee

April 02, 2011
by hariharan
hariharan's Avatar

dgikuljot, I think you should take this chance to learn about interrupts since it will solve your prob and leaarn something new. Check out the PCIC in the datasheet. Look at the ps2 tutorials and also, search it in the forums.

April 02, 2011
by hariharan
hariharan's Avatar

This was my first interrupt code. WHen the button in the PC 5 is pressed and it is a low, it fires a interrupt to blink. Hope this code helps!

// led_blink.c
    // for NerdKits with ATmega168
    // hevans@nerdkits.edu

    #define F_CPU 14745600

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

    #include "../libnerdkits/delay.h"
    #include "../libnerdkits/lcd.h"

    // PIN DEFINITIONS:
    //
    // PC4 -- LED anode

    void init_interrupt(){
     PCICR |= (1<<PCIE1); //set up interrupt values  This will pcint values 23-16 to fire the interrupt.

    PCMSK1 |= (1<<PCINT13); //This will mask the other pins so that only PC5 fires the interrupt.
    }

    int main() {
      // LED as output
      DDRC |= (1<<PC4);
      DDRC &= ~(1<<PC5);
    init_interrupt(); 
      // loop keeps looking forever
      while(1) {
        // turn on LED
        PORTC |= (1<<PC4);

        //delay for 500 milliseconds to let the light stay on
        delay_ms(500);

        // turn off LED
        PORTC &= ~(1<<PC4);

        //delay for 500 milliseconds to let the light stay off
        delay_ms(500);

      }
      }
     ISR(PCINT1_vect){
     sei();
     if (PINC&(1<<PC5)){
     PORTC |= (1<<PC4);

        //delay for 500 milliseconds to let the light stay on
        delay_ms(1000);

        // turn off LED
        PORTC &= ~(1<<PC4);

        //delay for 500 milliseconds to let the light stay off
        delay_ms(1000);
        //delay for 500 milliseconds to let the light stay on
        PORTC |= (1<<PC4);

        delay_ms(1000);

        // turn off LED
        PORTC &= ~(1<<PC4);

        //delay for 500 milliseconds to let the light stay off
        delay_ms(1000);

    }
    return 0;

    }
April 02, 2011
by Ralphxyz
Ralphxyz's Avatar

hariharan, does this code actually work?

You have the call to enable interrupts (line 46 sei();) in your interrupt handler. I do not see how your interuppt handler would ever be called.

The interrupt enabler (sei();) is usually in your main() function.

You will see interrupts being turned off in a interrupt handler and then turned back on, in the handler, but they usually are initiated first in main().

Ralph

April 02, 2011
by hariharan
hariharan's Avatar

Sorry! // led_blink.c // for NerdKits with ATmega168 // hevans@nerdkits.edu

#define F_CPU 14745600

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

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// PIN DEFINITIONS:
//
// PC4 -- LED anode

void init_interrupt(){
 PCICR |= (1<<PCIE1); //set up interrupt values  This will pcint values 23-16 to fire the interrupt.

PCMSK1 |= (1<<PCINT13); //This will mask the other pins so that only PC5 fires the interrupt.
}

int main() {
  // LED as output
  DDRC |= (1<<PC4);
  DDRC &= ~(1<<PC5);
init_interrupt(); 
  // loop keeps looking forever
  while(1) {
    // turn on LED
    PORTC |= (1<<PC4);

    //delay for 500 milliseconds to let the light stay on
    delay_ms(500);

    // turn off LED
    PORTC &= ~(1<<PC4);

    //delay for 500 milliseconds to let the light stay off
    delay_ms(500);

  }

sei();

  }
 ISR(PCINT1_vect){
      if (PINC&(1<<PC5)){
 PORTC |= (1<<PC4);

    //delay for 500 milliseconds to let the light stay on
    delay_ms(1000);

    // turn off LED
    PORTC &= ~(1<<PC4);

    //delay for 500 milliseconds to let the light stay off
    delay_ms(1000);
    //delay for 500 milliseconds to let the light stay on
    PORTC |= (1<<PC4);

    delay_ms(1000);

    // turn off LED
    PORTC &= ~(1<<PC4);

    //delay for 500 milliseconds to let the light stay off
    delay_ms(1000);

}
return 0;

}
December 11, 2011
by missle3944
missle3944's Avatar

I'm a little confused here. For some reason the code does not work. I'm new to interrupts. When PC5 goes High the led blink speed doesnt change. I've tested the code on an Atmega 168 and 328p

Thanks,

-Dan

Post a Reply

Please log in to post a reply.

Did you know that you can connect to certain car computers via the OBD-II port with a microcontroller? Learn more...