Skip to content

Instantly share code, notes, and snippets.

@epall
Created October 15, 2012 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save epall/3894193 to your computer and use it in GitHub Desktop.
Save epall/3894193 to your computer and use it in GitHub Desktop.
Vibration sensor using accelerometer on Hannah
// 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