No announcement yet.

Sending string text to MagicObject

  • Filter
  • Time
  • Show
Clear All
new posts

  • Sending string text to MagicObject


    MagicCode object works well from Test eXecutor when sending data to a MagicObject to update gauges and predefined string objects. How do I send a runtime dynamic string from eXecutor via MagicObject to a string object? Do I need one MagicObject to update predefined string objects and another for dynamic strings?

    I have to handle 30 string status fields, 8 of them are dynamic, from the host. I prefer to have a single MagicObject to multiplex string handling to minimize serial traffic. Everything is working great except for the 8 dynamic strings.

    Or am I missing something here using eXecutor?


  • #2
    Hi Scott,

    You can use a single Magic Object to display either a predefined or a dynamic string. You will need two things:

    1. A routine for handling the dynamic string received from the host.
    2. To display the received dynamic string "inside" Strings0 for example, you will need to know the font, the foreground and background colors, and the cursor position for Strings0. You will be responsible for "formatting" what is to be printed (ie, inserting new line characters to make sure that the text does not exceed the defined boundary for Strings0 etc). You will also be responsible for "erasing" what is already printed inside Strings0.

    For item 1:
    Please see the example project "FileAccess.4DGenie" in Workshop (File menu -> Samples -> ViSi Genie Magic (Picaso/Diablo)). The demo shows how a filename is extracted from the array which contains the bytes received from the serial port.

    For item 2:
    To know the font for a strings object, refer to section "5.2. Genie Magic useful Variables" of the ViSi-Genie reference manual.
    The foreground and background colors and the cursor position for a strings object are listed in the object inspector.
    Attached is an example project from a colleague that demonstrates the use of custom fonts with string objects.

    The attached project consists of 2 forms. The 1st form is to Set the desired Password and the 2nd form is to authenticate the input of the user to show if password entered is the same with the set password.
    I will try to post a working example of the application you described this week. I trust however that you can carry on ahead with the information above.

    Hope this helps and regards.

    Attached Files


    • #3
      Hi Doff,

      Thanks for the details and code. The code really got me started. It is working now.

      The problems were:

      It seemed intuitive that if I could send a number to an object, that a string would work the same. But I realized that the predefined strings are rendered and only the displayed file is called up by the string index. Probably why it is so fast.

      The undocumented hFonts[ ] function must have a matching hStrLocation[ ] type indexed array somewhere that we could use. Hard wired screen locations - or CONST's seem redundant and difficult to support for screen modifications - especially considering that the data structure must already exists.

      The Test eXecutor kept telling me the data sent to the MagicObject was wrong without saying why. It took a while to realize that the bytes had to be reversed when sent as bytes to a MagicObject - and sent in pairs to form a word using zero's when necessary for each pointer index (word location). I still have not located this in an App note or ref manual.

      The str_Printf command, of the 5 or 6 I tested, is the only print function I could get working. Some of the others had documentation that did not agree with the compiler. It is still obscure to me which works best for a particular situation. Most important, there is scant information on how to use these with MagicObjects.

      And still, the Genie code generator and ability to quickly add Magic Events and Objects got a display with 5 guages, 28 strings and 5 buttons with 55 dynamic menu options each, up and running in under a week with no prior 4D experience. Amazing. The Pro license was well worth the learning curve.

      Would like to have if available:

      Any code for converting seconds sent from the host to Hrs:Min:Sec ??
      Any array/code for referencing the string start locations??
      Any info - or the App Note you said you would work on - for using Host to Screen printing with Magic Objects?? I am content with all the coding except the prints to screen. I have it working, but I am not yet convinced it is the optimum



      • #4
        Hi Scott,

        The app notes for magic objects are still under construction or review. The ViSi-Genie Ref manual will be updated soon. But here are several additional info that may help you. Actually they have been added due to your inquiries.

        Click image for larger version

Name:	additionalCallableFunction.png
Views:	3
Size:	14.1 KB
ID:	44750

        Click image for larger version

Name:	usefulInternalVariablesArrays.png
Views:	1
Size:	52.1 KB
ID:	44752

        Attached is an example from another colleague. It demonstrates the use of the above.

        Attached Files


        • #5
          Hi Doff,

          Thanks for the new info and updates. I just tested the MagicFonts demo - works perfect. Much 'cleaner' coding than what I have now. Thanks, I am currently updating my dynamic string code and will let you know if I find any bug-a-boo's.

          Now a question on MagicEvents using a timer or such to trigger a call to a different function if the button is held down for at least say 2 seconds. This would call PowerDown, optional button functions, etc.

          With MagicEvent there is no apparent 'Button Up' event. It is probably simple yet I am not clear on how system timers interacts with MagicEvents. Any ideas??



          • #6
            Hi Doff,

            Hold the press! While rewriting my 80 odd WriteObject lines as PrintStrings, I made a blunder that led to an insight.

            It seemed just too simple to write:

            PrintString(strObjNum, "My literal string..", 1) ;

            without first formating font, foreground colour, xy location, etc. It made for quite an exotic yet unreadable display. And somehow I did not blow out the stack and lock up the display as with my earlier experiments with str_Printf, et al.

            So my question is this: could PrintStringF be used when by rare requirement one needed to output a string format differently (as foreground colour, for example) and use PrintString which always uses the pre-defined string formatting for the target string? This would save considerable coding for starters and still offer flexibility for the exceptions. This would make dynamic strings available with one command after defining and placing a string object on screen.

            I would gladly simplify my code again when this is available!

            Thanks in advance for your consideration of this,

            P.S. Where did you hide Find/Replace in the Genie Workshop?




            • #7
              >With MagicEvent there is no apparent 'Button Up' event.

              It is the same as events being sent to the host. Have a look at the UpDownRepeat example, it has the buttons set to momentary 'Both', this means the even will be called for both a presss and a release. The 'newval' passed to the event indicates whether it is a touch or a release.

              PrintStrings is a 'written' 4DGL function, you can find the source in C:\Program Files (x86)\4D Labs\4D Workshop 4 IDE\INCLUDE\CLPRINTSTRINGS.INC it sets up all the colors, boxes, positioning and other things required to print the object.

              str_printF() is an internal 4DGL function (hit F1 whilst the cursor is over it) it 'just' prints at the current position with the current colours, etc. So depending on what you had previously done (eg used PrintStrings to print "The value is ") using str_printF() might do exactly the right thing.

              >P.S. Where did you hide Find/Replace in the Genie Workshop?
              Oops, it's still the Genie Menu, no one had mentioned that before. We'll get that fixed. For the moment you can use the shortcut keys (^F, ^H, F3). Open a ViSi or Designer project to see all the missing buttons, hover over them to see the shortcut key.


              • #8
                Hi Mark,

                Thanks for clearing that up. That makes it simple to 'de-bounce' our hardware buttons (no touch screen will be used) by checking up/down button status each time around the loop. This prevents inadvertent multiple button presses - something I suspect is already handled by the touch screen button handler.

                Regarding the PrintStrings and stringinfo / Print methods described in the MagicFonts demo above:

                First, they work really well and eliminated a lot of my display code. And before I madly replace WriteObject(tStrings, ..., ...) with PrintStrings, I would ask if the WriteObject method is more processing efficient if I am only displaying a predefined string?

                And, is the dynamic string method using PrintStrings and stringinfo / Print add a significant overhead. These are updated about once a second and seem speedy enough.

                I have a stereo VU meter running constantly even while changing menus (user options). The host processor handles audio DSP functions and sends over VU updates about every 50 msec via Comm0 (testing now at 300kbaud). I anticipate adding more DSP requiring the Spectrum display meter soon. It would be customer unacceptable to have the meters freezing up while five pre-defined string objects update. These cover roughly 15 pix by 480 pix at the bottom of the screen. Whatever information is available on code/processing efficiency (haven't found much so far) would be greatly appreciated. If the Genie Pro environment compromises speed in these circumstances, can I export to Designer to optimize or modify the Genie Pro includes?

                Thanks for your assistance,


                • #9
                  WriteObject ends up calling PrintStrings, so calling PrintStrings directly is slightly faster.

                  PrintStrings does quite a bit more work than the bare minimum required to write a string to the screen, as it needs to 'redraw' the background of the entire 'strings' area. In reality this may not always be required, depending on how much work you do yourself and/or the 'size of what you are writing. For example

                  Edit C:\Program Files (x86)\4D Labs\4D Workshop 4 IDE\Include\ with a text editor.
                  Comment out lines 15 and 17, by adding // at the front
                  Change the word TRANSPARENT on line 28 to OPAQUE
                  Save this file.
                  Now rebuild your project.
                  The main side effect that you might/will see is that if you print "abcd" followed by "123" that the "d" will still be visible, so you will need to pad out your sent strings with blanks (and, depending on the font type, 'double' blanks) to ensure that the old string is erased.
                  There are other side effects that relate to background colours and/or images, which you may or may not see.


                  • #10
                    Hi, Mark

                    I have read on this forum about delays using TRANSPARENT and will remove it. Learned that from video production.

                    To solve the blanking of the old string, all but one of my strings are about 15 pix by 85 pix - really small. Only one RDS message string is screen width.

                    For simplicity, I have defined all 28 strings with the first string "0" as blank (\n). Thus it is simple for me to make five similar "page switch" actions by just selecting predefined string "0" for each string area I want to "disappear". All other predefined strings - or any dynamic string - sent to each of these 28 "fields" will cause the display "field" to reappear. Then, to erase the string before writing any dynamic string, I just use PrintStrings(myString, 0, 0) and the blank line erases everything. It seems speedy enough, even though reading pre-defined strings from SD card seems unnecessary.

                    So now I am studying how to move everything to the Flash pages. Maybe you have an example of how to do this with Genie Pro. If I am pushing Genie a little too hard, well, its because its so efficient for design - I just had to.

                    Here is the compiler data (Full Build/Load) from my program that maybe you could explain what part can be moved from SD to Flash:

                    Code size = 11548 bytes out of 32750 total -- See, still room for stuff
                    Aprox run RAM size = 7182 bytes out of 32768 total (Base:1054 Disk: 38 Strings:570 Img+Font_Controls:4624 Img_elements:896

                    Of course, this Flash idea could go right out the window if when the customer arrives for design review Tues. and asks for more graphics...



                    • #11

                      I have a simple question that has perplexed me, I would like to change the color of a Magic Object using code from my arduino. I have looked everywhere and have not found anything that will work.
                      Here is what I want to do:

                      if (Event.reportObject.index == 2)
                      genie.WriteObject(GENIE_MAGIC_OBJECT, 0, 1);

                      This would hopefully draw a circle of the desired color when a button is pressed via the Magic Object as follows:

                      func rMagicObject0(var action, var object, var newVal, var *ptr)

                      if (ptr[0])
                      gfx_CircleFilled(120,120,50,BLUE) ;
                      gfx_CircleFilled(120,120,50,BLACK) ;
                      serout(ACK) ; // send back an ACK to command, do this last, otherwise the master may send the next command first

                      Please don't refer me to section 6 of the Visi-Genie Reference Guide.

                      Thanks for your help,