Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
I2C example code
// Version 1.1 (21-08-2015)
function requestHandler(request, response) {
// Handle an incoming web request for a reading
try {
device.send("sense", true);
response.send(200, "OK");
} catch (ex) {
response.send(500, "Internal Server Error: " + ex);
}
}
// Print light reading trigger URL
server.log("Sensor Agent URL: " + http.agenturl());
// Register the HTTP handler
http.onrequest(requestHandler);
// Version 1.1 (21-08-2015)
// Configure the Adafruit/TAOS TSL2561 light sensor
// Note: Imp I2C command values are strings with
// the \x escape character to indicate a hex value
const TSL2561_COMMAND_BIT = "\x80"; // Command register. Bit 7 must be 1
const TSL2561_CONTROL_POWERON = "\x03"; // Power on setting
const TSL2561_CONTROL_POWEROFF = "\x00"; // Power off setting
const TSL2561_REGISTER_TIMING = "\x81"; // Access timing register
const TSL2561_REGISTER_ADC0_LSB = "\xAC"; // LSB of sensor's two-byte ADC value
const TSL2561_REGISTER_ADC1_LSB = "\xAE"; // LSB of sensor's two-byte ADC value
const TSL2561_GAIN_LOW_INT_10 = "\x01"; // Gain to low, integration timing to 101ms
const TSL2561_GAIN_LOW_INT_13 = "\x00"; // Gain to low, integration timing to 13.7ms
const TSL2561_GAIN_HI_INT_10 = "\x11"; // Gain to low, integration timing to 101ms
const TSL2561_GAIN_HI_INT_13 = "\x10"; // Gain to low, integration timing to 13.7ms
// Note: Imp I2C address values are integers
const TSL2561_ADDR_LOW = 0x29; // ADDR pin ground
const TSL2561_ADDR_HIGH = 0x49; // ADDR pin 3v3
const TSL2561_ADDR_FLOAT = 0x39; // ADDR pin floating
// Lux calculation constants
const LUX_SCALE = 14; // scale by 2^14
const RATIO_SCALE = 9; // scale ratio by 2^9
const B1C = 0x0204;
const M1C = 0x01ad;
const B2C = 0x0228;
const M2C = 0x02c1;
const B3C = 0x0253;
const M3C = 0x0363;
const B4C = 0x0282;
const M4C = 0x03df;
const B5C = 0x0177;
const M5C = 0x01dd;
const B6C = 0x0101;
const M6C = 0x0127;
const B7C = 0x0037;
const M7C = 0x002b;
const B8C = 0x0000;
const M8C = 0x0000;
const K1C = 0x0043;
const K2C = 0x0085;
const K3C = 0x00c8;
const K4C = 0x010a;
const K5C = 0x014d;
const K6C = 0x019a;
const K7C = 0x029a;
const K8C = 0x029a;
// DEFINE FUNCTIONS
function calculateLux(ch0, ch1) {
// Calculate the luminosity based on ADC Channel 0 (visible + IR) and
// Channel 1 (IR) values. Returns the luminosity. Assumes sensor
// integration time is 13ms, gain is 16x
local chScale = 29975;
local channel0 = (ch0 * chScale) >> 10;
local channel1 = (ch1 * chScale) >> 10;
local ratio1 = 0;
if (channel0 != 0) ratio1 = (channel1 << (RATIO_SCALE + 1)) / channel0;
// Round the ratio value
local ratio = (ratio1 + 1) >> 1;
local b = 0;
local m = 0;
if ((ratio >= 0) && (ratio <= K1C))
{b=B1C; m=M1C;}
else if (ratio <= K2C)
{b=B2C; m=M2C;}
else if (ratio <= K3C)
{b=B3C; m=M3C;}
else if (ratio <= K4C)
{b=B4C; m=M4C;}
else if (ratio <= K5C)
{b=B5C; m=M5C;}
else if (ratio <= K6C)
{b=B6C; m=M6C;}
else if (ratio <= K7C)
{b=B7C; m=M7C;}
else if (ratio > K8C)
{b=B8C; m=M8C;}
local temp = ((channel0 * b) - (channel1 * m));
// Do not allow a negative lux value
if (temp < 0) temp = 0;
temp += (1 << (LUX_SCALE - 1));
// Strip off fractional portion
local lux = temp >> LUX_SCALE;
return lux;
}
function readSensorAdc0() {
local word = i2c.read(i2cAddr, TSL2561_REGISTER_ADC0_LSB, 2);
local lumo = (word[1] << 8) + word[0];
return lumo;
}
function readSensorAdc1() {
local word = i2c.read(i2cAddr, TSL2561_REGISTER_ADC1_LSB, 2);
local lumo = (word[1] << 8) + word[0];
return lumo;
}
function getLumo(boolValue) {
if (boolValue) {
// Set command focus to ADC 0
i2c.write(i2cAddr, TSL2561_REGISTER_ADC0_LSB);
local lumo0 = readSensorAdc0();
server.log("Light level: " + lumo0);
i2c.write(i2cAddr, TSL2561_REGISTER_ADC1_LSB);
local lumo1 = readSensorAdc1();
server.log("IR level: " + lumo1);
local lux = calculateLux(lumo0, lumo1);
server.log("Lux: " + lux);
}
}
// PROGRAM START POINT
// Set up alias for i2c and set bus to 100kHz
i2c <- hardware.i2c12;
i2c.configure(CLOCK_SPEED_100_KHZ);
// Set sensor's address by shifting 7-bit address 1 bit leftward as per imp I2C spec
i2cAddr <- TSL2561_ADDR_FLOAT << 1;
// Set command focus to the control register
i2c.write(i2cAddr, TSL2561_COMMAND_BIT);
// Send power up command
i2c.write(i2cAddr, TSL2561_CONTROL_POWERON);
// Check the power is on: this will return string '3' or '51' if it is
local result = i2c.read(i2cAddr, TSL2561_CONTROL_POWERON, 1);
server.log("Power check: "+ result[0]);
// Issue command: write (0x80) to the timing register (0x01)
// ie. TSL2561_REGISTER_TIMING = 0x81
i2c.write(i2cAddr, TSL2561_REGISTER_TIMING);
// Set gain to low by writing a byte to the timing register
// bit 4 to the gain: 1 or 0 (gain high or low)
// bits 1,0 to the integration timing: 0,0 or 1,0 (timing 13.7ms or 101ms)
i2c.write(i2cAddr, TSL2561_GAIN_LOW_INT_10);
// Register a handler for "sense" messages from the agent
agent.on("sense", getLumo);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment