Multiple USB Serial ports?

258 views
Skip to first unread message

James Newton

unread,
Dec 29, 2017, 4:53:20 PM12/29/17
to DroidScript
We are getting to a point where an Android device can host multiple serial adapters via a small hub and OTG cable. Is there any way to address more than one serial port in DroidScript?

Steve Garman

unread,
Dec 30, 2017, 4:01:00 AM12/30/17
to DroidScript
I don't think there is anything that can do that at the moment.

Pretty much all of the usb stuff in DroidScript requires exclusive use of an OTG cable.

Dave Smart

unread,
Dec 30, 2017, 4:10:13 AM12/30/17
to DroidScript
Actually, you can target a particular usb device on a OTG usb hub using the last 'device' parameter of the CreateUSBSerial method.  Use the following keywords to target particular USB ports:-

"2nd"
"3rd"
"4th"

nicolas

unread,
Feb 28, 2024, 4:56:58 PMFeb 28
to DroidScript
Hello,
I have tried reading 2 usb devices (one being an arduino) with a usb hub connected to a OTG cable on smartphone.
I give you my entire code below such as you can say if this is the correct syntax.

//Global variables.
var usb=null, usb2=null, stop, timer=0,timer2, reply="",timer_arduino=60,timer_gps=60,stopin=0;
var rate, id_db=1, day, month, year, hour, min, sec, redfield="non";
var s,log="", maxLines=5, long, lat, sqm;
//var ti,timewait;

//Called when application is started.
function OnStart()
{
   
Date_time();
rate=2;    

  app.PreventScreenLock("Full");
  app.SetScreenBrightness( 0.2 );
 
  app.SetOrientation( "Portrait" );
 
  //Create a layout with objects vertically centered.
    lay = app.CreateLayout( "linear", "VCenter,FillXY" );    

    layh = app.CreateLayout( "Linear", "Horizontal" );
    lay.AddChild(layh);
   
    layh = app.CreateLayout( "Linear", "Horizontal" );
    lay.AddChild(layh);
   

    btn = app.CreateButton( "Acquisition mesures capteur", 0.2, 0.08 );
    btn.SetMargins( 0.1, 0.08, 0, 0 );
    lay.AddChild( btn );
    btn4 = app.CreateButton( "Acquisition mesures arduino", 0.2, 0.08 );
    btn4.SetMargins( 0.1, 0.08, 0, 0 );
    lay.AddChild( btn4 );
 
    //Set function to call when button pressed.
    btn.SetOnTouch( capteur_measurements );
    btn4.SetOnTouch( arduino_measurements );
   
            //Create a text control to show data log.
    txt2 = app.CreateText( "", 0.9, 0.129, "Multiline,Left" );
    txt2.SetTextColor( "#ffffffff" );
    lay.AddChild( txt2 );
   
    //Create a read-only edit box to show sqm responses.
    edtReply = app.CreateText( "", 1.0, 0.2, "MultiLine,Left,Monospace" );
    edtReply.SetMargins( 0,0,0,0.01 );
    edtReply.SetTextColor( "#ffffffff" );
    edtReply.SetTextSize( 12 );
    lay.AddChild( edtReply );
   
    //Create a read-only edit box to show sqm responses.
    edtReply_arduino = app.CreateText( "", 1.0, 0.2, "MultiLine,Left,Monospace" );
    edtReply_arduino.SetMargins( 0,0,0,0.01 );
    edtReply_arduino.SetTextColor( "#ffffffff" );
    edtReply_arduino.SetTextSize( 12 );
    lay.AddChild( edtReply_arduino );
   
    //Create an edit box containing an example sqm program.
    edt = app.CreateTextEdit( "", 1.0, 0.2, "NoSpell" );
    lay.AddChild( edt );
   
    //Add layout to app.    
    app.AddLayout( lay );
   
     
dbname = "/sdcard/capteur_"+day+"_"+month+"_"+year;
exists = app.FileExists( dbname );
if(exists === 0) app.WriteFile( dbname, "date;heure;lat;long;value\n")

dbname_arduino = "/sdcard/arduino_log_"+day+"_"+month+"_"+year+".txt";
exists = app.FileExists( dbname_arduino );
if(exists === 0) app.WriteFile( dbname_arduino, "date;heure;lux;freq;lat;long\n");    

usb2 = app.CreateUSBSerial(115200,8,1,0);
   
usb = app.CreateUSBSerial( 115200,8,1,0,'2nd')
   
}

function capteur_measurements()
{
   
 if( !usb )
    {
        app.ShowPopup( "Connecter le capteur" );
        return;
    }    
   
btn.SetText("Arret des mesures capteur");    
btn.SetOnTouch( btn_stop );  
stop=setInterval( btn_OnTouch , 160);
}

function arduino_measurements()
{
   
    if( !usb2 )
    {
        app.ShowPopup( "Connecter la carte Arduino" );
        return;
    }
   
btn4.SetText("Arret des mesures arduino");    
btn4.SetOnTouch( btn_stop_arduino );  
stop_arduino=setInterval( btn_OnTouch_arduino , 160);
}

function btn_stop()
{
clearInterval(stop);
btn.SetText("Acquisition des mesures capteur");    
btn.SetOnTouch( capteur_measurements )
}

function btn_stop_arduino()
{
clearInterval(stop_arduino);
btn4.SetText("Acquisition des mesures arduino");    
btn4.SetOnTouch( arduino_measurements );
}

function btn_OnTouch()
{
    app.ShowPopup( "prise de mesures capteur", "Bottom");
   
    if( usb )
    {
    setTimeout(usb.Write("ux"),20);
    Date_time();
    usb.SetOnReceive( usb_OnReceive );
    }
    else
    {
    app.ShowPopup( "Perte du signal du capteur ; Vérifier le branchement du cable" );
    return;
    }
}

function btn_OnTouch_arduino()
{  
    app.ShowPopup( "prise de mesures arduino", "Bottom");
   
   
    if( usb2 )
    {
    usb2.SetOnReceive( usb_OnReceive_arduino );    
    }
}


function usb_OnReceive( data )
{    
log +="capteur ";    
    //Speak the text at default pitch and speed.
var pitch = 4, speed = 1.;

if (timer==0) timer=parseFloat(min+sec/60);
timer2=parseFloat(min+sec/60);

    data_capteur=data.substring(3,260);
    var arr=data_capteur.split(",");          // Split on commas

 if (data.substring(3,9).indexOf("m") !== -1)
{
log += data.substring(3,9)+"\n";  
    var logLines = log.split("\n");
if( !maxLines ) maxLines = edtReply.GetMaxLines();
    logLines = logLines.slice( -maxLines );
    log = logLines.join("\n").toString();
    edtReply.SetText( log );  
     
    if ( (timer2-timer > 0.133) || (timer2-timer < 0) )
    {
app.TextToSpeech(data.substring(3,8), pitch, speed,null,"music" );
timer=0;
}
     
data_capteur=day+"/"+month+"/"+year+";"+hour+":"+min+":"+sec+":"+millisec+";"+lat+";"+long+";"+arr[0]+";"+arr[1]+";"+arr[2]+";"+arr[3]+";"+arr[4]+";"+redfield+";"+"\n";
app.WriteFile( dbname, data_capteur,"Append");
}
 
}

//Called when we get data from arduino.
function usb_OnReceive_arduino( data )
{
    //Speak the text at default pitch and speed.
var pitch = 4;speed = 1.;
   
   //console.log( data );
   data_arduino=data;
   app.WriteFile( dbname_arduino, data_arduino,"Append");
 
   var arr=data_arduino.split(";");
    if (arr[2]>1)
   timer_arduino-=4;
   else
   timer_arduino--;
   
    if (stopin==0 && timer_arduino<1)
{
    log += arr[0]+" "+arr[1]+" "+arr[2]+" "+arr[3]+" "+arr[4]+" "+arr[5]+"\n";
    var logLines = log.split("\n");
if( !maxLines ) maxLines = edtReply_arduino.GetMaxLines();
    logLines = logLines.slice( -maxLines );
    log = logLines.join("\n").toString();
    edtReply_arduino.SetText( log );

if (arr[1]>1 )
app.TextToSpeech( Math.round(arr[1])+"   lux", pitch, speed );

if ( timer_arduino<1) timer_arduino=60;

if ((arr[4]==0.0 || arr[5]==0.0) )
{
timer_gps-=10;
if ( timer_gps< 1 )
    {
app.TextToSpeech( "Perte signal G P S       ", pitch, speed);
timer_gps=60;
    }  
}
}

}

function Date_time()
{
d=new Date();
    day=d.getDate();
    month=1+d.getMonth();
    year=d.getFullYear();
    hour=d.getHours();
    min=d.getMinutes();
    sec=d.getSeconds();
    millisec=d.getMilliseconds();
  if (day < 10) day="0"+day;
  if (month < 10) month="0"+month;
  if (hour < 10) hour="0"+hour;
  if (min < 10) min="0"+min;
  if (sec < 10) sec="0"+sec;    
  if (millisec > 10 && millisec < 100) millisec="0"+millisec;
  if (millisec < 10) millisec="00"+millisec;      


I receive data from "capteur" but not from "arduino" ....
The 2 usb devices works well when they are used alone on another script.
The issue should come from the declaration of usb port
I'm looking for the whole forum but find nothing ....

Thank you in advance for your help,
Best regards,

Nicolas.

Symbroson

unread,
Mar 1, 2024, 10:48:01 AMMar 1
to DroidScript
I will paste an answer by Dave posted recently:

> When you can't find something in the docs, it's worth checking the release notes.
> If you look at the release notes for version 177b you will see these notes - 

> - Changed 'device' parameter of app.CreateUSBSerial() to select by PID not index.
>   - Allowed app.GetPermission( "usb:"+pid ) for USB devices.

> You can get the PID (Product ID) and  VID (Vendor ID) of a USB device by plugging it into a windows machine and going to Device Manager/Properties for that device.


nicolas

unread,
Mar 1, 2024, 11:25:30 AMMar 1
to DroidScript
Thanks for you answer. I'm using Droidscript 1.78 and I also read previously this mail of Dave using the following part of code instead of that I"ve put above :

app.GetPermission( 'usb2:'+'0x0043')  
usb2 = app.CreateUSBSerial(115200,8,1,0,'0x0043'); // PID for arduino device
app.GetPermission( 'usb:'+'0x6001')
usb = app.CreateUSBSerial( 115200,8,1,0,'0x6001');   

but I'm still the same issue.

Best regards.

Symbroson

unread,
Mar 1, 2024, 11:39:24 AMMar 1
to DroidScript
Are you sure you are using the correct product id displayed in the device properties on your PC?
Not sure if the GetPermission format is correct.
You probably have to use 'usb:' in GetPermission in both cases,
and maybe you have drop the 0x part of the PID, but I'm not 100% sure about that.

Symbroson

unread,
Mar 1, 2024, 12:27:43 PMMar 1
to DroidScript
Another hint:
Test both devices individually to see if both work correctly first.
Also test each USB Port individually to test of the adapter works correctly
Then try both controllers on different ports in case the order plays a role when connected simultaneously.

nicolas

unread,
Mar 7, 2024, 4:30:35 AMMar 7
to DroidScript
Thanks Symbroson for your answers.
I again did test of each usb device alone and the code works well for theses 2 devices but when I'm using both of them in the code, it does not work..
I also try the hub itself by varying the usb ports used.

If someone has a code example with 2 usb devices working together thanks in advance to share.

Best regards,
Nicolas.

Dave

unread,
Mar 7, 2024, 1:18:16 PMMar 7
to DroidScript
I don't think you want the quotes around your device product id's in the CreateUsbSerial call as that parameter is meant to be a number, so it will probably get converted to -1 and. just select the first device found.

Try this - 

app.GetPermission( 'usb2:0x0043' )  

usb2 = app.CreateUSBSerial(115200,8,1,0, 0x0043 ); 
app.GetPermission( 'usb:0x6001' )

nicolas

unread,
May 21, 2024, 3:39:30 AMMay 21
to DroidScript
I come back to my project.
Thanks Dave for the syntax.
Now, the code works but only during few seconds after my phone reboot ...
There is an instability I can not figure out ....
I've tried to put setTimeout(100) between the call to usb1 and usb2 and also for commands like usb.SetOnReceive( usb_OnReceive ) and usb2.SetOnReceive( usb_OnReceive_arduino ) but I have always a reboot ....

Thanks in advance for your help

Best regards.
Nicolas

Dave

unread,
May 22, 2024, 1:25:53 PMMay 22
to DroidScript
Just to be clear - Your phone is rebooting itself after running the app?

What phone are you using and what version of Android?

Are you using a passive OTG usb hub?  Is it drawing too much power and causing the phone to restart maybe?

Please give more details of your setup and the USB devices in use.

nicolas

unread,
May 22, 2024, 3:51:13 PMMay 22
to DroidScript
I'm using Huawei P8 lite 2017 with Android 7.0
Yes the phone reboot itself few seconds after running the app. 
I'm using a passive OTG where I connect a hub powered by 5 volts. I'm plugging in 2 devices : one arduino consuming 110mAh and another device consuming less than 20 mAh. I have no issues when I'm using only one of these devices by removing one app.CreateUSBSerial command.

Nicolas.

Dave

unread,
May 23, 2024, 2:34:18 PMMay 23
to DroidScript
- Is it USB-C or micro-USB ?
- Is it a very cheap OTG hub?

FYI: With USB-C devices you can charge your phone at the same time as using USB serial (and other devices) by using a hub like this one - 

nicolas

unread,
May 24, 2024, 5:25:10 AMMay 24
to DroidScript
Reply all
Reply to author
Forward
0 new messages