Demo




Things Used In This ProjectClick image for larger version  Name:	dice_things.png Views:	1 Size:	341.6 KB ID:	565


Working Flow

Click image for larger version  Name:	Dice_Working Flow.png Views:	1 Size:	5.8 KB ID:	566
Source Code

You can get library for MM7150 here: https://forum.phpoc.com/blogs/khanh-...rary-for-phpoc

Main task (task0.php)

This task responds for reading data from MM7150 and send it via websocket to Client
PHP Code:
<?php

if(_SERVER("REQUEST_METHOD"))
    exit; 
// avoid php execution via http request

include_once "/lib/sd_340.php";
include_once 
"/lib/vd_MM7150_pin_map.php";
include_once 
"/lib/vn_hid_i2c.php";
include_once 
"/lib/vd_MM7150.php";

function 
unsign2sign($val)
{
    if(
$val&0x8000)
        
$val = ($val&0x7fff) - 0x8000;

    return 
$val;
}
// Init user interface

i2c_setup(0MM7150_ADDR);
uio_setup(0INT_PIN"in");
uio_setup(1WAKEUP_PIN"out");
uio_out(1WAKEUP_PINHIGH);    
ws_setup(0"inclinometer""csv.phpoc");
//List of sensor in use

$sensor_list = array(
                
ACCEL_SENSOR_TYPE,
                
GYRO_SENSOR_TYPE,
                
CMP_SENSOR_TYPE,
                
ORI_SENSOR_TYPE,
                
INCL_SENSOR_TYPE);

// Init MM7150. Retrieve HID & report descriptors, and all device features
mm7150_init($sensor_list);

//$sensor_type = ACCEL_SENSOR_TYPE;
//$sensor_type = GYRO_SENSOR_TYPE;
//$sensor_type = CMP_SENSOR_TYPE;
//$sensor_type = ORI_SENSOR_TYPE;
$sensor_type INCL_SENSOR_TYPE;

mm7150_enable_sensor($sensor_type);

$mult hid_i2c_get_exponent($sensor_type);

$data "";    

hid_i2c_request_data($data$sensor_type);

$x_val unsign2sign(bin2int($data02)) * $mult;
$y_val unsign2sign(bin2int($data22)) * $mult;
$z_val unsign2sign(bin2int($data42)) * $mult;

while(
1)
{    
    
/*
    //Polling Driven
    hid_i2c_request_data($data, $sensor_type);

    $x_val = unsign2sign(bin2int($data, 0, 2)) * $mult;
    $y_val = unsign2sign(bin2int($data, 2, 2)) * $mult;
    $z_val = unsign2sign(bin2int($data, 4, 2)) * $mult;

    echo "pitch: ", $x_val , ",   ";
    echo "roll : ", $y_val , ",   ";
    echo "yaw  : ", $z_val , "\r\n";

    */

    // Event Driven
    
if(uio_in(0INT_PIN) == INT_ASSERTED)
    {                    
        
$data "";        

        
$in_sens_type hid_i2c_read_data($data);

        if(
$in_sens_type == $sensor_type)
        {
            
$x_val unsign2sign(bin2int($data02)) * $mult;
            
$y_val unsign2sign(bin2int($data22)) * $mult;
            
$z_val unsign2sign(bin2int($data42)) * $mult;

            echo 
"pitch: "$x_val ",   ";
            echo 
"roll : "$y_val ",   ";
            echo 
"yaw  : "$z_val "\r\n";

            if(
ws_state(0) == TCP_CONNECTED)
            {
                
$wbuf "[$x_val$y_val$z_val]";
                
ws_write(0$wbuf);
            }
        }
    }
    
//Client may request data for the first time to get offset.
    
if(ws_state(0) == TCP_CONNECTED)
    {
        
$rbuf "";
        
$rlen ws_read_line(0$rbuf);

        if(
$rlen)
        {
            
$wbuf "[$x_val$y_val$z_val]";
            
ws_write(0$wbuf);
        }
    }
}

?>



Web page (index.php)

This code responds for receive real-time data from PHPoC via web socket and update state of dice.
I use three js library https://threejs.org/ to draw 3D dice and rotate it
PHP Code:
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - geometry - cube</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body { text-align: center;}
            #myCanvas {
                margin-right: auto;
                margin-left: auto;
                width: 400px;
                height: 400px;
                position: relative;
                border: 1px solid #000;
                background-color: #000000;
            }
        </style>
        <script>
            var pitch = 0, roll = 0, yaw = 0;
            var pitch_offset = 0, roll_offset = 0, yaw_offset = 0;            
            var ws = null;
            var first_data = true;

            function ws_onopen()
            {
                document.getElementById("ws_state").innerHTML = "OPEN";
                document.getElementById("wc_conn").innerHTML = "Disconnect";
                first_data = true;
                //Send request to get data
                ws.send("0\r\n");
            }
            function ws_onclose()
            {
                document.getElementById("ws_state").innerHTML = "CLOSED";
                document.getElementById("wc_conn").innerHTML = "Connect";
                ws.onopen = null;
                ws.onclose = null;
                ws.onmessage = null;
                ws = null;
            }
            function ws_onmessage(e_msg)
            {
                var arr = JSON.parse(e_msg.data);
                if(first_data)
                {
                    first_data = false;
                    pitch_offset = arr[0];
                    roll_offset  = arr[1];
                    yaw_offset   = arr[2];
                }
                pitch = (arr[0] - pitch_offset) * Math.PI/180;
                roll  = (arr[1] - roll_offset) * Math.PI/180;
                yaw   = (arr[2] - yaw_offset) * Math.PI/180;
                console.log("pitch: "+ arr[0] +", roll: "+ arr[1] +", yaw: "+ arr[2]);
            }
            function wc_onclick()
            {
                if(ws == null)
                {
                    ws = new WebSocket("ws://<?echo _SERVER("HTTP_HOST")?>/inclinometer", "csv.phpoc");
                    document.getElementById("ws_state").innerHTML = "CONNECTING";

                    ws.onopen = ws_onopen;
                    ws.onclose = ws_onclose;
                    ws.onmessage = ws_onmessage;
                }
                else
                    ws.close();
            }
        </script>
    </head>
    <body>
        <canvas id="myCanvas"></canvas>
        <script src="https://threejs.org/build/three.js"></script>

        <script>

            var camera, scene, renderer;
            var mesh;

            init();
            animate();

            function init() {

                camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
                camera.position.y = 40;
                camera.position.z = 60;
                camera.lookAt(new THREE.Vector3( 0, -2, -5 ));

                scene = new THREE.Scene();

                var geometry = new THREE.BoxBufferGeometry(20, 20, 20, 2, 2, 2);

                //var material = new THREE.MeshBasicMaterial( { map: texture } );
                var materials = [
                       new THREE.MeshBasicMaterial({
                           map: new THREE.TextureLoader().load('dice_1.jpg')
                       }),
                       new THREE.MeshBasicMaterial({
                           map: new THREE.TextureLoader().load('dice_2.jpg')
                       }),
                       new THREE.MeshBasicMaterial({
                           map: new THREE.TextureLoader().load('dice_3.jpg')
                       }),
                       new THREE.MeshBasicMaterial({
                           map: new THREE.TextureLoader().load('dice_4.jpg')
                       }),
                       new THREE.MeshBasicMaterial({
                           map: new THREE.TextureLoader().load('dice_5.jpg')
                       }),
                       new THREE.MeshBasicMaterial({
                           map: new THREE.TextureLoader().load('dice_6.jpg')
                       })
                    ];

                mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial(materials ));
                mesh.position.y = 10;
                scene.add( mesh );

                var grid = new THREE.GridHelper( 50, 20, 0xFFFFFF, 0XFFFFFF);
                //grid.rotateOnAxis( new THREE.Vector3( 1, 0, 0 ), 90 * ( Math.PI/180 ) );
                grid.position.y = 0;
                grid.material.opacity = 0.25;
                grid.material.transparent = true;
                scene.add( grid );

                var canvas = document.getElementById("myCanvas");
                renderer = new THREE.WebGLRenderer({ canvas: canvas });

                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth/2, window.innerHeight/2 );
                document.body.appendChild( renderer.domElement );


                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth/2, window.innerHeight/2 );

            }

            function animate() {

                requestAnimationFrame( animate );

                mesh.rotation.x = roll;
                mesh.rotation.y = yaw;
                mesh.rotation.z = pitch;

                renderer.render( scene, camera );
            }

        </script>
        <p>WebSocket : <span id="ws_state">null</span><br></p>
        <button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button>
    </body>
</html>




You can get full source code here: full_source_dice.zip
Attached Files