Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: GR-PEACH_test_wo_rtos GR-PEACH_test_on_rtos_works_well Skywire_Demo_3 Skywire_Kinetis_K64_demo ... more
Revision 0:5d5aac272642, committed 2014-08-29
- Comitter:
- kenjiArai
- Date:
- Fri Aug 29 13:27:20 2014 +0000
- Child:
- 1:d4d569952436
- Commit message:
- New creation: LIS3DH / STMicroelectronics / MEMS motion sensor, 3-axis accelerometer library
Changed in this revision
| LIS3DH.cpp | Show annotated file Show diff for this revision Revisions of this file |
| LIS3DH.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS3DH.cpp Fri Aug 29 13:27:20 2014 +0000
@@ -0,0 +1,151 @@
+/*
+ * mbed library program
+ * LIS3DH MEMS motion sensor: 3-axis "nano" accelerometer, made by STMicroelectronics
+ * http://www.st-japan.co.jp/web/jp/catalog/sense_power/FM89/SC444/PF250725
+ *
+ * Copyright (c) 2014 Kenji Arai / JH1PJL
+ * http://www.page.sannet.ne.jp/kenjia/index.html
+ * http://mbed.org/users/kenjiArai/
+ * Created: July 14th, 2014
+ * Revised: August 29th, 2014
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "LIS3DH.h"
+
+LIS3DH::LIS3DH (PinName p_sda, PinName p_scl,
+ uint8_t addr, uint8_t data_rate, uint8_t fullscale) : i2c(p_sda, p_scl) {
+ initialize (addr, data_rate, fullscale);
+}
+
+LIS3DH::LIS3DH (I2C& p_i2c,
+ uint8_t addr, uint8_t data_rate, uint8_t fullscale) : i2c(p_i2c) {
+ initialize (addr, data_rate, fullscale);
+}
+
+void LIS3DH::initialize (uint8_t addr, uint8_t data_rate, uint8_t fullscale) {
+ // Check acc is available of not
+ acc_addr = addr;
+ dbf[0] = LIS3DH_WHO_AM_I;
+ i2c.write(acc_addr, dbf, 1);
+ i2c.read(acc_addr, dbf, 1);
+ if (dbf[0] == I_AM_LIS3DH){
+ acc_ready = 1;
+ } else {
+ acc_ready = 0;
+ return; // acc chip is NOT on I2C line then terminate
+ }
+ // Reg.1
+ dbf[0] = LIS3DH_CTRL_REG1;
+ dbf[1] = 0x07;
+ dbf[1] |= data_rate << 4;
+ i2c.write(acc_addr, dbf, 2);
+ // Reg.4
+ dbf[0] = LIS3DH_CTRL_REG4;
+ dbf[1] = 0x08; // High resolution
+ dbf[1] |= fullscale << 4;
+ i2c.write(acc_addr, dbf, 2);
+ switch (fullscale){
+ case LIS3DH_FS_2G:
+ fs_factor = LIS3DH_SENSITIVITY_2G;
+ break;
+ case LIS3DH_FS_4G:
+ fs_factor = LIS3DH_SENSITIVITY_4G;
+ break;
+ case LIS3DH_FS_8G:
+ fs_factor = LIS3DH_SENSITIVITY_8G;
+ break;
+ case LIS3DH_FS_16G:
+ fs_factor = LIS3DH_SENSITIVITY_16G;
+ break;
+ default:
+ ;
+ }
+}
+
+void LIS3DH::read_reg_data(char *data) {
+ // X,Y & Z
+ // manual said that
+ // In order to read multiple bytes, it is necessary to assert the most significant bit
+ // of the subaddress field.
+ // In other words, SUB(7) must be equal to ‘1’ while SUB(6-0) represents the address
+ // of the first register to be read.
+ dbf[0] = LIS3DH_OUT_X_L | 0x80;
+ i2c.write(acc_addr, dbf, 1, true);
+ i2c.read(acc_addr, data, 6, false);
+}
+
+void LIS3DH::read_mg_data(float *dt) {
+char data[6];
+
+ if (acc_ready == 0){
+ dt[0] = 0;
+ dt[1] = 0;
+ dt[2] = 0;
+ return;
+ }
+ read_reg_data(data);
+ // change data type
+ dt[0] = float(short((data[1] << 8) | data[0])) * fs_factor / 15;
+ dt[1] = float(short((data[3] << 8) | data[2])) * fs_factor / 15;
+ dt[2] = float(short((data[5] << 8) | data[4])) * fs_factor / 15;
+}
+
+void LIS3DH::read_data(float *dt) {
+char data[6];
+
+ if (acc_ready == 0){
+ dt[0] = 0;
+ dt[1] = 0;
+ dt[2] = 0;
+ return;
+ }
+ read_reg_data(data);
+ // change data type
+ dt[0] = float(short((data[1] << 8) | data[0])) * fs_factor / 15 * GRAVITY;
+ dt[1] = float(short((data[3] << 8) | data[2])) * fs_factor / 15 * GRAVITY;
+ dt[2] = float(short((data[5] << 8) | data[4])) * fs_factor / 15 * GRAVITY;
+}
+
+uint8_t LIS3DH::read_id() {
+ dbf[0] = LIS3DH_WHO_AM_I;
+ i2c.write(acc_addr, dbf, 1);
+ i2c.read(acc_addr, dbf, 1);
+ return (uint8_t)dbf[0];
+}
+
+uint8_t LIS3DH::data_ready() {
+ if (acc_ready == 1){
+ dbf[0] = LIS3DH_STATUS_REG_AUX;
+ i2c.write(acc_addr, dbf, 1);
+ i2c.read(acc_addr, dbf, 1);
+ if (!(dbf[0] & 0x01)){
+ return 0;
+ }
+ }
+ return 1;
+}
+
+uint8_t LIS3DH::read_reg(uint8_t addr) {
+ if (acc_ready == 1){
+ dbf[0] = addr;
+ i2c.write(acc_addr, dbf, 1);
+ i2c.read(acc_addr, dbf, 1);
+ } else {
+ dbf[0] = 0xff;
+ }
+ return (uint8_t)dbf[0];
+}
+
+void LIS3DH::write_reg(uint8_t addr, uint8_t data) {
+ if (acc_ready == 1){
+ dbf[0] = addr;
+ dbf[1] = data;
+ i2c.write(acc_addr, dbf, 2);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LIS3DH.h Fri Aug 29 13:27:20 2014 +0000
@@ -0,0 +1,211 @@
+/*
+ * mbed library program
+ * LIS3DH MEMS motion sensor: 3-axis "nano" accelerometer, made by STMicroelectronics
+ * http://www.st-japan.co.jp/web/jp/catalog/sense_power/FM89/SC444/PF250725
+ *
+ * Copyright (c) 2014 Kenji Arai / JH1PJL
+ * http://www.page.sannet.ne.jp/kenjia/index.html
+ * http://mbed.org/users/kenjiArai/
+ * Created: July 14th, 2014
+ * Revised: August 29th, 2014
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef LIS3DH_H
+#define LIS3DH_H
+
+#include "mbed.h"
+
+// LIS3DH Address
+// 7bit address = 0b001100x(0x18 or 0x19 depends on SA0/SDO)
+// -> 8bit = 0b001100x0(0x30,0x32) -> 0x31,0x33(Read) or 0x30,0x32(Write)
+#define LIS3DH_G_CHIP_ADDR 0x30 // SA0(=SDO pin) = Ground
+#define LIS3DH_V_CHIP_ADDR 0x32 // SA0(=SDO pin) = Vdd
+
+
+// LIS3DH ID
+#define I_AM_LIS3DH 0x33
+
+// Register's definition
+#define LIS3DH_STATUS_REG_AUX 0x07
+#define LIS3DH_OUT_ADC1_L 0x08
+#define LIS3DH_OUT_ADC1_H 0x09
+#define LIS3DH_OUT_ADC2_L 0x0a
+#define LIS3DH_OUT_ADC2_H 0x0b
+#define LIS3DH_OUT_ADC3_L 0x0c
+#define LIS3DH_OUT_ADC3_H 0x0d
+#define LIS3DH_INT_COUNTER_REG 0x0e
+#define LIS3DH_WHO_AM_I 0x0f
+#define LIS3DH_TEMP_CFG_REG 0x1f
+#define LIS3DH_CTRL_REG1 0x20
+#define LIS3DH_CTRL_REG2 0x21
+#define LIS3DH_CTRL_REG3 0x22
+#define LIS3DH_CTRL_REG4 0x23
+#define LIS3DH_CTRL_REG5 0x24
+#define LIS3DH_CTRL_REG6 0x25
+#define LIS3DH_REFERENCE 0x26
+#define LIS3DH_STATUS_REG2 0x27
+#define LIS3DH_OUT_X_L 0x28
+#define LIS3DH_OUT_X_H 0x29
+#define LIS3DH_OUT_Y_L 0x2a
+#define LIS3DH_OUT_Y_H 0x2b
+#define LIS3DH_OUT_Z_L 0x2c
+#define LIS3DH_OUT_Z_H 0x2d
+#define LIS3DH_FIFO_CTRL_REG 0x2e
+#define LIS3DH_FIFO_SRC_REG 0x2f
+#define LIS3DH_INT1_CFG 0x30
+#define LIS3DH_INT1_SOURCE 0x31
+#define LIS3DH_INT1_THS 0x32
+#define LIS3DH_INT1_DURATION 0x33
+#define LIS3DH_CLICK_CFG 0x38
+#define LIS3DH_CLICK_SRC 0x39
+#define LIS3DH_CLICK_THS 0x3a
+#define LIS3DH_TIME_LIMIT 0x3b
+#define LIS3DH_TIME_LATENCY 0x3c
+#define LIS3DH_TIME_WINDOW 0x3d
+
+// Output Data Rate (ODR)
+#define LIS3DH_DR_PWRDWN 0
+#define LIS3DH_DR_NR_LP_1HZ 1
+#define LIS3DH_DR_NR_LP_10HZ 2
+#define LIS3DH_DR_NR_LP_25HZ 3
+#define LIS3DH_DR_NR_LP_50HZ 4
+#define LIS3DH_DR_NR_LP_100HZ 5
+#define LIS3DH_DR_NR_LP_200HZ 6
+#define LIS3DH_DR_NR_LP_400HZ 7
+#define LIS3DH_DR_LP_1R6KHZ 8
+#define LIS3DH_DR_NR_1R25KHZ 9
+
+// Bandwidth (Low pass)
+#define LIS3DH_BW_LOW 0
+#define LIS3DH_BW_M_LOW 1
+#define LIS3DH_BW_M_HI 2
+#define LIS3DH_BW_HI 3
+
+// Low power mode enable/disable
+#define LIS3DH_LP_EN 0
+#define LIS3DH_LP_DIS 1
+
+// Axis control
+#define LIS3DH_X_EN 1
+#define LIS3DH_X_DIS 0
+#define LIS3DH_Y_EN 1
+#define LIS3DH_Y_DIS 0
+#define LIS3DH_Z_EN 1
+#define LIS3DH_Z_DIS 0
+
+// Full Scale
+#define LIS3DH_FS_2G 0
+#define LIS3DH_FS_4G 1
+#define LIS3DH_FS_8G 2
+#define LIS3DH_FS_16G 3
+
+// definition for Nomalization
+#define LIS3DH_SENSITIVITY_2G (0.001F)
+#define LIS3DH_SENSITIVITY_4G (0.002F)
+#define LIS3DH_SENSITIVITY_8G (0.004F)
+#define LIS3DH_SENSITIVITY_16G (0.012F)
+
+//Gravity at Earth's surface in m/s/s
+#define GRAVITY (9.80665F)
+
+/** Interface for STMicronics MEMS motion sensor: 3-axis "nano" accelerometer
+ * Chip: LIS3DH
+ *
+ * @code
+ * #include "mbed.h"
+ *
+ * // I2C Communication
+ * LIS3DH acc(p_sda, p_scl, chip_addr, datarate, bandwidth, fullscale);
+ * // If you connected I2C line not only this device but also other devices,
+ * // you need to declare following method.
+ * I2C i2c(dp5,dp27); // SDA, SCL
+ * LIS3DH acc(i2c, chip_addr, datarate, bandwidth, fullscale);
+ *
+ * int main() {
+ * float f[3];
+ *
+ * if (acc.read_id() == I_AM_LIS3DH){
+ * acc.read_data(f);
+ * }
+ * }
+ * @endcode
+ */
+
+class LIS3DH{
+public:
+ /** Configure data pin
+ * @param data SDA and SCL pins
+ * @param device address LIS3DH(SA0=0 or 1), LIS3DH_G_CHIP_ADDR or LIS3DH_V_CHIP_ADDR
+ * @param output data rate selection, power down mode, 1Hz to 5KHz
+ * @param full scale selection, +/-2g to +/-16g
+ */
+ LIS3DH(PinName p_sda, PinName p_scl,
+ uint8_t addr, uint8_t data_rate, uint8_t fullscale);
+
+ /** Configure data pin (with other devices on I2C line)
+ * @param I2C previous definition
+ * @param other parameters -> please see LIS3DH(PinName p_sda, PinName p_scl,...)
+ */
+ LIS3DH(I2C& p_i2c,
+ uint8_t addr, uint8_t data_rate, uint8_t fullscale);
+
+ /** Read a float type data from acc
+ * @param float type of three arry's address, e.g. float dt[3];
+ * @return acc motion data unit: m/s/s(m/s2)
+ * @return dt[0]->x, dt[1]->y, dt[2]->z
+ */
+ void read_data(float *dt);
+
+ /** Read a float type data from acc
+ * @param float type of three arry's address, e.g. float dt[3];
+ * @return acc motion data unit: mg
+ * @return dt[0]->x, dt[1]->y, dt[2]->z
+ */
+ void read_mg_data(float *dt);
+
+ /** Read a acc ID number
+ * @param none
+ * @return if STM MEMS acc, it should be I_AM_ LIS3DH(0x33)
+ */
+ uint8_t read_id();
+
+ /** Read Data Ready flag
+ * @param none
+ * @return 1 = Ready
+ */
+ uint8_t data_ready();
+
+ /** Read register (general purpose)
+ * @param register's address
+ * @return register data
+ */
+ uint8_t read_reg(uint8_t addr);
+
+ /** Write register (general purpose)
+ * @param register's address
+ * @param data
+ * @return none
+ */
+ void write_reg(uint8_t addr, uint8_t data);
+
+protected:
+ void initialize(uint8_t, uint8_t, uint8_t);
+ void read_reg_data(char *data);
+
+ I2C i2c;
+
+private:
+ float fs_factor; // full scale factor
+ char dbf[2]; // working buffer
+ uint8_t acc_addr; // acc sensor address
+ uint8_t acc_id; // acc ID
+ uint8_t acc_ready; // acc is on I2C line = 1, not = 0
+};
+
+#endif // LIS3DH_H