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 » Blinking LED Problem

February 14, 2012
by mechfeeney
mechfeeney's Avatar

I'm becoming increasingly familiar with the various codes provided in the nerdkits source download. I wanted to combine the LCD message from initialload.c and the blinking led from blink_led.c. I found that the current nerdkits source code for initialload turns on an LED at PC4 and then off shortly after. I investigated this a bit further by plugging in an LED at pin 27 (PC4) and indeed it turns on briefly. In turn the message on the LCD is displayed.

Here's my question. If I copy and paste the blink code with the delay into the forever while loop of initialload.c, I get an error that PC4 is "undeclared." How can this be?? It was declared beforehand and worked by turning on the LED and then off. I just want to blink the LED while the message on the LCD is displayed...and the error is seemingly enigmatic.

Here's the code...

// initialload.c
// for NerdKits with ATmega168
// mrobbins@mit.edu

#define F_CPU 14745600

#include <stdio.h>

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

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

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

int main() {
  // LED as output
  DDRC |= (1<<PC4);

  // turn on LED
  //PORTC |= (1<<PC4);

  // fire up the LCD
  lcd_init();
  lcd_home();

  // print message to screen
  //             20 columns wide:
  //                     01234567890123456789
  lcd_line_one();
  lcd_write_string(PSTR("  Congratulations!  "));
  lcd_line_two();
  lcd_write_string(PSTR("********************"));
  lcd_line_three();
  lcd_write_string(PSTR("  Your USB NerdKit  "));
  lcd_line_four();
  lcd_write_string(PSTR("      is alive!     "));

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

  // busy loop: THIS IS WHERE I COPY AND PASTED BLINK CODE. 
  // NOTHING ELSE WAS CHANGED AND BY REMOVING THE CONTENTS
  // INSIDE THE WHILE LOOP, THE CODE EXECUTES PROPERLY
  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);
  }

  return 0;
}
February 14, 2012
by dvdsnyd
dvdsnyd's Avatar

@mechfeeney

Just a thought, but have you attempted to comment out everything that has to do with the LCD, basically just leaving the infinite while loop and your blinking LED? I am not sure why it would do anything differently. It may shed some light on the issue though. I looked over your code and it seems solid...then again I have just started toying around with the Nerdkit about a month ago now.

David

February 14, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Did you save this file in the same directory as the rest of your code? If I'm not mistaken, PC4 should be defined in one of your headers. I'm new myself though, so I could be wrong.

February 14, 2012
by pcbolt
pcbolt's Avatar

@mechfeeney

Try replacing PC4 in your code with just the number 4. This should work since PC4 is defined in the header file "avr/io.h" as 4. Try looking inside "avr/io.h" to see if anything there got corrupted.

February 14, 2012
by mechfeeney
mechfeeney's Avatar

pcbolt appears to be right. I replaced instances of 'PC4' to 4. It worked. That seems really odd to me seeing as the pin name is PC4 and that was the original code provided by nerdkits.

February 14, 2012
by SpaceGhost
SpaceGhost's Avatar

This is odd - I just copied and pasted your code and it loaded fine for me. Works too. I looked at your code and I didn't see any reason why it wouldn't work, so I tried it.

LED blinks, & message displays.

Dave

February 14, 2012
by mechfeeney
mechfeeney's Avatar

Even more odd, PC4 was once recognized. I loaded the default led_blink code (with PC4) and it worked. Now it only works with 4 not PC4. This is beyond unintuitive.

February 14, 2012
by SpaceGhost
SpaceGhost's Avatar

Okay, so why did mechfeeney's original code work for me and not for him? I copied and pasted it with no modifications...

hmmm.. Is this deja vu, Ralph?

February 14, 2012
by SpaceGhost
SpaceGhost's Avatar

"Even more odd, PC4 was once recognized. I loaded the default led_blink code (with PC4) and it worked. Now it only works with 4 not PC4. This is beyond unintuitive."

That IS even "more odd"!

February 14, 2012
by SpaceGhost
SpaceGhost's Avatar

And, I don't understand why using only "4" would work (instead of declaring it as PC4). How does the program know that you don't mean PB4? How would you declare PB4??

February 14, 2012
by pcbolt
pcbolt's Avatar

I think in "io.h" there is a "define PC4 4" line that tells the compiler to substitute 4 everytime it encounters PC4 (same with PB4 and PD4). You'll notice the statement (1<<PC4) translates to (1<<4) which, in binary, takes 00000001b and turns it into 00010000b, setting pin 4 each time. This means the "define PC4 4" is not being found. So either the "io.h" file is messed up, or a Makefile is telling the compiler to use a different model of chip than the 168, maybe a chip that does not have PC4 on it.

I agree tho....very odd.

February 14, 2012
by mechfeeney
mechfeeney's Avatar

I forgot to mention. I'm using a 328p...I apologize. How do i remedy this issue so that it will recognize PC4.

February 14, 2012
by Rick_S
Rick_S's Avatar

ding ding ding... There's your answer. The header files for the 328 are incomplete. That is why the NK guys have an extra header you can download that adds those definitions to make your program work. Download the ATmega328P Upgrade Nano-Guide from the members area. Inside that PDF, there is a link to download the additional header that will cure your problem.

Rick

February 15, 2012
by mechfeeney
mechfeeney's Avatar

Thank you Dave, Spaceghost, theunfocusedone, pcbolt, and Rick. It's all working flawlessly.

February 15, 2012
by pcbolt
pcbolt's Avatar

@mechfeeney

Glad to see it's going well. Actually it was pretty interesting to see the progression of problem/solution in this case.

June 08, 2012
by raildoc
raildoc's Avatar

Header file not on site!?

June 09, 2012
by Ralphxyz
Ralphxyz's Avatar

Works for me, just like Rick said above:

Download the ATmega328P Upgrade Nano-Guide from the members area. Inside that PDF, there is a link to download the additional header that will cure your problem.

Ralph

June 10, 2012
by raildoc
raildoc's Avatar

TNX again Ralph. My bad: URL syntax error. In a "parallel" line, I want to keep the led blinking while then writing a scrolling lcd message. How do I transition from the infinite loop to continue to write to the lcd? So far with various loop exit options, I either blink or lcd_write--but not at the same time or sequentially. I've tried various parallel, goto, and break commands--as well as loop nesting. Everything compiles, but no soap. Any ideas?

June 10, 2012
by Ralphxyz
Ralphxyz's Avatar

Try embedding another loop within your first while loop.

Or you could embed a for statement but another while will work.

Ralph

June 11, 2012
by pcbolt
pcbolt's Avatar

@ raildoc

I would try using a small delay value inside the while(1) loop of say 1ms. Then you could have a counter variable increment each time the loop executes. Once the counter value reaches 500 you can blink the LED and reset the counter to 0. Meanwhile you can execute your scrolling text as often as you wish. Or, you could just use interrupts like the "realtimeclock" tutorial code.

June 11, 2012
by raildoc
raildoc's Avatar

pcbolt. TNX so much for your attention and the suggestion. I was also starting to think about interrupts, but I overlooked the "realtimeclock" tutorial code to make it happen. Looks promising! Because of my "OCD", I can't let this problem go - even though I could get by in my app without LED blink, and LCD scroll is just for effect. FYI, this going into a (very-low-cost) heritage streetcar traction control that I've designed to replace the original 100-year-old rheostat set-up. Because of our historic transit-authority mission, it must look authentic vintage (as I remember in my own streetcar days), but under the skin - it's state-of-the-art MIT NerdKit. I'll let you know what happens.

June 11, 2012
by pcbolt
pcbolt's Avatar

Glad to help. I'd be very interested to see how your project turns out. If you have time, please post some pics when you are done...I used to help my uncle build replicas of the old Harlem line in northern Westchester, NY complete with balsa wood depots and working turntables.

June 11, 2012
by raildoc
raildoc's Avatar

pcbolt. If you're into it, there is a very good PC simulator of the Harlem line by Auran Trainz. As part of my job, I used this as a guide with Google GPS and Streetview to simulate a streetcar ride on our Dallas route. If interested in this or our M Line, send me an email pschwarzkopf@earthlink.net and check out Car #754 on www.MATA.org. All aboard!

Post a Reply

Please log in to post a reply.

Did you know that interrupts can be used to trigger pieces of code when events happen? Learn more...