Created
October 15, 2012 18:31
-
-
Save epall/3894193 to your computer and use it in GitHub Desktop.
Vibration sensor using accelerometer on Hannah
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Vibration sensor using accelerometer on Hannah | |
//I2C Addresses | |
const i2c_ioexp = 0x7C; | |
const i2c_temp = 0x98; | |
const i2c_als = 0xE8; | |
const i2c_accel = 0x38; | |
//---------------------------------------- | |
//-- Configure I2C | |
//---------------------------------------- | |
hardware.configure(I2C_89); | |
local i2c = hardware.i2c89; | |
//---------------------------------------- | |
//-- IO Expander Functions | |
//---------------------------------------- | |
local function ioexp_read(addr) { | |
local result = i2c.read(i2c_ioexp, format("%c", addr), 1); | |
if (result == null) { | |
server.log("i2c read fail"); | |
return -1; | |
} else return result[0]; | |
} | |
local function ioexp_write(addr, data) { | |
i2c.write(i2c_ioexp, format("%c%c",addr, data)); | |
} | |
local function ioexp_writebit(addr, bitn, level) { | |
// read modify write | |
local reg = ioexp_read(addr); | |
reg = (level==0)?(reg&~(1<<bitn)) : (reg | (1<<bitn)); | |
ioexp_write(addr, reg) | |
} | |
local function ioexp_modify_write(addr, data, mask) { | |
local reg = ioexp_read(addr); | |
reg = (reg & ~mask) | (data & mask); | |
ioexp_write(addr, reg); | |
} | |
local function ioexp_setpin(gpio, level) { | |
ioexp_writebit(gpio>=8?0x10:0x11, gpio&7, level?1:0); | |
} | |
local function ioexp_setdir(gpio, output) { | |
ioexp_writebit(gpio>=8?0x0e:0x0f, gpio&7, output?0:1); | |
} | |
local function ioexp_setpullup(gpio, enable) { | |
ioexp_writebit(gpio>=8?0x06:0x07, gpio&7, enable); | |
} | |
local function ioexp_setirqmask(gpio, enable) { | |
ioexp_writebit(gpio>=8?0x12:0x13, gpio&7, enable); | |
} | |
local function ioexp_setirqedge(gpio, rising, falling) { | |
local addr = 0x17 - (gpio>>2); | |
local mask = 0x03 << ((gpio&3)<<1); | |
local data = (2*falling + rising) << ((gpio&3)<<1); | |
ioexp_modify_write(addr, data, mask); | |
} | |
local function ioexp_clearirq(gpio) { | |
ioexp_writebit(gpio>=8?0x18:0x19, gpio&7, 1); | |
} | |
local function ioexp_readpin(gpio) { | |
return (ioexp_read(gpio>=8?0x10:0x11)&(1<<(gpio&7)))?1:0; | |
} | |
local function ioexp_setled(gpio, led) { | |
ioexp_writebit(gpio>=8?0x20:0x21, gpio&7, led); | |
} | |
local function ioexp_update_leds(r,g,b) { | |
ioexp_write(0x3b, g); | |
ioexp_write(0x40, b); | |
ioexp_write(0x45, r); | |
} | |
//LED Driver Enable | |
ioexp_modify_write(0x01, 0xE0, 0xFF); | |
ioexp_modify_write(0x0f, 0xE0, 0x00); | |
ioexp_modify_write(0x0b, 0xE0, 0xFF); | |
ioexp_modify_write(0x21, 0xE0, 0xFF); | |
ioexp_write(0x1e, 0x50); | |
ioexp_write(0x1f, 0x10); | |
ioexp_update_leds(0,0,0); | |
ioexp_setpin(5, 0); | |
ioexp_setpin(6, 0); | |
ioexp_setpin(7, 0); | |
// Enable Potentiometer | |
ioexp_setpin(8, 0); | |
ioexp_setdir(8, 1); | |
hardware.pin2.configure(ANALOG_IN); | |
// Enable accelerometer | |
local e = i2c.write(i2c_accel, "\x20\x47"); | |
local out = OutputPort("Acceleration", "number") | |
local averageX = 0 | |
local averageY = 0 | |
local averageZ = 0 | |
local warmup = 0 | |
local exponentialFactor = 0.9 | |
function poll() { | |
imp.wakeup(0.05, poll) | |
local accel = i2c.read(i2c_accel, "\x29", 1) + i2c.read(i2c_accel, "\x2B", 1) + i2c.read(i2c_accel, "\x2D", 1) | |
local x = ((accel[0] + 128) % 256) - 128.0 | |
local y = ((accel[1] + 128) % 256) - 128.0 | |
local z = ((accel[2] + 128) % 256) - 128.0 | |
averageX = averageX * exponentialFactor + x * (1-exponentialFactor) | |
averageY = averageY * exponentialFactor + y * (1-exponentialFactor) | |
averageZ = averageZ * exponentialFactor + z * (1-exponentialFactor) | |
local motion = math.abs(x-averageX) + math.abs(y-averageY) + math.abs(z-averageZ) | |
if(motion > 5 && warmup > 3/(1-exponentialFactor)) { | |
server.log(format("triggered! %d", motion)) | |
} else { | |
warmup += 1 | |
} | |
} | |
poll() | |
imp.configure("Vibration sensor", [], [out]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment