No announcement yet.

Storing the last form opened + Controlling brightness via Arduino

  • Filter
  • Time
  • Show
Clear All
new posts

  • Storing the last form opened + Controlling brightness via Arduino

    Hi, all. I have a couple of questions

    I'm making a multi-gauge using a 50DT screen and Arduino adaptor. I've found that in the Visi IDE you can choose which Form your screen displays first when it starts up, but I'd like to know if it's possible to make the screen start up displaying the Form that it was displaying when it was last shut down. So for example, if it's displaying Form 4 when I switch off the screen, when I switch it back on, the display immediately starts at Form 4.

    Also, I'd like to set the brightness via an input pin on the Arduino. So, when the input pin is high, the screen brightness changes to a preset level. And when the pin is low, the display brightness changes to a different preset. Is this possible, if so how?

    Thanks in advance

  • #2
    Hello VooMan,

    There are lots ways on saving the last state of the display. One is to use the Arduino to check the last form before shutting down and then storing it in a non-volatile storage (EEPROM, etc.) and then at the next boot read this file and move the display back to that recent form. Another way is if you are using Workshop4 pro edition, you could write some magic codes for storing the last state of the display on its uSD card and then at start up will read this info and move to the recent form.

    Display contrast can be changed by using the genie code for write contrast.

    void ScreenContrast() {
      if (digitalRead(4) == HIGH) {
        genie.WriteContrast(15);    // Maximum contrast
      else {
        genie.WriteContrast(0);     // Lowest Contrast
    I hope this helps,


    • #3
      Hi. Thanks for the info.

      Display contrast: perfect, thanks!

      Storing last form: I like the idea of storing the state on uSD just because I don't need to add any more components to do it. Is there tutorial pdf for magic codes. I've never heard of them!


      • #4

        Magic Code is an addition that is available with the Pro licensed version of Workshop 4, It allows you to add snippets of code to a Visi-Genie program to extend it's capabilities. This appnote may help

        Using your attached Arduino wouldn't need any more components added, just a few lines of additional code and the EEPROM library. The latest version of the EEPROM library will just update the value stored in the EEPROM if it has changed.

        While your code is running it would be as simple as when you send the command to change the form you would write that number in the EEPROM.

        When you power up you would check the value in EEPROM and then show the form of that value.

        I hope this helps

        Best regards



        • #5
          Thanks again. I'm reading up on the EEPROM Library right now.

          One final question! :D

          If I wanted to allow users to change the colour schemes of the gauges by selecting them through a menu system on-screen, is there a way of coding this (eg. "if button selection is Purple, make angulameter0 TicksColor purple). Or would the only way be to make the same gauge in multiple colours on different forms?


          • #6
            Hello VooMan,

            Changing the color of the ticks during runtime is not possible, you will need to create the same gauges with different colors on different forms as what you are planning to do.

            Best regards,


            • #7
              You could also stack them on the same form but you will have to call and update the values of the needed gauge with your preferred color during runtime and when changing form.


              • #8
                Originally posted by Jerson View Post
                You could also stack them on the same form but you will have to call and update the values of the needed gauge with your preferred color during runtime and when changing form.
                That sounds like that might be better rather making a form for every colour of every gauge I want to add! I wouldn't have a clue how to do this though! Are you able to explain further, or perhaps suggest some help files to read that will show me?



                • #9
                  Hello VooMan,

                  On one form you should stack the same gauge with different colours with the same dimension and location, just remember what the colour each gauge has. On the Arduino side, to change colour you just have to update the particular gauge object with the needed colour, for instance:

                  Default colour is with gauge0
                  Alternative colour is with gauge1

                  When doing the colour change, you should just change the index of the gauge to be called by the genie write object function and update the needle value as well.

                  genie.WriteObject(GENIE_OBJ_COOL_GAUGE, index, value);

                  For Default colour, index is 0
                  For Alternative colour, index is 1

                  I hope this helps.

                  Best regards,


                  • #10
                    Thanks, Jerson. That's really helpful

                    So I've been reading up some more and I've now found how to navigate to a new form using the Arduino. Now I have rough idea of what needs to happen:

                    >When a form is activated via the touch screen, have the form send a message (On Activate -> Send Message)
                    >read the message with the Arduino (somehow!) and Update EEPROM with the number of the activated form
                    >Next time screen and Arduino are switched on, Read EEPROM and use the stored number to navigate to the correct form (Genie.WriteObject (GENIE_OBJ_FORM, etc...)

                    Is this correct? If so , how do I read the message from the activated form into the Arduino?
                    Last edited by VooMan; 23rd March 2018, 12:10 PM.


                    • #11
                      Hello VooMan,

                      You can read what any object through the Read Object function
                      genie.ReadObject(GENIE_OBJ_FORM, 0); // This will read what form is active
                      In the ViSi-genie event handler you should also add a report object handler for handling the report coming from the display

                      if (Event.reportObject.cmd == GENIE_REPORT_OBJ) {  
                        if (Event.reportObject.object == GENIE_OBJ_FORM) {      // If object report is from a Form
                             Form_Number = Event.reportObject.index                     // Receive form number here


                      • #12
                        Hi. I've been trying to get the Arduino to read and write Form numbers, but failed so far. By permanently changing "FormNumber" to "1" I know that my syntax to change forms is correct. I just can't work out how to write the number to the eeprom and read it back again. Can you see what I'm doing wrong here?

                        #include <genieArduino.h>
                        #include <EEPROM.h>
                        // Voltmeter Demo
                        // 4D Systems
                        // This Demo communicates with a 4D Systems Display, configured with ViSi-Genie.
                        // The display has an angular meter, a LED digits, a rocker switch, and a static text.
                        // The program sends digital voltage readings to the LED digits and angular meter of the display module.
                        // The digital voltage readings are derived from pin A0 using ADC.Analog input voltage range is 0 to 5 volts only.
                        // The rocker switch of the display module is used for "turning on" the application.
                        // First, the program reads from the rocker switch manually using the Read Object function.
                        // If the rocker switch is on, the computed digital voltage readings are sent to the angular meter and LED digits.
                        // If the rocker switch is off, the angular meter and LED digits are made to display zero volts.
                        // This appication comes with a documentation: 4D-AN-P4019-ViSi-Genie A Simple Digital Voltmeter Application using an Arduino Host
                        // Download it here:
                        NOTE: Some Arduino boards such as the Due operate at 3.3 volts and tolerate analog input voltage levels from ground up to 3.3 V only. 
                        Applying more than 3.3 V may damage the chip. If attempting to use 3.3V Arduino boards for this application, make sure to limit the 
                        analog input voltage to 3.3 volts only and please read carefully your board’s datasheet. 
                        int flag = 0;        //holds the "power status" of the voltmeter. flag = 0 means voltmeter is "off", flag = 1 means the voltmeter is "on".
                        int sensorPin = A0;  //the wiper of the trimmer potentiometer is connected to pin A0
                        int voltMeter;       //holds the digital voltage value to be sent to the angular meter
                        int voltLED;         //holds the digital voltage value to be sent to the LED digits
                        byte FormNumber;      //Holds number of last active form
                        int eepromAddress;  //read eeprom from address 0 (first byte)
                        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
                          // Reset the Display (change D4 to D2 if you have original 4D Arduino Adaptor)
                          // 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
                          digitalWrite(RESETLINE, 0);  // unReset the Display via D4
                          delay (3500);        //let the display start up
                          //Change active form to number stored in eeprom 
                          FormNumber =;
                          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) 
                            if(flag == 1){                                                
                              voltLED = ((5.0 * analogRead(sensorPin) * 1000.0) / 1023);
                              genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0x00, voltLED);      //write to Leddigits0 the value of voltLED 
                              voltMeter = voltLED/100;
                              genie.WriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, voltMeter); //write to Angularmeter0 the value of voltMeter     
                            else if(flag == 0){
                              genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 0); 
                              genie.WriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, 0);
                            // Do a manual read from Rockerswitch0.    The results of this call will    
                            // be available to myGenieEventHandler() after the display has responded
                            genie.ReadObject(GENIE_OBJ_ROCKERSW, 0x00);
                            waitPeriod = millis() + 50; // rerun this code to update Cool Gauge and Slider in another 50ms time.
                          genie.ReadObject(GENIE_OBJ_FORM, 0); // This will read what form is active
                        // 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) 
                          int rockersw_val;          //holds the status of Rockerswitch0
                          genieFrame Event;    
                          genie.DequeueEvent(&Event); // Remove the next queued event from the buffer, and process it below
                          //Evaluate the event
                          if (genie.EventIs(&Event, GENIE_REPORT_OBJ, GENIE_OBJ_ROCKERSW, 0x00)){ //if the event is a REPORT_OBJ from Rockerswitch0
                            rockersw_val = genie.GetEventData(&Event);  //extract the MSB and LSB values and pass them to rockersw_val
                            if (rockersw_val == 0)                     //if Rockerswitch0 is off
                              flag = 0;                                //"turn off" the voltmeter
                            else if (rockersw_val == 1)                //if Rockerswitch0 is on
                              flag = 1;                                //"turn on" the voltmeter
                          //Event handler for storing the current form
                          /*if (Event.reportObject.cmd == GENIE_REPORT_OBJ) 
                              if (Event.reportObject.object == GENIE_OBJ_FORM) {      // If object report is from a Form
                                FormNumber = Event.reportObject.index;                     // Receive form number here
                                EEPROM.update(eepromAddress, FormNumber);
                            if (genie.EventIs(&Event, GENIE_REPORT_OBJ, GENIE_OBJ_FORM, 0x00))  //If event is an object report from a form
                                  FormNumber = Event.reportObject.index;                       //Store form number here
                                  EEPROM.update(eepromAddress, FormNumber);


                        • #13
                          why are you reading the index? of course its wrong use geteventdata to get the form #



                          • #14
                            Originally posted by tonton81 View Post
                            why are you reading the index? of course its wrong use geteventdata to get the form #

                            I got it from two posts above!

                            if (Event.reportObject.cmd == GENIE_REPORT_OBJ) {
                            if (Event.reportObject.object == GENIE_OBJ_FORM) { // If object report is from a Form
                            Form_Number = Event.reportObject.index // Receive form number here

                            So you say that "form_number = Event.reportObject.index" is incorrect? Sorry, I don't know how to use "geteventdata". What's the exact syntax to use it? Cheers
                            Last edited by VooMan; 5th April 2018, 09:08 PM.


                            • #15

                              genie.GetEventData(&Event); if you call that in the handler you will get the value


                              Form_Number = genie.GetEventData(&Event);