Working sliders to control 4 axes
authorNick Downing <nick.downing@lifx.co>
Wed, 18 Mar 2020 04:32:41 +0000 (15:32 +1100)
committerNick Downing <nick.downing@lifx.co>
Wed, 18 Mar 2020 04:32:41 +0000 (15:32 +1100)
stty.sh
test.html.jst

diff --git a/stty.sh b/stty.sh
index 7cdfa6f..2c96885 100755 (executable)
--- a/stty.sh
+++ b/stty.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
-stty -F /dev/ttyUSB0 500000
+stty -F /dev/ttyUSB0 115200
 rmmod ch341
 rmmod usbserial
index a9a9ec8..4a00709 100644 (file)
@@ -7,27 +7,240 @@ return async env => {
     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`
+            )
         }
       }
     }
   )
-} 
+}