Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
DemonstrationWorking Flow
Read moreYou can get full source code here: http://www.phpoc.com/forum/download/file.php?id=441
Main task (task0.php)
PHPThis task responds for reading data from MM7150 and send it via websocket to Client.
You can get library for MM7150 here: http://www.phpoc.com/forum/viewtopic.php?f=42&t=223
You can get library for MM7150 here: http://www.phpoc.com/forum/viewtopic.php?f=42&t=223
<?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(0, MM7150_ADDR);
uio_setup(0, INT_PIN, "in");
uio_setup(1, WAKEUP_PIN, "out");
uio_out(1, WAKEUP_PIN, HIGH);
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($data, 0, 2)) * $mult;
$y_val = unsign2sign(bin2int($data, 2, 2)) * $mult;
$z_val = unsign2sign(bin2int($data, 4, 2)) * $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(0, INT_PIN) == INT_ASSERTED)
{
$data = "";
$in_sens_type = hid_i2c_read_data($data);
if($in_sens_type == $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";
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 Interface (index.php)
PHPThis 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
I use three js library https://threejs.org/ to draw 3D dice and rotate it
<!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>
Comments