Part Number: LAUNCHXL-F28379D
Tool/software: Code Composer Studio
hello.
I tried to use the example "XDS_SaveVariableToFile" in gui composer V2, for logging data.
I have copied the program to my guide, I have modified the index by adding the two lines of code.
my variables that I want to logging are
new_B.Fcn_T1
new_B.Fcn_T2
the problem is that when I press save and after stop, it downloads the file "mydata1.txt" but it is always empty.
thank you.
///////////////////////////////////////////////////////// newfile_0.js /////////////////////////////////////////////////////
/*
* gc global variable provides access to GUI Composer infrastructure components and project information.
* For more information, please see the Working with Javascript guide in the online help.
*/
var gc = gc || {};
gc.services = gc.services || {};
// How to use ti-widget-streamsaver
// 1. Add <ti-widget-streamsaver> to gui file.
// Open index.gui and search ti-widget-streamsaver to see how to add it. There are 2 lines,
// <link rel="import" href="../ti-widget-streamsaver/ti-widget-streamsaver.html">
// <ti-widget-streamsaver id="ti_widget_streamsaver" class="_TI_"></ti-widget-streamsaver>
// 2. Add a js file and add the following code. The idea is,
// (a) use saveStart to create a stream writer,
// (b) then use saveData to write data, you can have repeated calls here, see saveDummyData.
// If you keep calling saveData, you will find the browser eventually says it is 'downloading' a file.
// (c) use saveStop to flush and close the data stream. You will the browser finished 'downloaded' the file.
// After this point, you can no longer write data to the stream writer.
// (d) In case you want to abort the stream writer, use saveAbort.
// After this point, you can no longer write data to the stream writer.
// [ Start of code
var mystream;
var mywriter;
//Text Encoder.
var myTextEnc = new TextEncoder();
// index.gui file contains: <ti-widget-button id="ti_widget_button" label="Save Start" button-type="default" raised visible tooltip="Create stream writer to start save" bindable-trigger="8" animated elevation="1" onclick="saveStart()" class="_TI_" title="Create stream writer to start save"></ti-widget-button>
// which triggers this function being called to create necessary stream objects to be able to stream/write data to a file.
var saveStart = function(filename) {
if (!filename) filename = 'mydata1.txt';
mystream = streamSaver.createWriteStream(filename);
mywriter = mystream.getWriter();
};
// index.gui file contains: <ti-widget-button id="ti_widget_button2" label="Save Stop" button-type="default" raised visible tooltip="Finish save. The stream writer is closed here" bindable-trigger="10" animated elevation="1" onclick="saveStop()" class="_TI_" title="Finish save. The stream writer is closed here"></ti-widget-button>
// which triggers this function being called to stop writing to a file and close the stream.
var saveStop = function() {
if (mywriter) {
mywriter.close();
mywriter = null;
}
};
// index.gui file contains: <ti-widget-button id="ti_widget_button3" label="Save Abort" button-type="default" raised visible tooltip="Abort the stream writer." bindable-trigger="7" animated elevation="1" onclick="saveAbort()" class="_TI_" title="Abort the stream writer."></ti-widget-button>
// which triggers this function being called to abort writing to a file.
var saveAbort = function() {
if (mywriter){
mywriter.abort('reason');
mywriter = null;
}
};
/*
* Boilerplate code for creating computed data bindings
*/
document.addEventListener('gc-databind-ready', function()
{
/*
* Add custom computed value databindings here, using the following method:
*
* function gc.databind.registry.bind(targetBinding, modelBinding, [getter], [setter]);
*
* param targetBinding - single binding string or expression, or array of binding strings for multi-way binding.
* param modelBinding - single binding string or expression, or array of binding strings for multi-way binding.
* param getter - (optional) - custom getter function for computing the targetBinding value(s) based on modelBinding value(s).
* param setter - (optional) - custom setter function for computing the modelBinding value(s) based on targetBinding value(s).
*/
// For example, a simple computed values based on simple expression
// gc.databind.registry.bind('widget.id.propertyName', "targetVariable == 1 ? 'binding is one' : 'binding is not one'");
// Or a custom two-way binding with custome getter and setter functions. (setter is optional) (getter only indicates one-way binding)
// gc.databind.registry.bind('widget.id.propertyName', "targetVariable", function(value) { return value*5/9 + 32; }, function(value) { (return value-32)*9/5; });
// Event 1 to n bindings
/*
gc.databind.registry.bind('widget.date.value',
// dependant bindings needed in order to compute the date, in name/value pairs.
{
weekday: 'widget.dayOfWeek.selectedText',
day: 'widget.dayOfMonth.value',
month: 'widget.month.selectedText',
year: 'widget.year.value'
},
// getter for date computation
function(values)
{
// compute and return the string value to bind to the widget with id 'date'
return values.weekday + ', ' + values.month + ' ' + values.day + ', ' + values.year;
}
);
*/
// Regular bindings on target variables are used to perform some data transformation on data. In this case we are using
// these bindings to add additional functionality to save data to a file rather than to do any data transformation, thus
// we are returning the same the same unmodified value
//
// This function is bound to blinkCounter global variable and saves it to a file that is configured when user clicks Start button and
// dropdown widget is set to save blinkCounter.
gc.databind.registry.bind('widget.ti_widget_textbox10.value',"new_B.Fcn_T1",
// getter for date computation
function(value)
{
if (templateObj.$.ti_widget_droplist.selectedValue == "new_B.Fcn_T1" && mywriter) {
var encodedData = myTextEnc.encode(value.toString() + '\n');
mywriter.write(encodedData);
}
// compute and return the string value to bind to the widget with id 'date'
return value;
}
);
// Regular bindings on target variables are used to perform some data transformation on data. In this case we are using
// these bindings to add additional functionality to save data to a file rather than to do any data transformation, thus
// we are returning the same the same unmodified value
//
// This function is bound to tablicaArray global variable, which is an array of 10 elements and saves it to a file that is configured when user clicks Start button and
// dropdown widget is set to save tablicaArray.
gc.databind.registry.bind('ti_widget_scalargraph3.series_0_values',"new_B.Fcn_T2",
// getter for date computation
function(value)
{
if (templateObj.$.ti_widget_droplist.selectedValue == "new_B.Fcn_T2" && mywriter) {
var encodedData = myTextEnc.encode(value.toString() + '\n');
mywriter.write(encodedData);
}
// compute and return the string value to bind to the widget with id 'date'
return value;
}
);
});
/*
* Boilerplate code for creating custom actions
*/
document.addEventListener('gc-nav-ready', function()
{
/*
* Add custom actions for menu items using the following api:
*
* function gc.nav.registryAction(id, runable, [isAvailable], [isVisible]);
*
* param id - uniquely identifies the action, and should correspond to the action property of the menuaction widget.
* param runable - function that performs the custom action.
* param isAvailable - (optional) - function called when the menu action is about to appear. Return false to disable the action, or true to enable it.
* param isVisible - (optional) - function called when the menu action is about to appear. Return false to hide the action, or true to make it visible.
*/
// For example,
// gc.nav.registerAction('myCustomCloseAction', function() { window.close(); }, function() { return true; }, function() { return true; });
// Alternatively, to programmatically disable a menu action at any time use:
// gc.nav.disableAction('myCustomCloseAction); then enable it again using: gc.nav.enableAction('myCustomCloseAction');
});
/*
* Boilerplate code for working with components in the application gist
*/
var initComplete = false;
var templateObj;
// Wait for DOMContentLoaded event before trying to access the application template
var init = function() {
templateObj = document.querySelector('#template_obj');
// Wait for the template to fire a dom-change event to indicate that it has been 'stamped'
// before trying to access components in the application.
templateObj.addEventListener('dom-change',function(){
if (initComplete) return;
this.async(function(){
initComplete = true;
console.log("Application template has been stamped.");
// Now that the template has been stamped, you can use 'automatic node finding' $ syntax to access widgets.
// e.g. to access a widget with an id of 'widget_id' you can use templateObj.$.widgetId
},1);
});
};
templateObj = document.querySelector('#template_obj');
if (templateObj) {
init();
} else {
document.addEventListener('DOMContentLoaded',init.bind(this))
}
