利用WebUSB读取GPS接收机

利用WebUSB读取GPS接收机,gps,nmea,webusb,Gps,Nmea,Webusb,我正在尝试使用WebUSB从javascript中的USB连接的GPS接收器读取GPS坐标 我已经能够连接到接收器;但是,我不确定如何使用WebUSB访问NMEA消息 到目前为止,我有以下概念验证代码: <html> <head> <title>WebUSB Serial Sample Application</title> </head> <body> <a href="#"

我正在尝试使用WebUSB从javascript中的USB连接的GPS接收器读取GPS坐标

我已经能够连接到接收器;但是,我不确定如何使用WebUSB访问NMEA消息

到目前为止,我有以下概念验证代码:

<html>
  <head>
    <title>WebUSB Serial Sample Application</title>
  </head>


<body>
 <a href="#" id = "click">Connect</a><br>
 <a href="#" id = "send">Send Data</a><br>
 <a href="#" id = "read">Read Data</a><br>
 <script>
 
let y;
let device;

var connectButton = document.getElementById('click')
connectButton.addEventListener('click', function() {
    navigator.usb.requestDevice({
        filters: [{}]
    }).then((selectedDevice) => {
        device = selectedDevice;
        return device.open()
            .then(() => device.selectConfiguration(1))
            .then(() => device.claimInterface(device.configuration.interfaces[0].interfaceNumber))
            .then(() => device.selectAlternateInterface(device.configuration.interfaces[0].interfaceNumber, 0))
            .then(() => {
                y = device;
            })
    });
})

var sendButton = document.getElementById('send')    
var sendDecoder = new TextDecoder()
sendButton.addEventListener('click', async () => {
y.controlTransferOut({
    requestType: 'class',
    recipient: 'interface',
    request: 0x22,
    value: 0x01,
    index: 0x00});
    
y.controlTransferIn({
        requestType: 'standard',
        recipient: 'device',
        request: 0x06,
        value: 0x0302,
        index: 0x409
    }, 255)
        .then(result => {
            let decoder = new TextDecoder()
            console.log(sendDecoder.decode(result.data));
            console.log('sent req');
        }).catch(error => {
            console.log(error);
        });
});

 </script>
 </body>
 </html>

WebUSB串行示例应用程序



让y; let装置; var connectButton=document.getElementById('单击') connectButton.addEventListener('click',function(){ navigator.usb.requestDevice({ 筛选器:[{}] })。然后((所选设备)=>{ 设备=所选设备; 返回设备。打开() 。然后(()=>设备。选择配置(1)) .then(()=>device.claiInterface(device.configuration.interfaces[0].interfaceEnumber)) 。然后(()=>device.selectAlternateInterface(device.configuration.interfaces[0]。interfaceEnumber,0)) .然后(()=>{ y=装置; }) }); }) var sendButton=document.getElementById('send') var sendDecoder=新的TextDecoder() sendButton.addEventListener('click',async()=>{ y、 控制转移({ requestType:'类', 收件人:“接口”, 请求:0x22, 值:0x01, 索引:0x00}); y、 控制转移蛋白({ requestType:'标准', 收件人:'设备', 请求:0x06, 值:0x0302, 索引:0x409 }, 255) 。然后(结果=>{ let decoder=新文本解码器() log(sendDecoder.decode(result.data)); console.log('sent req'); }).catch(错误=>{ console.log(错误); }); });
transferOut语句允许我从设备读取供应商名称。所以,我知道我是有联系的,可以和它交流。我只是不知道从设备访问lat/lon需要什么特定命令

更新: 下面是设备配置信息的快照
为了实现目标,您需要了解几个层次。第一个是设备实现的USB接口

在您发布的示例代码中,有两个调用向设备发送命令。第一个是controlTransferOut(),它向设备发送标准USB CDC-ACM设置\控制\线路\状态请求(0x22),以启用DTR信号(0x01)。如果您的设备实现USB CDC-ACM协议,那么这就是要执行的写入操作,因为它会向设备发出主机软件已准备好接收数据的信号。如果您的设备未实现此协议,则该命令将被忽略或失败。您已经声明了第一个接口,要了解接口实现的USB协议,您应该检查
设备.配置.接口[0].替代[0].接口类
设备.配置.接口[1].替代[0].接口类
。USB CDC-ACM设备将有一个2级接口和一个10级接口。第2类为控制接口,第10类为数据接口。如果您的设备没有这两个接口,那么它可能没有实现USB CDC-ACM协议,您必须先了解它使用的协议

您进行的第二个调用是controlTransferIn(),它发送标准USB GET_描述符请求(0x06)以从设备读取字符串描述符。传递0x0302要求它读取索引2处的字符串描述符(类型3)。这将适用于任何USB设备(假设索引是正确的),因此不会告诉您是否已经了解接口支持的协议

假设这是一个USB CDC-ACM接口,那么您需要查看
device.configuration.interfaces[1]。alternates[0]。endpoints
,并计算出输入和输出端点的端点号。这些是您将传递给
transferIn()
transferOut()
以从设备发送和接收数据的内容


一旦你弄清楚了所有这些,你就需要弄清楚如何让设备开始发送NMEA消息。如果幸运的话,在默认模式下,它会自动发送它们,您可以开始调用
transferIn()
来接收它们。否则,您将必须确定向设备发送什么命令才能将其置于正确的模式。如果您有支持此设备的其他语言编写的设备和文档或示例代码,那么这将非常有助于解决此问题。

我终于解决了此问题。答案(无论如何,对我来说)是购买一个不同的GPS接收器,实现CDC-ACM接口,因为这个协议似乎有更多的例子和更好的文档

以下概念验证代码正在运行:

<html>
  <head>
    <title>WebUSB Serial Sample Application</title>
  </head>


<body>
 <a href="#" id = "click">Connect</a><br>
 <a href="#" id = "read">Read Data</a><br>
 <script>
 
let y;
let device;

var connectButton = document.getElementById('click')
connectButton.addEventListener('click', function() {
    navigator.usb.requestDevice({
        filters: [{}]
    })
    .then((selectedDevice) => {
        device = selectedDevice;
        return device.open();
    })
    .then(() => device.selectConfiguration(1))
    .then(() => device.claimInterface(device.configuration.interfaces[0].interfaceNumber))
    .then(() => device.claimInterface(device.configuration.interfaces[1].interfaceNumber))
    .then(() => device.selectAlternateInterface(device.configuration.interfaces[0].interfaceNumber, 0))
    .then(() => device.selectAlternateInterface(device.configuration.interfaces[1].interfaceNumber, 0))
    .then(() => {
        y = device;
    })
})

var readButton = document.getElementById('read')
var readDecoder = new TextDecoder()
var readLoop = () => {
    y.transferIn(2,64)
        .then(result => {
            let decoder = new TextDecoder()
            console.log(readDecoder.decode(result.data.buffer));
            readLoop();
        }).catch(error => {
            console.log(error);
        });
};

readButton.addEventListener('click', async () => {
    readLoop();
});


 </script>
 </body>
 </html>

WebUSB串行示例应用程序


让y; let装置; var connectButton=document.getElementById('单击') connectButton.addEventListener('click',function(){ navigator.usb.requestDevice({ 筛选器:[{}] }) 。然后((所选设备)=>{ 设备=所选设备; 返回设备。打开(); }) 。然后(()=>设备。选择配置(1)) .then(()=>device.claiInterface(device.configuration.interfaces[0].interfaceEnumber)) .then(()=>device.claiInterface(device.configuration.interfaces[1].interfaceEnumber)) 。然后(()=>device.selectAlternateInterface(device.configuration.interfaces[0]。interfaceEnumber,0)) 。然后(()=>device.selectAlternateInterface(device.configuration.interfaces[1]。interfaceEnumber,0)) .然后(()=>{ y=装置; }) }) var readButton=document.getElementById('read') var readDecoder=新文本解码器() var readLoop=()=>{ y、 转移蛋白(2,64) 。然后(结果=>{ let decoder=新文本解码器() log(readDecoder.decode(result.data.buffer)); readLoop(); }).catch(错误=>{