Announcement

Collapse
No announcement yet.

Arduino not responding to GENIE_REPORT_EVENT messages??

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

  • Arduino not responding to GENIE_REPORT_EVENT messages??

    Hi.

    I have a visi project that consists of several forms, each with several buttons. In Visi I set the forms and buttons to "On changed -> Report Message" The idea is that whenever a new form is opened, or a button is pressed, the display will send a message and the Arduino's event handler will run the appropriate bit of code. However, absolutely nothing happens!

    I thought there were two ways of interacting with a visi object;

    1 genie.ReadObject(object), then in the event handler do GENIE_OBJECT_REPORT...

    2 In Visi, set object to Report Message, then in the event handler do GENIE_REPORT_EVENT...

    Have I misunderstood how "Report Message" and "GENIE_REPORT_EVENT" works?

    Here is a snippet of the code showing the event handler.

    Code:
    void myGenieEventHandler(void)
    {
      genieFrame Event;
      genie.DequeueEvent(&Event);  //Remove the next queued event from the buffer and process it below
    
      if (genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_FORM, 0))  //When form changes
            {
              FormNumber = genie.GetEventData(&Event);                    //Store form number here
              EEPROM.update(FormPromAddress, FormNumber);        
            }
    
      if (ReportEvent(BoostColourBtn)) //When Boost colour button reports that it has been pressed.
      {
        static int i;                  //Cycle through the colours
        if (i < 7)
        {
          i++;
          BoostDayColour = BoostColours[i];
        }
        else
        {
          i=0;
          BoostDayColour = BoostColours[i];
        }
        
        
      }
      
    
    }
    You'll notice the line that says if (ReportEvent(BoostColourBtn)). In my code ReportEvent is a function and boostColourBtn is an alias used in a definition file. The ReportEvent function is below:

    Code:
    bool ReportEvent(int alias)
    {
      return genie.EventIs(&Event, GENIE_REPORT_EVENT, alias >> 8, alias & 0xFF);
    }

  • #2
    are you running genie.DoEvents(); in loop()? if not, the handler will never run

    events are for report events from the screen when interacting with widgets

    report object comes in when you request a ReadObject to check an object’s value.

    Tony

    Comment


    • #3
      Hi Vooman,

      As Tonton have mentioned, the genie.DoEvents() function must be inside the loop function.
      And yes, there are two ways of determining the status of an object.
      • First, you have to configure the object to transmit its status upon any change. For you to be able to do that, you have to set the OnChanged event of an object to “Report Message” and handle the events thrown by the object by setting the cmd of the EventIs() function to GENIE_REPORT_EVENT.
      • Second is by determining the current value of the object by using ReadObject () function. Note that upon receiving a right message, the display will reply a Report object message.
      I reviewed your code and it seems that there is nothing wrong with it.
      Can you please specify what the issue is?
      Have you checked if each of the objects you are using is sending a report message to the GTX (Genie Text eXecutor)?

      Best Regards,
      Pearl
      Pearl

      Comment


      • #4
        Hi. Yes, I have genie.DoEvents(). in Loop().

        I just remembered: the last time I had an issue like this, I solved it by increasing the startup delay 350ms to 500ms. Since I started the project, I have increased the size of the Visi file (well over 200MB on the SD card). I wonder if I need to further increase the startup delay?

        Comment


        • #5
          it should be 3 or 5 seconds, 500ms seems short

          Comment


          • #6
            Hi. My mistake. Meant to say 3500ms and 5000ms respectively

            Comment


            • #7
              Hi, Pearl. I just read your message fully and I've just tested the display with GTX. the objects do send messages when pressed. A message is also sent whenever I change a form.

              The Arduino is definitely communicating with the display too. Below is my whole code. Perhaps I've done something wrong in my coding? I hope I've commented it well enough to make sense!

              Brief description of the project: The project several forms, each with several Cool Gauges on. There is a button on each form that is supposed to cycle through several different colours for each gauge (Basically copies of the same gauge, in different colours - all placed on top of each other). The button is configured to report a message on changed.

              The forms are also configured to send a messages on changed. The Arduino is supposed to then store the last form opened in its eeprom.

              The issue is that the Arduino doesn't seem to notice when I the buttons or the forms send messages, therefore the gauges do not change and the last form opened is not stored on eeprom.


              Code:
              #include <genieArduino.h>
              #include <EEPROM.h>
              #include "OmniGaugeV8Const.h" //Header file holding names of all the Visi Genie objects
              
              const int MAPSensorPin = A0;       //MAP input pin THIS IS CURRENTLY THE ONLY ACTIVE PIN. THE OTHERS ARE NOT YET USED
              const int WBAFRSensorPin = A1;     //Wideband AFR input pin
              const int OilPressSensorPin = A2;  //Oil Pressure input pin
              const int OilTempSensorPin = A3;   //Oil Temperature input pin
              const int NightPin = 3;            //Connects to dash lights live (i/p voltage must be limited to 5v). Lights on = HIGH
              
              int BoostVal;     //Holds digital value to be sent to Boost gauge
              int AFRVal;       //Holds digital value to be sent to AFR gauge
              int OilPressVal;  //Holds digital value to be sent to oil pressure gauge
              int OilTempVal;   //Holds digital value to be sent to oil temperature gauge
              
              byte FormNumber = 0;                //Holds number of last active form
              int BoostDayColour = BoostGaugeWht;    //Holds day colour of last active boost gauge
              int BoostNightColour = BoostGaugeWht;  //Holds night colour of last active boost gauge
              int AFRDayColour = AFRGaugeWht;        //Holds day colour of last active AFR gauge
              int AFRNightColour = AFRGaugeWht;      //Holds night colour of last active AFR gauge, and so forth 
              int OilPressDayColour = OilPressGaugeWht; 
              int OilPressNightColour = OilPressGaugeWht;  
              int OilTempDayColour = OilTempGaugeWht; 
              int OilTempNightColour = OilTempGaugeWht;
              
              int BoostColours[] = {BoostGaugeWht, BoostGaugeGrn, BoostGaugeOrg, BoostGaugeBlu, BoostGaugeRed, BoostGaugeBlk, BoostGaugeBlank}; //This array is used to change the colour of each boost gauge
              
              const int FormPromAddress = 0;      //eeprom address to store form number (first 16 bits of eeprom)
              const int BoostDayPromAddress = 2;  //eeprom address to store Boost gauge colour (2nd 16 bits of eeprom, and so on)
              const int BoostNightPromAddress = 4;
              const int AFRDayPromAddress = 6;
              const int AFRNightPromAddress = 8;
              const int OilPressDayPromAddress = 10;
              const int OilPressNightPromAddress = 12;
              const int OilTempDayPromAddress = 14;
              const int OilTempNightPromAddress = 16;
              
              Genie genie;
              genieFrame Event;
              #define RESETLINE 4
              
              //Functions to replace Visi Genie object numbers with names given in the def file, OmniGaugeV8Const.h
              void WriteObject(int alias, int value)
              {
                genie.WriteObject(alias >> 8, alias & 0xFF, value);
              }
              
              void ReadObject(int alias)
              {
                genie.ReadObject(alias >> 8, alias & 0xFF);
              }
              
              bool ReportObject(int alias)
              {
                return genie.EventIs(&Event, GENIE_REPORT_OBJ, alias >> 8, alias & 0xFF); //No reports to send yet.
              }
              
              bool ReportEvent(int alias)
              {
                return genie.EventIs(&Event, GENIE_REPORT_EVENT, alias >> 8, alias & 0xFF);
              }
              
              ///////////////////////////////////////////////////////////////////////////////////////////////////////////
              
              void setup() 
              {
                Serial.begin (200000);  //Serial0 @ 200k Baud
                genie.Begin(Serial);    // Use Serial0 for talking to the Genie Library, and to the 4D Systems display
                
                genie.AttachEventHandler(myGenieEventHandler);
              
                // Reset the Display (change D4 to D2 if you have original 4D Arduino Adaptor)
                // THIS IS IMPORTANT AND CAN PREVENT OUT OF SYNC ISSUES, SLOW SPEED RESPONSE ETC
                // If NOT using a 4D Arduino Adaptor, digitalWrites must be reversed as Display Reset is Active Low, and
                // the 4D Arduino Adaptors invert this signal so must be Active High.  
                pinMode(RESETLINE, OUTPUT);  // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
                digitalWrite(RESETLINE, 1);  // Reset the Display via D4
                delay(100);
                digitalWrite(RESETLINE, 0);  // unReset the Display via D4
                delay (5000);        //let the display start up
                
                //Change active form to number stored in eeprom 
                FormNumber = EEPROM.read(FormPromAddress);
                genie.WriteObject(GENIE_OBJ_FORM, FormNumber, 0);
              
              }
              
              void loop()
              {
                static long waitPeriod = 50;    //Set up non-blocking delay to update gauges by this number of milliseconds.  Currently set to 0 for zero delay
                static long prevTime;         // Part of non-blocking delay
                
                static int BoostRead;  //Value read from MAP sensor
                static int BoostPrev;  //Previous MAP sensor value
                static int AFRRead;    //Value read from WB AFR controllor 
                static int AFRPrev;    //Previous value WB AFR sensor value
                
              
                genie.DoEvents();   //Genie events are received and queued here.
                
                //while (FormNumber == BAForm ) COMMENTED OUT BECAUSE THE FORM CHANGE FUNCTION ISN'T YET WORKING
                //{  COMMENTED OUT
                  if(millis() - prevTime >= waitPeriod)  //non-blocking delay
                  {
                   BoostPrev = BoostRead;
                   BoostRead = map(analogRead(MAPSensorPin), 0, 1023, 0, 300);  //get actual boost pressure, convert to gauge value
                   while (BoostPrev < BoostRead)
                   {
                    int diff = BoostRead - BoostPrev;
                    if (diff > 5) BoostPrev = BoostPrev + 0.25 * diff;  //Jumps needle several incrememnts 
                    if (diff <= 5) BoostPrev++; //Moves needle individual increments (Simulates analogue gauge movement)
                    if(digitalRead(NightPin) == LOW) WriteObject(BoostDayColour, BoostPrev);  //If lights are off Use the daylight colour gauge set by user
                    else if(digitalRead(NightPin) == HIGH) WriteObject(BoostNightColour, BoostPrev); //...Else use the nighttime colour gauge
                    BoostRead = map(analogRead(MAPSensorPin), 0, 1023, 0, 300);
                   }
                  
                   while (BoostPrev > BoostRead)
                   {
                    int diff = BoostPrev - BoostRead;
                    if (diff > 5) BoostPrev = BoostPrev - 0.25 * diff;
                    if (diff <= 5) BoostPrev--;
                    if(digitalRead(NightPin) == LOW) WriteObject(BoostDayColour, BoostPrev);
                    else if(digitalRead(NightPin) == HIGH) WriteObject(BoostNightColour, BoostPrev);
                    BoostRead = map(analogRead(MAPSensorPin), 0, 1023, 0, 300);
                   }
              
                   AFRPrev = AFRRead;
                   AFRRead = map(analogRead(WBAFRSensorPin), 0, 1023, 0, 1000);  //get actual boost pressure, convert to gauge value
                   while (AFRPrev < AFRRead)
                   {
                    int diff = AFRRead - AFRPrev;
                    if (diff > 20) AFRPrev = AFRPrev + 0.25 * diff;  //Jumps needle several incrememnts 
                    if (diff <= 20) AFRPrev++; //Moves needle individual increments (Simulates analogue gauge movement)
                    if(digitalRead(NightPin) == LOW) WriteObject(AFRDayColour, AFRPrev);
                    else if(digitalRead(NightPin) == HIGH) WriteObject(AFRNightColour, AFRPrev);
                    AFRRead = map(analogRead(WBAFRSensorPin), 0, 1023, 0, 1000);
                   } 
                  
                   while (AFRPrev > AFRRead)
                   {
                    int diff = AFRPrev - AFRRead;
                    if (diff > 20) AFRPrev = AFRPrev - 0.25 * diff;
                    if (diff <= 20) AFRPrev--;
                    if(digitalRead(NightPin) == LOW) WriteObject(AFRDayColour, AFRPrev);
                    else if(digitalRead(NightPin) == HIGH) WriteObject(AFRNightColour, AFRPrev);
                    AFRRead = map(analogRead(WBAFRSensorPin), 0, 1023, 0, 300);
                   }
              
                   prevTime = millis();
                  }
                //} COMMENTED OUT
              
              }
              
              
              
              ///////////////////////////////////////////////////////////////////////////////////////////////////////////
              //
              //Genie Event Handler
              // This is the user's event handler. It is called by genieDoEvents() 
              // when the following conditions are true
              //
              //    The link is in an IDLE state, and
              //    There is an event to handle
              //
              // The event can be either a REPORT_EVENT frame sent asynchrounously 
              // from the display or a REPORT_OBJ frame sent by the display in
              // response to a READ_OBJ request.
              //
              ///////////////////////////////////////////////////////////////////////////////////////////////////////////
              
              void myGenieEventHandler(void)
              {
                genieFrame Event;
                genie.DequeueEvent(&Event);  //Remove the next queued event from the buffer and process it below
              
                if (genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_FORM, 0))  //When form changes
                      {
                        FormNumber = genie.GetEventData(&Event);                    //Store form number here
                        EEPROM.update(FormPromAddress, FormNumber);
                      }
              
                if (ReportEvent(BoostColourBtn)) //When Boost colour button reports that it has been pressed
                {
                  static int i;                  //Cycle through the gauge colours
                  if (i < 7)
                  {
                    i++;
                    BoostDayColour = BoostColours[i];
                  }
                  else
                  {
                    i=0;
                    BoostDayColour = BoostColours[i];
                  }
                  
                  
                }
                
              
              }


              Comment


              • #8
                Hi Vooman,

                You have mentioned that the Arduino doesn’t seem to recognize which object is sending a report message.
                I have noticed that you use
                Code:
                 genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_FORM, 0)
                This function will return true only if Form 0 activates. Meaning if the last form opened was not equal to form 0, there will be no data stored in the variable FormNumber.
                For you to be able to store the last form opened. It is advisable to use
                Code:
                if (Event.reportObject.cmd == GENIE_REPORT_EVENT && Event.reportObject.object == GENIE_OBJ_FORM) {
                    // do something
                }
                This will handle report events from any form.
                Hope it helps.

                Best Regards,
                Pearl
                Pearl

                Comment


                • #9
                  Thanks that might fix a couple of issues.

                  Do you have any idea why my button to change the gauge colour doesn't work also?

                  Out of interest, is this:
                  Code:
                   if (Event.reportObject.cmd == GENIE_REPORT_EVENT && Event.reportObject.object == GENIE_OBJ_FORM)
                  Identical in function to this? :
                  Code:
                  if (genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_FORM))

                  Comment


                  • #10
                    Hi Vooman,

                    Code:
                    If (Event.reportObject.cmd == GENIE_REPORT_EVENT && Event.reportObject.object == GENIE_OBJ_FORM && Event.reportObject.index == 0)
                    {
                    //do something
                    }
                    Is the same with

                    Code:
                    If (genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_FORM, 0))
                    {
                    //do something
                    }
                    The first code is a long hand method while the other is a shorthand method. The codes above are used to handle a REPORT EVENT coming from an object FORM index 0.
                    With regards to the reason why your button isn’t able to change the color of the cool gauge, have you tried checking if the BoostDayColour changes? You may print its value to check.

                    Code:
                    if (ReportEvent(BoostColourBtn)) //When Boost colour button reports that it has been pressed
                    {
                    static int i; //Cycle through the gauge colours
                    if (i < 7)
                    {
                    i++;
                    BoostDayColour = BoostColours[i];
                    Serial.print(BoostDayColour);
                    }
                    else
                    {
                    i=0;
                    BoostDayColour = BoostColours[i];
                    Serial.print(BoostDayColour);
                    
                    }
                    }
                    Thank you.

                    BR,
                    Pearl
                    Last edited by Pearl; 19th July 2018, 09:53 AM.
                    Pearl

                    Comment


                    • #11
                      Hi.

                      For the form changing event and colour change event, I changed them both from GENIE_REPORT_EVENT to GENIE_REPORT_OBJ and then added lines to do a genieReadObject for each object at the end of the main loop.

                      The form change event works fine like this; it stores the last form opened in eeprom like it should.

                      The colour change event, on the other hand, goes completely crazy! Nothing happens when I press the BoostColourBtn button. Instead, the colour of the gauge changes every time the gauge needle moves! I have a pot connected to the gauge input pin on my Arduino and whenever I adjust the pot, the gauge colours go wild, changing colour with every input from the pot! I can't make sense of it. Please can you tell me why this is?

                      Also, please can you tell me why the GENIE_REPORT_EVENT doesn't work?

                      Many thanks

                      Comment


                      • #12
                        Hi Vooman,

                        I have made some changes in your code that might be the cause of the issue you have mentioned.

                        Code:
                        // Global
                        // genieFrame Event;
                         
                        bool ReportObject(genieFrame *Event, int alias)
                        {
                          return genie.EventIs(Event, GENIE_REPORT_OBJ, alias >> 8, alias & 0xFF);  //No reports to send yet.
                        }
                         
                        bool ReportEvent(genieFrame *Event, int alias)
                        {
                          return genie.EventIs(Event, GENIE_REPORT_EVENT, alias >> 8, alias & 0xFF);
                        }
                         
                        void myGenieEventHandler(void)
                        {
                          genieFrame Event;
                          genie.DequeueEvent(&Event);  //Remove the next queued event from the buffer and process it below
                         
                          if (genie.EventIs(&Event, GENIE_REPORT_EVENT, GENIE_OBJ_FORM, 0))  //When form changes
                                {
                                  FormNumber = genie.GetEventData(&Event);                    //Store form number here
                                  EEPROM.update(FormPromAddress, FormNumber);
                                }
                         
                          if (ReportEvent(&Event, BoostColourBtn)) //When Boost colour button reports that it has been pressed
                          {
                            static int i;                  //Cycle through the gauge colours
                            if (i < 7)
                            {
                              i++;
                              BoostDayColour = BoostColours[i];
                            }
                            else
                            {
                              i=0;
                              BoostDayColour = BoostColours[i];
                            }  
                          }
                        }
                        I have noticed this following:
                        • You declared the genieFrame *Event as a global variable as well as a local variable inside the myGenieEventHandler() function.

                        Please be reminded that local variables are declared within the function and can only be used inside the function.
                        • In your return statement in ReportEvent() function, the &Event parameter in genie.EventIs() function was used. However, since you have another genieFrame variable declared globally, it seems to be working. That is Arduino IDE will compile the code without errors. However, the event data from Report Events are passed to the local genieFrame variable inside the function myGenieEventHandler() and the global Event variable is always actually empty. Therefore, the old ReportEvent function may behave unpredictably.

                        Hope it helps.

                        BR,
                        Pearl
                        Last edited by Pearl; 26th July 2018, 11:09 AM.
                        Pearl

                        Comment


                        • #13
                          Thanks. I will try the code with your modifications.

                          I thought I understood how the Genie Events Handler works, but I evidently don't!! What do
                          Code:
                          *Events
                          and
                          Code:
                          &Events
                          do?

                          Comment


                          • #14
                            Hi again,

                            “&” and “*” are unary operators in C language in programming. The “address of” operator “&” gives the address of a given variable. While the “value of” operator “*” gives the value of a given variable.

                            For further understanding with regards to this two unary operators, kindly refer to these links:
                            https://www.tutorialspoint.com/cprog...c_pointers.htm
                            https://www.programiz.com/c-programming/c-pointers

                            Hope it helps.

                            BR,
                            Pearl
                            Pearl

                            Comment


                            • #15
                              Hi. Unfortunately none of this worked. If I did exactly what you showed, it wouldn't compile. I found that I could use the global version of genieFrame Event at the top of the screen and delete the local genieFrame Event from the Event Handler. But that was all. And the program still behaves in the same way; changing the gauge colour with every movement of the needle. It's like the program sees every genieWtrite event to the screen as a button press.

                              BTW, the event to report the form at save the last form number opened to eeprom works perfectly. It's just the gauge colour change Event that doesn't work properly.
                              Last edited by VooMan; 21st July 2018, 08:41 AM. Reason: added extra info.

                              Comment

                              Working...
                              X