Outline
  • Demo
  • Data flow
  • Things used in this project
  • Source Code


1. Demo



2. Data flow

Click image for larger version  Name:	phpoc_color_sensor_dataflow.PNG Views:	1 Size:	6.1 KB ID:	461


3. Things Used In This Project
  • PHPoC Blue
  • Color 2 click (color sensor)
  • Expansion board for Click boards (optional)
  • USB wireless LAN dongle

Click image for larger version  Name:	phpoc_color_sensor_things.PNG Views:	1 Size:	159.7 KB ID:	462

4. Source Code

Apart from library, there are two main source files in PHPoC:
  • index.php: once receiving http request from a client, PHPoC executes this file (only executing source inside <?php ?> tag) and then return a html file to client. So, client side is implemented in this file.
  • task0.php: this file contains the source code of server side. So you can implement the function to receive the command and control the robot here.

[Source code - index.php]
PHP Code:
    <?php
    $ws_host 
_SERVER("HTTP_HOST");
?>
<!DOCTYPE html>
<html>
<head>
<title>PHPoC Color Sensor</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<style type="text/css">
body { text-align: center; }

#color {
    margin-right: auto;
    margin-left: auto;
    width: 500px;
    height: 500px;
    background: url(background.png) no-repeat;
    background-size: contain;
    position: relative;
    margin-bottom: 10px;
    border: 1px solid #000;
}

</style>
<script type="text/javascript">
var ws = null;

function init()
{    
    //document.body.style.backgroundColor = "red";  
}
function ws_onmessage(e_msg)
{
    var arr = JSON.parse(e_msg.data);
    var R = Math.round(arr[0]);
    var G = Math.round(arr[1]);
    var B = Math.round(arr[2]);
    var color = "rgb(" + R + ", " + G + ", " + B +")";
    //document.body.style.backgroundColor = color;
    document.getElementById("color").style.backgroundColor = color;
    console.log(color);
}
function ws_onopen()
{
    document.getElementById("ws_state").innerHTML = "OPEN";
    document.getElementById("wc_conn").innerHTML = "Disconnect";
}
function ws_onclose()
{
    document.getElementById("ws_state").innerHTML = "CLOSED";
    document.getElementById("wc_conn").innerHTML = "Connect";
    console.log("socket was closed");
    ws.onopen = null;
    ws.onclose = null;
    ws.onmessage = null;
    ws = null;
}
function wc_onclick()
{
    if(ws == null)
    {
        ws = new WebSocket("ws://<?echo $ws_host?>/phpoc_color_sensor", "csv.phpoc");
        document.getElementById("ws_state").innerHTML = "CONNECTING";

        ws.onopen = ws_onopen;
        ws.onclose = ws_onclose;
        ws.onmessage = ws_onmessage;
    }
    else
        ws.close();
}
window.onload = init;
</script>
</head>
<body>
<div id="color" class="arrow_up"></div>
<p>
WebSocket : <span id="ws_state">null</span><br>
</p>
<button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button>
</body>
</html>


[Source code - task0.php]
PHP Code:
    <?php

include_once "/PHPoC_ISL29125.php";
include 
"/lib/sn_tcp_ws.php";

// Read sensor values for each color and print them to serial monitor
function read_rgb()
{
    
// Read sensor values (16 bit integers)
    
$red PHPoC_ISL29125_readRed();
    
$green PHPoC_ISL29125_readGreen();
    
$blue PHPoC_ISL29125_readBlue();

    
/*
    // Print out readings
    echo "\r\n Red: ", $red;
    echo "\r\n Green: ", $green;
    echo "\r\n Blue: ",  $blue;
    */

    
if(ws_state(0) == TCP_CONNECTED)
    {
        
$wbuf "[$red$green$blue]";
        
ws_write(0$wbuf);
    }
}

function 
sensor_setup()
{
  
// Initialize the ISL29125 with simple configuration so it starts sampling
  
if (PHPoC_ISL29125_init())
  {
    echo 
"Sensor Initialization Successful\n\r";
  }
  
read_rgb();
}

function 
i2c_sensor_setup()
{
    global 
$pid ;
    
$pid pid_open("/mmap/i2c0");
    
pid_ioctl($pid"req reset");
    
pid_ioctl($pid"set saddr 88");
    
pid_ioctl($pid"set mode sm");
    
pid_ioctl($pid"set role master");
    
//pid_close($pid);
}

$pid 0;

i2c_sensor_setup();
ws_setup(0"phpoc_color_sensor""csv.phpoc");
sensor_setup();

sleep(1);

while(
1)
{
    
read_rgb();
    
usleep(500000);
}


?>


[Library for color sensor - PHPoC_ISL_29125.php]
PHP Code:
    <?php

include_once "/lib/sd_340.php";
// ISL29125 I2C Address
define("ISL_I2C_ADDR"0x44);

// ISL29125 Registers
define("DEVICE_ID"0x00);
define("CONFIG_1"0x01);
define("CONFIG_2"0x02);
define("CONFIG_3"0x03);
define("THRESHOLD_LL"0x04);
define("THRESHOLD_LH"0x05);
define("THRESHOLD_HL"0x06);
define("THRESHOLD_HH"0x07);
define("STATUS"0x08);
define("GREEN_L"0x09);
define("GREEN_H"0x0A);
define("RED_L"0x0B);
define("RED_H"0x0C);
define("BLUE_L"0x0D);
define("BLUE_H"0x0E);

// Configuration Settings
define("CFG_DEFAULT"0x00);

// CONFIG1
// Pick a mode, determines what color[s] the sensor samples, if any
define("CFG1_MODE_POWERDOWN"0x00);
define("CFG1_MODE_G"0x01);
define("CFG1_MODE_R"0x02);
define("CFG1_MODE_B"0x03);
define("CFG1_MODE_STANDBY"0x04);
define("CFG1_MODE_RGB"0x05);
define("CFG1_MODE_RG"0x06);
define("CFG1_MODE_GB"0x07);

// Light intensity range
// In a dark environment 375Lux is best, otherwise 10KLux is likely the best option
define("CFG1_375LUX"0x00);
define("CFG1_10KLUX"0x08);

// Change this to 12 bit if you want less accuracy, but faster sensor reads
// At default 16 bit, each sensor sample for a given color is about ~100ms
define("CFG1_16BIT"0x00);
define("CFG1_12BIT"0x10);

// Unless you want the interrupt pin to be an input that triggers sensor sampling, leave this on normal
define("CFG1_ADC_SYNC_NORMAL"0x00);
define("CFG1_ADC_SYNC_TO_INT"0x20);

// CONFIG2
// Selects upper or lower range of IR filtering
define("CFG2_IR_OFFSET_OFF"0x00);
define("CFG2_IR_OFFSET_ON"0x80);

// Sets amount of IR filtering, can use these presets or any value between", 0x00 and", 0x3F
// Consult $datasheet for detailed IR filtering calibration
define("CFG2_IR_ADJUST_LOW"0x00);
define("CFG2_IR_ADJUST_MID"0x20);
define("CFG2_IR_ADJUST_HIGH"0x3F);

// CONFIG3
// No interrupts, or interrupts based on a selected color
define("CFG3_NO_INT"0x00);
define("CFG3_G_INT"0x01);
define("CFG3_R_INT"0x02);
define("CFG3_B_INT"0x03);

// How many times a sensor sample must hit a threshold before triggering an interrupt
// More consecutive samples means more times between interrupts, but less triggers from short transients
define("CFG3_INT_PRST1"0x00);
define("CFG3_INT_PRST2"0x04);
define("CFG3_INT_PRST4"0x08);
define("CFG3_INT_PRST8"0x0C);

// If you would rather have interrupts trigger when a sensor sampling is complete, enable this
// If this is disabled, interrupts are based on comparing sensor $data to threshold settings
define("CFG3_RGB_CONV_TO_INT_DISABLE"0x00);
define("CFG3_RGB_CONV_TO_INT_ENABLE"0x10);

// STATUS FLAG MASKS
define("FLAG_INT"0x01);
define("FLAG_CONV_DONE"0x02);
define("FLAG_BROWNOUT"0x04);
define("FLAG_CONV_G"0x10);
define("FLAG_CONV_R"0x20);
define("FLAG_CONV_B"0x30);

// Generic I2C read register (single byte)
function PHPoC_ISL29125_read8($addr_reg)
{
    global 
$pid ;
    
//$pid = pid_open("/mmap/i2c0"); // open I2C 0
    
pid_ioctl($pid"req reset");
    
//pid_write($pid, "\x30\x00");
    
pid_ioctl($pid"req write wait");
    
// register to read
    
pid_write($pid$addr_reg1);
    while(
pid_ioctl($pid"get txlen")); // check transmitted data

    
pid_ioctl($pid"req stop"); // stop writing data

    
$data 0;
    
pid_ioctl($pid"req read 1"); // request to read 1 bytes
    
while(pid_ioctl($pid"get rxlen") < 1// check received data
    
;
    
pid_read($pid$data1); // read buffer
    //pid_close($pid);

    
return $data;
}

// Generic I2C write $data to register (single byte)
function PHPoC_ISL29125_write8($addr_reg$data)
{
    global 
$pid ;
    
//$pid = pid_open("/mmap/i2c0"); // open I2C 0
    
pid_ioctl($pid"req reset");
    
//pid_write($pid, "\x40\x00");
    
pid_ioctl($pid"req write wait");
    
//register to read
    
pid_write($pid$addr_reg1);
    
pid_write($pid$data1);
    while(
pid_ioctl($pid"get txlen")); // check received data

    
pid_ioctl($pid"req stop"); // stop writing data
    //pid_close($pid);
}

// Generic I2C read registers (two bytes, LSB first)
function PHPoC_ISL29125_read16($addr_reg)
{
    
$data_lsb 0x00;
    
$data_msb 0x00;

    global 
$pid ;
    
//$pid = pid_open("/mmap/i2c0"); // open I2C 0
    
pid_ioctl($pid"req reset");
    
pid_ioctl($pid"req write wait");
    
// register to read
    
pid_write($pid$addr_reg1);
    
//while(pid_ioctl($pid, "get txlen")); // check transmitted data

    
pid_ioctl($pid"req stop"); // stop writing data

    
pid_ioctl($pid"req read 2"); // request to read 1 bytes
    
while(pid_ioctl($pid"get rxlen") < 2); // check received data

    
pid_read($pid$data_lsb1); // read buffer
    
pid_read($pid$data_msb1); // read buffer

    //pid_close($pid);
    
return ($data_lsb | ($data_msb << 8));
}

// Generic I2C write $data to registers (two bytes, LSB first)
function PHPoC_ISL29125_write16($addr_reg$data)
{
    
$data_lsb $data 0xff;
    
$data_msb $data >> 8;

    global 
$pid ;
    
//$pid = pid_open("/mmap/i2c0"); // open I2C 0
    
pid_ioctl($pid"req reset");
    
pid_ioctl($pid"req write wait");
    
//register to read
    
pid_write($pid$addr_reg1);
    
pid_write($pid$data_lsb1);
    
pid_write($pid$data_msb1);
    while(
pid_ioctl($pid"get txlen")); // check received data

    
pid_ioctl($pid"req stop"); // stop writing data
    //pid_close($pid);
}

// Setup Configuration registers (three registers) - returns 1 if successful
// Use CONFIG1 variables from PHPoC_ISL29125.h for first parameter $config1, CONFIG2 for $config2, 3 for 3
// Use CFG_DEFAULT for default configuration for that register
function PHPoC_ISL29125_config($config1$config2$config3)
{
  
$ret 1;
  
$data 0x00;

  
// Set 1st configuration register
  
PHPoC_ISL29125_write8(CONFIG_1$config1);
  
// Set 2nd configuration register
  
PHPoC_ISL29125_write8(CONFIG_2$config2);
  
// Set 3rd configuration register
  
PHPoC_ISL29125_write8(CONFIG_3$config3);

  
// Check if configurations were set correctly
  
$data PHPoC_ISL29125_read8(CONFIG_1);
  if (
$data != $config1)
  {
    
$ret &= 0;
  }
  
$data PHPoC_ISL29125_read8(CONFIG_2);
  if (
$data != $config2)
  {
    
$ret &= 0;
  }
  
$data PHPoC_ISL29125_read8(CONFIG_3);
  if (
$data != $config3)
  {
    
$ret &= 0;
  }
  return 
$ret;
}

// Sets upper threshold value for triggering interrupts
function PHPoC_ISL29125_setUpperThreshold($data)
{
  
PHPoC_ISL29125_write16(THRESHOLD_HL$data);
}

// Sets lower threshold value for triggering interrupts
function PHPoC_ISL29125_setLowerThreshold($data)
{
  
PHPoC_ISL29125_write16(THRESHOLD_LL$data);
}

// Check what the upper threshold is, 0xFFFF by default
function PHPoC_ISL29125_readUpperThreshold()
{
  return 
PHPoC_ISL29125_read16(THRESHOLD_HL);
}

// Check what the upper threshold is, 0x0000 by default
function PHPoC_ISL29125_readLowerThreshold()
{
  return 
PHPoC_ISL29125_read16(THRESHOLD_LL);
}

// Read the latest Sensor ADC reading for the color Red
function PHPoC_ISL29125_readRed()
{
  return 
PHPoC_ISL29125_read16(RED_L);
  
/*
  $data_lsb = PHPoC_ISL29125_read8(RED_L);
  $data_msb = PHPoC_ISL29125_read8(RED_H);
  return ($data_lsb | ($data_msb << 8));
  */
}

// Read the latest Sensor ADC reading for the color Green
function PHPoC_ISL29125_readGreen()
{
  return 
PHPoC_ISL29125_read16(GREEN_L);
  
/*
  $data_lsb = PHPoC_ISL29125_read8(GREEN_L);
  $data_msb = PHPoC_ISL29125_read8(GREEN_H);
  return ($data_lsb | ($data_msb << 8));
  */
}

// Read the latest Sensor ADC reading for the color Blue
function PHPoC_ISL29125_readBlue()
{
  return 
PHPoC_ISL29125_read16(BLUE_L);
  
/*
  $data_lsb = PHPoC_ISL29125_read8(BLUE_L);
  $data_msb = PHPoC_ISL29125_read8(BLUE_H);
  return ($data_lsb | ($data_msb << 8));
  */
}

// Check status flag register that allows for checking for interrupts, brownouts, and ADC conversion completions
function PHPoC_ISL29125_readStatus()
{
  return 
PHPoC_ISL29125_read8(STATUS);
}

// Reset all registers - returns 1 if successful
function PHPoC_ISL29125_reset()
{
  
$data 0x00;
  
// Reset registers
  
PHPoC_ISL29125_write8(DEVICE_ID0x46);
  
// Check reset
  
$data PHPoC_ISL29125_read8(CONFIG_1);
  
$data |= PHPoC_ISL29125_read8(CONFIG_2);
  
$data |= PHPoC_ISL29125_read8(CONFIG_3);
  
$data |= PHPoC_ISL29125_read8(STATUS);
  if (
$data != 0x00)
  {
    return 
0;
  }
  return 
1;
}

// Initialize - returns 1 if successful
// Starts Wire/I2C Communication
// Verifies sensor is there by checking its device ID
// Resets all registers/configurations to factory default
// Sets configuration registers for the common use case
function PHPoC_ISL29125_init()
{
  
$ret 1;
  
$data 0x00;

  
// Check device ID
  
$data PHPoC_ISL29125_read8(DEVICE_ID);
  if (
$data != 0x7D)
  {
    
$ret &= 0;
  }

  
// Reset registers
  
$ret &= PHPoC_ISL29125_reset();

  
// Set to RGB mode, 10k lux, and high IR compensation
  
$ret &= PHPoC_ISL29125_config(CFG1_MODE_RGB CFG1_10KLUXCFG2_IR_ADJUST_HIGHCFG_DEFAULT);

  return 
$ret;
}



Full source code here: PHPoC_Color_Sensor.zip

Thanks, and if you have any question, please don't hesitate to contact me or add comment!