Zum Hauptinhalt springen

Die serielle API ermöglicht Websites die Kommunikation mit seriellen Geräten.

igraal_de-de


Aktualisiert

¿Qué es la API serial?

Un puerto serie es una interfaz de comunicación bidireccional que permite enviar y recibir datos byte a byte.

La API serial proporciona una forma para que los sitios web lean y escriban en un dispositivo serial con JavaScript. Los dispositivos serie se conectan a través de un puerto serie en el sistema del usuario o mediante dispositivos USB y Bluetooth extraíbles que emulan un puerto serie.

En otras palabras, la API serial une la web y el mundo físico al permitir que los sitios web se comuniquen con dispositivos seriales, como microcontroladores e impresoras 3D.

Esta API también es un gran compañero para WebUSB Da Betriebssysteme erfordern, dass Anwendungen mit einigen seriellen Ports über ihre native serielle API der obersten Ebene anstelle der USB-API auf niedriger Ebene kommunizieren.

Este artículo refleja la API serial implementada en Chrome 86 y versiones posteriores. Algunos nombres de propiedades han cambiado con respecto a versiones anteriores.

Vorgeschlagene Anwendungsfälle

En los sectores educativo, aficionado e industrial, los usuarios conectan dispositivos periféricos a sus computadoras. Estos dispositivos a menudo son controlados por microcontroladores a través de una conexión en serie utilizada por software personalizado. Algún software personalizado para controlar estos dispositivos está construido con tecnología web:

En algunos casos, los sitios web se comunican con el dispositivo a través de una aplicación de agente nativo que los usuarios instalaron manualmente. En otros, la aplicación se entrega en una aplicación nativa empaquetada a través de un marco como Electron. Y en otros, el usuario debe realizar un paso adicional, como copiar una aplicación compilada al dispositivo a través de una unidad flash USB.

En todos estos casos, la experiencia del usuario se mejorará al proporcionar una comunicación directa entre el sitio web y el dispositivo que está controlando.

Tatsächlicher Zustand

Verwenden der seriellen API

Aktivieren Sie die Unterstützung während der Herkunftsnachweisphase

La API serial está disponible en todas las plataformas de escritorio (Chrome OS, Linux, macOS y Windows) como una prueba de origen en Chrome 80. Se espera que la prueba de origen finalice justo antes de que Chrome 89 se establezca en febrero de 2021. La API también puede habilitarse mediante una bandera.

Las pruebas de Origin le permiten probar nuevas funciones y brindar comentarios sobre su usabilidad, practicidad y efectividad a la comunidad de estándares web. Para obtener más información, consulte el Guía de pruebas de Origin para desarrolladores web. Um sich für diesen oder einen anderen Herkunftsnachweis anzumelden, besuchen Sie die página de registro.

Regístrese para la prueba de origen

  1. Fordern Sie einen Token an von Ihrer Herkunft.
  2. Agrega el token a tus páginas. Hay dos maneras de hacerlo:
    • Füge hinzu ein Ursprungsversuch etiqueta al encabezado de cada página. Por ejemplo, esto puede verse así:
    • Si puede configurar su servidor, también puede agregar el token usando un Origin-Trial Encabezado HTTP. El encabezado de respuesta resultante debería verse así:
      Origin-Trial: TOKEN_GOES_HERE

Habilitación a través de chrome: // flags

Aktivieren Sie die Option, um auf allen Desktop-Plattformen ohne Quelltest-Token lokal mit der seriellen API zu experimentieren #experimental-Web-Plattform-Funktionen Flagge an
chrome://flags.

Detección de características

Verwenden Sie Folgendes, um zu überprüfen, ob die serielle API unterstützt wird:

if ( "serial" im Navigator ) {
}}

Öffnen Sie eine serielle Schnittstelle

La API serial es asincrónica por diseño. Esto evita que la interfaz de usuario del sitio web se bloquee cuando se espera una entrada, lo cual es importante porque los datos en serie se pueden recibir en cualquier momento, lo que requiere una forma de escucharlos.

Um eine serielle Schnittstelle zu öffnen, greifen Sie zuerst auf a zu Serielle Schnittstelle Objekt. Zu diesem Zweck können Sie den Benutzer auffordern, eine einzelne serielle Schnittstelle auszuwählen, indem Sie anrufen
navigator.serial.requestPort ()oder wählen Sie eine von navigator.serial.getPorts ()
Hiermit wird eine Liste der seriellen Schnittstellen zurückgegeben, auf die die Website zuvor zugegriffen hat.


const port = warte auf Navigator . seriell . requestPort ( ) ;


const ports = warte auf Navigator . seriell . getPorts ( ) ;

das navigator.serial.requestPort () La función toma un literal de objeto opcional que define filtros. Se utilizan para hacer coincidir cualquier dispositivo serie conectado a través de USB con un proveedor USB obligatorio (usbVendorId) und optionale USB-Produktkennungen (usbProductId).


const filter = [
{ usbVendorId : 0x2341 , usbProductId : 0x0043 } ,
{ usbVendorId : 0x2341 , usbProductId : 0x0001 }
] ;


const port = warte auf Navigator . seriell . requestPort ( { Filter } ) ;

const { usbProductId , usbVendorId } = Port . getInfo ( ) ;

Serial-Port-Prompt-1927133
Eingabeaufforderung des Benutzers zur Auswahl eines BBC micro: bit

Vocación requestPort () fordert den Benutzer auf, ein Gerät auszuwählen, und gibt a zurück
Serielle Schnittstelle Objekt. Sobald Sie eine haben Serielle Schnittstelle Objektaufruf port.open ()
con la velocidad en baudios deseada se abrirá el puerto serie. los Baudrate El miembro de diccionario especifica qué tan rápido se envían los datos a través de una línea serial. Se expresa en unidades de bits por segundo (bps). Verifique la documentación de su dispositivo para el valor correcto ya que todos los datos que envía y recibe serán un galimatías si esto se especifica incorrectamente. Para algunos dispositivos USB y Bluetooth que emulan un puerto serie, este valor se puede establecer de forma segura en cualquier valor, ya que la emulación lo ignora.


const port = warte auf Navigator . seriell . requestPort ( ) ;


warte auf den Hafen . open ( { baudRate : 9600 } ) ;

También puede especificar cualquiera de las siguientes opciones al abrir un puerto serie. Estas opciones son opcionales y tienen vorgegebene Werte.

  • Daten Bits: El número de bits de datos por trama (7 u 8).
  • Stopp-Bits: El número de bits de parada al final de una trama (1 o 2).
  • Parität: Der Paritätsmodus (entweder "keiner", "sogar" oder "seltsam").
  • Puffergröße: El tamaño de los búferes de lectura y escritura que se deben crear (debe ser inferior a 16 MB).
  • Ablaufsteuerung: Der Durchflussregelungsmodus (entweder "keiner" oder "Hardware").

Lesen Sie von einer seriellen Schnittstelle

Die Eingabe- und Ausgabestreams in der seriellen API werden von der Streams-API verarbeitet.

Wenn die Streams für Sie neu sind, sehen Sie Streams API-Konzepte. Este artículo apenas toca la superficie de los arroyos y su manejo.

Una vez establecida la conexión del puerto serie, lesbar y schreibbar
Eigentum von Serielle Schnittstelle Objekt gibt a zurück ReadableStream und ein
WritableStream. Se utilizarán para recibir datos y enviar datos al dispositivo serie. Ambos usan Uint8Array Instanzen für die Datenübertragung.

Wenn neue Daten vom seriellen Gerät eingehen, port.readable.getReader (). read ()
devuelve dos propiedades de forma asincrónica: el Wert und ein erledigt Boolescher Wert. Ja
erledigt es cierto, el puerto serie se ha cerrado o no entran más datos. Llamando port.readable.getReader () Erstellen Sie einen Reader und blockieren Sie lesbar es. Während lesbar ist gesperrtkann die serielle Schnittstelle nicht geschlossen werden.

const reader = port . lesbar . getReader ( ) ;


while ( wahr ) {
const { value , done } = warte auf den Leser . read ( ) ;
if ( erledigt ) {
Leser . releaseLock ( ) ;
Pause ;
}}
Konsole . log ( Wert ) ;
}}

Algunos errores de lectura del puerto serie no fatales pueden ocurrir bajo algunas condiciones, como desbordamiento del búfer, errores de trama o errores de paridad. Esos se lanzan como excepciones y se pueden detectar agregando otro bucle encima del anterior que verifica port.readable. Dies funktioniert, weil, solange die Fehler nicht schwerwiegend sind, eine neue ReadableStream se crea automáticamente. Si se produce un error fatal, como la extracción del dispositivo serie, port.readable wird null.

while ( Port . lesbar ) {
const reader = port . lesbar . getReader ( ) ;

versuche {
while ( wahr ) {
const { value , done } = warte auf den Leser . read ( ) ;
if ( erledigt ) {

Leser . releaseLock ( ) ;
Pause ;
}}
if ( Wert ) {
Konsole . log ( Wert ) ;
}}
}}
} catch ( Fehler ) {

}}
}}

Si el dispositivo serie envía texto de vuelta, puede canalizar port.readable a través de un
TextDecoderStream Wie nachfolgend dargestellt. EIN TextDecoderStream ist ein Strom umwandeln
das packt alles Uint8Array Fragmente und verwandelt sie in Strings.

const textDecoder = neuer TextDecoderStream ( ) ;
const readableStreamClosed = Port . lesbar . pipeTo ( textDecoder . beschreibbar ) ;
const reader = textDecoder . lesbar . getReader ( ) ;


while ( wahr ) {
const { value , done } = warte auf den Leser . read ( ) ;
if ( erledigt ) {

Leser . releaseLock ( ) ;
Pause ;
}}

Konsole . log ( Wert ) ;
}}

Schreiben Sie an eine serielle Schnittstelle

Übergeben Sie die Daten an, um Daten an ein serielles Gerät zu senden
port.writable.getWriter (). write (). Vocación releaseLock () im
port.writable.getWriter () es necesario para que el puerto serie se cierre más tarde.

const writer = port . beschreibbar . getWriter ( ) ;

const data = new Uint8Array ( [ 104 , 101 , 108 , 108 , 111 ] ) ;
erwarte Schriftsteller . schreiben ( Daten ) ;


Schriftsteller . releaseLock ( ) ;

Envíe texto al dispositivo a través de un TextEncoderStream kanalisiert zu port.writable
Wie nachfolgend dargestellt.

const textEncoder = neuer TextEncoderStream ( ) ;
const writableStreamClosed = textEncoder. lesbar . pipeTo ( port . beschreibbar ) ;

const writer = textEncoder . beschreibbar . getWriter ( ) ;

erwarte Schriftsteller . schreiben ( "Hallo" ) ;

Schließen Sie eine serielle Schnittstelle

port.close () Schließen Sie die serielle Schnittstelle, wenn Ihre lesbar y schreibbar Die Mitglieder sind freigeschaltetSinn releaseLock () Es wurde von seinem jeweiligen Leser und Verfasser gerufen.

warte auf den Hafen . close ( ) ;

Wenn Sie jedoch kontinuierlich Daten von einem seriellen Gerät mithilfe einer Schleife lesen,
port.readable siempre estará bloqueado hasta que encuentre un error. En este caso, llamando reader.cancel () obligará reader.read () sofort zu lösen mit {Wert: undefiniert, erledigt: wahr} und somit die Schleife aufrufen lassen reader.releaseLock ().



const reader = port . lesbar . getReader ( ) ;


while ( wahr ) {
const { value , done } = warte auf den Leser . read ( ) ;
if ( erledigt ) {
Leser . releaseLock ( ) ;
Pause ;
}}

Konsole . log ( Wert ) ;
}}



erwarte Leser . cancel ( ) ;
warte auf den Hafen . close ( ) ;

Cerrar un puerto serie es más complicado cuando se usa Streams transformieren (Ich mag
TextDecoderStream y TextEncoderStream). Anruf reader.cancel () wie früher. Dann ruf an writer.close () y port.close (). Esto propaga los errores a través de los flujos de transformación al puerto serie subyacente. Debido a que la propagación de errores no ocurre de inmediato, debe utilizar el readableStreamClosed y
writableStreamClosed promesas creadas anteriormente para detectar cuándo port.readable
y port.writable wurden freigeschaltet. Sage ab Leser bewirkt, dass die Sequenz abgebrochen wird; Deshalb müssen Sie den resultierenden Fehler abfangen und ignorieren.



const textDecoder = neuer TextDecoderStream ( ) ;
const readableStreamClosed = Port . lesbar . pipeTo ( textDecoder . beschreibbar ) ;
const reader = textDecoder . lesbar . getReader ( ) ;


while ( wahr ) {
const { value , done } = warte auf den Leser . read ( ) ;
if ( erledigt ) {
Leser . releaseLock ( ) ;
Pause ;
}}

Konsole . log ( Wert ) ;
}}

const textEncoder = neuer TextEncoderStream ( ) ;
const writableStreamClosed = textEncoder. lesbar . pipeTo ( port . beschreibbar ) ;

Leser . cancel ( ) ;
Warten Sie auf readableStreamClosed . catch ( ( ) => { } ) ;

Schriftsteller . close ( ) ;
warte auf writableStreamClosed ;

warte auf den Hafen . close ( ) ;

Escuche la conexión y la desconexión

Wenn ein USB-Gerät eine serielle Schnittstelle bietet, kann dieses Gerät an das System angeschlossen oder von diesem getrennt werden. Wenn der Website die Berechtigung zum Zugriff auf eine serielle Schnittstelle erteilt wurde, sollte sie die Website überwachen verbinden y trennen Veranstaltungen.

Navigator . seriell . addEventListener ( "connect" , ( event ) => {
} ) ;

Navigator . seriell . addEventListener ( "trennen" , ( Ereignis ) => {
} ) ;

Manejar señales

Después de establecer la conexión del puerto serie, puede consultar y configurar explícitamente las señales expuestas por el puerto serie para la detección de dispositivos y el control de flujo. Estas señales se definen como valores booleanos. Por ejemplo, algunos dispositivos como Arduino entrarán en un modo de programación si se activa la señal Data Terminal Ready (DTR).

Einstellung señales de salida und bekomme señales de entrada werden jeweils durch Aufruf gemacht port.setSignals () y port.getSignals (). Consulte los ejemplos de uso a continuación.


warte auf den Hafen . setSignals ( { break : false } ) ;


warte auf den Hafen . setSignals ( { dataTerminalReady : true } ) ;


warte auf den Hafen . setSignals ( { requestToSend : false } ) ;

const- Signale = Port warten . getSignals ( ) ;
Konsole . log ( ` Clear To Send: $ { Signale . clearToSend } ` ) ;
Konsole . log ( ` Datenträgererkennung: $ { Signale . dataCarrierDetect } ` ) ;
Konsole . log ( ` Datensatz bereit: $ { Signale . dataSetReady } ` ) ;
Konsole . log ( ` Ring Indicator: $ { signalisiert . ringIndicator } ` ) ;

Streams transformieren

Cuando recibe datos del dispositivo serie, no necesariamente obtendrá todos los datos a la vez. Puede estar fragmentado arbitrariamente. Para más información, ver
Streams API-Konzepte.

Para lidiar con esto, puede usar algunas transmisiones de transformación integradas, como
TextDecoderStream o cree su propio flujo de transformación que le permite analizar el flujo entrante y devolver datos analizados. El flujo de transformación se encuentra entre el dispositivo serie y el bucle de lectura que consume el flujo. Puede aplicar una transformación arbitraria antes de que se consuman los datos. Piense en ello como una línea de montaje: a medida que un widget desciende por la línea, cada paso de la línea modifica el widget, de modo que cuando llega a su destino final, es un widget en pleno funcionamiento.

Flugzeugfabrik-2628261
Fábrica de aviones Castle Bromwich de la Segunda Guerra Mundial

Por ejemplo, considere cómo crear una clase de transmisión de transformación que consume una transmisión y la fragmenta en función de los saltos de línea. Sus transform () se llama al método cada vez que el flujo recibe nuevos datos. Puede poner los datos en cola o guardarlos para más tarde. los Flush () se llama al método cuando la secuencia está cerrada y maneja cualquier dato que aún no se haya procesado.

Para usar la clase de transmisión de transformación, debe canalizar una transmisión entrante a través de ella. En el tercer ejemplo de código en Leer desde un puerto serie, el flujo de entrada original solo se canalizó a través de un TextDecoderStreamdann müssen wir anrufen pipeThrough () para canalizarlo a través de nuestro nuevo LineBreakTransformer.

Klasse LineBreakTransformer {
Konstruktor ( ) {
das . chunks = "" ;
}}

transformieren ( Chunk , Controller ) {
das . Chunks + = Chunk ;
const lines = this . Brocken . split ( "rn" ) ;
das . Chunks = Zeilen . pop ( ) ;
Linien . forEach ( ( line ) => controller . enqueue ( line ) ) ;
}}

Flush ( Controller ) {
Controller . Enqueue ( dies . Brocken ) ;
}}
}}

const textDecoder = neuer TextDecoderStream ( ) ;
const readableStreamClosed = Port . lesbar . pipeTo ( textDecoder . beschreibbar ) ;
const reader = textDecoder . lesbar
. pipeThrough ( neuer TransformStream ( neuer LineBreakTransformer ( ) ) )
. getReader ( ) ;

Para depurar problemas de comunicación del dispositivo serie, utilice el Tee () método de
port.readable para dividir las transmisiones que van hacia o desde el dispositivo serie. Los dos flujos creados se pueden consumir de forma independiente y esto le permite imprimir uno en la consola para su inspección.

const [ appReadable , devReadable ] = Port . lesbar . tee ( ) ;

Codelab

Beim Laboratorio de código para desarrolladores de Google, usará la API serial para interactuar con un
BBC micro: bit tablero para mostrar imágenes en su matriz de LED de 5×5.

Polyfill

En Android, es posible admitir puertos serie basados ​​en USB mediante la API WebUSB y Polyfill API-Serie. Este polyfill está limitado a hardware y plataformas donde se puede acceder al dispositivo a través de la API WebUSB porque no ha sido reclamado por un controlador de dispositivo integrado.

Sicherheit und Privatsphäre

Los autores de especificaciones han diseñado e implementado la API serial utilizando los principios básicos definidos en Steuern Sie den Zugriff auf leistungsstarke Funktionen der Webplattform, incluido el control del usuario, la transparencia y la ergonomía. La capacidad de utilizar esta API está controlada principalmente por un modelo de permisos que otorga acceso a un solo dispositivo serie a la vez. En respuesta a una solicitud de usuario, el usuario debe tomar medidas activas para seleccionar un dispositivo serie en particular.

Informationen zu den Sicherheits-Kompromissen finden Sie in der Sicherheit y Privatsphäre
Serial API Explainer-Abschnitte.

Realimentación

Al equipo de Chrome le encantaría conocer sus pensamientos y experiencias con la API serial.

Cuéntanos sobre el diseño de la API

¿Hay algo en la API que no funcione como se esperaba? ¿O faltan métodos o propiedades que necesita para implementar su idea?

Legen Sie ein Spezifikationsproblem auf der GitHub-Repository der seriellen API oder fügen Sie Ihre Gedanken zu einem bestehenden Problem hinzu.

Informar un problema con la implementación

¿Encontraste un error con la implementación de Chrome? ¿O la implementación es diferente de la especificación?

Einen Fehler einreichen https://new.crbug.com. Asegúrese de incluir todos los detalles que pueda, proporcione instrucciones sencillas para reproducir el error y
Komponenten (bearbeiten) angepasst an Blinken> Seriennummer. Fehler funciona muy bien para compartir repros rápidos y fáciles.

Unterstützung zeigen

¿Está planeando utilizar la API serial? Su apoyo público ayuda al equipo de Chrome a priorizar funciones y muestra a otros proveedores de navegadores lo importante que es brindarles soporte.

Senden Sie einen Tweet an @Cromodev mit dem Hashtag
#SerialAPI

y háganos saber dónde y cómo lo está usando.

Enlaces Útiles

Población:

Vielen Dank

Dank an Reilly-Stipendium y Joe Medley por sus reseñas de este artículo. Foto de fábrica de aviones por Birmingham Museums Trust im Unsplash.