La API serial permite que los sitios la toile se comuniquen con dispositivos seriales.
Mise à jour
Qu'est-ce que l'API série?
Un port série est une interface de communication bidirectionnelle qui vous permet d'envoyer et de recevoir des données octet par octet.
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 Nom d'utilisateur o mediante dispositivos USB y Bluetooth extraíbles que emulan un puerto serie.
En d'autres termes, l'API série relie le Web et le monde physique en permettant aux sites Web de communiquer avec des périphériques série, tels que des microcontrôleurs et des imprimantes 3D.
Cette API est également un excellent compagnon pour WebUSB car les systèmes d'exploitation exigent que les applications communiquent avec certains ports série en utilisant leur API série native de premier niveau au lieu de l'API USB de bas niveau.
Cet article reflète l'API série implémentée dans Chrome 86 et versions ultérieures. Certains noms de propriétés ont changé par rapport aux versions précédentes.
Cas d'utilisation suggérés
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 Logiciel 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.
Dans tous ces cas, l'expérience utilisateur sera améliorée en fournissant une communication directe entre le site Web et l'appareil qu'il contrôle.
État actuel
Utilisation de l'API série
Activer le support lors de la phase de preuve d'origine
L'API série est disponible sur toutes les plates-formes de bureau (Chrome OS, Linux, macOS et Windows) comme preuve d'origine sur Chrome 80. La preuve d'origine devrait se terminer juste avant la mise en place de Chrome 89 en février 2021. L'API peut également être activé par un drapeau.
Les tests d'origine vous permettent de tester de nouvelles fonctionnalités et de fournir des commentaires sur leur convivialité, leur caractère pratique et leur efficacité à la communauté des normes Web. Pour plus d'informations, consultez le Guide de test d'origine pour les développeurs Web. Pour vous inscrire à cette preuve d'origine ou à toute autre preuve d'origine, visitez le page d'inscription.
Inscrivez-vous pour obtenir une preuve d'origine
- Demander un jeton par votre origine.
- Ajoutez le jeton à vos pages. Il y a deux façons de le faire:
- Ajouter un
origine-procès
balise à l'en-tête de chaque page. Par exemple, cela pourrait ressembler à ceci:
- Si puede configurar su serveur, también puede agregar el token usando un
Essai d'origine
Encabezado HTTP. El encabezado de respuesta resultante debería verse así:Essai d'origine: TOKEN_GOES_HERE
- Ajouter un
Activation via chrome: // flags
Pour expérimenter l'API série localement sur toutes les plates-formes de bureau, sans jeton de test source, activez le #experimental-web-platform-features
drapeau sur
chrome://flags
.
Détection des fonctionnalités
Pour vérifier si l'API série est prise en charge, utilisez:
si ("serial" dans navigateur) {
}
Ouvrez un port série
La API serial es asincrónica por diseño. Esto evita que la interface utilisateur 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.
Pour ouvrir un port série, accédez d'abord à un Port série
objet. Pour ce faire, vous pouvez demander à l'utilisateur de sélectionner un seul port série en appelant
navigator.serial.requestPort ()
ou choisissez l'un des navigator.serial.getPorts ()
qui renvoie une liste des ports série auxquels le site Web a précédemment accédé.
const port = attendre navigateur.serial.requestPort();
const ports = attendre navigateur.serial.getPorts();
Les navigator.serial.requestPort ()
La función toma un literal de objeto opcional que define les filtres. Se utilizan para hacer coincidir cualquier dispositivo serie conectado a través de USB con un proveedor USB obligatorio (usbVendorId
) et les identifiants de produit USB en option (usbProductId
).
const filters = [
{ usbVendorId: 0x2341, usbProductId: 0x0043 },
{ usbVendorId: 0x2341, usbProductId: 0x0001 }
];
const port = attendre navigateur.serial.requestPort({ filters });
const { usbProductId, usbVendorId } = port.getInfo();
Vocation requestPort ()
invite l'utilisateur à sélectionner un appareil et renvoie un
Port série
objet. Une fois que vous avez un Port série
appel d'objet port.open ()
avec le débit en bauds souhaité, le port série s'ouvrira. Les baudRate
Le membre du dictionnaire spécifie la vitesse à laquelle les données sont envoyées sur une ligne série. Il est exprimé en unités de bits par seconde (bps). Consultez la documentation de votre appareil pour la valeur correcte car toutes les données que vous envoyez et recevez seront du charabia si cela est spécifié de manière incorrecte. Pour certains périphériques USB et Bluetooth qui émulent un port série, cette valeur peut être définie en toute sécurité sur n'importe quelle valeur car elle est ignorée par l'émulation.
const port = attendre navigateur.serial.requestPort();
attendre port.open({ baudRate: 9600 });
Vous pouvez également spécifier l'une des options suivantes lors de l'ouverture d'un port série. Ces options sont facultatives et ont valeurs prédéterminées.
Bits de données
: Le nombre de bits de données par trame (7 ou 8).bits d'arrêt
: Le nombre de bits d'arrêt à la fin d'une trame (1 ou 2).parité
: El modo de paridad (ya être"rien"
,"même"
ou"impair"
).bufferSize
: La taille des tampons de lecture et d'écriture à créer (doit être inférieure à 16 Mo).contrôle de flux
: Le mode de contrôle de flux (soit"rien"
ou"Matériel"
).
Lire à partir d'un port série
Les flux d'entrée et de sortie de l'API série sont gérés par l'API Streams.
Si les flux sont nouveaux pour vous, consultez Concepts de l'API Streams. Cet article touche juste la surface des flux et leur gestion.
Une fois la connexion du port série établie, lisible
y inscriptible
propriétés de Port série
objet renvoie un ReadableStream et un
WritableStream. Ils seront utilisés pour recevoir des données et envoyer des données au périphérique série. Ils utilisent tous les deux Uint8Array
instances de transfert de données.
Lorsque de nouvelles données arrivent du périphérique série, port.readable.getReader (). read ()
renvoie deux propriétés de manière asynchrone: le valeur
et un Fini
booléen. Oui
Fini
c'est vrai, le port série a été fermé ou il n'y a plus de données entrantes. Appel port.readable.getReader ()
créer un lecteur et bloquer lisible
il. Alors que lisible
c'est fermé à clé, le port série ne peut pas être fermé.
const lecteur = port.lisible.getReader();
tandis que (vrai) {
const { valeur, Fini } = attendre lecteur.read();
si (Fini) {
lecteur.releaseLock();
break;
}
console.Journal(valeur);
}
Certaines erreurs de lecture de port série non fatales peuvent se produire dans certaines conditions, telles qu'un dépassement de mémoire tampon, des erreurs de cadrage ou des erreurs de parité. Ceux-ci sont lancés comme des exceptions et peuvent être interceptés en ajoutant une autre boucle au-dessus de la précédente qui vérifie port.lisible
. Cela fonctionne car tant que les erreurs ne sont pas fatales, un nouveau ReadableStream il est créé automatiquement. Si une erreur fatale telle que la suppression d'un périphérique série se produit, port.lisible
devient nul.
tandis que (port.lisible) {
const lecteur = port.lisible.getReader();
try {
tandis que (vrai) {
const { valeur, Fini } = attendre lecteur.read();
si (Fini) {
lecteur.releaseLock();
break;
}
si (valeur) {
console.Journal(valeur);
}
}
} catch (Erreur) {
}
}
Si le périphérique série renvoie du texte, vous pouvez rediriger port.lisible
à travers un
TextDecoderStream
Comme indiqué ci-dessous. ONGLE TextDecoderStream
c'est un transformer le courant
qui saisit tout Uint8Array
fragments et les transforme en chaînes.
const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.lisible.pipeTo(textDecoder.inscriptible);
const lecteur = textDecoder.lisible.getReader();
tandis que (vrai) {
const { valeur, Fini } = attendre lecteur.read();
si (Fini) {
lecteur.releaseLock();
break;
}
console.Journal(valeur);
}
Ecrire sur un port série
Pour envoyer des données à un périphérique série, transmettez les données à
port.writable.getWriter (). write ()
. Vocation releaseLock ()
au
port.writable.getWriter ()
il est nécessaire que le port série soit fermé plus tard.
const writer = port.inscriptible.getWriter();const Les données = new Uint8Array([104, 101, 108, 108, 111]);
attendre writer.write(Les données);
writer.releaseLock();
Envoyez du texte à l'appareil via un TextEncoderStream
canalisé vers port.writable
Comme indiqué ci-dessous.
const textEncoder = new TextEncoderStream();
const writableStreamClosed = textEncoder.lisible.pipeTo(port.inscriptible);const writer = textEncoder.inscriptible.getWriter();
attendre writer.write("hello");
Fermer un port série
port.close ()
fermez le port série si votre lisible
y inscriptible
Les membres sont déverrouillé, sens releaseLock ()
Il a été convoqué par ses lecteurs et écrivains respectifs.
attendre port.close();
Cependant, lors de la lecture continue des données d'un périphérique série à l'aide d'une boucle,
port.lisible
il sera toujours bloqué jusqu'à ce qu'il rencontre une erreur. Dans ce cas, appeler reader.cancel ()
obliger à reader.read ()
résoudre immédiatement avec {valeur: undefined, done: true}
et permettant ainsi à la boucle d'appeler reader.releaseLock ()
.
const lecteur = port.lisible.getReader();
tandis que (vrai) {
const { valeur, Fini } = attendre lecteur.read();
si (Fini) {
lecteur.releaseLock();
break;
}
console.Journal(valeur);
}
attendre lecteur.cancel();
attendre port.close();
La fermeture d'un port série est plus compliquée lors de son utilisation transformer les flux (J'aime
TextDecoderStream
y TextEncoderStream
). Appel reader.cancel ()
comme avant. Puis appelez écrivain.close ()
y port.close ()
. Cela propage les erreurs via les flux de transformation vers le port série sous-jacent. Étant donné que la propagation des erreurs ne se produit pas immédiatement, vous devez utiliser le readableStreamClosed
y
writableStreamClosed
précédemment créé promet de détecter quand port.lisible
y port.writable
ont été déverrouillés. Annuler le lecteur
provoque l'annulation de la séquence; c'est pourquoi vous devez attraper et ignorer l'erreur qui en résulte.
const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.lisible.pipeTo(textDecoder.inscriptible);
const lecteur = textDecoder.lisible.getReader();
tandis que (vrai) {
const { valeur, Fini } = attendre lecteur.read();
si (Fini) {
lecteur.releaseLock();
break;
}
console.Journal(valeur);
}
const textEncoder = new TextEncoderStream();
const writableStreamClosed = textEncoder.lisible.pipeTo(port.inscriptible);
lecteur.cancel();
attendre readableStreamClosed.catch(() => { });
writer.close();
attendre writableStreamClosed;
attendre port.close();
Écoutez la connexion et la déconnexion
Si un périphérique USB fournit un port série, ce périphérique peut être connecté ou déconnecté du système. Lorsque le site Web a reçu l'autorisation d'accéder à un port série, il doit surveiller le relier
y déconnecter
événements.
navigateur.serial.addEventListener("relier", (un événement) => {
});navigateur.serial.addEventListener("déconnecter", (un événement) => {
});
Gérer les signaux
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 programmation si se activa la señal Data Terminal Ready (DTR).
Ajustement panneaux de sortie et obtenir signaux d'entrée se font respectivement en appelant port.setSignals ()
y port.getSignals ()
. Consultez les exemples d'utilisation ci-dessous.
attendre port.setSignals({ break: faux });
attendre port.setSignals({ dataTerminalReady: vrai });
attendre port.setSignals({ requestToSend: faux });
const signals = attendre port.getSignals();
console.Journal(`Clear To Send: ${signals.clearToSend}`);
console.Journal(`Data Carrier Detect: ${signals.dataCarrierDetect}`);
console.Journal(`Data Set Ready: ${signals.dataSetReady}`);
console.Journal(`Ring Indicator: ${signals.ringIndicator}`);
Transformer les flux
Lorsque vous recevez des données du périphérique série, vous n'obtiendrez pas nécessairement toutes les données en même temps. Il peut être arbitrairement fragmenté. Pour plus d'informations, consultez
Concepts de l'API Streams.
Pour gérer cela, vous pouvez utiliser certains flux de transformation intégrés, tels que
TextDecoderStream
ou créez votre propre flux de transformation qui vous permet d'analyser le flux entrant et de renvoyer les données analysées. Le flux de transformation se situe entre le périphérique série et la boucle de lecture qui consomme le flux. Vous pouvez appliquer une transformation arbitraire avant que les données ne soient consommées. Considérez-le comme une ligne d'assemblage - lorsqu'un widget se déplace le long de la ligne, chaque étape de la ligne modifie le widget de sorte que lorsqu'il atteint sa destination finale, il soit un widget entièrement fonctionnel.
Par exemple, considérez comment créer une classe de flux de transformation qui consomme un flux et le segmente en fonction des sauts de ligne. Leur transformer ()
la méthode est appelée chaque fois que le flux reçoit de nouvelles données. Vous pouvez mettre les données en file d'attente ou les enregistrer pour plus tard. Les affleurer ()
La méthode est appelée lorsque le flux est fermé et gère toutes les données qui n'ont pas encore été traitées.
Pour utiliser la classe de flux de transformation, vous devez diriger un flux entrant à travers elle. Dans le troisième exemple de code en lecture à partir d'un port série, le flux d'entrée d'origine était uniquement acheminé via un TextDecoderStream
alors nous devons appeler pipeThrough ()
pour le canaliser à travers notre nouveau LineBreakTransformer
.
classer LineBreakTransformer {
constructeur() {
Este.chunks = "";
}transformer(chunk, controller) {
Este.chunks += chunk;
const lines = Este.chunks.split("rn");
Este.chunks = lines.pop();
lines.forEach((line) => controller.enqueue(line));
}
flush(controller) {
controller.enqueue(Este.chunks);
}
}
const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.lisible.pipeTo(textDecoder.inscriptible);
const lecteur = textDecoder.lisible
.pipeThrough(new TransformStream(new LineBreakTransformer()))
.getReader();
Pour déboguer les problèmes de communication des périphériques série, utilisez le tee()
méthode de
port.lisible
pour diviser les transmissions vers ou depuis le périphérique série. Les deux flux créés peuvent être consommés indépendamment et cela vous permet d'en imprimer un sur la console pour inspection.
const [appReadable, devReadable] = port.lisible.tee();
Codelab
Dans le Google Developer Code Lab, vous utiliserez l'API série pour interagir avec un
BBC micro: bit carte pour afficher les images sur sa matrice LED 5 × 5.
Polyfill
Sur Android, les ports série USB peuvent être pris en charge via l'API WebUSB et Série API Polyfill. Este polyfill está limitado a Matériel 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.
Sécurité et confidentialité
Les auteurs de la spécification ont conçu et implémenté l'API série en utilisant les principes de base définis dans Contrôlez l'accès aux fonctionnalités puissantes de la plate-forme Web, y compris le contrôle de l'utilisateur, la transparence et l'ergonomie. La possibilité d'utiliser cette API est principalement contrôlée par un modèle d'autorisations qui n'accorde l'accès qu'à un seul périphérique série à la fois. En réponse à une demande de l'utilisateur, l'utilisateur doit prendre des mesures actives pour sélectionner un périphérique série particulier.
Pour comprendre les compromis en matière de sécurité, consultez le sécurité y intimité
Sections Serial API Explainer.
Retour
L'équipe Chrome aimerait connaître vos impressions et vos expériences avec l'API Serial.
Parlez-nous de la conception de l'API
Y a-t-il quelque chose dans l'API qui ne fonctionne pas comme prévu? Ou vous manquez-vous des méthodes ou des propriétés dont vous avez besoin pour mettre en œuvre votre idée?
Déposer un problème de spécification sur le Dépôt GitHub de l'API série ou ajoutez vos réflexions à un problème existant.
Signaler un problème avec le déploiement
Vous avez trouvé un bogue avec la mise en œuvre de Chrome? Ou la mise en œuvre est-elle différente de la spécification?
Signaler un bogue dans https://new.crbug.com. Assurez-vous d'inclure autant de détails que possible, de fournir des instructions simples pour reproduire le bogue, et
Composants (modifier) ajusté à Clignoter> Série
. Échec fonctionne très bien pour un partage rapide et facile des répétitions.
Montrez votre soutien
¿Está planeando utilizar la API serial? Su apoyo público ayuda al equipo de Chrome a priorizar funciones y muestra a otros proveedores de navigateurs lo importante que es brindarles soporte.
Envoyer un tweeter à @Cromodev avec lui hashtag
#SerialAPI
et faites-nous savoir où et comment vous l'utilisez.
Liens utiles
Ville:
Merci
Grâce à Bourse Reilly y Joe medley pour leurs critiques de cet article. Photo d'usine d'aéronefs par Fiducie des musées de Birmingham au Unsplash.