ADC result on LCD

Discussion in 'Embedded Systems and Microcontrollers' started by Shagas, Jul 28, 2013.

  1. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Hello ,
    I've been recently trying to interface my atmega32 to a WINSTAR
    WH1601A LCD display .
    It works ( most of the time ) when I'm trying to send discrete characters .

    Now i'm trying to send a live feed of the ADC result to the LCD and it's not working .
    I'm trying to covert the result to a string and then send it.
    My LCD is showing blank (no results)
    Could someone see where my error in the code is? Particularly in the conversion using ITOA.

    Note: I'm only linking snippets of the relevant code

    Thanks in advance

    Code ( (Unknown Language)):
    1.  
    2.  
    3. int convert()
    4. {
    5.     ADCSRA |= ( 1 << ADSC);
    6.    
    7.     while((ADCSRA & (1<< ADSC)));
    8.      
    9.    
    10.     return ADC;
    11.    
    12. }
    13.  
    14. void SendString(char *CString)
    15. {
    16.     while(*CString > 0)
    17.     {
    18.         SendCharacter(*CString++);
    19.     }
    20.    
    21. }
    22.  
    23.  

    And the main routine:

    Code ( (Unknown Language)):
    1.  
    2.  
    3. int main(void)
    4. {  
    5.     ADMUX |= ( 1 << REFS0);
    6.     ADCSRA |= ( 1 << ADEN) | (1 << ADPS1) | ( 1 << ADPS0);
    7.     DDRD |= (1 << 2 ) | ( 1 << 5 ) | ( 1 << 7);
    8.    
    9.     _delay_ms(100);
    10.     SendCommand(0x01); //Clear Screen 0x01 = 00000001
    11.     _delay_ms(2);
    12.     SendCommand(0x38);
    13.     _delay_us(50);
    14.  
    15.     while(1)
    16.     {
    17.         convert();
    18.        
    19.        
    20.             SendCommand(0x01);
    21.             char adcResult[4];
    22.             itoa(ADC , adcResult, 10);
    23.             SendString(adcResult);
    24.             _delay_ms(10);
    25.            
    26.        
    27.    
    28.        
    29.        
    30.     }
    31. }
     
  2. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Is there some obvious reason why this isn't working?
     
  3. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Generally my SendString function doesn't really do it's job correctly .
    I got that part of the code and some other snippets from newbiehack.com

    I don't get how the SendString part works... but it works for the guy and it sometimes works for me .
    Anyway Here is the complete code , I'd REALLY appreciate it if someone shed some light on it .

    I know how almost everything in that code works ( I didn't just copy paste) . But the ones mentioned with '"apparently" I am not so sure of.

    Code ( (Unknown Language)):
    1.  
    2. #include <avr/io.h>
    3. #include <util/delay.h>
    4. #include <stdlib.h>
    5.  
    6. void Checkbusy(void);
    7. void Enable(void);
    8. void SendCharacter(unsigned char character);
    9. void SendCommand(unsigned char command);
    10. int convert(void);
    11. void SendString(char *CString);
    12.  
    13.  
    14. int main(void)
    15. {  
    16.     ADMUX |= ( 1 << REFS0);
    17.     ADCSRA |= ( 1 << ADEN) | (1 << ADPS1) | ( 1 << ADPS0);
    18.     DDRD |= (1 << 2 ) | ( 1 << 5 ) | ( 1 << 7);
    19.    
    20.     _delay_ms(100);
    21.     SendCommand(0x01); //Clear Screen 0x01 = 00000001
    22.     _delay_ms(2);      // apparently these delays are needed between commands
    23.     SendCommand(0x38); // apparently sets the LCD in 8bit mode
    24.     _delay_us(50);
    25.  
    26.     while(1)
    27.     {
    28.         convert(); // routine to start conversions of ADC and return result
    29.        
    30.        
    31.         SendCommand(0x01); // clearscreen
    32.         char adcResult[4];
    33.         *itoa(ADC , adcResult, 10);   // converting the ADC result to a string
    34.         SendString(adcResult);   // SendString routine
    35.         _delay_ms(10);
    36.        
    37.        
    38.        
    39.    
    40.        
    41.        
    42.     }
    43. }
    44.  
    45.  
    46. void Checkbusy()
    47. {  
    48.     DDRB = 0b00000000; //Put PortB in Input (read) Mode
    49.     PORTD &= ~(1<<2); //Turn on Command Mode (RS off)
    50.     PORTD |= (1<<7); //Set to Read (RW on)
    51.     while (PORTB >= 0x80); //D7 pin will be a "1" with any number above 0x80 (that's hex)
    52.     {
    53.         Enable(); // this is just another routine to turn the enable on and off
    54.     }
    55.     DDRB = 0xFF; //Set portB as output
    56. }
    57.  
    58. void Enable()
    59. {
    60.     PORTD |= (1<<5); //Turn Enable on
    61.     asm volatile ("nop"); // apparently this makes the MCU wait for 500 ns
    62.     asm volatile ("nop");
    63.     PORTD &= ~(1<<5); //turn off Enable
    64. }
    65. void SendCommand(unsigned char command)
    66. {
    67.     Checkbusy();
    68.    
    69.     PORTB = command;
    70.     PORTD &= ~((1<<2)|(1<<7)); //turn off RS (command mode) and RW (write mode)
    71.     Enable();
    72.     DDRB = 0;
    73. }
    74.  
    75. void SendCharacter(unsigned char character)
    76. {
    77.     Checkbusy();
    78.    
    79.     PORTB = character;
    80.     PORTD &= ~(1<<7); //turn off RW (write mode)
    81.     PORTD |= (1<<2); //turn on RS (character display mode)
    82.     Enable();
    83.     DDRB = 0;
    84. }
    85.  
    86. int convert()
    87. {
    88.     ADCSRA |= ( 1 << ADSC);
    89.    
    90.     while((ADCSRA & (1<< ADSC)));
    91.      
    92.    
    93.     return ADC;
    94.    
    95. }
    96.  
    97. void SendString(char *CString)
    98. {
    99.     while(*CString > 0)
    100.     {
    101.         SendCharacter(*CString++);  
    102.     }
    103.    
    104. }
    105.  
     
  4. mitko89

    Member

    Sep 20, 2012
    123
    19
    Two questions:
    1)Why don't you try with sprintf()
    2)ADC=? I didn't see where you assign any value to it.
     
  5. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Problem is that sometimes the LCD works ... sometimes I reprogram the MCU and it doesn't work anymore until I load a completely diffrent program.

    I do have my dataports of the LCD on PORTB on which also resides the AVRISP mkii
    Is it having a conflict with the LCD?
     
  6. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    The ADC value is returned after the convert(); function and put into the ITOA function.

    I do not know the sprintf() function . What does it do / how can I use it?
     
  7. mitko89

    Member

    Sep 20, 2012
    123
    19
    What the sprintf() does is: it takes a formatted input and makes a string out of it e.g.
    char mystring[20]; // this is your buffer string
    sprintf(mystring,"ADC value=%d", ADCvalue); // ADCvalue is your converted value
    The result of that is mystring now contains "ADC value=XXX" (your value). And then you can pass that string to your printer program, which sends the chars 1 by 1.
    I also suggest you get a volatile variable to contain the result from the conversion, because the compiler may optimize it and use a copy (you don't want that to happen).
     
    Shagas likes this.
  8. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Okay , thanks mitko89 , i'll try it.
    Do you have any idea why My lcd is sometimes working and sometimes not?
     
  9. mitko89

    Member

    Sep 20, 2012
    123
    19
    I also suggest you to take a look at this playlist of lectures from James Conrad (you can see how to use the sprintf() at lecutre 5).
     
  10. mitko89

    Member

    Sep 20, 2012
    123
    19
    I don't think it's a conflict with the SP, but you can try moving it to another pins, also can you describe the problem further? Do you get solid boxes or noting at the LCD at all? This is happening after few writes or nothing happens at all?
     
  11. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Thanks , i'll check out the tutorial
    Well sometimes It goes solid boxes and goes away after I restart it and sometimes it doesn't .
    Sometimes it just goes blank after I load in a new program.
    I think there is some error in my code .
    I tried copy/paste the code from
    http://www.newbiehack.com/MicrocontrollersABeginnersGuideOurFirstLCDProgram.aspx

    and it works now.

    Can you recommend some good libraries that I can use ?
    my LCD only has one row and 16 coloumns
     
  12. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Also .. how can I know if my LCD display is HD44780 compatable. I see this in every library.
     
  13. donpetru

    Active Member

    Nov 14, 2008
    186
    25
    sprintf() is a special mikroC function and is consumed more flash.
    Use the hex file attached below and tell me if it works on your LCD.
    I attached below and schedule work.
     
  14. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    How come the R/w Is grounded ?
    I'm going to need to reconfigure my LCD to 4bit
     
  15. mitko89

    Member

    Sep 20, 2012
    123
    19
    I suggested using sprintf(), because it is standard function and it makes doing changes and following the code easier... you are using ATMEGA32 and you are worried about flash in such project? - get real...
     
  16. donpetru

    Active Member

    Nov 14, 2008
    186
    25
    Try and test diagram posted above, together with the hex file.

    Connecting the R/W pin to the Ground, the messages will be normally displayed very well, but it will not be possible to read the busy flag since it is not possible to read the display either. Is a simple solution that works well in many applications. Try this.

    LATER EDIT:
    mitko89
    sprintf() eat pretty much flash.
    For example, use sprintf twice in a little more complex software and try to write it in an ATmega8 and see that you can not do that. In addition, not all Atmel microcontrollers supports sprintf().
     
  17. mitko89

    Member

    Sep 20, 2012
    123
    19
    In the particular case, Shagas is using ATmega32, I have never dealt with Atmel, but sprintf() is one of the most popular functions in embedded programming, he has to get familiar with it. Writing a code that is hard to follow just to save a bit of flash... if you want to do that you can use dynamic allocation. Always keep the code as readable as possible. If you want your code to take less memory, write it in assembly. If you are using C, take advantage of the high level or it's pretty much pointless.
     
  18. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74
    Thanks i'm going to try it now .
    I downloaded and configured some Library from Peter Fleury and it looks to be working .

    But when a string is sent my display only displays the first 8 characters .
    My display is 16 characters long x1 .
    I had this problem in previous programms before .

    I'm going to try your one now
     
  19. Shagas

    Thread Starter Active Member

    May 13, 2013
    802
    74

    I connected it , it works and displays :

    "ww.techn'
    It scrolls fine , but it still displays only the first 8 characters. Do you know why ?
     
  20. donpetru

    Active Member

    Nov 14, 2008
    186
    25
    Check the LCD to see if it works correctly. To test it, connect +5V and ground to the LCD , with nothing else, and see if displayed 16 black squares on display. If it displays only the first 8 characters, the LCD is compromised. I also have an LCD that
    got on ebay.com.

    LATER EDIT:

    Display all 16 characters?
    It is a URL that I made ​​to move on the screen. It is totally visible? If not, test the LCD as I said above.
     
Loading...