Seite 1 von 2
WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 20.12.2023 09:08
von Chregu
Nachdem ich alles mit PureBasic mache, und auch für Web-Anwendung schon ein SpiderBasic-Programm erfolgreich hingekriegt habe
http://carpatrain.magnetmotor.ch/umrech ... chner.html
wollte ich nun mit der WebSerial API auf die serielle Schnittstelle zugreifen
Beschreibung MC.net:
https://www.mikrocontroller.net/topic/556536
Manual zu Chrome:
https://developer.chrome.com/docs/capab ... rial?hl=de
Aber schon der einfachste Versuch mit
schlägt fehl, also genau lädt nicht mal die Seite.
Das Testprogramm:
Code: Alles auswählen
Procedure GadgetEvents()
Select EventGadget() ; To see which menu has been selected
Case 2 ;Umrechnen
EnableJS
v_port = await navigator.serial.requestPort();
;await port.open({ baudRate: 9600 });
DisableJS
SetGadgetText(10, "Test")
Default
;
EndSelect
EndProcedure
;
; We just have to open a window and see when an event happen on the menu
;
If OpenWindow(0, 0, 0, 300, 220, "WebSerial Test", #PB_Window_TitleBar + #PB_Window_ScreenCentered)
ButtonGadget(2, 30, 50, 240, 20, "Testen")
TextGadget(9, 30, 170, 180, 20, "Ausgabe:")
StringGadget(10, 220, 170, 50, 20, "0", #PB_String_ReadOnly)
BindEvent(#PB_Event_Gadget, @GadgetEvents())
EndIf
Das Ganze in JS zu machen schreckt mich anhand der Kompliziertheit etwas ab. Deshalb die Frage: Ist das überhaupt möglich mit SB? Am Schluss möchte ich einfach mit ein paar Buttons verschiedene Strings schicken und die Antwort im StringGadget anzeigen. Das Programm darf explizit blockierend auf den Antwort-String warten (endet mit \n).
Danke und
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 20.12.2023 14:51
von Kiffi
await darf nur in async - Funktionen aufgerufen werden:
Code: Alles auswählen
Procedure GadgetEvents()
Protected Port
Select EventGadget()
Case 2
! async function test() {
! v_port = await navigator.serial.requestPort();
; ....
! }
! test();
Default
EndSelect
EndProcedure
If OpenWindow(0, 0, 0, 300, 220, "WebSerial Test", #PB_Window_TitleBar + #PB_Window_ScreenCentered)
ButtonGadget(2, 30, 50, 240, 20, "Testen")
TextGadget(9, 30, 170, 180, 20, "Ausgabe:")
StringGadget(10, 220, 170, 50, 20, "0", #PB_String_ReadOnly)
BindEvent(#PB_Event_Gadget, @GadgetEvents())
EndIf
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 20.12.2023 17:06
von Chregu
Danke Kiffi!
Das funktioniert!
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 21.12.2023 09:32
von Chregu
Jetzt kommt natürlich das nächste Problem:
Code: Alles auswählen
Case 3 ;Daten senden
EnableJS
async function senden() {
const writer = v_port.writable.getWriter();
const Data = new Uint8Array([104, 101, 108, 108, 111]); // hello
await writer.write(Data);
// Allow the serial port To be closed later.
writer.releaseLock();
}
senden();
DisableJS
Erscheint in der Browser-Konsole:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'getWriter')
Wenn ich das "v_" nach "const writer =" weglasse kommt keine Fehlermeldung, gesendet wird aber nichts. Ich vermute einerseits, dass Variablen von einem InlineJS zum Nächsten "vergessen" werden, andererseits warscheinlich der Typ nicht stimmt. Scheint ja ein Objekt zu sein.
Diesbezüglich hält sich die Anleitung zu SB sehr spartanisch.
Gruss Chregu
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 21.12.2023 11:26
von Kiffi
In dem Fall solltest Du "Port" global deklarieren. Der Variablenpräfix ändert sich dann von "v_" zu "g_":
Code: Alles auswählen
Global Port
Procedure GadgetEvents()
Select EventGadget()
Case 2
! async function oeffnen() {
! g_port = await navigator.serial.requestPort();
! // ...
! }
! oeffnen();
Case 3
! async function senden() {
! const writer = g_port.writable.getWriter();
! // ...
! }
! senden();
Default
EndSelect
EndProcedure
(Das ist aber auch ein ganz normales Vorgehen in der Programmierung und hat nichts speziell mit SpiderBasic oder JavaScript zu tun)
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 21.12.2023 15:50
von Chregu
Danke, so geht's!
In dem Fall solltest Du "Port" global deklarieren. Der Variablenpräfix ändert sich dann von "v_" zu "g_":
Fast. Ich zitiere aus dem HTML Help:
Here are the naming rules to use when accessing SpiderBasic items: - JavaScript variable name is the same in lowercase with a 'v_' prefix. It's the same for local variable, global variable and function parameter.
Das ist aber auch ein ganz normales Vorgehen in der Programmierung und hat nichts speziell mit SpiderBasic oder JavaScript zu tun
Ich konnte mir nur noch nicht vorstellen, wie der Variablenaustausch zwischen den Beiden funktioniert.
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 21.12.2023 17:33
von Kiffi
Chregu hat geschrieben: 21.12.2023 15:50Fast. Ich zitiere aus dem HTML Help:
Here are the naming rules to use when accessing SpiderBasic items: - JavaScript variable name is the same in lowercase with a 'v_' prefix. It's the same for local variable, global variable and function parameter.
Das war früher einmal so. Die Dokumentation bedarf hier einer Überarbeitung. Den Präfix von (globalen) Variablen kannst Du Dir ganz gut in der Developer-Konsole Deines Browser anschauen.
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 21.12.2023 17:42
von Chregu
Danke Kiffi!
Ich komme dann wahrscheinlich noch einmal wegen dem reader mit einer Frage, das ist ja noch ein bisschen komplizierter...
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 27.12.2024 13:45
von Chregu
Also das
Code: Alles auswählen
EnableJS
async function verbinden() {
g_port = await navigator.serial.requestPort();
await g_port.open({ baudRate: 9600 });
}
verbinden();
DisableJS
SetGadgetText(10, "Serielle Schnittstelle geöffnet")
funktioniert schön. Aber ich wollte jetzt das Programm erweitern. Momentan wird sofort nach dem Klick auf "Verbinden" (das den Schnipsel aufruft) "Serielle Schnittstelle geöffnet" angezeigt, was ja manchmal nicht stimmt. Also das Problem ist, dass der Funktionsaufruf nicht auf das Ende wartet (was ja auch normal zu sein scheint) und ich keine Rückgabewerte bekommen kann. Also weder:
Code: Alles auswählen
EnableJS
async function verbinden() {
try {
g_port = await navigator.serial.requestPort();
await g_port.open({ baudRate: 9600 });
// Erfolgreiche Verbindung, also return null oder eine Erfolgsmeldung
g_fehler = 0;
} catch (err) {
if (err.name === 'AbortError') {
g_fehler = 42;
} else if (err.name === 'NotAllowedError') {
g_fehler = 43;
} else if (err.name === 'SecurityError') {
g_fehler = 44;
} else {
g_fehler = 45;
}
}
}
async function starten() {
await verbinden();
}
//verbinden();
starten();
DisableJS
MessageRequester("Rückgabewert: "+Str(fehler), #PB_MessageRequester_Ok)
SetGadgetText(10, "Serielle Schnittstelle geöffnet")
noch das Gleiche mit return geht nicht. Der Requester für die Schnittstelle erscheint dann gar nicht (bzw. scheint gar nicht zu erscheinen) stattdessen bekomme ich sofort 0 zurück, und beim nächsten Mal 45.
Diese .html Datei mit rein JS funktioniert:
Code: Alles auswählen
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Serial Port Verbindung</title>
</head>
<body>
<button id="connectButton">Verbindung herstellen</button>
<script>
let g_fehler = 0;
async function verbinden() {
try {
const port = await navigator.serial.requestPort(); // Warten auf Benutzerinteraktion
if (!port) {
console.error("Kein Port ausgewählt");
return;
}
await port.open({ baudRate: 9600 });
g_fehler = 0; // Erfolgreiche Verbindung
console.log("Verbindung erfolgreich mit Port:", port);
} catch (err) {
// Fehlerbehandlung
if (err.name === 'AbortError') {
g_fehler = 42;
} else if (err.name === 'NotAllowedError') {
g_fehler = 43;
} else if (err.name === 'SecurityError') {
g_fehler = 44;
} else {
g_fehler = 45;
}
console.error("Fehler bei der Verbindung:", err);
}
}
// Benutzerinteraktion auslösen
document.getElementById('connectButton').addEventListener('click', async () => {
await verbinden();
console.log("Fehlercode:", g_fehler);
});
</script>
</body>
</html>
Ich weiss nicht mehr weiter. Ich möchte nur, dass ich weiss, ob die Schnittstelle zur Verfügung steht, und dies beim Drücken anderer Buttons zum Senden verschiedener Strings berücksichtigt wird (Userfreundlichkeit). Momentan funktionierts so:
https://chregu73.github.io/carparameter.html
Gruss Chregu
Re: WebSerial mit SpiderBasic überhaupt möglich?
Verfasst: 28.12.2024 12:50
von Chregu
Der Requester für die Schnittstelle erscheint dann gar nicht (bzw. scheint gar nicht zu erscheinen)
Habe jetzt herausgefunden, dass wirklich nicht zu Erscheinen scheint. Wenn man die Ausgabe in die Konsole oder in ein Text-Gadget macht, geht es.
Aber der Unterschied ist, dass der in HTML eingebettete Code funktioniert, mit warten, aber in SpiderBasic nicht. Irgendwie funktioniert das mit dem async / await nicht richtig!
Gruss Chregu