Chrome App e comunicazione seriale

luca 07/06/2016 7

Introduzione

Durante lo sviluppo dei miei progetti, mi capita spesso di dover progettare una interfaccia utente (GUI) che dialoga via seriale con i dispositivi che realizzo.

In passato ho scelto di realizzare tali interfacce in C# utilizzando il Framework .Net, framework che consente uno sviluppo molto rapido, grandi possibilità di personalizzazione (come l’uso di font custom nella GUI di RTCSetup) e la capacità di accedere ai vari elementi del sistema operativo, quali la systray (vedi la GUI di Type4Me).

rtcsetup-gui

Mi sono però chiesto come poter realizzare una interfaccia cross-platform, in modo che possa essere utilizzata anche da utenti Linux e Mac. La prima possibilità è utilizzare un linguaggio di sviluppo che abbia un compilatore/interprete per ogni sistema operativo, come Java (volendo esiste anche il progetto Mono per il Framework .Net) o Phyton. Sviluppare GUI con tali linguaggi richiede però l’utilizzo di framework dedicati, spesso di terze parti. Java inoltre ha solo definito le specifiche relative alle API di comunicazione seriale (javax.comm); è quindi necessario adottare una libreria esterna (la più famosa è RxTx) che le implementi.

Oggi voglio invece presentarvi una alternativa che non richiede librerie esterne e che consente lo sviluppo di applicazioni cross-platform con le medesime tecniche di creazione di un sito web: le Chrome Apps.

L’utilizzo di una Chrome App è stata ad esempio la scelta del team di sviluppo di Cleanflight, uno dei più famosi firmware per schede di controllo di multicotteri.

Chrome App

Una Chrome App è essenzialmente una applicazione, sviluppata utilizzando le tecnologie web (HTML5, CSS, Javascript) che viene eseguita dal motore del browser Chrome.

I vantaggi rispetto ad un sito web sono:

  • maggiore integrazione con il desktop (no barra degli indirizzi…)
  • raggruppamento in un Launcher dedicato (vedi screenshot sotto)
  • possibilità di interfacciarsi con l’hardware (ad esempio le porte seriali)

chrome-launcher

Struttura di una Chrome App

Una Chrome App è formata da 3 elementi:

  • il file manifest, che contiene i metadati della applicazione (nome, versione, descrizione…)
  • lo script di background che si occupa di creare l’interfaccia della app
  • l’interfaccia, composta da pagine HTML, librerie javascript, fogli di stile (CSS)…

Ho preparato una app di esempio che “simula” il Serial Monitor dell’IDE di Arduino. La app è disponibile sul chrome web store e il suo codice sorgente nel mio repository Github.

Vediamo gli elementi nel dettaglio.

Il manifest.json contiene i metadati. Molto importante è la dichiarazione che andremo ad utilizzare la libreria serial e il nome del nostro script di background:

chrome-manifest

Lo script di background non fa altro che creare una finestra di 600 x 500 pixels non ridimensionabile e di aprire all’interno di tale finestra la pagina window.html:

chrome-background

L’applicazione principale è quindi composta da 3 files:

  • window.html, pagina HTML di base
  • main.js, funzioni javascript
  • main.css, foglio di stile per i vari elementi grafici

Ho inoltre utilizzato la libreria jQuery e il suo plugin jQuery.simplemodal per visualizzare i vari popup.

Accedere alle porte seriali

Per accedere via javascript alle porte seriali del PC, Chrome mette a disposizione le API chrome.serial.

Iniziamo a elencare le porte seriali disponibili sul PC e ad aggiungerle ad una combobox in modo che l’utente possa selezionare quella desiderata:

chrome.serial.getDevices(function(ports) {
 
	for (var i = 0; i < ports.length; i++) {
		var portName = ports[i].path;
		var newOption = '' + portName + '';
		var newOption = '<option value="' + portName + '">' + portName + '</option>';
		$("#serial_ports_combobox").append(newOption);
	}
});

chrome-serial-choose

Il collegamento alla porta seriale scelta avviene chiamando il metodo connect:

chrome.serial.connect(selectedPort, connectionOptions, onConnect);

A tale metodo va passato un array (connectionOptions) contenente le impostazioni della porta:

var connectionOptions = {
	"bitrate": 9600,
	"dataBits": "eight",
	"parityBit": "no",
	"stopBits": "one",
	"receiveTimeout": 500,
	"sendTimeout": 500
};

Una volta collegati, è possibile inviare dati con il metodo send:

chrome.serial.send(connectionId, convertStringToArrayBuffer(textToSend), function(sendInfo) {
	if(sendInfo.error) $.modal('<div id="title">Unable to send data: ' + sendInfo.error + '</div>')
});

In caso di errore viene valorizzato sendInfo.error ed è quindi possibile gestirlo (nell’esempio sopra viene visualizzato un popup di errore).

Chi programma in javascript sa che una caratteristica fondamentale di tale linguaggio è l’essere asincrono. La ricezione di dati dalla seriale segue proprio questo paradigma. Per prima cosa è necessario aggiungere un listener (una nostra funzione) all’evento onReceive:

chrome.serial.onReceive.addListener(onReceive);

La funzione onReceive() sarà quindi chiamata ogni volta che un nuovo dato è ricevuto sulla porta seriale:

function onReceive(info) {
 
	if (info.connectionId == connectionId &amp;&amp; info.data) {
 
		var str = convertArrayBufferToString(info.data);
		$("#receive_textarea").append(str);
		$("#receive_textarea").scrollTop($("#receive_textarea")[0].scrollHeight);
	}
}

La funzione verifica se effettivamente sono stati ricevuti dati e in caso affermativo converte l’oggetto ArrayBuffer in una stringa e la aggiunge alla textArea.

Test

E’ possibile provare una Chrome App semplicemente attivando la Developer mode nelle impostazioni di Chrome e successivamente cliccando su Load unpacked extension…

chrome-test

Selezionando la cartella che contiene l’app in fase di sviluppo, questa viene caricata da Chrome ed è possibile eseguirla.

Per quanto riguarda la distribuzione delle applicazioni, è possibile crearne un pacchetto installabile con la funzione Pack extension… o – in alternativa – esse possono essere caricate sul chrome web store previa iscrizione al programma Chrome Developer.

Conclusioni

In questo tutorial vi ho mostrato come si possa, grazie alle Chrome Apps, realizzare facilmente applicazioni cross-platform. In tal modo possiamo dotare i nostri progetti elettronici di una comoda interfaccia utente fruibile da chi utilizza Windows, Linux o MacOS (e in maniera sperimentale anche su Android e iOS).

Qual è la vostra scelta quando si tratta di realizzare GUI per i vostri progetti? Ditemelo nei commenti!

7 Comments »

  1. Dustin 08/06/2016 at 17:31 - Reply

    “Creating a Chrome App was for example the choice of the developing team of Cleanflight, one of the most famous firmware for multicopter’s flight control boards.”

    It is somewhat disrespectful to attribute this decision to anyone working on Cleanflight considering Cleanflight was a hostile fork of Baseflight and its GUI where the author who did all of the work on building the Chrome App (who also did work on other Chrome apps with USB backends).

    The choice to use Chrome was made long before Cleanflight was created, and the person who actually made the decision to use Chrome was unhappy about the Cleanflight team copying his work.

    • luca 09/06/2016 at 07:54 - Reply

      Hi Dustin! Thanks for your comment, I really wasn’t aware of this “cleanflight-vs-baseflight” war. I did a small research on google and found a lot of different versions and point of views about the story. Let’s keep it simple: if Cleanflight / Baseflight and also Multiwii (the “father”) has a Chrome App GUI, the technology works pretty well and it’s worth a try!

  2. mat 12/06/2016 at 06:25 - Reply

    Will this work on a Rapsberry Pi?

    • luca 13/06/2016 at 08:29 - Reply

      Hi Mat, yes Chrome Apps do work under Raspbian

  3. Sarb 11/08/2016 at 18:34 - Reply

    Hey Luca do you have a github with the complete source code provided? Im trying to build the same thing and am having trouble linking the html elements to the corresponding js parts.

    • luca 14/09/2016 at 08:27 - Reply

      Hi, of course the source is on Github (as explained in the article…)

  4. Pascal 18/10/2016 at 10:49 - Reply

    Thanks for sharing this – this tutorial was really helpful to get me started with tweaking Chrome Apps

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi