Announcement

Collapse
No announcement yet.

Gauges blink periodically.

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

  • Gauges blink periodically.

    Hi I'm using visi to make a dash display. Reading incoming serial data and parsing the data for the display. I have some of the gauges working but they blink every so often like the data is getting messed up. And they all do it at the same time so I'm pretty sure it's data related. Here is the code I have. Any ideas would be of great help.

    Code:
    #platform "Gen4-uLCD-50DT"
    
    #inherit "4DGL_16bitColours.fnc"
    
    #inherit "VisualConst.inc"
    
    #inherit "LEDDIGITSDISPLAY.inc"
    
    #inherit "gen2 DashConst.inc"
    
    
    
    var combuf[50];
    var seconds := 0;
    var secondsL;
    var nseconds := 1;
    var rpm := 0;
    var rpmL ;
    var temprpm := 0;
    var engine;
    var pulwth := 1000;
    var pulwthL, pulwthH ;
    var npulwth := 1001;
    var pulwththou, pulwthwhole;
    var map := 300;
    var mapL, mapth ;
    var nmap := 301;
    var barokpa, barokpaL, barokpath;
    var mat := 0;
    var matL, matth ;
    var clt := 0;
    var cltL, cltth ;
    var nclt := 101;
    var wue, wueL, wuebit, wuetest;
    var tps := 0;
    var tpsL, tpsth, tpswhole;
    var bat_volt, bat_voltL, bat_voltth;
    var ntps := 1;
    var afr, afrL, afrth ;
    var nafr := 1;
    var baro, baroL, baroth ;
    var tps_dot, tps_dotL ;
    var maf, mafL, mafhr, mafwhole;
    var maf_volt := 0;
    var maf_voltL, maf_voltthou, maf_voltwhole;
    var nmaf_volt := 1;
    var shown := 0;
    var nextpackage := 1;
    var p, n, state;
    var pagemode := 1;
    var ignadvance, ignadvth;
    var ignadvanceL;
    var nignadvance;
    var res;
    var hndl1;
    var fnp;
    var i;
    var x, y, on;
    var fname[6];
    
    
    func main()
    //  var hstrings ; // Handle to access uSD strings, uncomment if required
    //  var hFontx ;   // Handle to access uSD fonts, uncomment if required and change n to font number
    //  Uncomment the following if uSD images, fonts or strings used.
    
    
       putstr("Mounting...\n");
        if (!(file_Mount()))
            while(!(file_Mount()))
                putstr("Drive not mounted...");
                pause(200);
                gfx_Cls();
                pause(200);
            wend
        endif
         gfx_Cls();
    
    //    gfx_TransparentColour(0x0020);    // uncomment if transparency required
    //    gfx_Transparency(ON);             // uncomment if transparency required
         //var hFontn, hstrings;
        //hFontn := file_LoadImageControl("ESPDAS~1.dan", "ESPDAS~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("ESPDAS~1.txf", 'r') ; // Open handle to access uSD strings, uncomment if required
        hndl := file_LoadImageControl("GEN2DA~1.dat", "GEN2DA~1.gci", 1);
        com_SetBaud(COM0, 20000);
        com_Init(combuf,6,0);
        //touch_Set(TOUCH_ENABLE);
        gfx_Set(SCREEN_MODE,LANDSCAPE) ;
    
        // Form1 1.1 generated 6/13/2018 8:00:14 PM
        img_Show(hndl,iForm1) ;
        // Coolgauge0 1.0 generated 6/13/2018 8:03:11 PM
        //img_SetWord(hndl, iCoolgauge0, IMAGE_INDEX, frame) ; // where frame is 0 to 140 (for a displayed -1 to -1)
        img_Show(hndl,iCoolgauge0) ;
        img_Show(hndl, iCustomdigits4);  // show all digits at 0, only do this once
        img_Show(hndl,iGauge1) ;
        img_Show(hndl, iCustomdigits0);  // show all digits at 0, only do this once
    
    
    
    
    //////////////////////////////////////Main Loop begin//////////////////////////////
    repeat
         page1();                       //load or updat values on page1.
    
         if (com_Full())
                p := str_Ptr(combuf); // get a byte pointer from a word region
                datain();// When buffer is full call datain function.
                com_Init(combuf,6,0);
    
         endif
    
    
    
    
    
    
    forever
       //////////////////////////////////Main Loop End////////////////////////////////////
    endfunc
    
    
    
    //func touch()          //if a touch has occured then get x and y cordinates
        //if(touch_Get(TOUCH_STATUS) == TOUCH_PRESSED)    //get status
        // n := img_Touched(hndl, -1);//scan image list, looking for a touch
        //x := touch_Get(TOUCH_GETX);    //get y
       // y := touch_Get(TOUCH_GETY);    //get x
       // endif
    
        //endfunc
    
    
    
    
    
    func datain()
              rpmL := str_GetByte(p);
              rpm := str_GetByte(p+1);
              tps := str_GetByte(p+2);
              bat_volt := str_GetByte(p+3);
    
             /*seconds := str_GetByte(p);
             secondsL := str_GetByte(p+1);
             pulwthH := str_GetByte(p+2);
             pulwthL := str_GetByte(p+3);
             rpm := str_GetByte(p+6);
             rpmL := str_GetByte(p+7);
             ignadvance := str_GetByte(p+8);
             ignadvanceL := str_GetByte(p+9);
             engine := str_GetByte(p+11);
             barokpa := str_GetByte(p+16);
             barokpaL := str_GetByte(p+17);
             map := str_GetByte(p+18);
             mapL := str_GetByte(p+19);
             mat := str_GetByte(p+20);
             matL := str_GetByte(p+21);
             clt := str_GetByte(p+22) ;
             cltL  := str_GetByte(p+23) ;
             tps := str_GetByte(p+24);
             tpsL   := str_GetByte(p+25);
             bat_volt := str_GetByte(p+26);
             bat_voltL :=str_GetByte(p+27);
             afr := str_GetByte(p+28);
             afrL := str_GetByte(p+29);
             wue := str_GetByte(p+40);
             wueL := str_GetByte(p+41);
             baro := str_GetByte(p+46);
             baroL := str_GetByte(p+47);
              */
    
    
    
           seconds := seconds * 256 + secondsL;
           rpm := rpm * 256 + rpmL;
           map := map * 256 + mapL;
           mapth := map % 10 ;
           mat := mat * 256 + matL;
           matth := mat % 10;
           clt := clt * 256 + cltL;
           cltth := clt % 10;
    
           afr := afr * 256 + afrL;
           afrth := afr % 10 ;
    
           wue := wue * 256 + wueL;
    
           baro := baro * 256 + baroL;
           baroth := baro % 10 ;
    
           barokpa := barokpa * 256 + barokpaL;
           barokpath := barokpa % 10;
    
           tps_dot := tps_dot * 256 + tps_dotL;
    
    
    
    
    
    
        /*   hndl1 := file_Open((fnp), 'a');                  //send data to sdcard csv file
            to(DSK);                                      //to file send chars...
            print(seconds,",",rpm,",",map/10,".",mapth,",",pulwthwhole,".",pulwththou,",",ignadvance/10,".",ignadvth,",",mat/10,".",matth,",",clt/10,".",cltth,",",wue,",",bat_volt/10,".",bat_voltth,",",tpswhole,".",tpsth,",",tps_dot/10,",",baro/10,".",baroth,",",barokpa/10,".",baroth,",",afr/10,".",afrth,",",engine,"\n");
            res := file_Close(hndl1);
            */
        endfunc
    
    func page1()
    
    
    
        img_SetWord(hndl, iCoolgauge0, IMAGE_INDEX, rpm/100) ; // where frame is 0 to 140 (for a displayed -1 to -1)
        img_Show(hndl,iCoolgauge0) ;
    
        // Customdigits4 1.0 generated 6/13/2018 9:11:29 PM
    
        ledDigitsDisplay(rpm, iiCustomdigits4, 324, 5, 1, 31, 1) ;
        //img_Show(hndl, iCustomdigits4);
    
    
        // Gauge1 1.0 generated 6/14/2018 12:00:13 AM
        img_SetWord(hndl, iGauge1, IMAGE_INDEX, tps) ; // where frame is 0 to 100 (for a displayed 0 to 100)
        img_Show(hndl,iGauge1);
    
    
    
        // Customdigits0 1.0 generated 6/14/2018 12:18:38 AM
    
        ledDigitsDisplay(bat_volt, iiCustomdigits0, 552, 3, 1, 31, 1) ;
    
    
    
    
    
    
    
    
    
      endfunc
    This is just bits and pieces of code I had from another project. I know a lot needs to be done. Would just like to know what is happening to my data. I don't get any ACK at all. Only NAK. No matter how long I wait to send values to the display it does the same thing. I slowed the sending down to 4 times per second and still no ACK. Does this have anything to do with it?

  • #2
    Hi BHayes,

    How exactly do the gauges blink? Do they blink with a RED X? Or do they just blink as if being rewritten?
    If they’re blinking with a red X then it has something to with the data that you’re writing to the coolgauge. For example, the standard coolgauge has a minimum value of zero and a maximum value of 100, if the value that you’re using to write is beyond that range, then your coolgauge will blink with a red X.

    Can you try using this error checking routine so we can test if it’s really the issue? Just replace the page1 function with this one:

    func page1()

    if((rpm/100) >100 || (rpm/100) < 0 )
    txt_MoveCursor(0,0);
    print(rpm/100, " ");
    else
    img_SetWord(hndl, iCoolgauge0, IMAGE_INDEX, rpm/100) ; // where frame is 0 to 140 (for a displayed -1 to -1)
    img_Show(hndl,iCoolgauge0) ;
    endif

    ledDigitsDisplay(rpm, iiCustomdigits4, 324, 5, 1, 31, 1) ;
    img_Show(hndl, iCustomdigits4);

    if(tps >100 || tps < 0 )
    txt_MoveCursor(1,0);
    print(tps, " ");
    pause(500);
    else
    img_SetWord(hndl, iGauge1, IMAGE_INDEX, tps) ; // where frame is 0 to 100 (for a displayed 0 to 100)
    img_Show(hndl,iGauge1);

    ledDigitsDisplay(bat_volt, iiCustomdigits0, 552, 3, 1, 31, 1) ;
    endfunc
    If there’s nothing printed and the coolgauge’s still blinking, then your guess about the data communication might be right. In order for us to confirm your guess, can you explain more about the communication between the two hosts? What host do you use to send data to the display?
    How exactly do you send the data?

    You might also want to consider using the serin() function of receiving data from a host. More information can be read here: https://forum.4dsystems.com.au/forum...3972#post63972

    Best Regards,
    Eran
    Eran

    Comment


    • #3
      Ok, yes they do give a big X sometimes Just depends on the values. I am getting values printed that are out of range of the code you sent me. The host is an teensy 3.5 programmed in arduino. When powered up it waits 4 seconds and then startes sending serial data of real time values. I tried waiting on the ACK,"06", hex, before starting the data stream but I never get it. I read in the manual that when the com_Init() function is issued that it would send an ACK byte to confirm, unless there was an error then it send the NAK."16". Well the 16 is all I get.

      Code:
      void displayLcd()
      {
         byte displayStatus[DISPLAY_PACKET_SIZE];
          byte ackByte = (Serial1.read(), HEX);
          Serial.println(ackByte);
           
      
          
             displayStatus[0] = lowByte(currentStatus.RPM); //rpm HB
             displayStatus[1] = highByte(currentStatus.RPM); //rpm LB
             displayStatus[2] = currentStatus.TPS;
             displayStatus[3] = currentStatus.battery10;
         
            for(byte x=0; x<=4; x++)
               {
               Serial1.write(displayStatus[x]);
               
               }
            
      }
      This is what is sending the data now. It works. Just get some random data sometimes.

      Comment


      • #4
        An easy work around might be to add the Arduino function 'constrain' around the data that is being sent, so if its out of range it gets clamped, so the out of range Red X never occurs.
        https://www.arduino.cc/reference/en/...ath/constrain/

        Code:
        Serial1.write(constrain(displayStatus[x], 0, 100);
        For example.
        James

        Comment


        • #5
          Also depending on the source of your data, you might want to implement a median filter, which can remove outliers. Really depends on the source though if you think its necessary.

          One that I have used before is from here: https://github.com/RobTillaart/Ardui.../RunningMedian

          Set it up for say 5 values,

          Code:
          RunningMedian RPMInput = RunningMedian(5);
          then add values to the running median with something like this

          Code:
          RPMInput.add(RPMraw);
          and then print the values after extracting the 3 averaged median values from the filter doing something like this

          Code:
          float tempRPM = RPMInput.getAverage(3);
          Just a suggestion, but it has worked well for me in the past for RPM based values which can go randomly high or low, if the input source is subject to noise or glitches.
          James

          Comment


          • #6
            The values are coming straight from the ecu it self. As in, it is sending the values to the display. So random numbers are not present. Noise in the tx and rx lines maybe. I have a total of 8 gauges and they all jump at the same time as if the data is getting miss aligned or something. And they don't do it all the time.
            Last edited by BHayes; 15th June 2018, 01:25 PM.

            Comment


            • #7
              Hi BHayes,

              James is right. You can use the constrain function from the sender’s side. This will make the transmitted values from the teensy limited to your set values. If you’re worried about the noise on the TX/RX lines, then you can utilize the function that I sent you. You only need to modify it based on your expected output.

              Code:
              func page1()
              
              if((rpm/100) <= 100 && (rpm/100) >= 0 )
                 img_SetWord(hndl, iCoolgauge0, IMAGE_INDEX, rpm/100) ; // where frame is 0 to 140 (for a displayed -1 to -1)
                 img_Show(hndl,iCoolgauge0) ;
              endif
              
              ledDigitsDisplay(rpm, iiCustomdigits4, 324, 5, 1, 31, 1) ;
              img_Show(hndl, iCustomdigits4);
              
              if(tps <=100 && tps >= 0 )
                 img_SetWord(hndl, iGauge1, IMAGE_INDEX, tps) ; // where frame is 0 to 100 (for a displayed 0 to 100)
                 img_Show(hndl,iGauge1);
              endif
              
              ledDigitsDisplay(bat_volt, iiCustomdigits0, 552, 3, 1, 31, 1) ;
              endfunc
              Using a limiting function on each side will filter the unexpected data.

              If the issue is still there after trying these limiting functions, then you can implement a simple error checking routine by using a checksum of the received data.


              Best Regards,
              Eran

              Comment


              • #8
                Eran. I have implemented the code you sent. They do still jump. I'll have to search on how to do a check sum. I've never did anything like that.

                Comment


                • #9
                  Hi BHayes,

                  You may start researching about checksum in the following threads:

                  https://forum.4dsystems.com.au/forum...gen4-ulcd-50dt
                  https://forum.4dsystems.com.au/forum...7669#post37669
                  ViSi-Genie Reference Manual (Under the "Genie Standard Protocol" Section)

                  Or if it’s fine with you, you can send me your project via email and I’ll see what I can do to help you. Please use Workshop4's "zip tool" to ensure that all your project's relevant files are intact and compressed to be more suitable for sharing.

                  Email: john at 4dsystems dot com dot au

                  Hope this helps and Best Regards,
                  Eran

                  Comment

                  Working...
                  X