puckrotate code - for a puck lying flat

Posted on
  • I am working on my next project. I'd like to change volume via BLE by using the Puck lying flat on a table and rotating it left or right to send a BLE advertisement volume up (right) or volume down (left). So, rotate puck right - send signal "volumeup". rotate Puck left send signal "volume down".

    I don't want (I think) to use the hid keyboard/mouse etc options because I want just a passive signal being sent out to Espruino Hub and "translate" the advertisement via MQTT. I don't want the Puck to have to be connected.

    I have tried the various postings for compasses, mag/accel/ averaging but really had no luck. Must admit the maths go a bit over my head. I think what I should be watching is x? going positive or negative but haven't found that to be true in my tests.

    The I found the puckrotate posted code on the apploader(?) which works, if the button is vertical. I have tried to figure out how to change it such that it works with the button flat - with no luck.


  • For relative rotation you need to use gyro.
    An absolute orientation can be calculated vertically (because you can measure the direction of gravitation force), but horizontally you turn around the direction of gravity so that force is of no use. Compass could be a solution but probably too unreliable.
    But for your volume usecase relative should be good. So try to read gyro.
    (Didn't use IMU on puck yet myself so cannot help with specific commands, but do have experience from other hardware)

  • great pointer - thanks.

  • As mentioned, gyro would work well.

    However compass could be ok as long as there are no magnets floating around (or you could ensure you mount the Puck with a magnet nearby so that you're then measuring the rotation relative to that magnet). You just need to rotate the Puck a full 360 degrees when you start up so you can calibrate the max/minimum values.

    This is some old code I had kicking around that that works out an angle then lights up accordingly. Realistically to work nicely it needs a magnet nearby though

    var Vec3 = require("Vec3");
    var vmin = new Vec3(Puck.mag());
    var vmax = vmin;
    function onMag(xyz) {
      vmin = vmin.min(xyz);
      vmax = vmax.max(xyz);
      var c = vmin.add(vmax).mul(0.5).sub(xyz);
      var a = Math.atan2(c.x,c.y)*180/Math.PI;
    Puck.on('mag', onMag);
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

puckrotate code - for a puck lying flat

Posted by Avatar for kab @kab