-
Notifications
You must be signed in to change notification settings - Fork 335
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
sqfmi
committed
Feb 23, 2020
1 parent
83167af
commit 03ea538
Showing
10 changed files
with
9,710 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Watchy - Accelerometer Example | ||
* Prints out the BMA423 accelerometer data on Serial | ||
*/ | ||
|
||
#ifndef ESP32 | ||
#error Please select ESP32 Wrover Module under Tools > Board | ||
#endif | ||
|
||
#include <bma.h> | ||
|
||
BMA *bma = nullptr; | ||
I2CBus *i2c = nullptr; | ||
|
||
void setup() | ||
{ | ||
byte data; | ||
Serial.begin(115200); | ||
i2c = new I2CBus(); | ||
bma = new BMA(*i2c); | ||
bma->begin(); | ||
bma->enableAccel(); | ||
} | ||
|
||
void loop(){ | ||
Accel acc; | ||
bool res = bma->getAccel(acc); | ||
Serial.print(acc.x); | ||
Serial.print(" , "); | ||
Serial.print(acc.y); | ||
Serial.print(" , "); | ||
Serial.println(acc.z); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
#include "bma.h" | ||
#include <Arduino.h> | ||
|
||
I2CBus *BMA::_bus = nullptr; | ||
|
||
BMA::BMA(I2CBus &bus) | ||
{ | ||
_bus = &bus; | ||
} | ||
|
||
BMA::~BMA() | ||
{ | ||
|
||
} | ||
|
||
uint16_t BMA::read(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len) | ||
{ | ||
return _bus->readBytes(addr, reg, data, len); | ||
} | ||
|
||
uint16_t BMA::write(uint8_t addr, uint8_t reg, uint8_t *data, uint16_t len) | ||
{ | ||
return _bus->writeBytes(addr, reg, data, len); | ||
} | ||
|
||
bool BMA::begin() | ||
{ | ||
_dev.dev_addr = BMA4_I2C_ADDR_PRIMARY; | ||
_dev.interface = BMA4_I2C_INTERFACE; | ||
_dev.bus_read = read; | ||
_dev.bus_write = write; | ||
_dev.delay = delay; | ||
_dev.read_write_len = 8; | ||
_dev.resolution = 12; | ||
_dev.feature_len = BMA423_FEATURE_SIZE; | ||
|
||
reset(); | ||
|
||
delay(20); | ||
|
||
if (bma423_init(&_dev) != BMA4_OK) { | ||
Serial.println("bma4 init fail"); | ||
return false; | ||
} | ||
|
||
config(); | ||
|
||
return true; | ||
} | ||
|
||
void BMA::reset() | ||
{ | ||
uint8_t reg = 0xB6; | ||
_bus->writeBytes(BMA4_I2C_ADDR_PRIMARY, 0x7E, ®, 1); | ||
} | ||
|
||
uint16_t BMA::config() | ||
{ | ||
return bma423_write_config_file(&_dev); | ||
} | ||
|
||
bool BMA::getAccel(Accel &acc) | ||
{ | ||
memset(&acc, 0, sizeof(acc)); | ||
if (bma4_read_accel_xyz(&acc, &_dev) != BMA4_OK) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
uint8_t BMA::direction() | ||
{ | ||
Accel acc; | ||
if (bma4_read_accel_xyz(&acc, &_dev) != BMA4_OK) { | ||
return 0; | ||
} | ||
uint16_t absX = abs(acc.x); | ||
uint16_t absY = abs(acc.y); | ||
uint16_t absZ = abs(acc.z); | ||
|
||
if ((absZ > absX) && (absZ > absY)) { | ||
if (acc.z > 0) { | ||
return DIRECTION_DISP_DOWN; | ||
} else { | ||
return DIRECTION_DISP_UP; | ||
} | ||
} else if ((absY > absX) && (absY > absZ)) { | ||
if (acc.y > 0) { | ||
return DIRECTION_BOTTOM_EDGE; | ||
} else { | ||
return DIRECTION_TOP_EDGE; | ||
} | ||
} else { | ||
if (acc.x < 0) { | ||
return DIRECTION_RIGHT_EDGE; | ||
} else { | ||
return DIRECTION_LEFT_EDGE; | ||
} | ||
} | ||
} | ||
|
||
float BMA::temperature() | ||
{ | ||
int32_t data = 0; | ||
bma4_get_temperature(&data, BMA4_DEG, &_dev); | ||
float res = (float)data / (float)BMA4_SCALE_TEMP; | ||
/* 0x80 - temp read from the register and 23 is the ambient temp added. | ||
* If the temp read from register is 0x80, it means no valid | ||
* information is available */ | ||
if (((data - 23) / BMA4_SCALE_TEMP) == 0x80) { | ||
res = 0; | ||
} | ||
return res; | ||
} | ||
|
||
|
||
void BMA::enableAccel() | ||
{ | ||
if (bma4_set_accel_enable(BMA4_ENABLE, &_dev)) { | ||
return; | ||
} | ||
Acfg cfg; | ||
cfg.odr = BMA4_OUTPUT_DATA_RATE_100HZ; | ||
cfg.range = BMA4_ACCEL_RANGE_2G; | ||
cfg.bandwidth = BMA4_ACCEL_NORMAL_AVG4; | ||
cfg.perf_mode = BMA4_CONTINUOUS_MODE; | ||
|
||
if (bma4_set_accel_config(&cfg, &_dev)) { | ||
Serial.println("[bma4] set accel config fail"); | ||
return; | ||
} | ||
} | ||
|
||
void BMA::disalbeIrq() | ||
{ | ||
bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT /* |BMA423_WAKEUP_INT*/, BMA4_DISABLE, &_dev); | ||
} | ||
|
||
void BMA::enableIrq() | ||
{ | ||
bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT /* |BMA423_WAKEUP_INT*/, BMA4_ENABLE, &_dev); | ||
} | ||
|
||
//attachInterrupt bma423 int1 | ||
void BMA::attachInterrupt() | ||
{ | ||
uint16_t rslt = BMA4_OK; | ||
enableAccel(); | ||
// rslt |= bma423_reset_step_counter(&_dev); | ||
rslt |= bma423_step_detector_enable(BMA4_ENABLE, &_dev); | ||
rslt |= bma423_feature_enable(BMA423_STEP_CNTR, BMA4_ENABLE, &_dev); | ||
rslt |= bma423_feature_enable(BMA423_WAKEUP, BMA4_ENABLE, &_dev); | ||
rslt |= bma423_feature_enable(BMA423_TILT, BMA4_ENABLE, &_dev); | ||
rslt |= bma423_step_counter_set_watermark(100, &_dev); | ||
|
||
// rslt |= bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT | BMA423_WAKEUP_INT, BMA4_ENABLE, &_dev); | ||
|
||
rslt |= bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT, BMA4_ENABLE, &_dev); | ||
rslt |= bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_TILT_INT, BMA4_ENABLE, &_dev); | ||
|
||
bma423_anymotion_enable_axis(BMA423_ALL_AXIS_DIS, &_dev); | ||
|
||
struct bma4_int_pin_config config ; | ||
|
||
config.edge_ctrl = BMA4_LEVEL_TRIGGER; | ||
config.lvl = BMA4_ACTIVE_HIGH; | ||
config.od = BMA4_PUSH_PULL; | ||
config.output_en = BMA4_OUTPUT_ENABLE; | ||
config.input_en = BMA4_INPUT_DISABLE; | ||
rslt |= bma4_set_int_pin_config(&config, BMA4_INTR1_MAP, &_dev); | ||
|
||
// Serial.printf("[bma4] attachInterrupt %s\n", rslt != 0 ? "fail" : "pass"); | ||
|
||
|
||
struct bma423_axes_remap remap_data; | ||
remap_data.x_axis = 0; | ||
remap_data.x_axis_sign = 1; | ||
remap_data.y_axis = 1; | ||
remap_data.y_axis_sign = 1; | ||
remap_data.z_axis = 2; | ||
remap_data.z_axis_sign = 0; | ||
|
||
bma423_set_remap_axes(&remap_data, &_dev); | ||
|
||
} | ||
|
||
bool BMA::readInterrupt() | ||
{ | ||
return bma423_read_int_status(&_irqStatus, &_dev) == BMA4_OK; | ||
} | ||
|
||
uint8_t BMA::getIrqStatus() | ||
{ | ||
return _irqStatus; | ||
} | ||
|
||
uint32_t BMA::getCounter() | ||
{ | ||
uint32_t stepCount; | ||
if (bma423_step_counter_output(&stepCount, &_dev) == BMA4_OK) { | ||
return stepCount; | ||
} | ||
return 0; | ||
} | ||
|
||
bool BMA::isStepCounter() | ||
{ | ||
return (bool)(BMA423_STEP_CNTR_INT & _irqStatus); | ||
} | ||
|
||
bool BMA::isDoubleClick() | ||
{ | ||
return (bool)(BMA423_WAKEUP_INT & _irqStatus); | ||
} | ||
|
||
|
||
bool BMA::isTilt() | ||
{ | ||
return (bool)(BMA423_TILT_INT & _irqStatus); | ||
} | ||
|
||
|
||
bool BMA::isActivity() | ||
{ | ||
return (bool)(BMA423_ACTIVITY_INT & _irqStatus); | ||
} | ||
|
||
bool BMA::isAnyNoMotion() | ||
{ | ||
return (bool)(BMA423_ANY_NO_MOTION_INT & _irqStatus); | ||
} | ||
|
||
|
||
const char *BMA::getActivity() | ||
{ | ||
uint8_t activity; | ||
bma423_activity_output(&activity, &_dev); | ||
if (activity & BMA423_USER_STATIONARY) { | ||
return "BMA423_USER_STATIONARY"; | ||
} else if (activity & BMA423_USER_WALKING) { | ||
return "BMA423_USER_WALKING"; | ||
} else if (activity & BMA423_USER_RUNNING) { | ||
return "BMA423_USER_RUNNING"; | ||
} else if (activity & BMA423_STATE_INVALID) { | ||
return "BMA423_STATE_INVALID"; | ||
} | ||
return "None"; | ||
} | ||
|
||
bool BMA::enableStepCountInterrupt(bool en) | ||
{ | ||
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_STEP_CNTR_INT, en, &_dev)); | ||
} | ||
|
||
bool BMA::enableTiltInterrupt(bool en) | ||
{ | ||
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_TILT_INT, en, &_dev)); | ||
} | ||
|
||
bool BMA::enableWakeupInterrupt(bool en) | ||
{ | ||
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_WAKEUP_INT, en, &_dev)); | ||
} | ||
|
||
bool BMA::enableAnyNoMotionInterrupt(bool en) | ||
{ | ||
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_ANY_NO_MOTION_INT, en, &_dev)); | ||
} | ||
|
||
bool BMA::enableActivityInterrupt(bool en) | ||
{ | ||
return (BMA4_OK == bma423_map_interrupt(BMA4_INTR1_MAP, BMA423_ACTIVITY_INT, en, &_dev)); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
|
||
#pragma once | ||
|
||
#include "bma423.h" | ||
#include "i2c_bus.h" | ||
|
||
|
||
enum { | ||
DIRECTION_TOP_EDGE = 0, | ||
DIRECTION_BOTTOM_EDGE = 1, | ||
DIRECTION_LEFT_EDGE = 2, | ||
DIRECTION_RIGHT_EDGE = 3, | ||
DIRECTION_DISP_UP = 4, | ||
DIRECTION_DISP_DOWN = 5 | ||
} ; | ||
typedef struct bma4_dev Bma; | ||
typedef struct bma4_accel Accel; | ||
typedef struct bma4_accel_config Acfg; | ||
|
||
class BMA | ||
{ | ||
public: | ||
BMA(I2CBus &bus); | ||
~BMA(); | ||
bool begin(); | ||
void reset(); | ||
uint8_t direction(); | ||
float temperature(); | ||
void enableAccel(); | ||
|
||
void disalbeIrq(); | ||
void enableIrq(); | ||
void attachInterrupt(); | ||
uint32_t getCounter(); | ||
bool isStepCounter(); | ||
bool isDoubleClick(); | ||
bool readInterrupt(); | ||
bool isTilt(); | ||
bool isActivity(); | ||
bool isAnyNoMotion(); | ||
bool getAccel(Accel &acc); | ||
uint8_t getIrqStatus(); | ||
const char * getActivity(); | ||
|
||
bool enableStepCountInterrupt(bool en = true); | ||
bool enableTiltInterrupt(bool en = true); | ||
bool enableWakeupInterrupt(bool en = true); | ||
bool enableAnyNoMotionInterrupt(bool en = true); | ||
bool enableActivityInterrupt(bool en = true); | ||
|
||
private: | ||
static uint16_t read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *read_data, uint16_t len); | ||
static uint16_t write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *read_data, uint16_t len); | ||
|
||
uint16_t config(); | ||
Bma _dev; | ||
static bma4_com_fptr_t _read; | ||
static bma4_com_fptr_t _write; | ||
static I2CBus *_bus; | ||
bool _irqRead = false; | ||
uint16_t _irqStatus; | ||
|
||
}; |
Oops, something went wrong.