AtMega 328PU and 20x4 LCD pfleury libraries

Go To Last Post
148 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Alternately, you could display 1 character (using only 8 special characters at a time as proposed by Johan in post #95) of the name at a time, hold it a couple of seconds and then display the next by changing the custom chars and the contents of that portion of the DDRAM.

 

 Or perhaps doing something like loop of the characters displaying one on each pass through the loop:

    B       display for first pass

      I     display for second pass

        A   display on third pass

then repeat, may give the "illusion" that they are all present. (

I do not have a character display to test to see if the timing would allow persistence of vision to make this work effectively.)

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
You guys are always saying you waste your precious time with me. Well, it might have been wasted time for you, but I learnt quite some stuff in this thread.

 

So, that's what matters. There are people here from many different cultures and with different personalities. Some are very direct, for them it's perfectly normal, for others it may seem harsh, this is because of culture shock, mostly, so don't take it personally. Good luck with the project.

 

Edit:

frog_jr wrote:
Or perhaps doing something like loop of the characters displaying one on each pass through the loop: B display for first pass I display for second pass A display on third pass then repeat, may give the "illusion" that they are all present. ( I do not have a character display to test to see if the timing would allow persistence of vision to make this work effectively.)

 

This seems a good idea, you can divide the picture in frames, each one having only 8 custom characters, the rest blank. It will probably flicker badly, but it might be possible.

Last Edited: Sun. Jul 30, 2017 - 08:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
Edit: frog_jr wrote: Or perhaps doing something like loop of the characters displaying one on each pass through the loop: B display for first pass I display for second pass A display on third pass then repeat, may give the "illusion" that they are all present. ( I do not have a character display to test to see if the timing would allow persistence of vision to make this work effectively.)   This seems a good idea, you can divide the picture in frames, each one having only 8 custom characters, the rest blank. It will probably flicker badly, but it might be possible.

 

I consider that a fairly bad idea, with small probability of success. Liquid crystal displays are not like LEDs. They need on/off-times (sort of PWM, but don't take that too literally). This is all taken care of by the 44780. (If you look in the Hitachi data sheet you will see mention of "bias" and this is what I'm talking about.)

 

I see two outcomes as most probable:

  • You will, in every character cell used, see a mix of the characters ('B', 'I', and 'A' all superimposed on one another) - likely very faint, or
  • You will see almost nothing, perhaps some flickering.

 

Add to this that your brain (and BIAs!) is a fantastic integrating machine (that's why you perceive film/TV as smoothly moving although it is e.g. 25 frames per second of still images - it's your brain doing that, not the TV set).

 

I would consider the experiment likely to be wasted time, if the goal is to geet something that works.

 

If the goal of the experiment is to see how bad it gets, then do go ahead. And please tell us what the results are! (Seriously! I'm curious!)

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
For instance, my daughter's first name is BIA! So I wanted to draw each character using 5 columns and 4 rows (LCD has 4 rows) for each char.
 

Back to your quest.

This is what cross in my mind. Maybe you can get a better idea after looking at this. Please take a look.

 

I'm not sure how to upload a video here so I zip it.

 

 

MG

Attachment(s): 

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm sorry if this out of topic.

 

JohanEkdahl wrote:
If you want an animation in one character position, you only need to use one of the eight custom characters.

Challenge accepted!

The video is in the attachment.

 

The code:

const PROGMEM unsigned char custom_char[]={
0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1f,
0x0e, 0x1b, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x1f,
0x0e, 0x1b, 0x11, 0x11, 0x11, 0x1f, 0x1f, 0x1f,
0x0e, 0x1b, 0x11, 0x11, 0x1f, 0x1f, 0x1f, 0x1f,
0x0e, 0x1b, 0x11, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
0x0e, 0x1b, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
0x0e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f};

void load_cust_char(unsigned char index)
{
 for(uint8_t i=0;i<8;i++) lcd_data(pgm_read_byte_near(&custom_char[i + index * 8]));
}

...

int main(void)
{
 Lcd_PutStr(0, 0, "Custom Font");
 Lcd_PutStr(0, 1, "BATTERY CHARGE");  
 lcd_gotoXY(15,1);
 lcd_data(0);       //first custom char only
    
 while(1)
 {
  for(uint8_t i=0;i<7;i++)
  {
    Lcd_Cmd(0x40);
    load_cust_char(i);
    _delay_ms(300);
  }
 }
}

 

Edit: changed code as EL TANGAS advised. thanks man!

 

 

MG

Attachment(s): 

I don't know why I'm still doing this hobby

Last Edited: Tue. Aug 1, 2017 - 01:18 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But remember what we have been discussing in this thread. You don't need to change update DDRAM. So try this:

 

// put this outside the loop
lcd_gotoXY(15,1);
lcd_data(0);       //first custom char only

 while(1)
 {
  for(uint8_t i=0;i<7;i++)
  {
    Lcd_Cmd(0x40);      //set CGRAM address 0
    load_cust_char(i);
    /*
    lcd_gotoXY(15,1);
    lcd_data(0);       //first custom char only
    */
    _delay_ms(300);
  }
 }

 

Last Edited: Mon. Jul 31, 2017 - 10:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MicroGyro wrote:

PsySc0rpi0n wrote:
For instance, my daughter's first name is BIA! So I wanted to draw each character using 5 columns and 4 rows (LCD has 4 rows) for each char.
 

Back to your quest.

This is what cross in my mind. Maybe you can get a better idea after looking at this. Please take a look.

 

I'm not sure how to upload a video here so I zip it.

 

 

MG

 

I liked this idea! Have you used any kind of screen shifting to do that animation?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
But remember what we have been discussing in this thread. You don't need to change update DDRAM. So try this:

Done! Code edited!

Thanks man.

 

 

 

 

MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
Have you used any kind of screen shifting to do that animation?
 

Nope. Nothing but print whole screen every 200ms. Just want to show you my idea so I don't really think of the appropiate code. 

 

I don't have idea how to use only 8 CGRAM to do that.

 

Please take a look at the attachment of what I tried to do. I use 1 CGRAM to do battery icon and 3 for AVR text animation. Not sure if this is the right way.But I guess that's what you can do with CGRAM not for the whole screen. Maybe GLCD?

 

 

 

 

Weeks of very poor internet connection is killing me :(

 

 

MG

Attachment(s): 

I don't know why I'm still doing this hobby

Last Edited: Tue. Aug 1, 2017 - 02:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, after a few days trying to make anything out of it, I have changed my idea a little bit! I'm now trying to make something a bit more simple which is to print the same name but in a different way.

 

I want now to print the name but with a scrolling up effect and using a big B made of several small Bs like this:

 

B
B B
B  B
B B
B
B B
B  B
B B
B

For now it's only this but starting to print one line at a time, starting from the bottom line of the LCD.

Later I'll try to add the other two chars to the mix.

 

But I'm still struggling with the code to correctly set the internal LCD pointer to the correct positions!

 

I have this so far and it is not working yet:

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd.h"

int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};
   int j = 0, m = 3;

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();

   _delay_ms(1000);

   for(int k = 0; k < 2; k++){ //2 halves of big B- Upper side is equal do lower side
      lcd_gotoxy(0, m);
      for(int i = 0; i < 4; i++){ //each variable index
         while(chars[i][j] != '\0'){ //run until the each of each index
            lcd_putc(chars[i][j++]);
         }
         j = 0, m--;
         _delay_ms(250);
      }
      lcd_gotoxy(0,0); //debug line
      lcd_puts("M val:"); //debug line
      lcd_gotoxy(6, 0); //debug line
      lcd_putc(m); //debug line
      _delay_ms(500); //debug line
   }
   for(;;);
   //return 0;
}

Any help is appreciated. And I'm sorry if the changes in my mind are going to upset anyone! I just want to make thing simple at the beginning!

 

Thanks

Psy

 

 

Edited;

 

The debug lines are not working correctly either! The "m" value is printing CGRAM custom chars and I never asked it to go to CGRAM memory (the 0x40 command)!

 

 

Edited 2;

post updated!

Last Edited: Wed. Aug 2, 2017 - 10:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You define:

char *chars[4]={"B", "B B", "B  B", "B B"};

Then you do:

while(chars[i][j] != '\0'){ //run until the each of each index
      lcd_putc(chars[i][j++]);

Isn't that 2 dimensional array? Didn't you get compiler warning with that?

 

What I did in my example is nothing but printing the whole screen (lines ?) each time and update it after about 200ms.

       Lcd_PutStr(0, 0, "     "); //col 0 row 0
       Lcd_PutStr(0, 1, "     "); //col 0 row 1
       Lcd_PutStr(0, 2, "     "); //col 0 row 2
       Lcd_PutStr(0, 3, "     "); //col 0 row 3
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "     ");
       Lcd_PutStr(0, 1, "     ");
       Lcd_PutStr(0, 2, "     ");
       Lcd_PutStr(0, 3, "BBBB ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "     ");
       Lcd_PutStr(0, 1, "     ");
       Lcd_PutStr(0, 2, "BBBB ");
       Lcd_PutStr(0, 3, "B   B");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "     ");
       Lcd_PutStr(0, 1, "BBBB ");
       Lcd_PutStr(0, 2, "B   B");
       Lcd_PutStr(0, 3, "BBBB ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "BBBB ");
       Lcd_PutStr(0, 1, "B   B");
       Lcd_PutStr(0, 2, "BBBB ");
       Lcd_PutStr(0, 3, "B   B");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "B   B");
       Lcd_PutStr(0, 1, "BBBB ");
       Lcd_PutStr(0, 2, "B   B");
       Lcd_PutStr(0, 3, "BBBB ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "BBBB ");
       Lcd_PutStr(0, 1, "B   B");
       Lcd_PutStr(0, 2, "BBBB ");
       Lcd_PutStr(0, 3, "     ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "B   B");
       Lcd_PutStr(0, 1, "BBBB ");
       Lcd_PutStr(0, 2, "     ");
       Lcd_PutStr(0, 3, " III ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "BBBB ");
       Lcd_PutStr(0, 1, "     ");
       Lcd_PutStr(0, 2, " III ");
       Lcd_PutStr(0, 3, "  I  ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "     ");
       Lcd_PutStr(0, 1, " III ");
       Lcd_PutStr(0, 2, "  I  ");
       Lcd_PutStr(0, 3, "  I  ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, " III ");
       Lcd_PutStr(0, 1, "  I  ");
       Lcd_PutStr(0, 2, "  I  ");
       Lcd_PutStr(0, 3, "  I  ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "  I  ");
       Lcd_PutStr(0, 1, "  I  ");
       Lcd_PutStr(0, 2, "  I  ");
       Lcd_PutStr(0, 3, " III ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "  I  ");
       Lcd_PutStr(0, 1, "  I  ");
       Lcd_PutStr(0, 2, " III ");
       Lcd_PutStr(0, 3, "     ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "  I  ");
       Lcd_PutStr(0, 1, " III ");
       Lcd_PutStr(0, 2, "     ");
       Lcd_PutStr(0, 3, "  A  ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, " III ");
       Lcd_PutStr(0, 1, "     ");
       Lcd_PutStr(0, 2, "  A  ");
       Lcd_PutStr(0, 3, " A A ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "     ");
       Lcd_PutStr(0, 1, "  A  ");
       Lcd_PutStr(0, 2, " A A ");
       Lcd_PutStr(0, 3, "A   A");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "  A  ");
       Lcd_PutStr(0, 1, " A A ");
       Lcd_PutStr(0, 2, "A   A");
       Lcd_PutStr(0, 3, "AAAAA");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, " A A ");
       Lcd_PutStr(0, 1, "A   A");
       Lcd_PutStr(0, 2, "AAAAA");
       Lcd_PutStr(0, 3, "A   A");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "A   A");
       Lcd_PutStr(0, 1, "AAAAA");
       Lcd_PutStr(0, 2, "A   A");
       Lcd_PutStr(0, 3, "     ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "AAAAA");
       Lcd_PutStr(0, 1, "A   A");
       Lcd_PutStr(0, 2, "     ");
       Lcd_PutStr(0, 3, "     ");
       _delay_ms(200);
       
       Lcd_PutStr(0, 0, "A   A");
       Lcd_PutStr(0, 1, "     ");
       Lcd_PutStr(0, 2, "     ");
       Lcd_PutStr(0, 3, "     ");
       _delay_ms(200);

Surely that's ridiculous and not a great way but if you still have plenty of flash left this is the simplest way I guess.

Or you can do it with LUT for more neat code since it only repeated but at different place "text".

As you see you still have 15 column to print at each line which can give you "BOLD" or "Italic" effect, or do what frog_jr show you in post #102 which each character scroll in at different column.

 

Hope it helps.

 

 

MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@MicroGyro, yeah that was my first approach and it is working. I just want to make a better code using loops!

 

I'm still trying to figure out what is wrong in my code because it is still not printing in the correct lines!

 

About the compilation errors/warnings, no, I'm not getting any warnings or errors!

 

The code I have is this one but as I said it's not yet working but I'll eventually get there!

 

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd.h"
 
int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};
 
   lcd_init(LCD_DISP_ON);
   lcd_clrscr();
 
   for(uint8_t i = 3; i >= 0; i--){
      lcd_gotoxy(0, i);
      for(uint8_t j = 0, k = 0; j <= 3 - i ; j++){
         while(chars[j][k] != '\0')
            lcd_putc(chars[j][k++]);
      }
      _delay_ms(1000);
      lcd_gotoxy(0,0);
      lcd_puts("Debug");
      _delay_ms(1000);
      lcd_clrscr();
   }
   for(;;);
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure what's your code doing. (@@ )

 

 

 

MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MicroGyro wrote:

I'm not sure what's your code doing. (@@ )

 

 

 

MG

 

I changed it a bit:

 

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd.h"
 
int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};
 
   lcd_init(LCD_DISP_ON);
   lcd_clrscr();
 
   lcd_gotoxy(0, 3);                                 //go to first position wheren to print
   for(uint8_t i = 3; i >= 0; ){                     //will go trough all LCD lines, in an upwards diraction
      for(uint8_t j = 0, k = 0; j <= 3 - i ; j++){   //will go through all elements of variable chars
         while(chars[j][k] != '\0')                  //will go through all chars of each above element
            lcd_putc(chars[j][k++]);                 //print each char and move to next
         lcd_gotoxy(0, --i);                         //scroll up
      }
      lcd_clrscr();
   }
   for(;;);
}

I can't test the code because I'm at work and I don't know if it is possible to be tested online!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A char* array IS a two dimensional array. Think of the argv[] in a normal PC C program for example.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well Sir... I'm not too good with that little star (asterix ?) thing.
Thank you for inform me Sir.
.
MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok guys, I'm having a struggle here!

 

When I use lcd_gotoxy(), supposedly, a command to set DDRAM address should be issued, right?

 

The problem is that I'm calling that command and after that I try to print a number like lcd_putc(5) and it prints whatever is in CGRAM address 5! Why is that?

 

The code is this:

int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();
   _delay_ms(250);

   for(;;){
      lcd_gotoxy(0, 3);
      for(uint8_t i = 3; i >= 0; ){
         for(uint8_t j = 0, k = 0; j <= 3 - i ; j++){
            while(chars[j][k] != '\0')
               lcd_putc(chars[j][k++]);
            lcd_gotoxy(13, 0);
            lcd_putc(k);
            lcd_gotoxy(0, --i);
            _delay_ms(1500);
         }
      }
      lcd_clrscr();
   }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
I try to print a number like lcd_putc(5) and it prints whatever is in CGRAM address 5! Why is that?

Because that is what your code says.

 

Another example:

lcd_putc(67);

will print what is in the CGRAM/CGROM at position 67, and that is a 'C'. I.e. it prints the character with ASCII value 67.

 

If you want to print the character '3' then it's

lcd_putc('3');

or possibly

lcd_putc(51);

Have a look at any ASCII table available on the Web, e.g. http://www.asciitable.com/ to see what ASCII values correspond to which characters.

 

This is absolute basics about printing characters, and the principle holds for any C program and not only for the 44780 display controller. E.g. if you, in a C program running on your PC, do

printf("%c", 67);

the character 'C' will be output from the program when running it.

 

In the case of the 44780, things are a little different:

 

Instead of the 32 first characters in the table being "unprintable" characters
 

  1. the first eight are your special characters
     
  2. the 9th to 31st might be blanks, or might be special characters. For examples see pages 17-18 of the Hitachi data sheet that I have repeatedly urged you to look at. The actual characters in these positions can vary between displays. (As I understand it a display manufacturer can order 44780s with custom CGROM contents, so see the data sheet for your specific display also. You can always test what is in CGROM of your display by just printing out chars from 0 to 255.)

 

So, the 44780 "character map" is not the same as the standard ASCII character map, but the principle that an output device has a mapping from a numerical char value to a character to display is the same regardless. (And just to make it really clear, I use char to speak about a variable in your program and character to speak about what you see on your display.)

 

Again, the difference between

lcd_putc(3);

and

lcd_putc('3');

is absolute basic C matter.

 

If this is a mystery to you I would suggest that you should start out by learning these principles, and the C programming language, by writing small test programs on a PC for a PC (i.e. the progrm runs von a PC). It is much simpler to learn C that way than to do it using a microcontroller as the running platform.

 

And the eternal (it seems) question:; When will you pick up a textbook on C and read it?

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is your lcd_gotoxy() and lcd_putc() inside? Maybe something wrong inside?
And I'm still can't understand what's your code doing. Shouldn't you update the whole screen at once for each frame?
.
MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@JohanEkdahl, I know about the ASCII table and how things are printed in HD44780. I'm just struggling how to print 'k' variable value, since lcd_putc(k) prints a CGRAM custom char and lcd_putc('k') printf the 'k' char itself! I also understood how things works when it comes to printing basic chars, and custom chars and other stuff in HD44780. My question is now how to print the 'k' variable!

 

And yes, I have PDF version of Dennis Ritchie C book and I read it some times!

 

@MicroGyro those 2 functions were written by some experienced gentleman! Peter Fleury, so they are working as supposed!

About the code, I know it's a bit confusing, I'm still trying my self to understand what is wrong with it and how to change it to make what I want!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
I'm just struggling how to print 'k' variable value

So why not ask about that?!? Above you wanted to print the character '3'.

 

Again, if k happens to be e.g. 68 then you will with 

 lcd_putc(k)

print the character 'D'. If you want to print the value of the variable k, i.e. as a string '68' ,then you must convert your integer variable k to a string with e.g. itoa() or sprintf().

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:

PsySc0rpi0n wrote:
I'm just struggling how to print 'k' variable value

So why not ask about that?!? Above you wanted to print the character '3'.

 

Again, if k happens to be e.g. 68 then you will with 

 lcd_putc(k)

print the character 'D'. If you want to print the value of the variable k, i.e. as a string '68' ,then you must convert your integer variable k to a string with e.g. itoa() or sprintf().

 

It's clear that I cannot express myself well...

 

I never wanted to print the character 3. I always wanted to print the 'k' variable value!

I'm sorry, I'm not the best writer! I'm doing the best I can!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, communicating in text is different from communicating with speech. The advantege of text is that you can compose your text, take a break, come back and read it with the mindset "how will this be understood at the other end?".

Don't type your immediate thoughts into a post here as if you were speaking to someone in person. That is doomed to cause misunderstandings and confusion.

Anyway, it's itoa() or sprintf() you want..

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Sat. Aug 5, 2017 - 11:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johan I think he's looking for itoa() to convert the binary value in 'k' to ASCII printables.
.
The problem here seems to be trying to program an AVR in C without having first learned the basics of C (which is far easier done by cutting the AVR out of the loop and done on a PC alone).

Last Edited: Sat. Aug 5, 2017 - 11:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:

@JohanEkdahl, I know about the ASCII table and how things are printed in HD44780. I'm just struggling how to print 'k' variable value, since lcd_putc(k) prints a CGRAM custom char and lcd_putc('k') printf the 'k' char itself! I also understood how things works when it comes to printing basic chars, and custom chars and other stuff in HD44780. My question is now how to print the 'k' variable!

 

And yes, I have PDF version of Dennis Ritchie C book and I read it some times!

 

@MicroGyro those 2 functions were written by some experienced gentleman! Peter Fleury, so they are working as supposed!

About the code, I know it's a bit confusing, I'm still trying my self to understand what is wrong with it and how to change it to make what I want!

 

If you are sure that k is a single digit, that is, between 0 and 9, you can do lcd_putc(k+'0').

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Johan I think he's looking for itoa() to convert the binary value in 'k' to ASCII printables.

So do I, and I have said so twice above.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Yes, communicating in text is different from communicating with speech. The advantege of text is that you can compose your text, take a break, come back and read it with the mindset "how will this be understood at the other end?". Don't type your immediate thoughts into a post here as if you were speaking to someone in person. That is doomed to cause misunderstandings and confusion. Anyway, it's itoa() or sprintf() you want..

 

That will be always an unknown... Nobody can predict what's going on in other's mind! And you bet I read my own text more than once and I got back a lot of times to replace words here and there and fix errors and so on and on! But it looks like it's never enough. The mistake is always on my side!

 

 

@clawson

I already said more than once that I have the basics of C, that I know about the ASCII table, I know how things are printed in terms of '%c', '%s' and so on, but I'm not an expert in any of the subjects! Neither C neither micro-controllers. And as this is the first time that I'm going through this particular situation of printing an integer that a variable is holding, I cannot guess, by magic, the solution, however, this is always considered lack of basic knowledge! The need of converting an integer to a char to be printed in a uC is not related with C, basics of C or advanced knowledge of C. In my opinion it is related to a specific need of HD44780. Any knowledge on C I could ever have, would tell me that that would need to be converted to a char to be printed!

Anyway, I'll take the blame, as usual.

 

Also, I would never need to convert an integer to a char to print the value if I was coding in a PC, so that would be useless in this situation!

 

 

 

 

El Tangas wrote:

PsySc0rpi0n wrote:

@JohanEkdahl, I know about the ASCII table and how things are printed in HD44780. I'm just struggling how to print 'k' variable value, since lcd_putc(k) prints a CGRAM custom char and lcd_putc('k') printf the 'k' char itself! I also understood how things works when it comes to printing basic chars, and custom chars and other stuff in HD44780. My question is now how to print the 'k' variable!

 

And yes, I have PDF version of Dennis Ritchie C book and I read it some times!

 

@MicroGyro those 2 functions were written by some experienced gentleman! Peter Fleury, so they are working as supposed!

About the code, I know it's a bit confusing, I'm still trying my self to understand what is wrong with it and how to change it to make what I want!

 

If you are sure that k is a single digit, that is, between 0 and 9, you can do lcd_putc(k+'0').

 

Yes, 'k' is holding a value between 0 and 4, so it shouldn't be a problem. But I got my situation solved now with itoa().

Last Edited: Sat. Aug 5, 2017 - 07:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
The need of converting an integer to a char to be printed in a uC is not related with C, basics of C or advanced knowledge of C.

 

Of course it is. Just go to a PC and try with the standard C function putchar(). Nothing to do with MCUs or the HD44780. What you need to understand is the difference between 1 and '1'.

 

edit: also, '...' used on a variable doesn't evaluate that variable. It gives the ASCII code of the character inside. If your variable name had more than one character, it would fail to even compile. So, you see, this is basic C knowledge you didn't have.

Last Edited: Sat. Aug 5, 2017 - 08:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
What you need to understand is the difference between 1 and '1'.

My point entirely.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

PsySc0rpi0n wrote:
The need of converting an integer to a char to be printed in a uC is not related with C, basics of C or advanced knowledge of C.

 

Of course it is. Just go to a PC and try with the standard C function putchar(). Nothing to do with MCUs or the HD44780. What you need to understand is the difference between 1 and '1'.

 

 

 

I know the difference between 1 and '1'... Please stop saying I don't know the difference between chars, integers and ASCII table correspondence. This starts to be exhausting to hear the same over and over again! 

 

And a putchar() function takes an integer as an argument but in this case, you cannot compare putchar() from standard C with lcd_putchar() from pfleury's libraries... They cannot be compared because when lcd_putchar() is called with an integer as an argument, it won't print the corresponding ASCII table char. It will print CGRAM address memory content corresponding to the integer passed to lcd_putc().

 

Anyway, what I would like help with was with my code. I can't figure out a way of doing what I want! I'll explain again because anytime I post here a question, I get all sort of answers  not directly related with my question and conversation deviates from main purpose!

 

I intend to get the following effect on my LCD:

 

 

Line 0 --------------------------

Line 1 --------------------------

Line 2 --------------------------

Line 3 B------------------------

 

------------------------------------------

 

Line 0 --------------------------

Line 1 --------------------------

Line 2 B-------------------------

Line 3 B B----------------------

 

------------------------------------------

 

Line 0 --------------------------

Line 1 B------------------------

Line 2 B B----------------------

Line 3 B  B---------------------

 

------------------------------------------

 

Line 0 B-----------------------

Line 1 B B---------------------

Line 2 B  B--------------------

Line 3 B B---------------------

 

------------------------------------------

 

Line 0 B B--------------------

Line 1 B  B-------------------

Line 2 B B--------------------

Line 3 B----------------------

 

------------------------------------------

 

Line 0 B  B-------------------

Line 1 B B--------------------

Line 2 B----------------------

Line 3 B B--------------------

 

------------------------------------------

 

Line 0 B B--------------------

Line 1 B----------------------

Line 2 B B--------------------

Line 3 B  B-------------------

 

------------------------------------------

 

Line 0 B----------------------

Line 1 B B--------------------

Line 2 B  B-------------------

Line 3 B B--------------------

 

------------------------------------------

 

Line 0 B B--------------------

Line 1 B  B-------------------

Line 2 B B--------------------

Line 3 B----------------------

 

 

I did the code the hard way for half of the B but I can't do it using loops!

 

The code I have so far is this, but it prints a P and it only scrolls up until the P is complete! Then it starts all over again!

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include "lcd.h"

int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();
   _delay_ms(250);

   for(;;){
      lcd_gotoxy(0, 3);
      for(uint8_t i = 3; i >= 0; ){
         for(uint8_t j = 0, k = 0; j <= 3 - i-- ; j++){

            while(chars[j][k] != '\0')
               lcd_putc(chars[j][k++]);

            k = 0;
            lcd_gotoxy(0, i);
            _delay_ms(1000);
         }

         lcd_clrscr();
         i = 3;
         lcd_gotoxy(0, 3);
      }
   }
}

 

And a video to better ilustrate

https://www.youtube.com/watch?v=...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to divide the problem in smaller problems. I suggest that you start by writing a function, that from array

 

char *chars[4]={"BB", "B B", "B  B", "B B", "BB"};

writes the lines from index "start" to index "end". Prototype:

 

void printlines (char** chars, int start, int end);

So, if you call printline(chars, 2, 4) would print:

 

B  B
B B
BB

 

Once this is done and working, we can continue.

 

Edit:btw, I think the library has a lcd_puts() function, you should use that to print each line, instead of multiple calls to lcd_putc().

Last Edited: Sat. Aug 5, 2017 - 10:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

You need to divide the problem in smaller problems. I suggest that you start by writing a function, that from array

 

char *chars[4]={"BB", "B B", "B  B", "B B", "BB"};

writes the lines from index "start" to index "end". Prototype:

 

void printlines (char** chars, int start, int end);

So, if you call printline(chars, 2, 4) would print:

 

B  B
B B
BB

 

Once this is done and working, we can continue.

 

 

Is it this what you mean?

 

void print_array(char *array[], uint8_t start, uint8_t end){
   for (uint8_t j = 0; start <= end; start++){
      while(chars[start][j] != '\0')
         lcd_putc(chars[start][j++]);
   }
}

 

This does not care about location where to print! The example you gave suggests console printing, therefore, scrolling up is, so to speak, automatic!

Last Edited: Sat. Aug 5, 2017 - 10:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:
This does not care about location where to print! The example you gave suggests console printing, therefore, scrolling up is, so to speak, automatic!

 

Indeed. So now, solve that problem, it's not difficult, is it? You will probably need global variables with the x and y positions. And use lcd_puts(), if the library has it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, but I think the problem is that one of the loops needs to change the exit condition, so that in the first run, it only prints the 1st array index, in the 2nd run it will print the 1st and the 2nd array indexes and so on! But I'll try!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:

Ok, but I think the problem is that one of the loops needs to change the exit condition, so that in the first run, it only prints the 1st array index, in the 2nd run it will print the 1st and the 2nd array indexes and so on! But I'll try!

 

Yes, but that's why that function is needed. If you pass "start" and "end" equal, it should print only one line. The function doesn't care about anything else. Positioning the cursor, deciding how many lines to print, and which, should be done outside the function.

This is what I mean by dividing the problem into smaller problems.

 

edit: now, probably the simple and lazy way to solve this is to add empty strings beffore and after the real ones:

 

char *chars[4]={"", "", "", "", "BB", "B B", "B  B", "B B", "BB", "", "", "", ""};

this way, you can always print 4 lines starting at coords 0,0. Then you advance through the array, always printing a window of 4 lines.

Last Edited: Sat. Aug 5, 2017 - 10:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I came up with this...

 

Not tested yet... Going to test now!

 

I have the positioning control of the LCD internal pointer inside that function!

 

Will test while you see my post.

 

void print_array(char *array[], uint8_t start, uint8_t end, uint8_t line){
   uint8_t offset = 1;

   for (uint8_t i = 0; start <= end; start++){
      while(array[start][i] != '\0')
         lcd_putc(array[start][i++]);
      if(line != 3)
         lcd_gotoxy(0, line + offset++);
      i = 0;
      _delay_ms(1000);
   }
}

int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();

   for( ; ; ){
      for(uint8_t i = 3; i >= 0; i--){
         lcd_gotoxy(0, i);
         print_array(&chars[], 0, 3 - i, i);
      }
   }

 

I'm getting these errors after compiling:

avr-gcc -g -Wall -Os -mmcu=atmega328p -std=c99 -DF_CPU=16000000UL   -c -o test_lcd_mine3.o test_lcd_mine3.c
test_lcd_mine3.c: In function ‘main’:
test_lcd_mine3.c:30:29: error: expected expression before ‘]’ token
          print_array(&chars[], 0, 3 - i, i);
                             ^
test_lcd_mine3.c:30:10: error: too few arguments to function ‘print_array’
          print_array(&chars[], 0, 3 - i, i);
          ^
test_lcd_mine3.c:8:6: note: declared here
 void print_array(char *array[], uint8_t start, uint8_t end, uint8_t line){
      ^
test_lcd_mine3.c:22:10: warning: variable ‘chars’ set but not used [-Wunused-but-set-variable]
    char *chars[4]={"B", "B B", "B  B", "B B"};
          ^
<builtin>: recipe for target 'test_lcd_mine3.o' failed
make: *** [test_lcd_mine3.o] Error 1

 

Last Edited: Sat. Aug 5, 2017 - 11:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's &chars, not &chars[].

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"B   B" is a rather dangerous initializer for [4]!

 

(while it "fits" you won't be getting \0 at the end) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

It's &chars, not &chars[].

 

 

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include "lcd.h"

void print_array(char *array[], uint8_t start, uint8_t end, uint8_t line){
   uint8_t offset = 1;

   for (uint8_t i = 0; start <= end; start++){
      while(array[start][i] != '\0')
         lcd_putc(array[start][i++]);
      if(line != 3)
         lcd_gotoxy(0, line + offset++);
      i = 0;
      _delay_ms(1000);
   }
}

int main(void){
   char *chars[4]={"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();

   for( ; ; ){
      for(uint8_t i = 3; i >= 0; i--){
         lcd_gotoxy(0, i);
         print_array(&chars, 0, 3 - i, i);
      }
   }

 

 

Not working either.

 

avr-gcc -g -Wall -Os -mmcu=atmega328p -std=c99 -DF_CPU=16000000UL   -c -o test_lcd_mine3.o test_lcd_mine3.c
test_lcd_mine3.c: In function ‘main’:
test_lcd_mine3.c:30:22: warning: passing argument 1 of ‘print_array’ from incompatible pointer type
          print_array(&chars, 0, 3 - i, i);
                      ^
test_lcd_mine3.c:8:6: note: expected ‘char **’ but argument is of type ‘char * (*)[4]’
 void print_array(char *array[], uint8_t start, uint8_t end, uint8_t line){
      ^
avr-gcc -g -Wall -Os -mmcu=atmega328p -std=c99 -DF_CPU=16000000UL -Wl,-Map,test_lcd_mine3.map -o test_lcd_mine3.elf test_lcd_mine3.o lcd.c 
avr-objdump -h -S test_lcd_mine3.elf > test_lcd_mine3.lst
avr-objcopy -j .text -j .data -O ihex test_lcd_mine3.elf test_lcd_mine3.hex
avr-objcopy -j .text -j .data -O binary test_lcd_mine3.elf test_lcd_mine3.bin
avr-objcopy -j .text -j .data -O srec test_lcd_mine3.elf test_lcd_mine3.srec
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O ihex test_lcd_mine3.elf test_lcd_mine3_eeprom.hex \
|| { echo empty test_lcd_mine3_eeprom.hex not generated; exit 0; }
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O binary test_lcd_mine3.elf test_lcd_mine3_eeprom.bin \
|| { echo empty test_lcd_mine3_eeprom.bin not generated; exit 0; }
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
avr-objcopy -j .eeprom --change-section-lma .eeprom=0 -O srec test_lcd_mine3.elf test_lcd_mine3_eeprom.srec \
|| { echo empty test_lcd_mine3_eeprom.srec not generated; exit 0; }
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used

 

 

clawson wrote:

"B   B" is a rather dangerous initializer for [4]!

 

(while it "fits" you won't be getting \0 at the end) 

 

This is a subject that I do not understand very well, so I cannot talk much about this, but when I initialise the array as "char *chars[4]" I'm initialising an array of 4 "null terminated strings", so I that the number 4 present in that declaration is not determining the amount of chars in each string, rather is determining the amount of strings in that array! I don't know if what I said is correct, but is the idea I have...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I already fixed the array problems.

It should be:

 

Variable declaration

char *chars[4]={"B", "B B", "B  B", "B B"};

 

Function declaration

void print_array(char *array[], uint8_t start, uint8_t end, uint8_t line);

 

Function usage:

print_array(chars, 0, 3 - i, i);

 

or yet:

print_array(&chars[0], 0, 3 - i, i);

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code is a bit confusing. If you want to print a string, why use:

      while(array[start][i] != '\0')
         lcd_putc(array[start][i++]);

instead of

    lcd_puts(array[start]);

I'm not familiar with Fleury's library, but it should work, right?

 

And if you just want to move the print position to the start of the next line, why don't you use:

    lcd_putc('\n');

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can do that, but the problem is not there! The loops are not working yet correctly!

 

After a few loops, only garbage is being printed in the LCD!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PsySc0rpi0n wrote:

I can do that, but the problem is not there! The loops are not working yet correctly!

 

After a few loops, only garbage is being printed in the LCD!

 

I understand that, but if your code is messy, people here won't even bother to try and decipher it. If it's clean, it's more likely someone will take a look and help you. So please rewrite it in a cleaner way and the bugs will be easier to find.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I have the code like this:

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include "lcd.h"

void print_array(char *array[], uint8_t start, uint8_t end){
   for(; start <= end; start++){
      lcd_puts(array[start]);
   }
}

int main(void){
   char *chars[4] = {"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();

   for( ; ; ){
      for(uint8_t i = 3; i >= 0; i--){
         lcd_gotoxy(0, i);
         print_array(chars, 0, 3 - i);
      }
      _delay_ms(1000);
   }
}

But the loops are still not working! After some loops and some, what looks like, random lcd_gotoxy() calss, it only prints garbage!

Last Edited: Sun. Aug 6, 2017 - 08:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, after compiling the above code and uploading it onto the uC, it only prints garbage!

 

 

 

Edited;

 

I changed the code in some lines but still not good!

 

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include "lcd.h"

void print_array(char *array[], uint8_t start, uint8_t end){
   for(; start <= end; start++){
      lcd_puts(array[start]);
   }
}

int main(void){
   char *chars[4] = {"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();

   for( ; ; ){
      for(uint8_t i = 3; i >= 0; i--){
         lcd_gotoxy(0, i);
         print_array(chars, 0, 3 - i);
         _delay_ms(1000);
         if( !i ){
            i = 3;
            lcd_clrscr();
            _delay_ms(500);
         }
      }
      //code is not reaching here
      lcd_gotoxy(0, 3); //debug lines
      lcd_puts("Here"); //debug lines
      _delay_ms(1000);  //debug lines
   }
}

 

There is yet a part of code missing because at some point, each array element is being printed in the same line!

 

This is how the code is running now:

https://www.youtube.com/watch?v=...

 

 

 

 

 

--------------------------edited 2;--------------------------

 

Ok, some more changes in the code and I think I'm closer!

 

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include "lcd.h"

void print_array(char *array[], uint8_t start, uint8_t end, uint8_t curr_line){
   for(; start <= end; start++){
      lcd_puts(array[start]);
      lcd_gotoxy(0, ++curr_line);
   }
}

int main(void){
   char *chars[4] = {"B", "B B", "B  B", "B B"};

   lcd_init(LCD_DISP_ON);
   lcd_clrscr();

   for( ; ; ){
      for(uint8_t i = 3; i >= 0; i--){
         lcd_gotoxy(0, i);
         print_array(chars, 0, 3 - i, i);
         _delay_ms(1000);
         if( !i ){
            i = 3;
            lcd_clrscr();
            _delay_ms(500);
         }
      }
      //I think code is not reaching here
      lcd_gotoxy(0, 3);
      lcd_puts("Here");
      _delay_ms(1000);
   }
}

Video:

https://www.youtube.com/watch?v=...

Last Edited: Sun. Aug 6, 2017 - 09:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In my opinion, when you execute

 

      lcd_gotoxy(0, ++curr_line);

the last time, when curr_line = 3, you call

      lcd_gotoxy(0, 4);

Since 4 is an invalid line number, it's possible the function will have undefined behavior, causing unpredictable results, like printing that extra "B". I think you should get rid of the curr_line variable, and replace that problematic line by

      lcd_putc('\n');

to advance one line.

 

Edit: Ah, yes, your other problem of unreachable code. That is because of this block:

         if( !i ){
            i = 3;
            lcd_clrscr();
            _delay_ms(500);
         }

So, when i reaches 0, you make it 3 again. Then, the i-- of the for loop is executed, and you get i=2. This obeys the for condition i >= 0, so the for doesn't end, it starts again with i=2, that's why you start with 2 lines printed. Then this repeats forever.

 

BTW, you could have easily discovered this by debugging the code, you know... I suppose you're using Atmel Studio? It comes with a powerful debugger, so learn to use it.

Last Edited: Sun. Aug 6, 2017 - 10:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is getting bigger than a Cecil B. DeMille production (Cecil with a whistle on the Ce part). cheeky

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Pages