Announcement

Collapse
No announcement yet.

Unexpected behavior with Repeat-Until function

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unexpected behavior with Repeat-Until function

    Hello 4D Systems support,

    I'm having a weird problem with the Repeat-Until function. The loop repeats as expected and ends as expected, but then goes back into the loop somehow. Here is the code:

    Code:
        if(errorFlash == 1 && status == 1)
            img_Disable(hndl, -1);
    
            repeat
                if(sys_GetTimer(TIMER7) == 0 && errorFlash == 1)
                    if(errorToneCounter < 8)
                        error_sound();
                        errorToneCounter++;
                    else if(errorToneCounter > 30)
                        errorToneCounter := 0;
                    else
                        errorToneCounter++;
                    endif
    
                    error_flash();
    
                    sys_SetTimer(TIMER7, errorSoundDelay);
                endif
            until(touch_Get(TOUCH_STATUS) == TOUCH_PRESSED);
    
            errorFlash == 0;
    
            display_main_screen();
    
        endif
    After the screen is touched, display_main_screen() is called as expected, but then error_flash() gets called again in less than a second and the looping starts again. I was hoping someone might have an idea why this phenomenon could be happening. Did I misuse the Repeat-Until function? Any advice would be greatly appreciated. Thank you!

  • #2
    In 4DGL code, to equate or assign a value to a variable you must use the := operator

    errorFlash := 0;

    Comment


    • #3
      Ah! Embarrassing... Sometimes you just need an extra set of eyes on it. Thank you!

      Comment


      • #4
        Hello,

        The code in my first post still has the unusual behavior with the Repeat-Until function even with that typo fixed. Here is a bit more context.
        Code:
        // Error state
                if(errorFlash == 1 && (status == 1 || status == 8))
                    img_Disable(hndl, -1);
                    repeat
                        if(sys_GetTimer(TIMER7) == 0 && errorFlash == 1)  // TIMER7 = errorSoundDelay
                            if(status == 1)
                                errorFlashColor := 0;
                            else if(status == 8)
                                errorFlashColor := 2;
                            endif
                            error_flash();
                            if(errorToneCounter < 8)
                                file_PlayWAV(errorSoundFile3);
                                errorToneCounter++;
                            else if(errorToneCounter > 20)
                                errorToneCounter := 0;
                            else
                                errorToneCounter++;
                            endif
                            sys_SetTimer(TIMER7, errorSoundDelay);
                        endif                
                    until(touch_Get(TOUCH_STATUS) == TOUCH_PRESSED);            
                    errorToneCounter := 0;
                    errorFlash := 0;
                    display_main_screen();
                    display_status_notify_message(lastMessage[0], lastMessage[1], "");
                endif
        Any ideas?

        Thank you!

        Comment


        • #5
          Hi Umich,

          When exactly are you calling your repeat-until? Would it be possible for you to make a new project and use the block of code that you’ve previously posted and see if it is functioning or not?
          I may not be able to point directly the issue with your project as I don’t know when and how frequent you’re calling your error_Flash() function or your repeat-until. Nevertheless, I tried simulating your setup. I used your code but without the other user functions. Your repeat-until breaks exactly as soon as I touch the screen. Please have a look at the attached file.

          For more information about the repeat-until, you may read the language Flow Control Section of the 4DGL Programmers Reference Manual.

          Hope this helps and Best Regards
          Attached Files
          Eran

          Comment


          • #6
            Hi Eran, thank you for the code example. I just ran it and noticed a few differences. For one, I have that repeat-until function inside my main(). Also, all the error_flash() function does is redraw the screen alternately red or white based on errorFlashColor when an error is detected. The if statements in the repeat-until serve to count the number of times the errorSoundFile3 is played.

            When an error is detected, the error_flash() function works properly and draws the screen red. The PlayWAV function also works properly. The unusual behavior occurs after tapping the screen. What I would expect is that display_main_screen() would execute and the code would move on to the next repeat-until loop to watch for button presses again. Instead, what happens is that upon touching the screen during the error state, the main screen is redraw with display_main_screen() but then immediately error_flash() is run again and the screen turns red once more. Upon touching the screen a second time, display_main_screen() is once again run and the main screen is redrawn. At this point it will exit he repeat-until loop and move on to the next loop to watch for button presses. The unusual part is that two touches are necessary for the loop to exit. The error_flash() function should not be allowed to run again because the errorFlash variable is set to 0. How is the loop executing an additional time? Have you seen this behavior before?
            Code:
            func main()        
                // Error state       
                if(errorFlash == 1 && (status == 1 || status == 8))
                    img_Disable(hndl, -1);            
                    repeat                
                        if(sys_GetTimer(TIMER7) == 0 && errorFlash == 1)  // TIMER7 = errorSoundDelay                    
                            if(status == 1)                        
                                errorFlashColor := 0;                    
                            else if(status == 8)                        
                                errorFlashColor := 2;                    
                            endif                    
                            error_flash();                    
                            if(errorToneCounter < 8)                        
                                file_PlayWAV(errorSoundFile3);                        
                                errorToneCounter++;                    
                            else if(errorToneCounter > 20)                        
                                errorToneCounter := 0;                    
                            else                        
                                errorToneCounter++;                    
                            endif                    
                            sys_SetTimer(TIMER7, errorSoundDelay);                
                        endif                            
                    until(touch_Get(TOUCH_STATUS) == TOUCH_PRESSED);                        
                    errorToneCounter := 0;            
                    errorFlash := 0;            
                    display_main_screen();            
                    display_status_notify_message(lastMessage[0], lastMessage[1], "");        
                endif               
            
                // Another loop that watches for button presses               
                // This code all works fine               
                repeat                   
                    // Button press code               
                forever
            
            endfunc
            
            func error_flash() // This function redraws the screen red when an error is detected
                    // Drawing code
            endfunc

            Comment


            • #7
              Eran, I modified your code example to more closely resemble what my code does. When modified to the way my code is, your code example properly exits the repeat-until when the screen is touched. Could there be some kind of delay because my error_flash() function redraws the entire screen?

              Code:
              #platform "Gen4-uLCD-50DT"
              
              
              // Program Skeleton 1.3 generated 11/15/2018 9:04:13 AM
              
              #inherit "4DGL_16bitColours.fnc"
              
              #inherit "VisualConst.inc"
              
              #inherit "repeatUntilConst.inc"
              var errorFlash, status, errorToneCounter, errorFlashColor;
              func main()
               /*
                  putstr("Mounting...\n");
                  if (!(file_Mount()))
                      while(!(file_Mount()))
                          putstr("Drive not mounted...");
                          pause(200);
                          gfx_Cls();
                          pause(200);
                      wend
                  endif  */
              //    gfx_TransparentColour(0x0020);    // uncomment if transparency required
              //    gfx_Transparency(ON);             // uncomment if transparency required
              
              //  hFontn := file_LoadImageControl("REPEAT~1.dan", "REPEAT~1.gcn", 1); // Open handle to access uSD fonts, uncomment if required and change n to font number dropping a and c if > 9
              //  hstrings := file_Open("REPEAT~1.txf", 'r') ; // Open handle to access uSD strings, uncomment if required
               //   hndl := file_LoadImageControl("REPEAT~1.dat", "REPEAT~1.gci", 1);
                  touch_Set(TOUCH_ENABLE);
                  errorFlash := 1;
                  status := 1;
                  errorToneCounter := 0;
              
                  if(errorFlash == 1 && (status == 1 || status == 8))
                          repeat
                          txt_MoveCursor(0,0);
              
                          txt_MoveCursor(1,0);
                              if(sys_GetTimer(TIMER7) == 0 && errorFlash == 1)  // TIMER7 = errorSoundDelay
                                  if(status == 1)
                                      errorFlashColor := 0;
                                  else if(status == 8)
                                      errorFlashColor := 2;
                                  endif
              
                                  errorState(errorToneCounter);
              
                                  if(errorToneCounter < 8)
                                      //file_PlayWAV(errorSoundFile3);
                                      errorToneCounter++;
                                      print("Count is less than 8            ");
                                  else if(errorToneCounter > 20)
                                      errorToneCounter := 0;
                                      print("Count is less more than 20              ");
                                  else
                                      errorToneCounter++;
                                      print("adding count                             ");
                                  endif
                                  sys_SetTimer(TIMER7, 1000);
                              endif
                          until(touch_Get(TOUCH_STATUS) == TOUCH_PRESSED);
                          errorToneCounter := 0;
                          errorFlash := 0;
                          //display_main_screen();
                         // display_status_notify_message(lastMessage[0], lastMessage[1], "");
                      endif
              
              
              
              
                  print("                                                        ");
              
              
                  repeat
                  txt_MoveCursor(1,0);
              
                  print("Inside Repeat Forever                      ");
                  forever
              endfunc
              
              
              func errorState(var errorToneCounter)
                  print("Inside Repeat Until. Count: ", errorToneCounter, "     ");
              endfunc

              Comment


              • #8
                Hi Umich,

                I think you can debug your code easier when you comment your error_flash(); function for the meantime. If the issue is still there, then it has nothing to do with your error_flash() function, but if your repeat-until smoothly functions without this function, then our next step would be looking into that function, in which I might need to ask for that function’s code as well.

                Hope this helps and Best Regards,
                Eran

                Comment

                Working...
                X