This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

rfreader

#include<reg51.h>
void boud_rate()
{
        SCON = 0x50;
        TMOD = 0x20;                /* timer 1, mode 2, 8-bit reload */
        TH1  = 0xFD;                /* reload value for 2400 baud */
        TR1  = 1;
        TI   = 1;
}
char serial_receive()
{
    char chr;        /* variable to hold the new character */
        while (RI != 1) {;}
        chr = SBUF;
        RI = 0;
        return(chr);
}

void main(void)
{

        boud_rate();
  unsigned char rx_data;

  for(;;)
  {
    rx_data = serial_receive();

    switch(rx_data)
    {
//      case '1': open_door();
          case 0067892341 : open_door();
        break;
//      case '9': open_door();
       case 0045780034 : open_door();
        break;

      default: dont_open();
    }

    proper_delay();
  }
}

errors

'rx_data':undefined identifier
 illigal octal digit

please tell me how to overcum these errors

Parents
  • void serial_int (void) interrupt 4
    {
      static char chr = '\0'; /* character buffer */
    if (RI == 1) /* it was a receive interrupt */
    {
            chr = SBUF; /* read the character into our local buffer */
            RI = 0; /* clear the received interrupt flag */
            TI = 1; /* signal that there's a new character to send */
    }
            else if (TI == 1) /* otherwise, assume it was a transmit interrupt */
            {
                    TI = 0; /* clear the transmit interrupt flag */
                    if (chr != '\0') /* if there's something in the local buffer... */
                    {
                            if (chr == '\r') chr = '\n'; /* convert to */
                            SBUF = chr;  /* put the character into thetransmit buffer */
                            chr = '\0';
                    }
            }
    }
    int main()
    {
            unsigned char a[5][11]={{0,0,0,1,6,2,2,1,8,2,6},{0,2,3,1,5,6,7,3,6,4,5},{0,0,1,8,9,6,7,6,4,2,3},{0,2,5,8,9,6,4,7,2,3,0},{0,6,4,3,7,8,0,2,5,3,7}};
            unsigned char c[10],i,j;
            char chr;
            lcd_init();
            SCON = 0x50;        /* mode 1, 8-bit uart, enable receiver */
            TMOD = 0x20;        /* timer 1, mode 2, 8-bit reload */
             TH1  = 0xFD;        /* reload value for 2400 baud */
             ET0  = 0;                /* we don't want this timer to make interrupts */
             TR1  = 1;                /* start the timer */
             TI   = 1;               /* clear the buffer */
             ES   = 1;                /* allow serial interrupts */
             EA   = 1;                /* enable interrupts */
            lcd_command(0x10);
            lcd_prinit(chr);
            c[10]=chr;
            for(j=0;j<5;j++)
                    {
                            i=1;
                            if(a[j][i]==c[i])
                            {
                                    for(i=1;i<9;i++)
                                    {
                                            if(a[j][i]!=c[i])
                                                    break;
                                    }
                                    if(i==10)
                                    {
    //                                      opn_dor=1;
                                            lcd_printxy(2,1,"yes");
                                    }
                            }
    //                      opn_dor=0;
                            lcd_printxy(2,1,"NO");
                    }
    }
    


    there are no errors and according to me the logic is correct... but still not getting the output(display-yes or no) please help me
    me not able to get the characters which are received in the interrupt program

Reply
  • void serial_int (void) interrupt 4
    {
      static char chr = '\0'; /* character buffer */
    if (RI == 1) /* it was a receive interrupt */
    {
            chr = SBUF; /* read the character into our local buffer */
            RI = 0; /* clear the received interrupt flag */
            TI = 1; /* signal that there's a new character to send */
    }
            else if (TI == 1) /* otherwise, assume it was a transmit interrupt */
            {
                    TI = 0; /* clear the transmit interrupt flag */
                    if (chr != '\0') /* if there's something in the local buffer... */
                    {
                            if (chr == '\r') chr = '\n'; /* convert to */
                            SBUF = chr;  /* put the character into thetransmit buffer */
                            chr = '\0';
                    }
            }
    }
    int main()
    {
            unsigned char a[5][11]={{0,0,0,1,6,2,2,1,8,2,6},{0,2,3,1,5,6,7,3,6,4,5},{0,0,1,8,9,6,7,6,4,2,3},{0,2,5,8,9,6,4,7,2,3,0},{0,6,4,3,7,8,0,2,5,3,7}};
            unsigned char c[10],i,j;
            char chr;
            lcd_init();
            SCON = 0x50;        /* mode 1, 8-bit uart, enable receiver */
            TMOD = 0x20;        /* timer 1, mode 2, 8-bit reload */
             TH1  = 0xFD;        /* reload value for 2400 baud */
             ET0  = 0;                /* we don't want this timer to make interrupts */
             TR1  = 1;                /* start the timer */
             TI   = 1;               /* clear the buffer */
             ES   = 1;                /* allow serial interrupts */
             EA   = 1;                /* enable interrupts */
            lcd_command(0x10);
            lcd_prinit(chr);
            c[10]=chr;
            for(j=0;j<5;j++)
                    {
                            i=1;
                            if(a[j][i]==c[i])
                            {
                                    for(i=1;i<9;i++)
                                    {
                                            if(a[j][i]!=c[i])
                                                    break;
                                    }
                                    if(i==10)
                                    {
    //                                      opn_dor=1;
                                            lcd_printxy(2,1,"yes");
                                    }
                            }
    //                      opn_dor=0;
                            lcd_printxy(2,1,"NO");
                    }
    }
    


    there are no errors and according to me the logic is correct... but still not getting the output(display-yes or no) please help me
    me not able to get the characters which are received in the interrupt program

Children
  • So, are you _really_ sure your code is correct?

    unsigned char c[10]; <= 10 elements
    
    c[10]=chr; <= assigning to the 11th, element...
    
    i=1; <= ignoring first character (zero) and start with second character (index 1).
    if(a[j][i]==c[i])
    
    for(i=1;i<9;i++) { ... }
    if (i==10) { ... } <= how would i reach the value 10, when the loop ends if i reaches 9?
    
    lcd_printxy(2,1,"NO"); <= printing "NO" even if you just printed "yes".
    

    So - exactly how much did you verify your code? What was the result of the debugging? Did you really step through the code and check the values of the variables and how the execution jumped? Or did you just _assume_ what it would do?

    Next thing - guess how much simpler your code would have been if you had stored the keys as strings:

    char key[] = "00016221826";
    char input_key[12] = "";
    
    ...
    if (!strcmp(input_key,key)) { lcd_printxy(2,1,"yes"); }
    

    Any special reason why you decided to ignore the suggestion to look at strcmp()?

  • By the way - when will you take care of the use of the "chr" variable?

    You have one such variable in your interrupt handler. You seem to attempt some broken variant of echo.

    You have another variable with same name (but totally different variable) in main(). But you never fill the 10 - or 11 - slots of your c[] array. So what will you then compare with the stored keys?

    Wouldn't it be better if c[] was global, and the interrupt checked if the array was available or not? If available, then the interrupt handler adds a character at a time until you get the newline. If you get newline after exactly 11 digits, you set a flag that main() can process. And your interrupt needs to ignore all new characters received until main() is done. If you get the newline too early, then you failed somewhere and have to reset counter and start getting 11 new digits. If you get a 12th digit, then you also fail and have to wait for a newline to regain sync.

    Same algorithm if using strings - but then you have to add yet another character ('\0') when you have all digits, to terminate the string.

  • the reason is-the data receiving through rs232 is not a string its a character. if u help me how to receive the string then I can follow ur method
    
    the reason why i am starting the loop for i=1 is i dont want to compare the 1st character because when read it on hyper terminal it is showing  $0062...... the rfreader is automatically including $, but $ is not present in the id-card.
    so I have taken an array of 11. I tried to take $ in the array of 11 numbers but it is giving syntax error. so i have replaced $ with 0 in the array i,e a[5][11]={{$,0,0,6,2.....},{$,0,4,6,7,8,.,.},.,.} is replaced with a[5][11]={{0,0,0,6,2,....},{0,0,4,6,7....},.,.,}. This
    is the reason I am taking i=1 in skipping 0($) as it is common for every no.
    
    I am sorry for all other mistakes..
    

  • Yes; but a string is just a sequence of chatacters (plus a NUL terminator) - isn't it...?

    BTW: Note how you've messed-up the thread by using the pre tags incorrectly...

  • in the interrupt handler i am receiving the characters in the variable 'chr'. how to use it in main to compare? do i need to take chr as a static global variable?

    Wouldn't it be better if c[] was global, and the interrupt checked if the array was available or not? If available, then the interrupt handler adds a character at a time until you get the newline. I didnt get this point.... I am using c[] for received variables

    using string compare(strcmp) we can compare with only one variable at a time ... how to compare with all other nos

  • Each strcmp() tests the input string with one of your stored keys.
    So if you have 5 keys, you need up to 5 strcmp() calls.

    See any issues?

    I did explain how to receive character-by-character and make a string of it.

  • k, but I am receiving characters in the interrupt handler, how to use those characters in main?

  • Was there something wrong with the solution I have already described?

  • "a[5][11]={{$,0,0,6,2.....},{$,0,4,6,7,8,.,.},.,.}"

    Of course the above gives a syntax error.

    Don't you realize the difference between characters and numbers?

    0 is a number with value zero. You write it using a single digit.
    '0' is the ASCII character zero. It does not have the numeric value 0. It has the numeric value 0x30 = 48.

    If you can see the codes on the hyperterminal, then the codes are sent out as printable text. So each character you receive on the serial port is a '0', '1', '2', ...

    You really have to keep track of the difference betweeen 0 and '0' because you can't perform the comparison unless you have the same format on both sides of the comparison operator.

    And you have to understand that the compiler can handle an array of numbers (as long as the numbers are within the range of the data type for the array) but numbers can't contain any $. And your arrays can just as well be filled with the characters '0', '1', '2', ...

    C strings like "123" is an array of characters { '1', '2', '3', '\0' } which indicates what strcmp() would do when comparing a printable string of code digits as received from your RFID receiver with the strings you have stored as known keys.

    Have you invested in a good book about C?
    Have you read it?
    Have you worked yourself through the exercises in the book?

    C is not a language suitable for people who just try random code constructs.

  • #include<reg51.h>
    #include<string.h>
    #include"_LCD_R8C.c"
    void serial_int (void) interrupt 4
    {
            static unsigned char chr='\0';
            unsigned char str1[]="$0016221826";
            unsigned char str2[]="$0123456789";
            unsigned char c[11],str[11],i,j,str0[11];
    
    
            if (RI==1)                      /* it was a receive interrupt */
            {
                    RI = 0;                 /* clear the received interrupt flag */
    //              TI = 0;                /* signal that there's a new character to send */
                    chr = SBUF;             /* read the character into our local buffer */
                    c[11]=chr;
                    lcd_command(0x10);
                    lcd_print_b(chr);
                    for(j=0;j<1;j++)
                    {
                            for (i = 0; i < 11; i++)
                            {
                                     str[i] = c[i] ;
                            }
                            str[11]='\0';
                     }
                    strcpy(str0,str);               /*this step is not necessary*/
                    j=strcmp(str0,str1);
                    if(j==0)
                    {
                            lcd_printxy(1,1,"YES");
                    }
                    else
                    {
                            j=strcmp(str0,str2);
                                    if(j==0)
                                    {
                                            //open_door();
                                            lcd_printxy(1,1,"YES");
                                    }
                                    else
                                    {
                                            //close_door();
                                            lcd_printxy(2,5,"NO");
                                     }
                     }
    
            }
    }
    //      else if(TI == 1)
    //              {
    //                      TI = 0;
    //                      if (chr != '\0')
    //                      {
    //                              if (chr == '\r') chr = '\n';
    //                              SBUF = chr;
    //                              chr = '\0';
    //                      }
    //              }
    int main()
    {
    
        lcd_init();
        lcd_clear();
        SCON = 0x50;
        TMOD = 0x20;
        TH1  = 0xFD;
        ET0  = 0;
        TR1  = 1;
    //  RI   = 1;
        ES   = 1;
        EA   = 1;
    }
    

    here in this method using string comparison the program will be too long to compare 250 no. what to do?
    I have blocked TI interrupt because I am not sending any data.
    please tell me any mistakes if i have done

  • My eyes are bleeding.

    An ISR should end quickly.
    Your ISR should just pick up characters and either place them in a ring buffer for main to pick up and process. Or maybe support the knowledge of the length of keys and that they start with '@' and end with '\n' and fill an array with a single ID and then inform main() when the ID is ready to compare.

    Was there anywhere in the answers you got any text that could be seen as us recommending you to move all your code into the ISR?

    Your program haven't even a loop anymore - so what do you think happen when main() reaches the final "}"?

    c[11]=chr;
    


    You always assign at index 11 - which is outside of an array of 11 elements (0 to 10).
    When do you assign the first character to position 0?
    When do you assign the second character to position 1?
    ...

    for (i = 0; i < 11; i++)
    {
        str[i] = c[i] ;
    }
    str[11]='\0';
    


    What advantage do you see in (for every received character) copy a character array of 11 characters into a string? Especially since a string in C is also an array of characters, but with a character '\0' as terminator to tell strlen(), strcmp(), strcpy() etc where to stop.

    You have nested if (strcmp()) statements - why? Haven't you realized that C can have arrays of arrays? So you can have an array of strings with known keys, and iterate through this array until you find a match or runs out of keys to check?

    By the way - such a loop should obviously not be in the interrupt service handler that is intended to pick up a received character or send a character.

    Shouldn't you pick up a book about C programming, and spend some time with it?
    Right now, you seem to produce mistakes at a very high speed - enough so that your examples could fill a book about different programming mistakes.

    You do not get anywhere by random trial and error. Actually, you can get far with that approach. But genetic methods aren't fast. It takes a huge number of generations/iterations to progress. So please stop throwing dices to decide what random changes to make, and get a basic knowledge about C data structures, control statements, data types etc.

  • I wonder if Keil is using PHP.

    The broken display of this thread seems to be caused by a dollar sign in one of my previous posts, that seems to have trigged a replace operation that resulted in an end of the table cell and table row in the middle of the text - so the remaining part of my post is emitted inside a <table> tag but outside any <tr> or <td> tags.

    Note to web designers - do care about search/replace with user-supplied data and proper handling of break characters. In this case it is broken html output. In many cases, it is database implementations that allows SQL injection hijacking or killing services.

  • #include<reg51.h>
    #include<string.h>
    #include"_LCD_R8C.c"
    unsigned char chr;
    unsigned char c[11];
    void serial_int (void) interrupt 4
    {
       if (RI==1)
      {
       RI = 0;
       TI = 0;
       chr = SBUF;
       }
    }
    int main()
    {
    unsigned char a[2][11]={"$0016221826","$0123456789"};
        int i,j;
        lcd_init();
        lcd_clear();
        SCON = 0x50;
        TMOD = 0x20;
        TH1  = 0xFD;
        ET0  = 0;
        TR1  = 1;
        RI   = 1;
        ES   = 1;
        EA   = 1;
        for(j=0;j<1;j++)
         {
           for(i=0;i<=10;i++)
            {
              c[i]=chr;
            }
           c[11]='\0';
         }
        for(i=0;i<=1;i++)
       {
           j=strcmp(a,c);
            if(j==0)
             {
                 lcd_printxy(1,1,"yes");
             }
            else
              {
                lcd_printxy(1,6,"no");
               }
       }
    }
    

    you have told me to use array of strings
    the compiler is giving warning in line strcmp(a,c),(BOLD): pointer to different objects.
    please help me.

  • You are continuing your programming by introduction of random changes.
    Genetic programming really is not a fast route.

    You have arrays of type unsigned char - what did the manual say that strcmp() expects? So why did you make your decision to use unsigned char arrays?

    You still don't process received data character-by-character, to get a $ followed by 10 digits before you terminate the string with a '\0' and start comparing with your reference keys.

    And you have zero synchronization between your interrupt handler and your main loop.

    Your programs are never even close to function, because you are constantly ignoring the information you get about existing errors in the code. Moving the code will not remove the bugs in the code. Or will not automagically include extra code lines to perform the actions that your code do not make.

    Why are you even using an interrupt handler for serial communication, if you haven't implemented any buffered solution so that the interrupt handler can operate independently of the main loop? You take the disadvantages with an interrupt-based solution while gaining none of the advantages...

    When will you finally consider to spend some time with a good book about C programming?

  • When will you finally consider to spend some time with a good book about C programming?

    newsflash
    today pradeepkumar read a C book
    today pradeepkumar followed the suggestions in this thread
    in other news: today hell froze over