Thread: Need help

  1. #1
    Registered User
    Join Date
    May 2016
    Posts
    11

    Need help

    i'm trying to scan array of bytes from a keypad, display it on LCD and then send it from atmega32 to another atmega32 using UART. excuse me if there is a fatal mistakes i'm a bit newbie.

    Code:
    #include <avr/io.h>
    # define F_CPU 1000000UL
    #include "BASICTYPES.h"
    #include "util/delay.h"
    #include "keypad.h"
    #include "LCD.h"
    #include "UART.h"
    
    
    
    
    void send_password(void);
    
    
    
    
    int main(void)
    { 
        keypad_init();
        
        LCD_init();
        
        UART_Init();
        
        while(1)
        {
        
            send_password();
            
            
        }
        
        
        
    }
    
    
    
    
    void send_password(void)
    {
        u8 k=0,l=0,c=0,cond;
        
        u8 *passw;
        LCD_print("Enter password");
        LCD_goto(4,2);
        
        while(1)
        {
            
            k=keypad_read();
            
            _delay_ms(50);
            
            if (k)
            {  
                passw[l]=k;
                LCD_data(k);
                k=0;
                _delay_ms(50);
                l++;
            
               if (l==4)
                {break;}
                        
                     
            }
            _delay_ms(50);
        }
        
        
        
            for (c=4;c>0;c--)
            {
                UART_SendByte(passw[4-c]);
                _delay_ms(10);
            }
    
    
            
        
        
    
    
        while (UART_ReciveData()!=0)
        {
            cond=UART_ReciveData();
            if (cond==0X01)
            {
                
                LCD_goto(0,2);
                LCD_print("Correct password");
                
            }
            else if (cond==0X02)
            {
                
                LCD_goto(0,2);
                LCD_print("Wrong password");
            }
        }
        
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > u8 *passw;
    This isn't pointing at any valid memory.
    It's easy to use a 4 byte array here.

    > cond=UART_ReciveData();
    > if (cond==0X01)
    How does this check that the received character is what you want?

    > then send it from atmega32 to another atmega32 using UART
    Then you need TWO programs.
    - One does the read and transmit.
    - The other does the receive, check and print
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2016
    Posts
    11
    thanks alot, making it an array of 4 bytes solved a bit of the problem but the code still can't do the what i want and sure i have two codes on two microcontrollers here is the receiver code
    Code:
    #include <avr/io.h>
    #include "UART.h"
    #include "BASICTYPES.h"
    #include "EEPROM_Driver.h"
    # define F_CPU 1000000UL
    
    
    void stor_pass_eeprom(void);
    void compare_passes(void);
    
    
    u8 password[4]="5555";
    
    
    u8 crct_pass_flag;
    
    
    
    
    int main(void)
    {
        
        
        UART_Init();
        
        
        while(1)
        { 
            stor_pass_eeprom();
            
            compare_passes();
            
            
        }
    }
    
    
    
    
    
    
    void stor_pass_eeprom(void)
    {
        u16 i;
        for(i=4;i>0;i--)
        {
            EEPROM_Write((4-i),password[i]);
        }
    }
    
    
    void compare_passes(void)
    { u8 rx_pass[4],z=0;
        
        while(UART_ReciveData()!=0)
        {
            rx_pass[z]=UART_ReciveData();
            z++;
            if(z==4)
            {
                break;
            }
        }
        
            if(rx_pass==password)
            {
                UART_SendByte(0X01);    
            }
         
        
          else  
            {
            
                   UART_SendByte(0X02);    
            
             }
             
        
        
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Some points.
    1. Learn to indent code consistently -> Indent style - Wikipedia, the free encyclopedia
    Your code is short, but already its hard to read.

    2. Not sure why you like running loops backwards.
    > for(i=4;i>0;i--)
    > EEPROM_Write((4-i),password[i]);
    But you have managed to achieve a buffer overrun in the process.

    3. This will read every other character.
    > while(UART_ReciveData()!=0)
    > rx_pass[z]=UART_ReciveData();
    Try
    u8 ch;
    // read a char from the UART, assign it to ch, and compare it with zero
    while ( (ch=UART_ReciveData())!=0)
    rx_pass[z] = ch;


    > if(rx_pass==password)
    This is not how you compare strings. Use strcmp()
    Further, neither password nor rx_pass has a \0 character, so perhaps you need strncmp() instead.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    May 2016
    Posts
    11
    i'm sorry for the bad code. i think i read that it's a better practice to use backward loops but not sure. i'm searching for what buffer overrun is, but here is what i tried to do but also didn't work.
    Code:
    #include <avr/io.h>
    #include "UART.h"
    #include "BASICTYPES.h"
    #include "EEPROM_Driver.h"
    # define F_CPU 1000000UL
    
    
    void stor_pass_eeprom(void);
    void compare_passes(void);
    
    
    u8 password[4]="5555";
    
    
    
    
    
    
    
    
    int main(void)
    {
        
        
        UART_Init();
        
        
        while(1)
        { 
            //stor_pass_eeprom();
            
            compare_passes();
            
            
        }
    }
    
    
    
    
    
    
    /*void stor_pass_eeprom(void)
    {
        u16 i;
        
        for(i=4;i>0;i--)
        {
            EEPROM_Write((4-i),password[i]);
        }
    }*/
    
    
    void compare_passes(void)
    {
           u8 rx_pass[4],z=0,ch=0;
        
        
            while ((ch=UART_ReciveData())!=0)
            {
                  rx_pass[z]=ch;
                  z++;
                  if(z==4)
                  {
                       break;
                  }
            }
              
     
            if(strcmp(rx_pass,password))
           {
                      UART_SendByte(0X01);    
           }
           else  
           {
                      UART_SendByte(0X02);        
                }    
    }
    Last edited by Ahmed El-Wakil; 05-27-2016 at 06:07 AM.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Like I said, use strncmp because strcmp relies on a \0, and neither of your arrays (rx_pass or password) as a \0
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Some processors have a "decrement and branch on not zero" instruction.
    On these, the assembly code could be more efficient if the loop counted down to zero.

    -

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Quote Originally Posted by megafiddle View Post
    Some processors have a "decrement and branch on not zero" instruction.
    On these, the assembly code could be more efficient if the loop counted down to zero.

    -
    True enough, but we're writing in a high level language, so we shouldn't be second-guessing what the compiler will do.
    The first order of business is to write clear and simple code, so
    - you can easily understand it
    - through clarity of understanding, there is less chance of subtle bugs (as aptly demonstrated already - attempting to be smart has back-fired)
    - gives the compiler the best chance to optimise it without having to unpick needless obfuscation.

    Indexing an array backwards could play havoc with data cache prediction logic, which may assume that linear access is forwards through memory.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    May 2016
    Posts
    11
    after hundred of trials i found that i have a problem with my uart driver which i copied from the data sheet, i'm trying to make the most simple send and receive commands but it's not working. i would highly appreciate it if anyone can help me cuz i'm about to get mad.

    UART DRIVER
    Code:
    #include <avr/io.h>
    #include "BASICTYPES.h"
    
    
    #define BAUD_PRESCALE 25
    
    
    
    
    void UART_Init(void)
    {
       UBRRL = BAUD_PRESCALE;
       UBRRH = (u8)(BAUD_PRESCALE>>8);
       UCSRB=(1<<TXEN)|(1<<RXEN);
       UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }
     void UART_SendByte(u8 Data)
    {
    	while(! (UCSRA & (1<<UDRE)));
    		
    	UDR=Data;
    }
    u8 UART_ReciveData(void)
    {
    	
    	while(!(UCSRA & (1<<RXC)));
    	
    	 return UDR;
    	
    }
    void USART_Flush( void )
    {
    	unsigned char dummy;
    	while ( UCSRA & (1<<RXC) ) dummy = UDR;
    }
    first uc
    Code:
    int main(void)
    {
        keypad_init();
        LCD_init();
        UART_Init();
        _delay_ms(100);
        
        while(1)
        {
            UART_SendByte(k);
    		_delay_ms(100);
            l=UART_ReciveData();
    		if (l==CORRECT_PASSWORD)
    		{
    			LCD_print("yes");
    		}
    		else if(l==WRONG_PASWORD)
    		{
    			LCD_print("no");
    		}
        }
    }

    second uc
    Code:
    int main(void)
    {
    	UART_Init();
    	_delay_ms(100);
    
    
    	while(1)
    	{
    		
    		
    		g=UART_ReciveData();
    		_delay_ms(100);
    		if (g==5)
    		{
    	    	UART_SendByte(CORRECT_PASSWORD);
    		}
    		else
    		{
    		    UART_SendByte(WRONG_PASWORD);
    		}
    		
    	   
    	}
    }

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    atmega32 - Google Search
    The first experiment is to make the 2nd controller just do this
    Code:
    while ( 1 ) {
      // just echo everything back
      UART_SendByte(UART_ReciveData());
    }
    And make the first controller do this
    Code:
    for ( ch = ' ' ; ch <= '~' ; ch++ ) {
      UART_SendByte(ch);
      rxch = UART_ReciveData();
      LCD_print(rxch);
      _delay_ms(100);
    }
    When you see a steady alphabet appear on screen, you know you have a working round trip communication.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    May 2016
    Posts
    11
    nothing appeared on the screen and i still couldn't find what's wrong with the driver, i'm using proteus btw could it be the reason?

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    What is 'proteus'?
    Your IDE - I doubt that would have any effect.
    A tiny OS on your devices - possibly.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    May 2016
    Posts
    11
    Proteus is the simulation tool that i'm using to simulate the project , also Atmel studio is my IDE.using windows 10 as an OS

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Do you have any example codes which use the serial port?
    Have you tried them on the simulator?
    Do they work?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    May 2016
    Posts
    11
    no i don't have any it's my first try to use serial port .i didn't but it's working with a friend using different version of the program. he uses the same driver and yes it's working perfect.

Popular pages Recent additions subscribe to a feed

Tags for this Thread