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.
Hello,
I'm building an application in GUI composer that works with an MSP430 processor. I have been successful with implementing some of the functionality via binding of numeric fields to global variables in my MSP code. I am having some difficulties using the same method to pass strings.
Basically, I want to have a text field and a button. When I click the button I want the string in the text box to be loaded to a char array in my MSP code. Any ideas on how I can achieve that?
Yarden,
I don't recall when executing a DSS script from an action is implemented, I think it is CCSv6. This method is no as trivial as binding the text box to an array of char.
I don't think binding to an array of char for writing to the target is implemented yet. I have filed a CQ request for bi-directional binding. See SDSCM00049786.
Now, to implement a DSS scripting binding with a button. You need to create a text box, give it an id 'textBox'. Create a dsScript.js file and place it in the project. Add this snippet to the dsScript.js file.
importPackage(Packages.com.ti.ccstudio.scripting.environment)
function update(value) {
var debugServer = ScriptingEnvironment.instance().getServer("DebugServer.1");
var session = debugServer.openSession("*", "*");
for (var i = 0; i < value.length; ++i) {
session.expression.evaluate('test[' + i + '] = \'' + value[i] + '\'');
}
}
For the button that you want to perform a target write, add this line to the onclick event handler of the widget: TI.DSS('update', dijit.byId('textBox').value)
Regards,
Patrick
Hi Patrick,
Thanks for the response. I'd like to try your solution, but I have a few questions about it:
1) I didn't quite understand what you meant in the first sentence. Are you not sure if this solution would work on CCS version before v6? I am running CCSv5.5 at the moment, so if it won't work am I expected to see some error pop-up or something?
2) Am I supposed to bind the text box to a char array in my code?
3) Is there a way to run the javascript code line by line or place breakpoints and see the variables while the app is running?
Hi Yarden,
Re 1) Action binding is supported in v6. What I meant is that I don't know if v5.5 has this feature or not.
Re 2) If you want to see the String from the target, you need one text box that binds to the array. And another text box that doesn't bind to any target variable, this text box will be use to send the String to the target when the user press a button.
Re 3) You can debug the javascript code that is running in the browser. But not the code that is running inside DSS. To debug the browser side code, you can use an external chrome browser and enter localhost:4242 (CCSv5.x) and localhost:8888 (CCSv6 beta).
Regards,
Patrick
Hi again Patrick,
One last question. Suppose my char array is named strSN in my MSP code. Where would that variable name appear in the GUI project? In the javascript snippet?
In the snippet that I sent in my first post. i.e replace test with strSN in the session.expression.evaluate() function call. And bind it to the text box that you use to display the string.
Patrick
Patrick,
I tried integrating the code and the settings in CCSv5.5 and it did not work. I tried it in CCSv6 and it doesn't work.
I'm looking for a way to see what exactly isn't working, so I simplified it a bit.
My code:
...
int test = 5;
while(1);
...
dsScript.js is:
importPackage(Packages.com.ti.ccstudio.scripting.environment);
function update(value) {
var debugServer = ScriptingEnvironment.instance().getServer("DebugServer.1");
var session = debugServer.openSession("*", "*");
for (var i = 0; i < value.length; ++i) {
session.expression.evaluate('test = 9');
}
}
The text box id is textBox and the onclick event handler for the button is TI.DSS('update', dijit.byId('textBox').value).
When I click the button the value in test does not change to 9.
Can you think of a specific setting that I need to set for this to work? For example I thought setting optimization to off makes sense.
Do you have any other thoughts?
Yarden
----------------------- update ---------------------------------------
I tried running each line of the script in the scripting console separately and that writes 9 into test. It seems to me that the onclick event is not running the update function.
Hi Yarden,
Can you copy and paste the html file snippet for the button widget here? To test whether the button onclick event handler is hit or not, you can replace the TI.DSS line with alert('I am hit') to opens an message dialog.
Regards,
Patrick
Hi Patrick,
The message dialog works.
Here is the HTML code with the DSS onclick event:
<!DOCTYPE html>
<html>
<!-- Do not remove or modify this line --><head data-gc-version="1.5.201403071400">
<meta charset="utf-8"/>
<title>Untitled</title>
<script type="text/javascript" src="lib/davinci.dojo_1_8/WebContent/dojo/dojo/dojo.js" data-dojo-config="'parseOnLoad':true,'async':true,'packages':[{'name':'gc','location':'../../../../davinci.gc_1_5/WebContent/gc'},{'name':'maqetta','location':'../../../../davinci.gc_1_5/WebContent/maqetta'}]"></script>
<script type="text/javascript">
require([
"dijit/dijit",
"dojo/parser",
"maqetta/space",
"maqetta/AppStates",
"dijit/form/Button",
"dijit/form/TextBox"
]);
</script>
<style>@import "lib/davinci.dojo_1_8/WebContent/maqetta/themes/claro/document.css";@import "lib/davinci.dojo_1_8/WebContent/maqetta/themes/claro/claro.css";@import "app.css";
</style>
<script type="text/javascript" src="app.js"></script>
</head>
<body data-maq-flow-layout="false" data-maq-comptype="desktop" class="claro" data-maq-ws="collapse" id="myapp" data-maq-appstates="{}">
<input type="button" data-dojo-type="dijit.form.Button" intermediateChanges="false" label="Send" iconClass="dijitNoIcon" style="position: absolute; z-index: 900; left: 382px; top: 29.001524925231934px;" onclick="TI.DSS('update', dijit.byId('textBox').value)"></input>
<input type="text" data-dojo-type="dijit.form.TextBox" id="textBox" intermediateChanges="false" trim="false" uppercase="false" lowercase="false" propercase="false" selectOnClick="false" style="position: absolute; z-index: 900; width: 52.109375px; left: 314.01410007476807px; top: 33.217225074768066px;"></input>
</body>
</html>
OK. That means something is not right in the dsScript.js file, it could be the update function is not call or the there is an issue in the script within this function.
Can you try these
1. Do a simple expression evaluation and write to an integer variable and see if this variable is updated in the expressions view. If this works, then there must be something wrong with your script.
2. You can attach a chrome debugger to debug the GUI app (in preview mode). Enter localhost:8888 (CCSv6) or localhost:4242 (CCSv5) in your chrome browser. Once the chrome debugger is ready, switch to the Sources tab and navigate to this node. 127.0.0.0.1:7272/gc/maqetta_preview/<app name>/lib/davinci_gc_1.x/WebContent/gc/backplane/guiComposer.js. Open this file, make sure that there is a TI.DSS defined in this file. It should be around line 1521. You can even set a breakpoint here and see if it get hit when you press the button.
P.S we have remove the debug port number in new CCSv6 beta, so if you can't attach chrome. You need to manually enable it in the com.ti.chromium.browser plugin under <install dir>\ccsv6\eclipse\plugins folder. The .default_settings has a port number property that you can configure. You can use winzip or equivalent application to open the jar file.
If things still not working for you. We can have a webex session, I can take a look at your setup and see why you can't write to the string array.
Regards,
Patrick
Hi Patrick,
I think we're making some advancements. I loaded the chrome debugger and couldn't find the path that you mentioned. I was able to reach
127.0.01:7272/gc/maqetta_preview/StrTest/lib/davinci.gc_1_5/WebContent/maqetta
There were no other "folders" under lib but davinci.gc_1_5/WebContent/maqetta.
In addition, under 127.0.01:7272/gc/maqetta_preview/StrTest/lib/ I found the project files, but I couldn't see the dsScript.js file that I added. I tried copying the code from it to app.js and the chrome debugger reported an error in the line importPackage(Packages.com.ti.ccstudio.scripting.environment):
"Uncaught ReferenceError: Packeges is not defined".
I tried removing the line, but still the guiComposer.js file is not reachable.
Yarden
Hi Yarden,
There should be a gc/backplane folder under the WebContent folder. Otherwise, no server binding will work. Maybe try refreshing the chrome debugger once you have attached (F5).
dsScript.js is a DSS script and can only be execute in the DSS scripting environment. Where as app.js will be execute in the browser environment.
P.S I'll be away for a week starting tomorrow. If we can't resolve this issue today, I'll ask one of my colleague to follow up on this thread.
Regards,
Patrick
Patrick,
I did a little test and tried the debugger in while CCSv5.5 was running. I was able to reach guiComposer.js, but that version has about 1200 lines (davinci_gc_1_2_...) and doesn't have anything with dss. Still, in CCSV6 I can't see that file in the debugger, although the file does exist on my harddrive (the version is davinci_gc_1_5_...).
Could there be a problem having 2 versions of CCS installed on my PC?
Yarden
Are you using a CCSv5 project in CCSv6? There is a path dependency for the GC library. If you look in the hmlt file, the path is right at the top. Try creating a new project in CCSv6 from scratch to have a clean setup.
Patrick
Hi Patrick, or whoever else is reading :),
After a bit of thinking, I've decided that I would like to have the GUI compiled in CCSv5.5 since I will be using the app at another PC with GUI composer runtime, which is v5.5 right now (if I'm not mistaken). Since dss is a bit of a problem with v5.5, I have an idea how to avoid the dss. Since the text I would like to write is limited to about 20 chars I thought that maybe I could have 20 different hidden controls on my GUI that would bind to 20 different char variables in my code. Maybe I can break down the string char by char and send each char to a different control (let say textbox) and that would automatically update the variable via binding.
In this case, how can I update a control with an ID that I set? I tried dijit.byId('textBox2').value = "7"; and it doesn't seem to update the field. Is there maybe a setValue function to this control? Where can I see the API?
Yarden
GUI Composer 5.5 and up has a feature “GUI Vars”. You can see it at the left side of the GUI Composer window below “pallet” and “outline”. It lets you listen to target variable changes and perform any action you want – in your case – update a widget. Using it will save you the trouble from adding 20 hidden widgets.
You can see in the JSON file instead of binding target variables to widgets I am binding them to GUIVars. Any change in the target variable will be stored in the corresponding GUIVar and the property change function "onAnyCharChanged" will be called.
Here is my target code, HTML, JSON and js files. It works in CCS 5.5:
main.c
--------------------------------------------------------
#include <stdio.h>
char char00 = 'a';
char char01 = 'b';
char char02 = 'c';
char char03 = 'd';
void incChar( char* ch) {
(*ch) ++;
if( (*ch) > 'z') {
(*ch) = 'a';
}
}
void main(void) {
while( 1) {
incChar(&char00);
incChar(&char01);
incChar(&char02);
incChar(&char03);
}
}
----------------------------------
App.json
------------------------------------
{"widgetBindings": [
{
"propertyName": "char00",
"serverBindName": "char00",
"widgetId": "prop",
"options": {
"onPropertyChanged": "onAnyCharChanged",
"dataType": "String"
}
},
{
"propertyName": "char01",
"serverBindName": "char01",
"widgetId": "prop",
"options": {
"onPropertyChanged": "onAnyCharChanged",
"dataType": "String"
}
},
{
"propertyName": "char02",
"serverBindName": "char02",
"widgetId": "prop",
"options": {
"onPropertyChanged": "onAnyCharChanged",
"dataType": "String"
}
},
{
"propertyName": "char03",
"serverBindName": "char03",
"widgetId": "prop",
"options": {
"onPropertyChanged": "onAnyCharChanged",
"dataType": "String"
}
}
]}
--------------------------------
App.html
---------------------------------
<!DOCTYPE html>
<html>
<head data-gc-version="1.2.201308270800">
<meta charset="utf-8"/>
<title>Untitled</title>
<script type="text/javascript" src="lib/davinci.dojo_1_8/WebContent/dojo/dojo/dojo.js" data-dojo-config="'parseOnLoad':true,'async':true,'packages':[{'name':'gc','location':'../../../../davinci.gc_1_2/WebContent/gc'},{'name':'maqetta','location':'../../../../davinci.gc_1_2/WebContent/maqetta'}]"></script>
<script type="text/javascript">
require([
"dijit/dijit",
"dojo/parser",
"maqetta/space",
"maqetta/AppStates",
"gc/dijit/TextBox"
]);
</script>
<style>@import "lib/davinci.dojo_1_8/WebContent/maqetta/themes/claro/document.css";@import "lib/davinci.dojo_1_8/WebContent/maqetta/themes/claro/claro.css";@import "lib/davinci.dojo_1_8/WebContent/dojo/dojo/resources/dojo.css";@import "lib/davinci.gc_1_2/WebContent/gc/dijit/libs/css/widgets.css";
</style>
<script type="text/javascript" src="lib/davinci.gc_1_2/WebContent/gc/backplane/guiComposer.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body class="claro" data-maq-flow-layout="false" data-maq-ws="collapse" id="myapp" data-maq-appstates="{}">
<input id="widget_text" type="text" data-dojo-type="gc.dijit.TextBox" intermediateChanges="false" trim="false" uppercase="false" lowercase="false" propercase="false" selectOnClick="false" visible="true" style="position: absolute; z-index: 900; left: 108px; top: 52px;"></input>
</body>
</html>
------------------------------
App.js
------------------------------
/*
* This file is provided for custom JavaScript logic that your HTML files might need.
* GUI Composer includes this JavaScript file by default within HTML pages authored in GUI Composer.
*/
require(["dojo/ready"], function(ready){
ready(function(){
// logic that requires that Dojo is fully initialized should go here
});
});
function toChar( i) {
return String.fromCharCode( i);
}
function onAnyCharChanged( propertyName, newValue, oldValue) {
var t = $TI.GUIVars;
var v0 = t.getValue('char00');
var v1 = t.getValue('char01');
var v2 = t.getValue('char02');
var v3 = t.getValue('char03');
dijit.byId('widget_text').set('value', toChar(v0) + toChar(v1) + toChar(v2) + toChar(v3));
}
Hello Yarden,
When I implement the solution for your request I want to make sure that when the value of the string is made longer it does scribbles on top of neighboring variables. To do that I need to make sure the string is defined as array with specific size instead of a pointer:
So if you have your string declared as char name[20] = "John Smith"; your users will be able to change the value. If you have the string declared as char* name = "John Smith"; the string won't be modifiable. For string allocated in the heap GUI Composer won’t know the allowed size of the array, so it won’t let the user modify the value.
Will this solution work for you?
Thanks
Dobrin