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();
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
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:
This is the current source code from the video: