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

Interrupt received value not updating automatically

Hello,

I am working with serial communication interrupt in LPC1768. In that I am receiving a three parameter data in the form of string as X:2341Y:114Z:75 via serial interrupt.

After receiving I am splitting this string and storing 2341 in array1[],114 in array2[] and 75 in array3[] and converting into integer and using in the main function as follows.

int main(){
....
....
....
while(1){
cut_count = (((int)(cut_preset_value[0]-0x30)*1000)+((int)(cut_preset_value[1]-0x30)*100)+((int)(cut_preset_value[2]-0x30)*10)+((int)(cut_preset_value[3]-0x30)));

          duty_count = (((int)(duty_cycle_value[0]-0x30)*10)+((int)(duty_cycle_value[1]-0x30)));

          TOTAL_TIME = ceil((ONE_MIN_IN_MSEC)/(cut_count));     //ceil func. is to round off the value

          dividend_value = ((TOTAL_TIME)*(duty_count));

          ON_TIME_VALUE = ceil(dividend_value/PERCENT_DIVISOR_VALUE);   //ceil func. is to round off the value

          OFF_TIME_VALUE = ceil(((TOTAL_TIME)-(ON_TIME_VALUE)));         //ceil func. is to round off the value


} }

Note:Here cut_preset_value[],suction_preset_value[] and duty_cycle_value[] are the three globally defined arrays for storing values.

Within the while loop the arrays are not updating without board reset.

kindly provide some solution for this.
Thank you.

  • Supply the solution for what?

    And I'm not sure your "converting to integer" is the correct thing - have you first converted from string to a number before storing the value in the array? And does the array have a data type suitable for the task? So why do you then need a type cast (int)?

  • Are you clearing the serial interrupt flag? (i cant see it in the while loop, may be you are doing it in isr, i guess)

    are you disabling the serial interrupt anywhere in the rest of your program?

    converting into integer
    Have you considered using sscanf or atoi to convert ASCII into Integer value??

  • Hi WesterMark,

    have you first converted from string to a number before storing the value in the array?

    Because the RBR is 8-bit the string values are stored in byte-wise as ascii data in array locations 0,1,2 and 3. And those ascii values are converting into integer in main fn. with the step,

    cut_count=(((int)(cut_preset_value[0]-0x30)*1000)......
    

    and working properly for first time interrupt. And if the interrupt occurs second time and so on the values are not get updated.

    does the array have a data type suitable for the task

    Yes I am defined the array as "uint8_t" and as "global variable"..

    why do you then need a type cast (int)?

    Its not needed over there.Just for taking the integer value if (cut_preset_value[0]-0x30) doesn't works.

  • Hi Solanki,

    Are you clearing the serial interrupt flag?

    Yes I using variable named "U0_flag" and setting it while RDA interrupt occurs and clearing within the routine itself after reading the data from uart buffer.

    And I didn't disabled the serial interrupt anywhere in my program.

    using sscanf or atoi

    There is no problem with ascii to integer conversion.Its working fine and I used to work with atoi and not used sscanf.

  • But honestly using fixed field lengths seems to suggest an extreme lack of foresight.

    Are you sure you don't have issues with earlier code?

  • The code fragment that we see doesn't tell is if you have made the arrays volatile, i.e. telling the compiler that the contents may be modified asynchronously.

    The code fragment doesn't show that you have any form of synchronization to make sure that the four bytes of the array are actually from the same transfer, and you don't happen to compute values in the middle of a transfer.

  • Forgot to mention - the code in your loop seem to assume that the arrays contains valid ASCII digits, i.e. characters between '0' and '9' - how do you know that is true? Do you have any intelligence in your ISR? What happens if you get a transfer error, or misses the synchronization?

  • "code fragment doesn't tell is if you have made the arrays volatile"

    Yes I used to check with the arrays which is defined,but it also doesn't works.

    And an error is arising for the case of ascii-to-integer conversion using "atoi function" if I use volatile array as argument instead of const char *str.

    Vignesh

  • "how do you know that is true? Do you have any intelligence in your ISR?"

    I am using timer interrupt also and timer count is incremented for every millisecond in timer interrupt routine.

    I am using that ON_TIME_VALUE and OFF_TIME_VALUE as a conditional value for switching ON or OFF the relay as follows.

    
                   if(count == ON_TIME_VALUE)
                    {
                            LPC_GPIO1->FIOCLR |= (1<<8);
                            //LPC_GPIO1->FIOSET |= (1<<9);
    
                    }
                    if(count == TOTAL_TIME)
                    {
                            //LPC_GPIO1->FIOCLR |= (1<<9);
                            LPC_GPIO1->FIOSET |= (1<<8);
                            count=0;
                    }
    
    

    Its surely working for the first time value replace process and not on further..

  • Hello Pier,

    "Are you sure you don't have issues with earlier code?"

    Always my parameter data will be 4 bytes for 1st array,3 bytes for 2nd array and 2 bytes for 3rd array.
    So I thought that the data will over-written within allocated 4,3 and 2 bytes.

    And having issues with data replacement in my main function only..

  • "So I thought that the data will over-written within allocated 4,3 and 2 bytes."

    Irrelevant to this. How do you synchronize? How does the UART ISR know what is the first character of a message? And how does your main loop know when a full message has been received?

    "Yes I used to check with the arrays which is defined,but it also doesn't works."
    Don't know what you mean. But any global variable that is written to by an ISR and that is read by the main loop must be declared volatile, to make sure that the source code generated will read the physical memory for the current variable contents instead of relying on on data that might be cached in a processor register.

    Synchronization of UART receive in relation to main loop processing is totally separate from whatever you may do with a timer to control any relay.

    Any time you have an ISR produce data that can't be written and handed over to the main loop as one single, atomic, memory write, you (!) must implement some synchronization logic that can switch ownership of the data between ISR and main loop. So ownership of the variables are handed to the ISR until a complete message has been received. Then ownership shifted to the main loop, which needs to be allowed to read out all bytes of data before it returns back the ownership to the ISR again for reception of more data.

  • Yes the word volatile is missed in previous post.

    I checked with the arrays which is defined as volatile,but the same error happens over there also. That's what I came to explain in my older post.

    "implement some synchronization logic that can switch ownership of the data between ISR and main loop."

    So shall I use some flag variable and wait for it to set after one complete reception is occured? Or any other method is there for synchronising ISR and main loop variable?.

  • Have you dared to search for different synchronization solutions?

  • Yes I tried with flag method by setting it after I received a single package of whole 15 bytes by using the following piece of code within the handler,but it also doesn't works.

    
                    if((UART0Buffer[UART0Count-str_count])== 'C')
                       {
                               str_count++;
                               if(str_count==TOTAL_CHAR_LENGTH)
                               U0_flag=1;
                       }
    
    

    In default str_count=0; and TOTAL_CHAR_LENGTH=15;

    And once the flag is set, I am retrieving data from the three arrays as discussed earlier. So I am getting data from the array after one complete string reception only.

  • "also doesn't work" doesn't tell any reader anything useful about your problem.

    And you are posting a tiny bit of your source code, making impossible to see if your code have other interesting bugs. You haven't even shown us the declaration of that new flag variable.

    And you haven't explained what a correct message should look like. And if your code is written in a way that it can correctly resynchronize if you connect the cable in the middle of a message or if one character for some reason gets corrupted.

    Is "C" a unique character terminating a message but never used anywhere else? In that case, the code should be able to do alternative things if str_count does not match TOTAL_CHAR_LENGTH when the 'C' is received.

    Anyway - what results do _you_ see when _you_ are busy debugging _your_ code? What did you expect would happen, and what does actually happen? And what are your conclusions from the difference between what was expected and the reality?