Announcement

Collapse
No announcement yet.

Multiple Displays and Multiple Forms Using a Teensy 4.1 as Arduino

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

  • Multiple Displays and Multiple Forms Using a Teensy 4.1 as Arduino

    Hi so I have made some good progress on my project but would am stuck on exactly how I would code form changes using buttons on a 32DCT-CLB-AR correlating to specific forms on a 24D-CLB display which is going to be placed right above it and both are wired to the Teensy. I know it might involve using the WriteObject() function something like this display1/display2.WriteObject(GENIE_OBJ_FORM, 0x00, ) unsure of what to really put in the last parameter. Do you think that something like this would best be achieved using a form number array and essentially just indexing it whenever I click a certain button? Also I am a a bit confused on what to do within the 4DWS code as far as do I need to change event settings for something in order for it to correspond to commands to change forms from a different display? I'll attach everything I have here so far.

    Also, another question I have is if I have say an Internal LED Digits widget on the 24D-CLB and I want it to be just reading data that i write to it from some Arduino code and not from an input widget is that possible because I sit there thinking what is should assign as the event but I really just need the 24D-CLB to be reading what I send to it not necessarily things that are from an input widget more like serial data or just serial data that I've deconstructed on the Arduino side and simplified to send over to the display. Any questions just let me know!
    Attached Files

  • #2
    Hello,

    If you want to change forms from your arduino code, then yes you use the WriteObject command, pointing to the GENIE_OBJ_FORM object, writing the form index, and without any value as that field is not used for Form changes.

    display1.WriteObject(GENIE_OBJ_FORM, 1, 0); // Display 1 Form 1
    display1.WriteObject(GENIE_OBJ_FORM, 2, 0); // Display 1 Form 2
    display2.WriteObject(GENIE_OBJ_FORM, 5, 0); // Display 2 Form 5
    etc

    I would suggest you don't use Hex in case it trips you up as you get passed 9, due to hexadecimal going 0x0A, 0x0B, 0x0C etc too.

    You don't need any Event for form changes from the Arduino code. Events are for telling the Arduino when something happens on the display, such as a button push.
    However you have said you want it to happen on button pushes, so you could set up a Reported Message on the button, and then in your myGenieEventHandler capture that event for the button, and change the form from the handler.

    Or another way is have the button change the form for you, in the display, directly. You don't need to do this via the Arduino if you don't want. Just set the display event to be Form1Activate, etc, or whatever the form number it is you want it to change to that is present in your project. The Arduino wont know what form you are on, but that isn't necessarily a problem unless you are writing to objects that are only on the current form etc.

    Regarding the internal LED digit, again you don't need an Event on this as you are not sending from the display to the Arduino, you are wanting Arduino to display. So you simply write the data to the LED Digits object using the WriteIntLedDigits function. You can find all this in the readme of the genieArduno library on Github. https://github.com/4dsystems/ViSi-Genie-Arduino-Library

    display1.WriteIntLedDigits(0, 100); // Display 1 Internal LED Digits 0, Value of 100

    I hope that helps

    Regards
    James

    Comment


    • Riptor919
      Riptor919 commented
      Editing a comment
      Very helpful thank you!!

  • #3
    So if I am using two event handlers (as I should right?) for the two different displays, how should i set up the code as far as where I say change the form at this certain index button press? if I want to change the display2 form but I click a button on display 1 to do so, would that be within eventhandler1 (display1 handler) or eventhandler2 (display2 handler)? a bit confused by this and I just tried to code it and it failed to do anything on display2 (top screen)
    Attached Files
    Last edited by Riptor919; 15 July 2021, 06:37 AM.

    Comment


    • #4
      Originally posted by Riptor919 View Post
      So if I am using two event handlers (as I should right?) for the two different displays, how should i set up the code as far as where I say change the form at this certain index button press? if I want to change the display2 form but I click a button on display 1 to do so, would that be within eventhandler1 (display1 handler) or eventhandler2 (display2 handler)? a bit confused by this and I just tried to code it and it failed to do anything on display2 (top screen)
      Well the event handler is the function which handles the received data from a specific display. So if you push the button on display1, then you handle the code in display1's handler as that is what is triggered when you push the button on display1. Obviously display 2's handler wont be triggered if you push a button on display 1.

      Having a quick look at your code, the nested code you have doesn't look right.

      Code:
      if (Event.reportObject.index == 2)    // MAIN MENU -- FREQUENCY button -- Already includes a change of form to Form0 as Event
            {
              display2.WriteObject(GENIE_OBJ_FORM, 1, 0);
      
              if (Event.reportObject.index == 0)    // RESET Button on 4D Display
              {
                // RESET BOTH Digit Objects to all zeros
                Serial.println("RESETTING FREQUENCIES");
                ClearLedDigits0();
                ClearLedDigits1();
              }
      
            }
      if the index is 2, then its 2, it is never going to be 0 after being 2 (ie the code further nested in here, so that code will never execute).
      I assume you more intended to do this:

      Code:
            if (Event.reportObject.index == 0)    // RESET Button on 4D Display
            {
              // RESET BOTH Digit Objects to all zeros
              Serial.println("RESETTING FREQUENCIES");
              ClearLedDigits0();
              ClearLedDigits1();
            }
            if (Event.reportObject.index == 2)    // MAIN MENU -- FREQUENCY button -- Already includes a change of form to Form0 as Event
            {
              display2.WriteObject(GENIE_OBJ_FORM, 1, 0);
            }
      I'm not sure if you intended this or not, but you have display2 in your handler for display1, in all the cases, and then also display2 in display2's handler.

      Have a look anyway, and if you are still stuck, please send your full code for both displays, and your arduino ino again, and ill try and simulate it here myself.

      Regards
      James

      Comment


      • #5
        So i get what you are saying, but i wrote in my code is actually what i meant to do so here is my thought process: if the user clicks 4dButton2 it takes them to Form0 on the Bottom display which was done already within 4DWS program via Form0Activate on the events for that button (keyboard and the 2 buttons RESET and MAIN MENU), and form 1 on the top display (SET Frequency and SWAP Frequency) which i seem to only be able to do with code and not inherently on 4DWS since i would be trying to change the form of a different display and that is not inherent to the events tab for a Button only for the current display you are on right? So now we are within that nested if statement (display2 is the top display which i have changed to easier naming scheme in my updated code) and on the new form0 on the bottom display and form 1 for the top display right? so now if the user presses 4DButton0(which is only on form 0 of the bottom display/display1), then it will reset the ILedDigit widgets on the top display on form 1. So do you understand now what i am meaning to do i had a feeling the code was weird but i am not sure how to properly deal with the 2 displays in the correct way i guess. I will attach my updated code i have not really changed anything but the naming of the displays. Know that the Bottom display (BotDisplay) is the 32DCT-CLB-AR and the top display (TopDisplay) is the 24D-CLB which is not touch screen so i am basically wanting to just write to that one and control it using buttons on the lower display at the discretion of the user. If you need any clarification let me know and i will happily do so. Thanks again!! This diagram might help you understand what i am doing here!
        Attached Files
        Last edited by Riptor919; 17 July 2021, 04:58 AM.

        Comment


        • #6
          Sorry that was incredibly hard to understand, so no I don't follow you 100%.

          Regardless, when you do something on the display and a Reported Message is in the Event handler of a button etc, the Arduino code will jump to the myGenieEventHandler function for that display, check the event and exit the handler within milliseconds, it does not sit there and hang around. So if you are thinking it will do the index == 0 operation and then wait there and then do the index == 2 operation, then you are mistaken, that is not how it works.
          The code flows extremely fast and will loop around and around the main loop and only jump into the event handler 1 single time for 1 single event that happens from the display, and then it goes back to the main loop again, until another event happens and triggers the handler.

          I cannot see how the 4Dbutton index can be 2 and then 0 in the exact same event. That is not how it works. The nested code for 0 will never execute in my eyes. It will do the 2 code when you do 4Dbutton2, set the top display to form 1, and then quit the handler. Likewise for the same code you have in the bottom display handler. Even if you next time round trigger the 4Dbutton index of 2, it will never execute as you code is checking for 0, it can not reach the 2 code. Nested code here is not correct.

          If you change the form from the display, using ActivateFormX in the Event tab of WS4, then nothing happens in the Arduino myGenieEventHanlder code. If you want something to happen in the Arduino code then you need to put a reported Message even on the Form itself, so when the display changes the form to say Form2, then Form2 Reported Event will fire which you can capture in the event handler, telling the Arduino that the display has changed Form. This will only Fire if the display changes the form though (ie setting the ActivateFormX event and having the Form as Reported Message), it will not fire if you get the Arduino code to change the Form, as the Form Reported Message will not fire in that situation..

          You haven't sent your WS4 code, which I am guessing has changed, so its very hard to follow even with your docx file you attached.

          Anyway, I hope the above helps.

          Regards
          James
          James

          Comment


          • Riptor919
            Riptor919 commented
            Editing a comment
            thank you i will send an update with the ws4 file tomorrow sorry for the confusion

        • #7
          So i have tried coding a bit more like you said but the screens still don't change form properly. Maybe you can spot what's wrong with my code. I attached the report message to all of the forms in the 4DWS Program, and got rid of the nested if branches where it was inappropriate. I am still confused on when i should include something in the top display handler or bottom display handler? that doesn't make any sense to me so i just assumed the bottom display and blocked out most of the lower display code for the handler there
          Attached Files

          Comment


          • #8
            Hello.

            Ill try and explain it again.

            The handler in the Arduino, is to 'handle' events which come from the specific display it is for.
            You have 2 displays, Top Display, and Bottom Display.
            So any events that come from the Top Display, such as a touch to a 4D Button, would trigger the Top Displays handler in the arduino code, to trigger. You then 'handle' the event in the Handler, and do what is appropriate for that single event.

            So if you touch a button on Top Display, then your Top Display's handler then needs to decrypt the message that comes in, and do whatever is appropriate.
            If you touch something on the Bottom Display, then the Bottom Display's handler needs to handle it.
            Only the appropriate handler will fire depending on what display you triggered the event on.

            If you want the Top Display's button to make the Bottom display do something, then the Top Displays handler needs to have code which will cause the Bottom display to do something.

            I hope that is clear.

            I will have a look at your code now.
            James

            Comment


            • #9
              Hello again

              Just a few things to point out, some are minor but I wanted to mention them anyway.

              Code:
              Serial.begin(9600);  // Serial5 @ 9600 (9.6K) Baud -- starts a serial stream to BotDisplay
              The comment is wrong. This is for the Serial Monitor, nothing to do with the Bot Display, and its not Serial 5 as per the comment. Just to make this more readable.

              Code:
              // Attach the user function Event Handler for processing events to BotDisplay and TopDisplay
              BotDisplay.AttachEventHandler(myGenieEventHandlerBot);
              TopDisplay.AttachEventHandler(myGenieEventHandlerTop);
              The comment really should be
              Code:
              // Attach the user function Event Handler for processing events FROM BotDisplay and TopDisplay
              Events come from the display, which is what the Arduino handler is capturing and then handling. It is not for sending things to the display, it is for capturing things like touched buttons, sliders, etc, from the display.

              Code:
               // Write a string to the BotDisplay to show the version of the library used
              BotDisplay.WriteStr(0, GENIE_VERSION);
              TopDisplay.WriteStr(0, GENIE_VERSION);
              You are writing to String0 on both the Top Display and the Bottom Display, however I can not see any String object at all in your WS4 application. This is a big no-no. You can not write to something which does not exist as it can cause all sorts of problems. These lines need to be removed.

              Code:
               } else if (Event.reportObject.index == 11) { // FUEL TANKS -- TANK 2
              TopDisplay.WriteObject(GENIE_OBJ_FORM, 3, 0);
              
              } else if (Event.reportObject.index == 12) { // FUEL TANKS -- TANKS 3, AUX 1, and AUX 2
              TopDisplay.WriteObject(GENIE_OBJ_FORM, 4, 0);
              
              } else if (Event.reportObject.index == 13) { // FUEL TANKS -- TANKS 4 and 5
              TopDisplay.WriteObject(GENIE_OBJ_FORM, 5, 0);
              
              } else if (Event.reportObject.index == 15) { // FUEL TANKS -- FLOW 1
              TopDisplay.WriteObject(GENIE_OBJ_FORM, 6, 0);
              
              } else if (Event.reportObject.index == 16) { // FUEL TANKS -- FLOW 2
              TopDisplay.WriteObject(GENIE_OBJ_FORM, 7, 0);
              You are writing to Forms which don't exist. In the WS4 code you sent, it has Form0, Form1 and Form2, there is no Form3,4,5,6,7, so this could be causing problems if those buttons are pressed. I assume this is due to this still being developed, but you need to be careful you don't write to things which don't exist in the display.

              Looking at your buttons now.
              On Form0, you have 4DButton0, which has its event set to Reported Message. This looks fine, as you have corresponding code in your Arduino code to check for Button0's event, which resets frequencies or something like that.
              You then have 4DButton1, which is set to Form1Activate, so that will change to Form1 all by itself. That looks fine, you have no code in the Arduino (which wouldnt work anyway as you are not Reporting Message here), so that is fine.
              You have Form0 reporting a message too, but you have no code in your Arduino to check for this. It would only happen if there was a button set to Form0Activate anyway. You currently only capture events for GENIE_OBJ_4DBUTTON and GENIE_OBJ_KEYBOARD, nothing for GENIE_OBJ_FORM yet. Work in progress I assume.

              On Form1, you have 4DButton2, which is Reported Message, and you have Arduino code for it. This then changes both displays Forms. Bottom goes back to Form0 and Top goes to Form1. That should be fine.
              You then have 4DButton3 which does an Form2Activate, which is fine.
              4DButton4 (and 5, 6 and 7) does a Reported Message, but currently no code to handle this in Arduino.
              4DButton8 and 9 do nothing.
              Form1 also Reports a Message itself, but no code to handle this if it was to happen from a Form1Activate button directly.

              On Form2, you have 4DButtons10, 11, 12 and 13, all Reporting Messages, but changing to forms from your arduino code which dont exist in your WS4 application.
              4DButton14 does a Form1Activate, which is fine
              4DButton15 and 16 do the same as 10,11,12,13 above.
              Form2 has Reported Message set also, no code to handle it though.

              So what exactly is not working?
              You are missing lots of forms, so half the buttons wont do anything, and you have no code to check if a Form Change happened from the display directly.

              I haven't looked at the Keyboard stuff, given you have not mentioned that as being a problem.

              I will try and set up some hardware to try and simulate this here, but do both displays use the same Workshop4 application, or are they different?

              Regards
              James

              Comment


              • #10
                I totally forgot to include the other workshop file I'm sorry I was assuming they zipped together since I had them both open it will make more sense with this file as well. Each display is using a separate workshop file which I upload to an SD card and then place the proper one in each display. let me try working what you said into my code for a bit and get back to you
                Attached Files
                Last edited by Riptor919; 22 July 2021, 04:33 AM.

                Comment


                • #11
                  " you have no code to check if a Form Change happened from the display directly"

                  Could you give me a code example/snippet for this i am kind of confused on how to do this. Would i just have an if statement? And you said it can only occur if there is a button on screen which activates a specific form with FormXActivate or is it possible for it to work with report message? This doesn't seem doable if I am trying to change the top display form using buttons and forms of the bottom display. I am confused what is going on as far as when you set a form to report message what happens/ what can you do with that and why is it necessary? also I know you said that the code involved with 4DButton2 looked fine but it actually does not change the top display but the bottom display changes, (although its slower than the form activate method). Side question: is there a part number for the 5pin Female to female connector between the gen4-ib that is labeled with +5v, TX, TX, GND, RES as i can not find it anywhere besides in kits.
                  Attached Files
                  Last edited by Riptor919; 22 July 2021, 08:06 AM.

                  Comment


                  • #12
                    Hello again,

                    OK I will set up both displays and the Arduino and try and see what the problem is.

                    Regarding the form change.

                    Basically, if you get the Arduino to change the form of the display, then the display will not report back using 'Reported Message' on the Form object, when the page changes. This is intentional, as if the Arduino says to go to Form 1, then there is no point the display replying saying 'I am on form 1' as the Arduino would already know that given it told the display to change. Typically you would have a variable called Form or something in your project, so when the Arduino change the display form, you update the Form variable with the form number so you know what form that display is on.
                    So if you want the Reported Message of Form1 to work, you would use the Form1Activate from a button directly in WS4 on say Form0. That would then fire off the Reported Message to the Arduino when it changes to Form1, as the Arduino will not have known that happened as the display did the form change, not the Arduino. Because the Arduino is not setting the form (and you updating the Form variable), the only way the Arduino will know the page/form has changed is if you can get the display to tell it, which is where this comes in.

                    This really is only relevant though if you are wanting to track what form you are currently on, in your Arduino code. You are not doing this, so really this detail is not important to you at the moment.

                    But for completeness, to capture the Reported Message from the Form object, you would do this in the appropriate Handler.

                    You have this:
                    Code:
                    if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)
                    in your handler, which filters out when the event is about a 4D Button

                    And you have this:
                    Code:
                    else if (Event.reportObject.object == GENIE_OBJ_KEYBOARD)
                    in your handler, to filter out when the event is about the Keyboard

                    So you would add another one:
                    Code:
                    else if (Event.reportObject.object == GENIE_OBJ_FORM)
                    in your handler, to filter out when the event is about the Form

                    This is untested, but something like this likely would work:
                    Code:
                    else if (Event.reportObject.object == GENIE_OBJ_FORM)
                    {
                        if (Event.reportObject.index == 0) // If it's Form 0
                        {
                            Form = Event.reportObject.index; // Copy the index (ie the Form number) into a variable to use elsewhere in your code
                            Serial.print("Form ");
                            Serial.println(Event.reportObject.index);
                        }
                    }
                    You would then use the Form variable elsewhere in your code, to only write to things that are on that current form, for example. Can help speed the project up, rather than having led digits and gauges etc be updated by the Arduino all the time, you can change the code to only update when you are on a particular form, ie the form that widget is on.
                    In the cases that the Arduino is changing the Form, which is done using your 4DButtons at the moment, you would just update the Form variable there, you would need 1 for each display, to keep track of them.

                    I hope that is clear what I am trying to explain.

                    I will look at your code now. If I find a problem I will update it, and I will add this Form code in your program too so you can see what I am talking about.
                    James

                    Comment


                    • Riptor919
                      Riptor919 commented
                      Editing a comment
                      Thank you thank you! this is very helpful

                  • #13
                    So I have loaded this on to 2 display modules I had on hand, just changed your project to suit them, same resolution so easy change.
                    Noticed 1 display is set to use COM1 while the other is set to use COM0. So I assume you have set the COM1 version up to be wired like that to your Teensy ? This is the COM port out of the display, ie the 2 Diablo pins you have set COM1 to be, nothing to do with the Arduino. Just checking.
                    I set it to be COM0 for my set up as its easier.
                    Both are on 9600 baud as you had it.
                    I dont have a Teensy 4.1, so I am just using a old Arduino Mega1280.
                    Changed the Serial ports to be 2 and 3, instead of the 4 and 5 you had, as this Arduino only goes up to Serial3.
                    I also changed the Reset pins to be 6 and 7, just to suit how I connected them.
                    So really no changes over what you had.

                    I removed the 2 lines which I mentioned earlier, which print to Strings which don't exist.

                    I then ran the demo, and forms are changing correctly.

                    Made a very basic video, which you can see here.
                    Can you see any problems?

                    James

                    Comment


                    • #14
                      So that looks great!! I remember being told that i am not able to use COMM 0 since my computer hogs that space so I switched to using COMM 1 and a 4DUPA and yes i have GPIO1 = PA3 as the TX for the bottom display and GPIO10 = PA4 as the RX for the bottom display which correspond from the 4D UPA Schematic. Although now i am questioning whether or not that is set up properly. Do you think that the top display should be set to COMM1 instead of COMM0? I have the top display just connected through a gen4-IB which is connected straight to my Teensy I program the top display through a gen4-IB 4D programming cable combo while I program the bottom display with the 4d-UPA setup and a USB. Also weird thing: I notice that when I press the reset button on my Teensy that only the top display flashes and not the bottom display. Anyways I will work on this for a while an see if I can get it working like you have on your end. Do you think that i could just use 2 gen4-IB adapters instead of 1 and a 4d-UPA? I feel like that might be messing me up. I just triple checked all the connections though and i don't see anything wrong but even when i change the COMM nothing different occurs on the top display. Also do you think that i don't even really need a top display handler since it is not touch screen?
                      Last edited by Riptor919; 23 July 2021, 03:57 AM.

                      Comment


                      • #15
                        Actually I just got it to work haha I had two pins on my Teensy Switched in the wrong direction for the Tx and the Rx for the top display :,) I was so certain of the wiring but yeah it works!! I will be back soon with more questions! thank you again for your help thus far

                        Comment

                        Working...
                        X