Announcement

Collapse
No announcement yet.

Trying to update Cool Gauge in IF statement - ridiculously slow!

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

  • Trying to update Cool Gauge in IF statement - ridiculously slow!

    Hi. I have a piece of code that reads an analogue pin and updates a cool gauge. At first I just had the code reading the pin and updating the directly. This worked fine, but the movement of the needle was jerky because the screen can't keep up. So next I made an if statement with a non-blocking timer to to control the speed that the needle moves. The needle does move - but ridiculously slowly! About one minor increment every 2 seconds!. And it's always the same even if I completely disable the timer. Pleae can somebody tell me why the heck this is happening and how I can overcome it?

    Here's a snippet of the relevant code. I've cut out a few lines that aren't relevant to this issue. I hope it still makes sense.

    Code:
    void loop()
    {
      static long waitPeriod = 0;  //Set up non-blocking delay to update gauges by this number of milliseconds. (AT ZERO TO DISABLE IT, BUT MAKES NO DIFFERENCE ANYWAY)
      static long prevTime;         // Part of non-blocking delay
      static int BoostTarget;    // Target value for boost gauge (the actual value from the sensor)
      static int BoostCurrent;  // Current boost gauge value
      
    
      genie.DoEvents();   //Genie events are received and queued here.
    
      if(millis() - prevTime >= waitPeriod)  //non-blocking delay
      {
        BoostTarget = analogRead(MAPSensorPin);
        if(BoostCurrent < BoostTarget)
        {
          BoostCurrent++;
          BoostVal = ((3 * BoostCurrent * 10) / 1023);  // ((([3bar - -1bar] * value) / resolution) -1bar) * multiplier
        }
             
       
        if(BoostCurrent > BoostTarget)
        {
          BoostCurrent--;
          BoostVal = ((3 * BoostCurrent * 10) / 1023);
        }
      
          WriteObject(BoostDayColour, BoostVal);
          prevTime = millis();
    }

  • #2
    Hi Vooman,

    Tried this code and it seems to be working smoothly on my end with just minor modifications from your attached code.

    *I used a potentiometer in my setup. You may adjust the waitPeriod and notice the delay of the coolGauge’s update.

    I’m not sure if this is what you’re trying to achieve, but if not, then can you please attach a simplified version of your project? Please include only the relevant parts so we can help you more.

    Best Regards,
    Attached Files
    Eran

    Comment


    • #3
      Hi, thanks for the zip file. When I downloaded the files to my Arduino and screen, the gauge didn't work. However, I did use that "map" function to replace all the maths I had going on to translate the Arduino's ADC values into numbers for the gauge. That's a much easier way of doing it!

      The gauge still reacts ridiculously slowly though! It takes about 10 seconds for the needle to move one single increment and I can't see why. It's like there's some sort of weird processing error - like it's stuck doing something else instead of updating the gauge.

      I don't mind posting up my code but I'd prefer not to share the screen publicly yet! Do you have an email address that I can send the files to? The 4DGenie file is over 200MB, so I'll have to share it via WeTransfer.

      Comment


      • #4
        Hi Vooman,

        Sure. You can email it to me here: john at 4dsystems dot com dot au and I’ll look into your code.

        For the convenience of us both, can you try simplifying your code to a shorter version and include the relevant ones (the parts which you’re having bugs on) only? You may also use the “Zip Project” Tool of Workshop4 IDE under the File Section to ensure that all of your project's relevant files are intact and compressed. This way, your project won’t cost you that much size and will be more suitable for sharing via email.

        Best Regards,
        Eran

        Comment


        • #5
          Hi. I've just emailed you. Many thanks

          Comment


          • #6
            Hi Vooman,

            I received your email and will see what I can do to help you.

            Best Regards,
            Eran

            Comment


            • #7

              Hi Vooman,

              I’ve tried the project file that you sent me and it’s working the way it should be on my side. Still, I want to comment few things.

              The reason behind the slow update is because of their size. Large images introduce a long ACK response, and it is normal. You can read more about this issue in this thread:
              https://forum.4dsystems.com.au/forum...0146#post60146

              To show that it actually is the reason, I sent you back two modified versions of your code. It’s apparent from the two versions that the smaller the size is, the faster the gauge updates; and the more the objects that need an update, the slower the update rate is.

              Can you try the two versions that I sent you and compare it to your original project? A feedback about the difference between the two modified versions and your original version would be great.

              Best Regards,
              Eran

              Comment


              • #8
                Hi. Thanks for responding to my email. Very much appreciated. Thanks as well for the link. some of it went over my head so I'll have to read again a few times!

                I see what you mean; making the gauges smaller does make them respond a lot quicker ( although it does completely scupper the aim of my project!)

                I also significantly sped up the gauge movement by simply putting the ADC-to-gauge conversion at the beginning, so now "BoostCurrent" only counts up to a maximum of 30 instead of 1023!

                Code:
                 BoostTarget = map(analogRead(MAPSensorPin), 0, 1023, 0, 30);  //get actual boost pressure
                    if(BoostCurrent < BoostTarget)  //if gauge needle is below actual boost level...
                    {
                      BoostCurrent++;  //increase gauge needle
                    }
                    
                    if(BoostCurrent > BoostTarget)  //if gauge needle is above actual boost level
                    {
                      BoostCurrent--;  //decrease gauge
                    } 
                    //BoostVal = map(BoostCurrent, 0, 1023, 0, 20);  // Convert ADC value to gauge numbers
                    BoostVal = BoostCurrent;
                 
                   
                    AFRVal = 0;
                    OilPressVal = 0; 
                    OilTempVal = 0; 
                
                    //This would be used to change the colour of the gauges but is unused here
                    if(digitalRead(NightPin) == LOW)
                    { 
                      WriteObject(BoostDayColour, BoostVal);
                ETC...

                One thing I still don't get is why doing the IF statements as above is still massively slower than immediately updating the the gauge like this:

                Code:
                 {
                   BoostVal = map(analogRead(MAPSensorPin), 0, 1023, 0, 30);
                    AFRVal = 0;
                    OilPressVal = 0;
                    OilTempVal = 0; 
                
                    if(digitalRead(NightPin) == LOW)
                    { 
                      WriteObject(BoostDayColour, BoostVal);
                Are you able to explain why this is?
                Is there anything else I can do to decrease the time it takes for the gauge needle to move?

                Comment


                • #9
                  Hi Vooman,

                  I have sent you a video of the first version of the code that I suggested in my previous email. Can you check if the behavior of your gauges is the same as the one that I just sent you?

                  About the above post, can you try changing your two if statements into a single "if-else if" statement?


                  Code:
                  if(BoostCurrent < BoostTarget)  //if gauge needle is below actual boost level...
                      {
                        BoostCurrent++;  //increase gauge needle
                      }
                     
                   else if(BoostCurrent > BoostTarget)  //if gauge needle is above actual boost level
                      {
                        BoostCurrent--;  //decrease gauge
                      }

                  This is just an initial assessment based on the part of the code that you have posted, I'd still need to have a deeper look into the entirety of your code and get back to you.

                  Best Regards,
                  Eran

                  Comment


                  • #10
                    I just tried the If-Else If statement. Still goes at the same speed. It seems at the moment that this is the maximum speed that the screen can handle.

                    Comment


                    • #11
                      You shouldn't be drawing every image between boost current and boost target, otherwise it will take a long time.

                      Why not just draw the target?

                      There are other things you could do, if you are looking for some 'apparent' transition.

                      The time it takes to draw each images is based on the read time from uSD, for the Picaso processor this is about 650,000 pixels per second. For Diablo it is 2,100,000 pixels per second.

                      So it's important not to waste time drawing every point between current and target, just as it is important not to keep rewriting the same value, or to have values in your gauge that have no discernable difference to adjacent values
                      Mark

                      Comment


                      • #12
                        Hi, Mark. Having the transitions in gauge movement is crucial because I want it to move like an analogue gauge.

                        Thanks for the advicea advice. I'll have to make sure the Arduino only sends discernable values to the gauge.

                        How do I make sure it doesn't rewrite the same values? Probably simple, but I can't think of a way!

                        Comment


                        • #13
                          Ahh, but why do you really want to have it move like an analogue gauge? You can't even see how an analogue gauge moves, as your eye can't discern much more than 25fps (which is the main reason why movies are 25fps, or 30fps in some locales). Even at 15 fps many people will struggle to see transition.

                          Plus Analogue gauges are not smooth, they have lag at the start, the accelerate quickly and have overshoot at the end. They are also notoriously inaccurate, maybe by even 10-20%.

                          So how you update the gauge is up to you, but there is absolutely no need to send every incremental value, it is just a waste of time any effort.


                          As for your second question, just compare the current value to the new one before sending, if they are the same, don't send

                          Mark

                          Comment


                          • #14
                            Nice one thank you. Thought it would be simple!

                            When I say "move like an analogue gauge" I just mean that it needs to move more smoothly and not jump from one side of the dial to the other, which is the best I can manage so far!

                            Comment


                            • #15
                              Greetings VooMan,

                              I created a code that you might want to check. It is an implementation of a gauge widget that more or less responds just like an analog gauge.

                              Attached are the files needed for the implementation.

                              Hope this will help.


                              Best regards,
                              Attached Files
                              Vince_4D

                              Comment

                              Working...
                              X