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.
Tool/software: Code Composer Studio
I'm working on a collect data project, and I need to save the tables send to a textbox as a file text.
Have anyone know how to save a file from gui composer to a .txt text file?
Hi Martin.
Thank you for response. I'm using Json protocol to send ASCII data to a ti_tile_textbox. I'd like to use a button to download the data shown in the textbox.
Hi Lucas,
My apologies for delayed response. We have put together an example that hopefully will help. URL below points to an application that is visible in Gallery that has a sample implementation of how to save data to a file. I would suggest that you first click on link below, which should show the sample application in Gallery, and then click on App tile to activate the application. There are some instructions in Readme that should pop up to help guide you. After you verify its functionality, please import it into GC Designer. You would do this by clicking in dial icon (GUI Composer icon) to import it into designer, on first screen after clicking on link below. You will then be able to perform actions that are described in readme, which you can access from Project->Edit Readme menu.
Thank you very much for the example you developed.
It has helped me a lot, and it's working perfectly.
But, I have now another question, how to write in the text area via uart using JSON?
I need to make a Message Console.
Thanks for the help.
/* * 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 || {}; /* * Boilerplate code for encoding and decoding data transmitted to / received from TI devices. */ /** * This code implements the IPacketCodec interface. * * @constructor * @implements gc.databind.IPacketCodec */ CustomCodec = function() { }; CustomCodec.prototype.rxPktCtr = 0; CustomCodec.prototype.rxMsgCtr = 0; CustomCodec.prototype.txPktCtr = 0; CustomCodec.prototype.txMsgCtr = 0; CustomCodec.prototype.strRxBuffer = ""; CustomCodec.prototype.strTxBuffer = ""; CustomCodec.prototype.isConnect = false; CustomCodec.prototype.initComplete = false; /** * Encodes data into a packet for sending to the target device. * * @param target - function to call to pass on the encoded data towards the target * @param data - The data object from the GUI that is to be encoded into a packet for sending. */ CustomCodec.prototype.encode = function(target,data){ this.txPktCtr++; /* The following example code shows how to decode JSON strings going down to the target into a Javascript object. You would use this if you wanted to intercept data from the GUI and rework it before passing it on to the target device. this.txMsgCtr++; if (this.txMsgCtr % 256){ console.log("Number of tx messages to target: "+this.txMsgCtr); } var strToSend = JSON.stringify(jsonObj) +"\n"; // send the string to the target target(strToSend); } catch(ex){ console.log("CustomCodec.encode (to target): exception="+ex); } } */ }; /** * Decodes packets from the target device into data objects. One object for each packet of data. * Unless you have chained your custom codec with the CR codec, the packet data is not framed, * so this method is responsible for decoding partial packets as well as multiple packets. Partial packets * should not be returned, but deferred until the next decode method call with more raw data to process. As a * result, this method may return 0 or more packets of data on each invocation. * * @param target - function to call to pass on the encoded data towards the GUI * @param data - The raw data received that needs to be decoded from packets into objects. * @return - true if connected (i.e. valid data received), false if not connected */ CustomCodec.prototype.decode = function(target, data) { this.isConnected = true; this.rxPktCtr++; /* The following example code shows how to decode JSON strings coming up from the target into a Javascript object. You would use this if you wanted to intercept data from the target and rework it before passing it on to the GUI for binding */ var strRxData = data.map(function(value) { return String.fromCharCode(value);} ).join(""); this.strRxBuffer = this.strRxBuffer+strRxData; var strMessage = ''; while (this.strRxBuffer.indexOf('\n') !== -1) { strMessage = this.strRxBuffer.substring(0, this.strRxBuffer.indexOf('\n') + 1); this.strRxBuffer = this.strRxBuffer.substring(strMessage.length); // Rework the following code if your codec is not receiving Javascript objects from the GUI try { var jsonObj = JSON.parse(strMessage); this.rxMsgCtr++; if (this.rxMsgCtr % 256){ console.log("Number of tx messages from target: "+this.rxMsgCtr); } templateObj.$.textArea.value += strMessage; // send the received and decoded javascript object to the application where you can use it to bind to widget properties target(jsonObj); } catch(ex){ console.log("CustomCodec.decode (from target): strMessage="+strMessage+", exception="+ex); } } // Return true to set the 'Hardware Connected' status in the status bar return this.isConnected; }; var close = function(){ gc.databind.unregisterCustomCodec("custom",CustomCodec); CustomCodec.initComplete = false; CustomCodec.isConnected = false; }; var saveText = function(fname, text, mime) { var blob = new Blob([text], { type: mime }); saveAs(blob, fname); return false; } var initComplete = false; var templateObj; // Wait for DOMContentLoaded event before trying to access the application template var init = function() { templateObj = document.querySelector('#template_obj'); // You can 'chain' codecs together to make it easier to work with the data // coming from the device or going to the device. // The following codecs are provided: // CR - use this if the target data uses /n as a delimiter for framing. // The CR codec will take care of buffering the incoming data so that // your codec will only receive complete 'ready to use' packets // If your target uses /n delimited strings, set baseCodecs = "CR" // If your target uses some other format for data (e.g. binary data or custom strings) leave baseCodecs = "undefined" var baseCodecs = undefined; console.log("custom codec: about to register..."); // log a message that you will be able to see in the debugger gc.databind.registerCustomCodec("custom",CustomCodec, baseCodecs); CustomCodec.initComplete = true; templateObj.addEventListener('dom-change', function() { if (initComplete) return; this.async(function() { initComplete = true; console.log("Application template has been stamped."); // The key dependency that enables this is the ti-core-assets component. // To see how this is added, close this editor and click the < > button in the designer menu bar to open the // "gist editor", which displays the essential bits of html used for this project. // Note that the import section at the top has a line that has a custom tag that references ti-core-assets.html. if (window.File && window.FileReader && window.FileList && window.Blob) { templateObj.$.ti_widget_label.label = "This browser supports file writing..."; } else { templateObj.$.ti_widget_label.label = "The File APIs are not fully supported in this browser." } // 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 templateObj.$.ti_widget_button.addEventListener("click", function(event) { saveText(templateObj.$.ti_widget_input.value, templateObj.$.textArea.value, 'text/plain;charset=utf-8'); }); }, 1); }); }; templateObj = document.querySelector('#template_obj'); if (templateObj) { init(); } else { document.addEventListener('DOMContentLoaded',init.bind(this)) }
Hi Lucas,
This is a bit tricky to provide instructions, but hopefully I will not miss a step.
You would need open project properties and click on Next to get to Target Communication page and click on uart node (where you pick the device) and change the protocol to "custom". You would then go to File->New ->Custom Codec File ,which will add a new file to your project.
You would then need to open that (click on Folder toolbar button to show projects view) and double click on customCodec_0.js file to open it in editor. Copy entire line #127 (templateObj=...) and paste it just below line #111 (inside init function).
Now uncomment lines 76 -96. This sample code parses JSON objects thus you do not need to change this code. However, you can now insert your own code to update textarea in this function. e.g. insert
templateObj.$.textArea.value += strMessage;
on line #89. textArea is the widgetID, thus it needs to match whatever widget you are trying to send data to.
I have attached a .js that should have all these changes