0

I have a problem with my code, I am programming a microcontroller pic18f4520 to read two reflective sensors, but when I print a status from any sensor become a infinite loop let me explain better

example:

  • Sensor A
  • Sensor B
  1. when sensor A is on (0) print "BAG INICIALIZE"
  2. when sensor A and B are on (0) print "BAG IN PLACE"
  3. when sensor A and B are off (1) print "BAG REMOVED"

The print is well but is infinite

my referencial code is: everything is inside while(1)

//reading ports when boot
//Sensor A = J13 
//Sensor B = J6

void USART_EnviaMsg(char *str);
void USART_EnviaMsg (char *msgout)
{
    char letraout;
    while(*msgout != 0x00)      //As long as I don't come across the null at the end of the string.
    {
        letraout=*msgout;       //Read the pointer letter.
        msgout++;               //pointer go forward.
        while (TXIF==0){}       //wait to send
        TXREG=letraout;         //send the letter.
    }                
}

while(1){
 if ((PORTDbits.RD3 == 0) && (J6 == 1)) 
        {
                __delay_ms(100);         //Antibounce.
       if (PORTDbits.RD3 == 0) //I check again that it is pressed.
            {
            J6 = 0;
            }
        }
      if (PORTDbits.RD3 == 1)
            J6 = 1;
            //Bolsa A - J13...
      if ((PORTDbits.RD2 == 0) && (J13 == 1)) //J13
        {
                __delay_ms(100);         //Antibounce.
      if (PORTDbits.RD2 == 0) //I check again that it is pressed.
            {
            J13 = 0;
            }
        }
      if (PORTDbits.RD2 == 1)
                J13 = 1;
       
      if (J13 == 0 && J6 == 0){
          ValorBag = 2;
          USART_EnviaMsg("BAG IN PLACE");
          USART_EnviaMsg(CRLF);
      }
      if (J13 == 0 && J6 == 1){
          ValorBag = 0;
          USART_EnviaMsg("BAG PUTTING");
          USART_EnviaMsg(CRLF);
      }
      if (J13 == 1 && J6 == 0){
          ValorBag = 0;
          USART_EnviaMsg("BAG ERROR");
          USART_EnviaMsg(CRLF);
      }
      if ((J13 && J6)== 1){
          ValorBag = 1;
          USART_EnviaMsg("BAG REMOVED");
          USART_EnviaMsg(CRLF);
      }
}

if some condition is true print infinite loop example:

"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
"BAG REMOVED"
5
  • 2
    You don't seem to have a terminating condition for your loop. You have a while(1) statement but you never break out of it. Commented Apr 4, 2021 at 19:40
  • 1
    What would be the expected behaviour? Why is the current behaviour surprising? Two conditions make 4 combinations. One combination is always true in the while(1) loop. Commented Apr 4, 2021 at 19:42
  • The code itself is OK. The logic is fine and has no "bugs," but I bet that the expected behavior is to print once it changes. Also, the coding style is pretty hard to understand. Commented Apr 4, 2021 at 20:14
  • You are right the expected behavior is to print once it changes, the code was from an ex employee and yes is hard to understand, I have to made some changes to make it "work". Commented Apr 4, 2021 at 21:15
  • Masters some advice that can help me with this? the expected behavior is to print once it changes the condition but no with infinity loop Commented Apr 5, 2021 at 0:51

1 Answer 1

0

Pack both input bits in one integer. Remember its last value and write out message only if it is changed since last time, like this:

void foo()
{
    static const int SensorA=1;
    static const int SensorB=2;
    int Status =0; //Bitmap of above Bitmasks
    int lastStatus=Status; //Bitmap of above Bitmasks
    while(1)
    {
        if ((PORTDbits.RD3 == 0) && (Status & SensorA))
        {
            __delay_ms(100);         //Antibounce.
            if (PORTDbits.RD3 == 0) //I check again that it is still pressed.
            {
                Status &= ~SensorA; //Clear bit
            }
        }
        if (PORTDbits.RD3 == 1)
            Status |= SensorA; //Set bit

        if ((PORTDbits.RD2 == 0) && (Status & SensorB))
        {
            __delay_ms(100);         //Antibounce.
            if (PORTDbits.RD2 == 0) //I check again that it is still pressed.
            {
                Status &= ~SensorB; //Clear bit
            }
        }
        if (PORTDbits.RD2 == 1)
            Status |= SensorB; //Set bit

        if (Status == lastStatus) continue; //nothing changed

        lastStatus = Status; //Changed. Remember current Status. Issue Msg only once.
        switch (Status)
        {
            case 0:
                USART_EnviaMsg("A=0, B=0");
                break;
            case SensorA:
                USART_EnviaMsg("A=1, B=0");
                break;
            case SensorB:
                USART_EnviaMsg("A=0, B=1");
                break;
            case SensorA+SensorB:
                USART_EnviaMsg("A=1, B=1");
                break;
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I'll try this as soon as possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.