• Thx @Mr.Peu, here I recorded a short video (it is really unstable, because of one handed work)
    short preview video

    It looks better and is really stable if the MPU lays on the desk and you flip and rotate it.
    Next steps:

    • get some OLED displays (currently I have 2 with CS pin and 2 without)
    • connect all displays to Pico
    • laser cut cube and built everything in

    This is the current source code from the video:

    var mpu;
    var direction = -1;
    var maxAccThreshold = 15000;
    var maxRotThreshold = 5000;
    var value = 0;
    var detectRotation = false;
    
    // get sum of all values
    function getSum(xyz) {
      return (Math.abs(xyz[0])+Math.abs(xyz[1])+Math.abs(xyz[2]));
    }
    
    // get -1 or 1 for each value depending on the acceleration reach the threshold
    function getDirectionByAccelerationThreshold(xzzAcc) {
      var xyzAccDir = [0,0,0];
      var index = 0;
      xzzAcc.forEach(function(xyzValue) {
        if (xyzValue < -maxAccThreshold) xyzAccDir[index] = -1;
        if (xyzValue > maxAccThreshold)  xyzAccDir[index] = 1;    
        index++;
      });
      return xyzAccDir;
    }
    
    // get direction (up,down,left,right,back,front) by xyz
    function getDirection(xyzAcc) {
      var newDirection = -1;
      if (xyzAcc[2] === 1)       newDirection = 0; /*up*/
      else if (xyzAcc[2] === -1) newDirection = 1; /*down*/
      else if (xyzAcc[1] ===  1) newDirection = 2; /*left*/
      else if (xyzAcc[1] === -1) newDirection = 3; /*right*/
      else if (xyzAcc[0] ===  1) newDirection = 4; /*back*/
      else if (xyzAcc[0] === -1) newDirection = 5; /*front*/
      return newDirection;
    }
    
    // get rotation (left: -1, right: 1) by up,down,left,right,back,front
    function getRotationByDirection(xyzRot, dir) {
      var newRotation = 0;
      switch(dir) {
        case 0: /*up*/    newRotation = -xyzRot[2]; break;
        case 1: /*down*/  newRotation = xyzRot[2];  break;
        case 2: /*left*/  newRotation = -xyzRot[1]; break;
        case 3: /*right*/ newRotation = xyzRot[1];  break;
        case 4: /*back*/  newRotation = -xyzRot[0]; break;
        case 5: /*front*/ newRotation = xyzRot[0];  break;
        default: console.log("cube direction: undefined"); break;
      }
      return newRotation;
    }
    
    // get -1 or 1 for each value depending on the rotation reach the threshold
    function getDirectionByRotationThreshold(xzzRot) {
      var xyzRotDir = [0,0,0];
      var index = 0;
      xzzRot.forEach(function(xyzValue) {
        if (xyzValue < -maxRotThreshold) xyzRotDir[index] = -1;
        if (xyzValue > maxRotThreshold)  xyzRotDir[index] = 1;    
        index++;
      });
      return xyzRotDir;
    }
    
    // get rotation step (-50 to +50) by up,down,left,right,back,front
    function getRotationStepByDirection(xyzRotPerSec, dir) {
      var rotationStep = 0;
      switch(dir) {
        case 0: /*up*/    rotationStep = -xyzRotPerSec[2]; break;
        case 1: /*down*/  rotationStep = xyzRotPerSec[2];  break;
        case 2: /*left*/  rotationStep = -xyzRotPerSec[1]; break;
        case 3: /*right*/ rotationStep = xyzRotPerSec[1];  break;
        case 4: /*back*/  rotationStep = -xyzRotPerSec[0]; break;
        case 5: /*front*/ rotationStep = xyzRotPerSec[0];  break;
        default: console.log("cube direction: undefined"); break;
      }
      return Math.round(rotationStep);
    }
    
    // print cube direction log
    function printDirectionLog(dir) {
      switch(dir) {
        case 0:  console.log("cube side: up");        break;
        case 1:  console.log("cube side: down");      break;
        case 2:  console.log("cube side: left");      break;
        case 3:  console.log("cube side: right");     break;
        case 4:  console.log("cube side: back");      break;
        case 5:  console.log("cube side: front");     break;
        default: console.log("cube side: undefined"); break;
      }
    }
    
    // read accelerations and get direction
    function readMPU6050() {
      var xzzAcceleration = mpu.getAcceleration();
      
      // get direction (-1 or 1) for each value (x/y/z)
      var xyzAccDirection = getDirectionByAccelerationThreshold(xzzAcceleration);
      // get sum of all acceleration values
      var sumAcc = getSum(xyzAccDirection); 
      // is the sum 0 than no cube side is active
      if (sumAcc != 1)
        return;
      
      // get new direction (x/y/z is -1 or 1)
      var newDirection = getDirection(xyzAccDirection);
      
      // print new direction log
      if (direction != newDirection) {
        printDirectionLog(newDirection);
        // reset rotation value and restart capture after 500ms
        detectRotation = false;
        //print("detectRotation: false");
        if (!detectRotation) {
          setTimeout(function() {
            value = 0;
            detectRotation = true;
            //print("detectRotation: true");
          }, 500);
        }
      }
      direction = newDirection;
      // detect new rotation
      if (detectRotation) {
        // get rotation of x/y/z 
        var xytRotation = mpu.getRotation();
    
        // get direction (-1 or 1) for each value (x/y/z)
        var xyzRotDirection = getDirectionByRotationThreshold(xytRotation);
    
        // get sum of all rotation values
        var sumRot = getSum(xyzRotDirection);
        // is the sum 0 than no rotation detected
        if (sumRot != 1)
          return;
    
        // get rotation direction (left/right) by cube side (up,down,left,front,...)
        // left: -1, right: 1
        var rotationDirection = getRotationByDirection(xyzRotDirection, direction);
        // get step size for left or right rotation
        var xyzRotationPerSec = mpu.getDegreesPerSecond();
        var rotationStep = getRotationStepByDirection(xyzRotationPerSec, direction);
    
        // print log of rotation direction and value by step size
        value += rotationStep;
        value = Math.max(Math.min(value, 1000), -1000);
        print("rotation: "+(rotationDirection === -1 ? "left" : "right")+ " value: "+value);
      } // if (detectRotation)
    }
    
    // init the module and start interval
    function onInit() {
      I2C2.setup({scl:B10,sda:B3});
      mpu = require("MPU6050").connect(I2C2);
      setInterval(readMPU6050, 100);
    }
    
    onInit();
    
About

Avatar for Jorgen @Jorgen started