This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3519: GUI Composer & buttons

Part Number: MSPM0G3519

Hi,

I can't figure out how the button widget works. I don't understand how I can get something in my microcontroller to change when the button gets clicked.

I am using the GUI Composer v3 template, with JSON type data exchange. 

Also, whichever component I check, when I right-clic and select component info, I get to a blank page with an error message.

Thanks in advance for your help,

Adrien

  • Hi Adrien,

    The GUI Composer button does not directly modify an MSPM0 variable when the application uses the JSON data model. The button must execute a JavaScript click handler, and that handler writes a value to a JSON-model binding. GUI Composer then transmits the JSON field over the configured UART/USB transport, and the MSPM0 firmware must parse the received field and perform the requested action.

    For example, assign the button an ID such as commandButton, create a writable JSON field such as buttonCommand, and add the following to the application JavaScript file:

    GcWidget.querySelector('#commandButton').then((button) => {
        button.addEventListener('click', () => {
            const command =
                bindingRegistry.getBinding('buttonCommand');
    
            command.setValue(1);
        });
    });

    Use the exact binding name shown in your project’s Bindings panel. GUI Composer v3 supports registering the button’s click event through GcWidget.querySelector(), and target/model values can then be written with the binding’s setValue() method.

    The transmitted data would normally contain a field similar to:

    {"buttonCommand":1}

    Your MSPM0 application must detect this field in its JSON receive handler and take the desired action:

    if (buttonCommandReceived)
    {
        buttonCommandReceived = false;
    
        /* Example action */
        DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
    }

    For a command that must register every button press, avoid repeatedly writing the same value because unchanged values may not always cause another transaction. A command counter is a reliable approach:

    let commandSequence = 0;
    
    GcWidget.querySelector('#commandButton').then((button) => {
        button.addEventListener('click', () => {
            commandSequence++;
    
            bindingRegistry
                .getBinding('buttonCommand')
                .setValue(commandSequence);
        });
    });

    Your MSPM0 application must detect this field in its JSON receive handler and take the desired action. If you need a persistent ON/OFF state instead of a momentary command, use a toggle button and bind its checked property to a Boolean JSON field. The blank aComponent Info pge is not expected and is separate from the MSPM0 or JSON communication. GUI Composer v3 component help should display the widget properties and supported events. Please try refreshing the GUI Composer application, clearing the browser cache, or opening it in a current Chrome or Edge private window. If it remains blank, please provide the GUI Composer version, browser version, screenshot of the error, and any browser-console error text so the GUI Composer tools team can investigate.

    Hope this helps!

    -Brian

  • Hi Brian,

    Thanks for the explanation, and my apologies for the delayed response (summer vacation).

    I have tried to copy the code in the index.js file, created the corresponding callback function in my code with a breakpoint and a dummy variable, however I never stop at the breakpoint, nor does the dummy variable ever change.

    I suspect there is something I missed in the "create a writable JSON field" action you mentionned : should I also manually edit the index.json file ?

    Thanks in advance for your help

    Best regards,

    Adrien

  • Hi Adrien, no worries, everyone deserves a summer break!

    Hi Adrien,

    You should not need to edit `index.json` manually. GUI Composer generates that file when you configure the button’s data binding.

    For a `gc-widget-button`, the simplest approach is:

    1. Select the button in GUI Composer.
    2. Open its data-binding settings.
    3. Bind the button’s `bindableTrigger` property to:
      `widget.streaming.buttonCommand`

    The `bindableTrigger` value increments each time the button is clicked, so no additional JavaScript should be required. After saving, GUI Composer should generate a binding similar to:


    {
    "widgetId": "commandButton",
    "serverBindName": "widget.streaming.buttonCommand",
    "propertyName": "bindableTrigger"
    }

    On the MSPM0 side, make sure buttonCommand is registered in the receive-command table:

    static volatile bool buttonCommandReceived = false;

    static void callback_buttonCommand(char *string)
    {
    (void) GUIComm_ReadUInt32(string);
    buttonCommandReceived = true;
    }

    const tGUI_RxCmd GUI_RXCommands[] = {
    /* Existing commands */
    {"buttonCommand", callback_buttonCommand},
    };

    The complete table must then be passed to GUI_InitRxCmd():


    GUI_InitRxCmd(&GUI_RXCommands[0], sizeof(GUI_RXCommands) / sizeof(GUI_RXCommands[0]));

    The command name is case-sensitive and must be buttonCommand in both GUI Composer and the firmware.

    My earlier JavaScript example omitted the full model name. If JavaScript is used, the binding would be:

    bindingRegistry.getBinding('widget.streaming.buttonCommand');

    However, binding `bindableTrigger` directly is simpler and avoids the JavaScript entirely.

    If the callback still does not execute, please verify that:

    - The active connection configuration includes JSON and streaming, such as `usb+cr+json+streaming`.
    - The UART port and baud rate are correct.
    - `buttonCommand` is included in `GUI_RXCommands`.
    - `GUI_InitRxCmd()` is called after the entire command table has been defined.

    These provide some additional details for your reference:

    [1] https://dev.ti.com/gc/v2/help/GC_UserGuide_v2/uart_v3.html

    [2] https://dev.ti.com/gallery/view/TIMSPGC/MSPM0_SimpleGUI_JSON/ver/1.0.0/

  • Hi Brian,

    I'm sorry, I don't what's going on onmy end, but something seems to be wrong...

    First, I should say that I don't have issues exchanging data in general between the gui composer and the MCU. In the capture below, left column are data sent to the MCU, right column are data coming from the MCU. I can watch the data transfer both ways directly in CCS in debug mode. so the issue is only with the button ("apply desired settings" in the screenshot). data transfert both ways with boolean (switches) and floats / iq is operational

    However, when I open the button properties, there is no "bindable trigger" property. Here, I set the required property to "tooltip", which is obviously wrong, but I can't figure out where to set it properly. 

    all the appropriate callback functions and parameters are set in the code, now I "just" need to figure out how to actually send the data when pressing the button.

    Thanks in advance for your help,

    Adrien

  • Hi Adrien,

    You did not miss anything—bindableTrigger is not exposed for this GCv3 button. My previous guidance was incorrect. Remove the tooltip binding; it only changes the hover text.

    Add this once to index.gui:

    <script type="module" src="./index.js"></script>

    Use this in index.js:

    import { GcWidget } from './components/@ti/gc-widget-base/lib/GcWidget';
    import { bindingRegistry } from './components/@ti/gc-core-databind/lib/CoreDatabind';
    
    let sequence = 0;
    
    async function init() {
        await bindingRegistry.waitForModelReady('streaming');
    
        const button =
            await GcWidget.querySelector('#button_apply_basic');
        const command =
            bindingRegistry.getBinding('streaming.button_set_basic');
    
        button.addEventListener('click', () => {
            command.setValue(++sequence);
        });
    }
    
    document.addEventListener('DOMContentLoaded', init);

    Each click sends a new value for button_set_basic (1, 2, 3, etc.), ensuring the MSPM0 callback runs every time. Use the exact case-sensitive name in GUI_RXCommands. You do not need to edit index.json. Let me know if this works.

    -Brian

**Attention** This is a public forum