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 » LCD library error? Only Line 4 and on line1 ???

February 18, 2012
by 4bits4e4
4bits4e4's Avatar

New to embedded C but not much else in the hobby. Just got the kit, wired up fine, got the message all was good. Hooked up the tempsensor circuit, uploaded the file and all was OK! But now the display is boogered. Line 1 is all that displays and it is shifted 1 character to the left. A four line write always ends up in line one. Verified the hook-up. Wrote a few test progs to verify the chip. Tryed a different display, same thing. Tryed editing lcd.c several times, no change. Anyone else seen this kind of trouble? Only the projects using the lcd have given me trouble. I hope it's something simple, circuits don't get much simpler than this one. Thinking it might be an old lcd library? I've been studying it but haven't found any gross errors. Any ideas out there? Any help is much appreciated.

February 18, 2012
by Ralphxyz
Ralphxyz's Avatar

4bits4e4, are you "still" able to run the initialload program, correctly?

Ralph

February 18, 2012
by 4bits4e4
4bits4e4's Avatar

Everything seems to running fine but, the display is not getting formatted correctly. Have discovered since my post that the lcd_goto_posistion is not happening. Was able to replace those calls with lcd_write_byte statements and get the screen looking right. Don't really understand, yet, why the lcd functions are to blame. Using Hitiachi and clone, same command set in both. Ever seen this problem? Thought at first it might be a library access problem due to my install but, have since narrowed down to this lcd function call not working.

February 18, 2012
by 4bits4e4
4bits4e4's Avatar

Let me be more specific to what is happening. ANY of the projects that use the LCD that I compile, do not format the lcd. ALL lines sent to the lcd go to line 1. So the lcd_goto_position function is not sending the correct DDRAM address. lcd_write_byte(0x80 | (row_offset + col)); The row_offset + col is always 0x00. Running the code straight out of the nerdkits folder. avr_dude doesn't report any trouble with the Makefile. Was hoping to get a little further before hitting a brick wall.

February 19, 2012
by 4bits4e4
4bits4e4's Avatar

Still not sure why the function isn't working for me. Here's my work around!

// write message to LCD
    lcd_home();
    lcd_write_string(PSTR("ADC: "));
    lcd_write_int16(last_sample);
    lcd_write_string(PSTR(" of 1024   "));
    //lcd_line_two();
    PORTD &= ~(1<<PD7); // RS=command
    lcd_write_byte(0xc0); // Set DDRAM addr
    fprintf_P(&lcd_stream, PSTR("Temperature: %.2f"), temp_avg);
    lcd_write_data(0xdf);
    lcd_write_string(PSTR("F      "));

All this does is circumvent the calls to lcd_line_two and subsequently the call to lcd_goto_position. Without an emulator and, adequate knowledge of this compiler, I'm as yet unable to determine where the vars are being re-assigned to 0. Having lots of fun! Really! No, Really!

February 19, 2012
by pcbolt
pcbolt's Avatar

@4bits4e4

Your work around actually eliminates many possible problems (makefile, wiring, etc). I think your next step would be to try and introduce a debug variable into the program. Since you want to track inside the "lcd.c" library, you'd have to declare a variable, say "uint8_t debug;" inside the "lcd.h" so it is visible to both the library and your main program (place it after the first define statement). Next change this line (make sure you save a copy of the originals):

lcd_write_byte(0x80 | (row_offset + col));

To:

debug = 0x80 | (row_offset + col);
lcd_write_byte(debug);

Then somewhere in your main program, just print debug to line one. By changing the different placement of debug, you might be able to track the problem. It's a hack I know, but it the poor man's debugger and it works wonders sometimes.

February 19, 2012
by 4bits4e4
4bits4e4's Avatar

Thanks for the info, looks like a great approach and, I'm very familiar with the poor man's way of doing things. I'll have to really look this over, doesn't seem right that I would have so much trouble with a simple program like this. Learning embedded C is my goal and troubleshooting this silly problem has taught me some. Not sure how my work around could mask wiring or Makefile errors. I'll be learning what it takes to solve this, thanks again for your suggestion and help. I'll keep you updated.

February 19, 2012
by pcbolt
pcbolt's Avatar

Cool.

My first thoughts earlier in the thread were to check wires and the makefile, but since your work around succeeded, you shouldn't have to worry about those things right now. It's odd the LCD library isn't working for you, I've never had a problem with it....yet.

It's good you have a positive attitude. I've always learned the most when tracking down bugs.

Good luck.

February 19, 2012
by 4bits4e4
4bits4e4's Avatar

I've ordered a few more chips just to see if the problem is in the hardware. I gave the debug idea a shot and here are the results. As written, I always get 255 from debug = (0x80 | (row_offset + col)); and "50 2" when debug = row_offset ; regardless of which lcd_line_xxx I call. Very strange. I'm using lcd_write_int16(debug ); but I haven't fully deciphered that routine yet, hope it isn't skewing the result. There are so many variables to consider while solving this trouble. New untested Ubuntu 11.10 install, unfamiliar IDE and barely understood compiler. The list goes on but I thought I would mention it so when I say I have a lot to learn, it would seem more profound!!! Learning is what keeps me young both in mind and at heart. uC programming is a great hobby and I was once quite proficient at it. I'll not let a decade of ignoring technological advances humble me. I look forward to being a valued contributor to this forum and the tech community in general with sharing knowledge, patience, and practical experience.

February 20, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi 4bits4e4,

Something to try. Go into the makefiles for initialload and libnerdkits and change the compiler optimization option from -Os to -O0 (dash O zero). Then make sure you delete all .hex and .o files both in initialload and in libnerdkits, then recompile the code. This will turn off all compiler optimizations, which might fix the issue.

Humberto

February 20, 2012
by 4bits4e4
4bits4e4's Avatar

BINGO!!!! What an obscure bug for a newbie to find. Works like advertised. Pleased as punch. Will have to read up on this, wonder what makes my dev system different. Thanks again, you MIT guys are allllllright!!

August 21, 2012
by thinairart
thinairart's Avatar

I have this same issue using the latest version of CrossPack (formerly AVRMacPack) on OSX 10.7

Disabling compiler optimizations did fix the LCD problem described in this thread, but I'm curious as to the actual cause so I can fix the LCD code to work with compiler optimizations (the display update seems slower, perhaps just my imagination). Has anyone else ran into this issue since this thread was originally posted (about 6 months ago) ?

August 21, 2012
by thinairart
thinairart's Avatar

I should note that the latest version of CrossPack uses gcc 4.5.1

I have not had any problems with the LCD code in the past, but I was using the AVRMacPack build from 2008, which used gcc 4.3.0

August 21, 2012
by thinairart
thinairart's Avatar

Found a fix for the issue, at least for OSX and the latest version of CrossPack. The following code solves the problem described in this thread. There was some sort of type casting issue when compiler optimizations were turned on, so I simply spelled out the bitwise math literally in a single statement. If you are having this issue, just replace lcd_goto_position in lcd.c with the following:

void lcd_goto_position(uint8_t row, uint8_t col) {
  lcd_set_type_command();

  // 20x4 LCD: offsets 0, 0x40, 20, 0x40+20
  uint8_t row_offset = 0;
  switch(row) {
    case 0: row_offset = (0x80 | (0x00 + col)); break;
    case 1: row_offset = (0x80 | (0x40 + col)); break;
    case 2: row_offset = (0x80 | (20 + col)); break;
    case 3: row_offset = (0x80 | ((0x40+20) + col)); break;
  }
  lcd_write_byte(row_offset);
}

Post a Reply

Please log in to post a reply.

Did you know that you can make a huge, multi-panel LED display? Learn more...