Announcement

Collapse
No announcement yet.

Limp/dead mode

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

  • Limp/dead mode

    Why is it that when the screen is not connected during HOST boot OR it is disconnected during processing of HOST send/receives, the host either goes into LIMP mode or freezes altogether, this is on arduino mega2560, I think you should have a timeout in your library or verification if your display is actually connected rather than letting the host limp or freeze completely, this makes the HOST entirely dependant on the lcd! If the lcd ever fails in future, your project will stop working along with it! Not a very good thing to do, specially in an industrial environment, This also happens if you use 2 lcds, remove one, boot the host, and watch it extremely lag or freeze altogether, please fix this issue with the library, disconnected devices should NOT freeze the host
    Displays tested: uLCD43-PT + uLCD70-DT
    thanks

  • #2
    Hi tonton81

    Thanks for the feedback.
    The library is open source, you are welcome to change it as you see fit. Fork the repository and make your own changes, you have the full source code for the library there.
    The library was originally provided for people to start with something easily, but its been adopted by so many as the only option, when it is not the only option.
    The full ViSi-Genie protocol is outlined in our ViSi-Genie documentation, and this library was just a way to provide customers to get going faster.
    Yes the library is dependent on the display being there, and thus so is the host, as that is what the library was designed for, to have the LCD connected. It was never made with the thought in mind that a user might disconnect the display, nor was it in mind for this library to be used in Industry. Not saying it cant be, but it was never the design for it to do so.

    Your comments are noted though, and we can put this on our list of things to improve when we have a resource available, but if you want a faster result you might want to look at doing these improvements yourself, if you are able.

    Or, you can use ViSi and write your own protocol and library from scratch - maybe with features like connection/disconnection detection, and anything else you require.

    I hope this helps somewhat, but I suspect it wasn't the answer you were looking for.

    Regards
    James

    Comment


    • #3
      I have a solution! and given the solution, the same fix also gained a few new features as well. I was going through the .H & .CPP files and found a few things.
      a few new features:
      1) With SD usage of about 1.6GB for a uLCD-70DT, the delay from setup() is now from 5500 down to 200ms after a reset before you can do contrast etc. I will explain this in a bit
      2) Hot plug ability at the expense of a few ms from library timing out in HOST only mode (no display), i would say this is equivalent to ~ 100-500ms delay in loop(), but will not prevent the rest of your HOST code to function without the display.
      3) If you hot plug your display, no need to restart your host, the settings are streamed live without reinitializing the baud rate and settings.
      4) you can start your host controller without the lcd connected, and it will run fine at the reduced (100-500ms) delay each loop cycle, after which, if you plug your lcd in later on after the HOST is online, it'll run at full speed and no need to reinitialize the LCD Class

      So, while I am by any way no means an expert on library modifications, I will invite others who are willing to improve upon this code to more efficiently handle the task, and while it may not be a perfect solution, a limp mode or totally frozen host is worth sacrificing a 100-500ms delay for each loop cycle

      Oh! and no longer need to wait for LCD to boot. I am using 200000 baud on arduino mega, RX2/TX2 and the delay is now delay(200) before setting contrast.
      Enjoy?

      in genieArduino.h

      Code:
      #define TIMEOUT_PERIOD 1000 // leave at 1000
      #define RESYNC_PERIOD 1 // make this 1, 0 will lock up without lcd, going higher will delay loop cycles if lcd is disconnected.
      in genieArduino.cpp

      goto this area and add command in bold (break

      Code:
      ////////////////////// Genie::WaitForIdle ////////////////////////
      //
      // Wait for the link to become idle or for the timeout period,
      // whichever comes first.
      //
      void Genie::WaitForIdle (void) {
      uint16_t do_event_result;
      long timeout = millis() + Timeout;
      
      for ( ; millis() < timeout;) {
      do_event_result = DoEvents(false);
      // if there was a character received from the
      // display restart the timeout because doEvents
      // is in the process of receiving something
      if (do_event_result == GENIE_EVENT_RXCHAR) {
      timeout = millis() + Timeout;
      break;
      }
      
      if (GetLinkState() == GENIE_LINK_IDLE) {
      return;
      }
      }
      
      Error = ERROR_TIMEOUT;
      handleError();
      return;
      }
      Last edited by tonton81; 9th April 2016, 11:26 PM.

      Comment


      • #4
        to me the delay in setup is not necessarily for the lcd to start, but for the class itself (and partial communication (not necessarily dependant)), because, plugging in the LCD after the arduino bootup up was streaming live gauge data right away without any delays at full speed.

        Comment


        • #5
          This is the video posted with random data being output to several ints at same time during hot plugging
          note that this is without rebooting the host.
          https://www.youtube.com/watch?v=VVPc...ature=youtu.be

          Comment


          • #6
            also know this, that the more objects you write, the more delays it causes, a workaround that is I make the host work by current form selection, why write data when the page isn't loaded on lcd?
            if you do this you won't experience much, if any delays, you won't get actually ANY delays if you do this, the delay is only by accessing the genie.Write objects. So writing them as form dependant can be more efficient, plus this type of concept above will add hot plug, fast start, and anti-lockup features at same time

            Comment


            • #7
              Hi tonton81

              Yes alot of that is already known, and some of it is in the Sticky at the top of the Arduino section on the forum.

              Thanks for the information you have provided. We have already added this onto the list of things to look at once a resource is available. I will note down this topic as a point of reference.
              Great news about the reduction in delay you have found though with the modifications you have made. We will certainly study this closely, and see what (if any) other things may be affected, positive or negative.

              Many thanks for your input. Its suggested input like this which helps make a better product.

              Regards
              James

              Comment


              • #8
                At first look it looks like your mod is stopping the code waiting for the ACK from the display.

                If this is indeed what it is doing it can only lead to problems.
                Mark

                Comment


                • #9
                  the event handler doesnt seem to be working either with this mod, output only, besides on a serial line is bi-directional and no acks/naks should be needed unless it's i2c, even _some_ spi devices dont need acks/naks. Usually the data is discarded if it's not useful to the device since there is no error checking with serial, but at least I've inspired a possible fix for someone more capable than i am to code :P

                  Comment


                  • #10
                    OK, i got a little bored today so i decided to do a new mod which works for hotplugging, no delay after reset, and deals with receiving responses as well!
                    I will post the mods and the 2 files as well if anyone wants to play with it. You will require 2 pull down resistors on the UART line to force an error state when lcd is disconnected, as the wire will act as an antenna causing the error frame to process as valid data. The resistors are 10K ohm. Click image for larger version

Name:	shieldless4dresistormod.png
Views:	6
Size:	907.6 KB
ID:	52647


                    The code will not fully function without the resisters to put the uart floating pins in a known state, this is required.

                    2 files will need to be edited. I will list the modifications in BOLD for your viewing curiosity.

                    in genieArduino.h:

                    modify these 2 lines:

                    Code:
                    #define TIMEOUT_PERIOD 100
                    #define RESYNC_PERIOD 0
                    Then go down a few pages of the same file and look for:

                    Code:
                    // Global error variable
                    int Error;
                    int genieErrorCounter = 0; // This needs to be added.
                    Save file and exit.



                    in genieArduino.cpp

                    Goto this function:

                    Code:
                    void Genie::WaitForIdle (void) {
                        uint16_t do_event_result;
                        long timeout = millis() + Timeout;
                    
                        for ( ; millis() < timeout;) {
                            do_event_result = DoEvents(false);
                            // if there was a character received from the
                            // display restart the timeout because doEvents
                            // is in the process of receiving something
                            if (do_event_result == GENIE_EVENT_RXCHAR) {
                                timeout = millis() + Timeout;
                              genieErrorCounter++;  //ADD THIS LINE
                                if ( genieErrorCounter> 10 ) {  //ADD THIS LINE
                                   genieErrorCounter= 0;  //ADD THIS LINE
                                   return;  //ADD THIS LINE
                                  }  //ADD THIS LINE
                            }
                    
                            if (GetLinkState() == GENIE_LINK_IDLE) {
                              genieErrorCounter = 0;  //ADD THIS LINE
                                return;
                            }
                        }
                      while (deviceSerial->read() >= 0);  //ADD THIS LINE
                        EventQueue.rd_index = 0;  //ADD THIS LINE
                        EventQueue.wr_index = 0;  //ADD THIS LINE
                        EventQueue.n_events = 0;  //ADD THIS LINE
                        Timeouts = 0;  //ADD THIS LINE
                        LinkState = &LinkStates[0];  //ADD THIS LINE
                        *LinkState = GENIE_LINK_IDLE;  //ADD THIS LINE
                        Error = ERROR_TIMEOUT;
                        handleError();
                        return;
                    }
                    Attached Files
                    Last edited by tonton81; 22nd May 2016, 07:29 AM.

                    Comment


                    • #11
                      Don't forget to remove the delay in your sketch.

                      Tested working:

                      1) no delays now (as opposed to my last attempt at 200ms).
                      2) non-blocking other code, whether lcd connected or not your sketch can do other stuff.
                      3) responses now work as opposed to my last attempt.
                      4) no need to modify your sketch, this runs inline the library to save you some recode work, just get rid of the delay!
                      5) hot plugging works as well.
                      Last edited by tonton81; 22nd May 2016, 07:38 AM.

                      Comment


                      • #12
                        10K resistor benchtest: https://youtu.be/1eRAKZJ1ZHQ
                        hotplugging 4 times: https://youtu.be/JBxP0Xa5LVE
                        hotplug twice while background random numbers print to serial monitor, showing loop function still running normally: https://youtu.be/E2A6NPt4GXY
                        button press responses: https://youtu.be/m8Fc0VqIMGI
                        Last edited by tonton81; 22nd May 2016, 08:01 AM.

                        Comment


                        • #13
                          Interesting stuff.
                          That hotplugging test, can you unplug for >10 seconds, rather than just plugging it back in straight away?
                          Can you start your sketch with the display unplugged and then plug it in once the sketch has started?
                          Curious what the results are.
                          That first video is like 2 seconds long, I have no idea what it is trying to show.
                          James

                          Comment


                          • #14
                            ill try that now and ill re-edit this post**

                            1) hot unplug > 10 secs == works.
                            2) boot up arduino, THEN plug in lcd == works.

                            the first video shows the 2 resistors i added, the code will not work without it as the uart pins float, and prevents the ERROR_TIMEOUT from triggering because:

                            Code:
                                    if (do_event_result == GENIE_EVENT_RXCHAR) {
                                        timeout = millis() + Timeout;
                            that is taking priority over timing out due to the random data from a floating line, so it never reaches the timeout error. lots of debugging but i figured it out
                            once the lcd is disconnected, the lines get pulled low, forcing the pins in a known state and processing the ERROR_TIMEOUT to actually work better.
                            Last edited by tonton81; 22nd May 2016, 08:11 AM.

                            Comment


                            • #15
                              this is the test arduino code:
                              Code:
                              #include <genieArduino.h>
                              Genie genie;
                              
                              void setup() {
                                Serial.begin(115200);
                                Serial1.begin(200000);
                                genie.Begin(Serial1);
                                genie.AttachEventHandler(myGenieEventHandler);
                                pinMode(23, OUTPUT); digitalWrite(23, 0); delay(100); digitalWrite(23, 1); // RESET DISPLAY
                              //  delay(3500); <-- removed :)
                                genie.WriteContrast(15);
                              }
                              
                              void loop() {
                                genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0 , random(50));
                                genie.DoEvents();
                                Serial.print('\t');
                                Serial.print('\t');
                                Serial.print('\t');
                                Serial.println(random(10, 99));
                              }
                              
                              void myGenieEventHandler(void) {
                                genieFrame Event;
                                genie.DequeueEvent(&Event);
                                Serial.println(Event.reportObject.object);
                                Serial.println(Event.reportObject.index);
                                Serial.println(genie.GetEventData(&Event));
                              }

                              Comment

                              Working...
                              X