async _out => {},
// body
async _out => {
- div.slidecontainer {
- input.slider#myRange(type="range" min="1" max="100" value="50") {}
+ div {
+ div.container-fluid {
+ div.row {
+ div.col-sm-8 {
+ 'MiRobot status: '
+ span#connection-status {'Disconnected'}
+ }
+ div.col-sm-4 {
+ button.btn.btn-block.btn-primary.float-right#connect-disconnect(type="button") {'Connect'}
+ }
+ }
+ }
+ }
+ div {
+ div.container-fluid {
+ div.row {
+ div.col-sm-8 {
+ input.slider#slider-a(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-4 {
+ 'Value: '
+ span#value-a {'0'}
+ }
+ }
+ }
+ }
+ div {
+ div.container-fluid {
+ div.row {
+ div.col-sm-8 {
+ input.slider#slider-b(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-4 {
+ 'Value: '
+ span#value-b {'0'}
+ }
+ }
+ }
+ }
+ div {
+ div.container-fluid {
+ div.row {
+ div.col-sm-8 {
+ input.slider#slider-c(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-4 {
+ 'Value: '
+ span#value-c {'0'}
+ }
+ }
+ }
}
div {
- 'Value: '
- span#demo {'50'}
+ div.container-fluid {
+ div.row {
+ div.col-sm-8 {
+ input.slider#slider-d(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-4 {
+ 'Value: '
+ span#value-d {'0'}
+ }
+ }
+ }
}
}
// scripts
async _out => {
script {
+ let sleep = ms => {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
+
+ let rx_active = false
+ let rx_cont = false
+ let rx_buf = ''
+ let rx_task = async device => {
+ console.log('rx_task')
+ rx_active = true
+ try {
+ while (rx_cont) {
+ transfer_result = await device.transferIn(2, 1)
+ //console.log('transfer_result', transfer_result)
+ if (transfer_result.status === 'ok')
+ for (let i = 0; i < transfer_result.data.byteLength; ++i) {
+ if (rx_buf.length >= 1024) {
+ console.log('rx_task overrun')
+ break
+ }
+ rx_buf += String.fromCharCode(
+ transfer_result.data.getUint8(0)
+ )
+ }
+ }
+ }
+ catch (err) {
+ console.log('rx_task err', err.message)
+ }
+ console.log('rx_task done')
+ rx_active = false
+ }
+ let rx_stop = async () => {
+ console.log('rx_stop')
+ rx_cont = false
+ while (rx_active)
+ await sleep(100)
+ console.log('rx_stop done')
+ }
+
+ let tx_immediate = async (device, text) => {
+ console.log('tx_immediate', text)
+ data = new Uint8Array(text.length);
+ for (var i = 0; i < text.length; ++i)
+ data[i] = text.charCodeAt(i);
+ await device.transferOut(2, data.buffer)
+ }
+
+ let device, device_busy = false
+ document.getElementById('connect-disconnect').addEventListener(
+ 'click',
+ () => {
+ ;(
+ async () => {
+ if (!device_busy) {
+ device_busy = true
+ if (device === undefined) {
+ // connect request
+ try {
+ device = await navigator.usb.requestDevice(
+ {filters: [{vendorId: 0x1a86, productId: 0x7523}]}
+ )
+ await device.open()
+ try {
+ await device.selectConfiguration(1)
+ await device.claimInterface(0)
+
+ console.assert(!rx_active, '!rx_active')
+ rx_cont = true
+ rx_task(device)
+
+ await sleep(100)
+ rx_buf = ''
+
+ tx_immediate(device, '\n')
+ await sleep(100)
+ if (rx_buf.slice(0, 1) === '>') {
+ console.log('prompt detected')
+ rx_buf = rx_buf.slice(1)
+ document.getElementById('connection-status').innerHTML = 'Connected'
+ document.getElementById('connect-disconnect').innerHTML = 'Disconnect'
+ }
+ else {
+ console.log('no prompt detected')
+ device.close()
+ await rx_stop()
+ device = undefined
+ }
+ }
+ catch (err) {
+ console.log('exception', err.message)
+ device.close()
+ await rx_stop()
+ device = undefined
+ }
+ }
+ catch (err) {
+ console.log('exception', err.message)
+ device = undefined
+ }
+ }
+ else {
+ // disconnect request
+ device.close()
+ await rx_stop()
+ device = undefined
+ document.getElementById('connection-status').innerHTML = 'Disconnected'
+ document.getElementById('connect-disconnect').innerHTML = 'Connect'
+ }
+ device_busy = false
+ }
+ }
+ )()
+ }
+ )
+
// see https://www.w3schools.com/howto/howto_js_rangeslider.asp
- var slider = document.getElementById("myRange");
- var output = document.getElementById("demo");
- output.innerHTML = slider.value; // Display the default slider value
+ var slider_a = document.getElementById("slider-a");
+ var value_a = document.getElementById("value-a");
+ value_a.innerHTML = slider_a.value;
+ slider_a.oninput = function() {
+ value_a.innerHTML = this.value
+ if (device && !device_busy)
+ tx_immediate(
+ device,
+ `a32000 A${Math.round(this.value * (16000 / 90) + 24000)}\n`
+ )
+ }
+
+ var slider_b = document.getElementById("slider-b");
+ var value_b = document.getElementById("value-b");
+ value_b.innerHTML = slider_b.value;
+ slider_b.oninput = function() {
+ value_b.innerHTML = this.value
+ if (device && !device_busy)
+ tx_immediate(
+ device,
+ `b32000 B${Math.round(this.value * (16000 / 90) + 24000)}\n`
+ )
+ }
+
+ var slider_c = document.getElementById("slider-c");
+ var value_c = document.getElementById("value-c");
+ value_c.innerHTML = slider_c.value;
+ slider_c.oninput = function() {
+ value_c.innerHTML = this.value
+ if (device && !device_busy)
+ tx_immediate(
+ device,
+ `c32000 C${Math.round(this.value * (16000 / 90) + 24000)}\n`
+ )
+ }
- // Update the current slider value (each time you drag the slider handle)
- slider.oninput = function() {
- output.innerHTML = this.value;
+ var slider_d = document.getElementById("slider-d");
+ var value_d = document.getElementById("value-d");
+ value_d.innerHTML = slider_d.value;
+ slider_d.oninput = function() {
+ value_d.innerHTML = this.value
+ if (device && !device_busy)
+ tx_immediate(
+ device,
+ `d32000 D${Math.round(this.value * (16000 / 90) + 24000)}\n`
+ )
}
}
}
)
-}
+}