'wakeOnTouch' for Bangle.js 2

Posted on
  • Hi,
    I'm trying to get a 'Bangle.js 2' to wake up whenever the screen is touched.

    I've isolated my code into this silly test app :

    var dummy = 0;
    Bangle.on("touch", function() {
      g.drawString((++dummy).toString(), 10, 10);

    Touch events are properly captured when the device is awake, but once it sleeps (dim LED backlight), no further events are thrown. Only after a BTN1 click, events are recognized again.

    The wakeOnTouch option seems to be properly set :

    ={ gestureStartThresh: 640000, gestureEndThresh: 4000000, gestureInactiveCount: 4, gestureMinLength: 10,
      stepCounterThresholdLow: 32, stepCounterThresholdHigh: 78149, twistThreshold: 819, twistTimeout: 1000, twistMaxY: -800,
      wakeOnBTN1: true, wakeOnBTN2: true, wakeOnBTN3: true, wakeOnFaceUp: false, wakeOnTouch: true,
      wakeOnTwist: true, powerSave: false, lockTimeout: 10000, lcdPowerTimeout: 0, backlightTimeout: 10000 }
      VERSION: "2v09.120",
      GIT_COMMIT: "8c650226b",
      FLASH: 1048576, SPIFLASH: 8388608, HWVERSION: 2, STORAGE: 8388608, RAM: 262144,
      SERIAL: "5705650f-3ec9f6bf",
      CONSOLE: "Bluetooth",
      MODULES: "Flash,Storage,heatshrink,locale",
      EXPTR: 536884176 }

    Is this expected behavior ? What am I missing ?


  • Ahh, yes, it's a bit more confusing now.

    The challenge is that the touchscreen itself draws quite a lot of power when it's on. You can't really leave it on all the time or it'll drain the battery over the course of a week or so.

    So there's now this idea of 'locking'. When the device is locked the lock icon appears and the touchscreen is turned off. You can do Bangle.setLocked(false) as well as Bangle.setOptions({lockTimeout:0}) (http://www.espruino.com/Reference#t_l_Ba­ngle_setOptions) to force the touchscreen to be enabled all the time.

    However then touches go through to apps all the time.

    I guess the ideal solution might be to use the accelerometer for tap detection. It has something built-in, but right now it seems badly calibrated:

    Bangle.on('tap',function(t) {
      print(t); // for debugging
      if (t.double) Bangle.setLocked(0);
    Bangle.accelWr(0x1E,[0x3F]); // enable tap detect

    Even so you seem to be able to unlock it pretty well by just tapping twice (about the speed you'd say 'one two' - not too quick).

    I think the TDTC, TTH, TTL, FTD, STD, TLT and TWS values could do with some fine tuning though - maybe making it less sensitive but then more able to detect faster double taps.

    More info at https://kionixfs.azureedge.net/en/datash­eet/KX023-1025%20Specifications%20Rev%20­12.0.pdf - you can just use Bangle.accelWr to poke the relevant values

  • Just to add I think this is something that I should probably add internally on Bangle.js 2? Keep tap to wake, but make it use the accelerometer instead.

  • The 'tap' event works fine, but it is not very 'sensitive'. One has to tap pretty hard...

    Handling it internally is of course always a good idea (and keeps the interface identical across different Espruino devices).

    (I could not find the documentation for the 'tap' event on the Espruino Hardware Reference page.)

  • I'd implemented it all on Bangle.js 1 (it was always in there) but it wasn't working because it seems I'd forgotten Bangle.accelWr(0x1E,[0x3F]), so I'd stopped it appearing in the documentation!

    For some reason I also seemed to have moved to some non-standard thresholds for the accelerometer, so I've now just set them back to normal and tap detect does work a bit more sensibly.

    So in cutting edge builds, everything is now working. Plus on Bangle.js 2, tap to wake now works using the accelerometer as well!

  • That's great. Also, the KX023 datasheet mentions to clear the PC1 bit before changing some/all registers, so the thing I did is :

    var tmp = Bangle.accelRd(0x18);    // CNTL_1
    Bangle.accelWr(0x18,[tmp & 0x7F]); // Clear PC1 bit : reset state
    Bangle.accelWr(0x1E,[0x3F]);       // INC3 : enable X,Y,Z axis interrupts
    Bangle.accelWr(0x18,[tmp | 0x80]); // Set PC1 : start accelerometer with new settings
  • With the above solution I've been using a 'wake on tap' mechanism to get the Bangle.js 2 out of the locked state with a tap on the screen. With 2V09 firmware, this works flawlessly.

    > // Tap on a locked Bangle.js 2
    tap {
      "dir": "back",
      "double": false, "x": 0, "y": 0, "z": 1 }

    I now have a Bangle.js 2 with 2V10 firmware. All of the above no longer works. How can I use the 'tap' event in 2V10 ?

    > // Some taps here
  • Sorry, not sure what's up with this. I'll check now.

    However for wake on tap, it's now built in. If you go to Settings -> LCD -> Wake on Touch and set it to on, tapping on the display will now automatically unlock the watch

  • Sorry about that - just fixed, so cutting edge builds will have that change in. As I think you might be making your own JS firmware for the watch, you can use Bangle.setOptions to set up the wake on tap behaviour if you want

  • OK. (Not OK really, because I now have a bunch of watches to update, but at least it's fixed.)

  • With your suggestions above, I've got a working solution :

    Bangle.on("touch", function(b, xy) 
      console.log("main - touch",b,xy, Bangle.isLocked());

    But it looks like, when in locked state, I have to tap twice - not a 'double tap', but tap - wait - tap :

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v10.89 (c) 2021 G.Williams
    // Tap
    // No response <============
    // Tap
    // Response
    main - touch 2 { "x": 91, "y": 77, "type": 0 } false
    // Tap
    // Response
    main - touch 1 { "x": 58, "y": 112, "type": 0 } false
    // Tap
    // Response
    main - touch 1 { "x": 62, "y": 110, "type": 0 } false
    // Wait until locked
    // Tap
    // No response <============
    // Tap
    // Response
    main - touch 2 { "x": 90, "y": 76, "type": 0 } false
    // Tap
    // Response
    main - touch 2 { "x": 92, "y": 78, "type": 0 } false

    Or is this normal behavior ?

  • Yes, that's expected - because if your app is using the tap event you probably wouldn't want the initial one to be counted. You could however respond to the Bangle.on('lock' event.

    If you don't want the behaviour then you can just have wakeOnTouch:false and all the taps will go through

  • Ah OK. I overlooked the 'lock' event. I does indeed fire after the first tap.
    Thank you

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

'wakeOnTouch' for Bangle.js 2

Posted by Avatar for jgw @jgw