Announcement

Collapse
No announcement yet.

How to use Visi Genie generated Header Files?

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

  • How to use Visi Genie generated Header Files?

    Hi. I created a Visi Genie generated header file for use in my Arduino sketch that I'm about to write. Please excuse me if this is a daft question, but how do you actually use it? :D

    In my sketch I tried typing #include [name of generated file].h but that just resulted in the sketch failing to compile, saying no such file or directory. I tried putting the header file into the same folder as the Arduino sketch but that didn't work either.

    Am I just supposed to copy the text inside the file and paste it into my Arduino sketch?

  • #2
    ...Think I got it!

    I went to Arduino/Libraries folder, created a new folder and put the header file into there. Now the Arduino sketch compiles. Whether the header file will work is another question!

    Please comment if I have done this incorrectly or if there is extra information I need to know for my header file to work.

    Thanks

    Comment


    • #3
      Hi VooMan,

      Calling the header file can be done by the following methods:
      • #include <myFile.h>
      - compiler searches for the file in the include path list (default directory for libraries)
      • #include “myFile.h”
      - compiler searches for the file first in the current directory only then it will search in the include path list
      Note: < > is different with “ ”

      Most probably, putting the header file along with the sketch file didn’t work when you did it, it’s because you used the first method hence the compiler was not able to find the file.
      When you placed it in the default directory for libraries, it worked since the file can now be accessed by the compiler.

      But traditionally, header file/s must be placed in the same directory as the sketch file hence, the second method is being implemented.

      You might also want to check this app note about Visi-Genie Generated Header for additional information, https://www.4dsystems.com.au/appnote/4D-AN-00190/.

      Hope this helps.

      Best regards,

      Vince

      Comment


      • #4
        Perfect. Thank you

        Comment


        • #5
          No worries VooMan.
          If you encounter any problem on your project, we will gladly help.

          BR,
          Vince

          Comment


          • #6
            Actually, I just realised I don't know how to call the defined objects in my Arduino sketch!

            For example:

            In my header file I have the line #define BoostGaugeWht 0x0800

            In my Arduino sketch, how do I write to this object? Do I put something like: genie.WriteObject(BoostGaugeWht, 0); Instead of the usual genie.WriteObject(GENIE_OBJ_COOL_GAUGE, 0, 0);
            ?



            Comment


            • #7

              Hi VooMan.

              The genie.WriteObject(GENIE_OBJ_COOL_GAUGE, 0, 0) command can still be used in writing an object in the display since GENIE_OBJ_COOL_GAUGE is a defined object ID in the library.

              But if you want to use the generated data in the header file, you can implement it as shown below.

              genie.WriteObject(BoostGaugeWht>>8, BoostGaugeWht & 0xFF, frame)
              • BoostGaugeWht>>8 – gets the high byte
              • BoostGaugeWht & 0xFF – gets the low byte

              Relative to your example data: #define BoostGaugeWht 0x0800
              • 08 – high byte containing the Object ID
              • 00 – low byte containing the Object index

              Note:
              Define variables in the header should not be the same with define variables in the library

              Kindly check the app note I sent you in an earlier post. It might give you additional information with regards to utilizing headers.

              Hope this helps.

              Best regards,
              Vince

              Comment


              • #8
                Hi, thanks again for the reply. The app note you sent me is the same one I used to learn how to generate header files. However, from what you said in you last post, it seems I've misunderstood the pupose of header files. I'll try to explain my reason for wanting to use header files so perhaps you can explain the correct way of doing it:
                • My project consists of several forms, each with 16 gauges (basically the same gauge in different colours).
                • The user presses a Winbutton to change the colour of the gauge. (in code, pressing the button changes the index of the gauge being written to)
                • Because I have so many gauges, I want to write my Arduino sketch using the aliase names, rather than me having to try and remember which index corresponds to which colour.
                I hope that makes sense!

                Comment


                • #9
                  Hi again VooMan.

                  • Because I have so many gauges, I want to write my Arduino sketch using the aliase names, rather than me having to try and remember which index corresponds to which colour.
                  If you want to utilize the defined variables generated in the header file by creating a function that writes on a specific object, you can implement it as shown below.


                  Code:
                  void WriteObject(int alias, int value) {
                    genie.WriteObject(alias >> 8, alias & 0xFF, value);         
                  }
                  So if you want to use the function, it would be

                  Code:
                  WriteObject(BoostGaugeWht, frame);

                  Relative to your example: #define BoostGaugeWht 0x0800

                  alias >> 8 - gets the object ID (08)
                  alias & 0xFF – gets the object Index (00)


                  Hope this will help.

                  Best regards,
                  Vince

                  Comment


                  • #10
                    I think I see. When you say alias & 0xFF – gets the object Index (00) Did you mean alias & 0x00? That would make more sense to me as being object Index (00)

                    So at the top of the sketch, where I declare my variables, would I write, for example:
                    Code:
                    void WriteObject(int alias, int value) {
                    genie.WriteObject(BoostGaugeWht >> 8, BoostGaugeWht & 0x00, 0);
                    }
                    
                    void WriteObject(int alias, int value){
                    genie.WriteObject(BoostGaugeBlk >> 8, BoostGaugeBlk & 0x01, 0);
                    
                    void WriteObject(int alias, int value){
                    genie.WriteObject(BoostGaugeRed >> 8, BoostGaugeRed & 0x02, 0)
                    }
                    ...And so on, for all the diferent gauges?

                    Then later for the rest of my code I can just use the aliases for the gauges, such as:

                    Code:
                    WriteObject(BoostGaugeWht, 0) **Do some stuff**
                    
                    ReadObject(BoostGaugeRed, 0) **Do some more stuff**
                    Thanks again

                    Comment


                    • #11
                      Hi VooMan.

                      Let me clarify first about genie.WriteObject() function. Based on the genieArduino library, the function has the syntax WriteObject (uint16_t object, uint16_t index, uint16_t data). (refer to https://github.com/4dsystems/ViSi-Ge...nieArduino.cpp)

                      So, the correct implementation would be, (reference data BoostGaugeBlk 0x0801)
                      genie.WriteObject(BoostGaugeBlk>>8, BoostGaugeBlk & 0xFF, frame);

                      Explanation:
                      • For BoostGaugeBlk >> 8
                      BoostGaugeBlk = 0x0801
                      = 0000 1000 0000 0001 - 16-bit
                      = 2049 - DEC (integer) (does not represent an Object ID)
                      BoostGaugeBlk >> 8
                      = 0000 1000 0000 0001 shift 8 bits to right
                      = 0000 0000 0000 1000 - 16-bit
                      = 8 - DEC (integer)

                      Note:8 is an Object ID for coolgauge
                      • For BoostGaugeBlk & 0xFF
                      0000 1000 0000 0001 ---- 16bit representation of BoostGaugeBlk
                      &
                      0000 0000 1111 1111 ----- 0xFF
                      0000 0000 0000 0001 ----> 1 DEC (integer)

                      Note: 1 is an Object index for coolgauge, in your case, represents black coolgauge

                      With regards to using the new function created;
                      Code:
                      void WriteObject(int alias, int value) {
                        genie.WriteObject(alias >> 8, alias & 0xFF, value);        
                      }
                      You'll only need one function. So when you implement it, do it as follows

                      WriteObject(BoostGaugeBlk, 0)
                      where
                      alias = BoostGaugeBlk
                      value = 0

                      and/or
                      WriteObject(BoostGaugeWht, 0)
                      where
                      alias = BoostGaugeWht
                      value = 0


                      Best regards,

                      Vince

                      Comment


                      • #12
                        Thanks, your explanation was extremely useful. I read up on how functions work as well, now I understand how this works.

                        With luck this should be the last question:

                        In my Genie event handler function I have a line of code that goes:

                        Code:
                        if (genie.EventIs(&Event, GENIE_REPORT_OBJ, GENIE_OBJ_WINBUTTON, 0x00))
                        How would I substitute in the alias for Winbutton0 in situations like this?

                        Comment


                        • #13
                          No worries VooMan, I’m glad it helped.

                          If you want the function to be an identifier of a report event from a certain object (in your case WINBUTTON), you can create it like this:

                          Code:
                          bool ReportEvent(int alias){
                          return genie.EventIs(&Event, GENIE_REPORT_OBJ, alias >> 8, alias & 0xFF)
                          }
                          This function will return TRUE if all the fields match the caller's parameters

                          So if you will use it,
                          Example (report event from WINBUTTON with alias ControlBTN)
                          Code:
                          If (ReportEvent(ControlBTN) == 1){               // check if the report event is from ControlBTN
                          Do something
                          }
                          can also be written as
                          Code:
                          If (ReportEvent(ControlBTN) ){
                          Do something
                          }
                          BR,

                          Vince

                          Comment


                          • #14
                            I'm stuck already!

                            I've put down some code (it doesn't really do anything of use yet) and tried to compile it, but it keeps saying 'genie' was not declared in this scope. It says this for the three lines that I've higlighted in the code. If I comment out these three lines then the code compiles just fine.

                            Code:
                            #include <genieArduino.h>
                            #include <EEPROM.h>
                            #include "OmniGaugeV8Const.h" //Header file holding names of all the Visi Genie objects
                            
                            int MAPSensorPin = A0;       //MAP input pin
                            int WBAFRSensorPin = A1;     //Wideband AFR input pin
                            int OilPressSensorPin = A2;  //Oil Pressure input pin
                            int OilTempSensorPin = A3;   //Oil Temperature input pin
                            
                            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 = 0x00;  //Holds number of last active form
                            byte BoostDayColour = BoostGaugeWht; //Holds day colour of last active boost gauge
                            //byte BoostNightColour = ???;  //Holds night colour of last active boost gauge
                            //byte AFRDayColour = ???;  //Holds day colour of last active AFR gauge
                            //byte AFRNightColour = ???;  //Holds night colour of last active AFR gauge, and so forth 
                            //byte OilPressDayColour = ???; 
                            //byte OilPressNightColour = ???;  
                            //byte OilTempDayColour = ???; 
                            //byte OilTempNightColour = ???;  
                            
                            int FormPromAddress = 0;  //eeprom address to store form number (first byte of eeprom)
                            int BoostDayPromAddress = 1;  //eeprom address to store Boost gauge colour (2nd byte of eeprom, and so on)
                            int BoostNightPromAddress = 2;
                            int AFRDayPromAddress = 3;
                            int AFRNightPromAddress = 4;
                            int OilPressDayPromAddress = 5;
                            int OilPressNightPromAddress = 6;
                            int OiltTempPromAddress = 7;
                            int OilTempPromAddress = 8;
                            
                            //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, int value)
                            {
                              genie.ReadObject(alias >> 8, alias & 0xFF, value);
                            }
                            
                            bool ReportEvent(int alias)
                            {
                              return genie.EventIs(&Event, GENIE_REPORT_OBJ, alias >> 8, alias & 0xFF);
                            }
                            
                            
                            Genie genie;
                            #define RESETLINE 4
                            
                            void setup() 
                            {
                              Serial.begin (200000);  //Serial0 @ 200000
                              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 (3500);        //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 = millis();
                            
                              genie.DoEvents();   //Genie events are received and queued here.
                            
                              if (millis() >= waitPeriod)
                              {
                                BoostVal = ((3 * analogRead(MAPSensorPin)) / 1023 - 1);  // (max gauge number * reading) / resolution  - 1 [turns abs to gauge]
                              }
                            
                            }
                            
                            
                            
                            
                            void myGenieEventHandler(void)
                            {
                            
                              genieFrame Event;
                              genie.DequeueEvent(&Event);  //Remove the next queued event from the buffer and process it below
                            
                              
                            }

                            Comment


                            • #15
                              Hi again VooMan.

                              I checked and fixed what might be the cause of the error of your code.
                              Based on what I observed, the following are the reasons why it didn’t work:
                              • Calling the function in the library with different parameters.
                              • Improper implementation of non-blocking delay
                              • Not declaring variables in Global if intended to be used in different functions

                              Below is the modified version of your code.

                              Note: Kindly read the comments in the code to be guided.

                              Code:
                              #include <genieArduino.h>
                              #include <EEPROM.h>
                              #include "OmniGaugeV8Const.h" //Header file holding names of all the Visi Genie objects
                               
                              Genie genie;                               // initialise genie
                              #define RESETLINE 4
                              genieFrame Event;                       / must be declared globally since it is used in multiple functions
                               
                              int MAPSensorPin = A0;       //MAP input pin
                              int WBAFRSensorPin = A1;     //Wideband AFR input pin
                              int OilPressSensorPin = A2;  //Oil Pressure input pin
                              int OilTempSensorPin = A3;   //Oil Temperature input pin
                               
                              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 = 0x00;  //Holds number of last active form
                              byte BoostDayColour = BoostGaugeWht; //Holds day colour of last active boost gauge
                              //byte BoostNightColour = ???;  //Holds night colour of last active boost gauge
                              //byte AFRDayColour = ???;  //Holds day colour of last active AFR gauge
                              //byte AFRNightColour = ???;  //Holds night colour of last active AFR gauge, and so forth
                              //byte OilPressDayColour = ???;
                              //byte OilPressNightColour = ???;
                              //byte OilTempDayColour = ???;
                              //byte OilTempNightColour = ???;
                               
                              int FormPromAddress = 0;  //eeprom address to store form number (first byte of eeprom)
                              int BoostDayPromAddress = 1;  //eeprom address to store Boost gauge colour (2nd byte of eeprom, and so on)
                              int BoostNightPromAddress = 2;
                              int AFRDayPromAddress = 3;
                              int AFRNightPromAddress = 4;
                              int OilPressDayPromAddress = 5;
                              int OilPressNightPromAddress = 6;
                              int OiltTempPromAddress = 7;
                              int OilTempPromAddress = 8;
                               
                              static long waitPeriod = 100;
                              static long prevTime;
                               
                              //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, int value)
                              {
                                genie.ReadObject(alias >> 8, alias & 0xFF);             // ReadObject only needs 2 paramaters - refer to genieArduino library
                              }
                               
                              bool ReportEvent(int alias)
                              {
                                return genie.EventIs(&Event, GENIE_REPORT_OBJ, alias >> 8, alias & 0xFF);
                              }
                               
                               
                              void setup()
                              {
                                Serial.begin (200000);  //Serial0 @ 200000
                                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 (3500);        //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()
                              {
                                genie.DoEvents();   //Genie events are received and queued here.
                               
                                if (millis() - prevTime >= waitPeriod)            // updating the value every 100ms ---> non-blocking delay
                                {
                                  BoostVal = ((3 * analogRead(MAPSensorPin)) / 1023 - 1);  // (max gauge number * reading) / resolution  - 1 [turns abs to gauge]
                                  prevTime = millis();
                                }
                              }
                               
                              void myGenieEventHandler(void)
                              {
                                genie.DequeueEvent(&Event);  //Remove the next queued event from the buffer and process it below
                               
                                // do something
                              }
                              Hope this will help.

                              Best regards,
                              Vince

                              Comment

                              Working...
                              X