FTE-denshi / Mbed 2 deprecated FTE-06

Dependencies:   mbed FATFileSystem

Fork of FTE-06 by Tetsushi Amano

Files at this revision

API Documentation at this revision

Comitter:
mizuki_akaike
Date:
Mon Aug 14 04:56:52 2017 +0000
Parent:
22:b2e90f18ea55
Child:
24:8080c0516969
Commit message:
?????????????;

Changed in this revision

BME280.lib Show diff for this revision Revisions of this file
BME280/BME280.cpp Show annotated file Show diff for this revision Revisions of this file
BME280/BME280.h Show annotated file Show diff for this revision Revisions of this file
BMP085.lib Show diff for this revision Revisions of this file
BMP085/BMP085.cpp Show annotated file Show diff for this revision Revisions of this file
BMP085/BMP085.h Show annotated file Show diff for this revision Revisions of this file
IM920.lib Show diff for this revision Revisions of this file
IM920/CBuffer.h Show annotated file Show diff for this revision Revisions of this file
IM920/IM920.cpp Show annotated file Show diff for this revision Revisions of this file
IM920/IM920.h Show annotated file Show diff for this revision Revisions of this file
IM920/IM920_cmd.cpp Show annotated file Show diff for this revision Revisions of this file
IM920/IM920_conf.h Show annotated file Show diff for this revision Revisions of this file
IM920/IM920_hal.cpp Show annotated file Show diff for this revision Revisions of this file
IM920/IM920_msg.cpp Show annotated file Show diff for this revision Revisions of this file
IM920/IM920_util.cpp Show annotated file Show diff for this revision Revisions of this file
L3GD20.lib Show diff for this revision Revisions of this file
L3GD20/L3GD20.cpp Show annotated file Show diff for this revision Revisions of this file
L3GD20/L3GD20.h Show annotated file Show diff for this revision Revisions of this file
LSM303DLHC.lib Show diff for this revision Revisions of this file
LSM303DLHC/LSM303DLHC.cpp Show annotated file Show diff for this revision Revisions of this file
LSM303DLHC/LSM303DLHC.h Show annotated file Show diff for this revision Revisions of this file
Servo.lib Show diff for this revision Revisions of this file
Servo/Servo.cpp Show annotated file Show diff for this revision Revisions of this file
Servo/Servo.h Show annotated file Show diff for this revision Revisions of this file
--- a/BME280.lib	Mon Aug 14 04:55:38 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/Calcium/code/BME280/#a399ad3155fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BME280/BME280.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,192 @@
+/**
+ *  BME280 Combined humidity and pressure sensor library
+ *
+ *  @author  Toyomasa Watarai
+ *  @version 1.0
+ *  @date    06-April-2015
+ *
+ *  Library for "BME280 temperature, humidity and pressure sensor module" from Switch Science
+ *    https://www.switch-science.com/catalog/2236/
+ *
+ *  For more information about the BME280:
+ *    http://ae-bst.resource.bosch.com/media/products/dokumente/bme280/BST-BME280_DS001-10.pdf
+ */
+
+#include "mbed.h"
+#include "BME280.h"
+
+BME280::BME280(PinName sda, PinName scl, char slave_adr)
+    :
+    i2c_p(new I2C(sda, scl)), 
+    i2c(*i2c_p),
+    address(slave_adr),
+    t_fine(0)
+{
+    initialize();
+}
+
+BME280::BME280(I2C &i2c_obj, char slave_adr)
+    :
+    i2c_p(NULL), 
+    i2c(i2c_obj),
+    address(slave_adr),
+    t_fine(0)
+{
+    initialize();
+}
+
+BME280::~BME280()
+{
+    if (NULL != i2c_p)
+        delete  i2c_p;
+}
+    
+void BME280::initialize()
+{
+    char cmd[18];
+ 
+    cmd[0] = 0xf2; // ctrl_hum
+    cmd[1] = 0x01; // Humidity oversampling x1
+    i2c.write(address, cmd, 2);
+ 
+    cmd[0] = 0xf4; // ctrl_meas
+    cmd[1] = 0x27; // Temparature oversampling x1, Pressure oversampling x1, Normal mode
+    i2c.write(address, cmd, 2);
+ 
+    cmd[0] = 0xf5; // config
+    cmd[1] = 0xa0; // Standby 1000ms, Filter off
+    i2c.write(address, cmd, 2);
+ 
+    cmd[0] = 0x88; // read dig_T regs
+    i2c.write(address, cmd, 1);
+    i2c.read(address, cmd, 6);
+ 
+    dig_T1 = (cmd[1] << 8) | cmd[0];
+    dig_T2 = (cmd[3] << 8) | cmd[2];
+    dig_T3 = (cmd[5] << 8) | cmd[4];
+ 
+    DEBUG_PRINT("dig_T = 0x%x, 0x%x, 0x%x\n", dig_T1, dig_T2, dig_T3);
+ 
+    cmd[0] = 0x8E; // read dig_P regs
+    i2c.write(address, cmd, 1);
+    i2c.read(address, cmd, 18);
+ 
+    dig_P1 = (cmd[ 1] << 8) | cmd[ 0];
+    dig_P2 = (cmd[ 3] << 8) | cmd[ 2];
+    dig_P3 = (cmd[ 5] << 8) | cmd[ 4];
+    dig_P4 = (cmd[ 7] << 8) | cmd[ 6];
+    dig_P5 = (cmd[ 9] << 8) | cmd[ 8];
+    dig_P6 = (cmd[11] << 8) | cmd[10];
+    dig_P7 = (cmd[13] << 8) | cmd[12];
+    dig_P8 = (cmd[15] << 8) | cmd[14];
+    dig_P9 = (cmd[17] << 8) | cmd[16];
+ 
+    DEBUG_PRINT("dig_P = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9);
+ 
+    cmd[0] = 0xA1; // read dig_H regs
+    i2c.write(address, cmd, 1);
+    i2c.read(address, cmd, 1);
+     cmd[1] = 0xE1; // read dig_H regs
+    i2c.write(address, &cmd[1], 1);
+    i2c.read(address, &cmd[1], 7);
+
+    dig_H1 = cmd[0];
+    dig_H2 = (cmd[2] << 8) | cmd[1];
+    dig_H3 = cmd[3];
+    dig_H4 = (cmd[4] << 4) | (cmd[5] & 0x0f);
+    dig_H5 = (cmd[6] << 4) | ((cmd[5]>>4) & 0x0f);
+    dig_H6 = cmd[7];
+ 
+    DEBUG_PRINT("dig_H = 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", dig_H1, dig_H2, dig_H3, dig_H4, dig_H5, dig_H6);
+}
+ 
+float BME280::getTemperature()
+{
+    uint32_t temp_raw;
+    float tempf;
+    char cmd[4];
+ 
+    cmd[0] = 0xfa; // temp_msb
+    i2c.write(address, cmd, 1);
+    i2c.read(address, &cmd[1], 3);
+ 
+    temp_raw = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);
+ 
+    int32_t temp;
+ 
+    temp =
+        (((((temp_raw >> 3) - (dig_T1 << 1))) * dig_T2) >> 11) +
+        ((((((temp_raw >> 4) - dig_T1) * ((temp_raw >> 4) - dig_T1)) >> 12) * dig_T3) >> 14);
+ 
+    t_fine = temp;
+    temp = (temp * 5 + 128) >> 8;
+    tempf = (float)temp;
+ 
+    return (tempf/100.0f);
+}
+ 
+float BME280::getPressure()
+{
+    uint32_t press_raw;
+    float pressf;
+    char cmd[4];
+ 
+    cmd[0] = 0xf7; // press_msb
+    i2c.write(address, cmd, 1);
+    i2c.read(address, &cmd[1], 3);
+ 
+    press_raw = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);
+ 
+    int32_t var1, var2;
+    uint32_t press;
+ 
+    var1 = (t_fine >> 1) - 64000;
+    var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * dig_P6;
+    var2 = var2 + ((var1 * dig_P5) << 1);
+    var2 = (var2 >> 2) + (dig_P4 << 16);
+    var1 = (((dig_P3 * (((var1 >> 2)*(var1 >> 2)) >> 13)) >> 3) + ((dig_P2 * var1) >> 1)) >> 18;
+    var1 = ((32768 + var1) * dig_P1) >> 15;
+    if (var1 == 0) {
+        return 0;
+    }
+    press = (((1048576 - press_raw) - (var2 >> 12))) * 3125;
+    if(press < 0x80000000) {
+        press = (press << 1) / var1;
+    } else {
+        press = (press / var1) * 2;
+    }
+    var1 = ((int32_t)dig_P9 * ((int32_t)(((press >> 3) * (press >> 3)) >> 13))) >> 12;
+    var2 = (((int32_t)(press >> 2)) * (int32_t)dig_P8) >> 13;
+    press = (press + ((var1 + var2 + dig_P7) >> 4));
+ 
+    pressf = (float)press;
+    return (pressf/100.0f);
+}
+ 
+float BME280::getHumidity()
+{
+    uint32_t hum_raw;
+    float humf;
+    char cmd[4];
+ 
+    cmd[0] = 0xfd; // hum_msb
+    i2c.write(address, cmd, 1);
+    i2c.read(address, &cmd[1], 2);
+ 
+    hum_raw = (cmd[1] << 8) | cmd[2];
+ 
+    int32_t v_x1;
+ 
+    v_x1 = t_fine - 76800;
+    v_x1 =  (((((hum_raw << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) * v_x1)) +
+               ((int32_t)16384)) >> 15) * (((((((v_x1 * (int32_t)dig_H6) >> 10) *
+                                            (((v_x1 * ((int32_t)dig_H3)) >> 11) + 32768)) >> 10) + 2097152) *
+                                            (int32_t)dig_H2 + 8192) >> 14));
+    v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * (int32_t)dig_H1) >> 4));
+    v_x1 = (v_x1 < 0 ? 0 : v_x1);
+    v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
+ 
+    humf = (float)(v_x1 >> 12);
+ 
+    return (humf/1024.0f);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BME280/BME280.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,101 @@
+/**
+ *  BME280 Combined humidity and pressure sensor library
+ *
+ *  @author  Toyomasa Watarai
+ *  @version 1.0
+ *  @date    06-April-2015
+ *
+ *  Library for "BME280 temperature, humidity and pressure sensor module" from Switch Science
+ *    https://www.switch-science.com/catalog/2236/
+ *
+ *  For more information about the BME280:
+ *    http://ae-bst.resource.bosch.com/media/products/dokumente/bme280/BST-BME280_DS001-10.pdf
+ */
+ 
+#ifndef MBED_BME280_H
+#define MBED_BME280_H
+
+#include "mbed.h"
+
+//#define _DEBUG
+#define DEFAULT_SLAVE_ADDRESS (0x76 << 1)
+
+#ifdef _DEBUG
+extern Serial pc;
+#define DEBUG_PRINT(...) pc.printf(__VA_ARGS__)
+#else
+#define DEBUG_PRINT(...)
+#endif
+
+ 
+/** BME280 class
+ *
+ *  BME280: A library to correct environmental data using Boshe BME280 device
+ *
+ *  BME280 is an environmental sensor
+ *  @endcode
+ */
+ 
+class BME280
+{
+public:
+
+    /** Create a BME280 instance
+     *  which is connected to specified I2C pins with specified address
+     *
+     * @param sda I2C-bus SDA pin
+     * @param scl I2C-bus SCL pin
+     * @param slave_adr (option) I2C-bus address (default: 0x76)
+     */
+    BME280(PinName sda, PinName sck, char slave_adr = DEFAULT_SLAVE_ADDRESS);
+
+    /** Create a BME280 instance
+     *  which is connected to specified I2C pins with specified address
+     *
+     * @param i2c_obj I2C object (instance)
+     * @param slave_adr (option) I2C-bus address (default: 0x76)
+     */
+    BME280(I2C &i2c_obj, char slave_adr = DEFAULT_SLAVE_ADDRESS);
+
+    /** Destructor of BME280
+     */
+    virtual ~BME280();
+
+    /** Initializa BME280 sensor
+     *
+     *  Configure sensor setting and read parameters for calibration
+     *
+     */
+    void initialize(void);
+
+    /** Read the current temperature value (degree Celsius) from BME280 sensor
+     *
+     */
+    float getTemperature(void);
+
+    /** Read the current pressure value (hectopascal)from BME280 sensor
+     *
+     */
+    float getPressure(void);
+
+    /** Read the current humidity value (humidity %) from BME280 sensor
+     *
+     */
+    float getHumidity(void);
+
+private:
+
+    I2C         *i2c_p;
+    I2C         &i2c;
+    char        address;
+    uint16_t    dig_T1;
+    int16_t     dig_T2, dig_T3;
+    uint16_t    dig_P1;
+    int16_t     dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
+    uint16_t    dig_H1, dig_H3;
+    int16_t     dig_H2, dig_H4, dig_H5, dig_H6;
+    int32_t     t_fine;
+
+};
+
+#endif // MBED_BME280_H
--- a/BMP085.lib	Mon Aug 14 04:55:38 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/okini3939/code/BMP085/#5e2b1f3c0a6a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP085/BMP085.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,152 @@
+/*
+ * mbed library to use a Bosch Sensortec BMP085/BMP180 sensor
+ * Copyright (c) 2010 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file BMP085.cpp
+ * @brief mbed library to use a Bosch Sensortec BMP085/BMP180 sensor
+ * barometric pressure sensor BMP085/BMP180 (Bosch Sensortec)
+ * interface: I2C digital
+ */
+
+#include "mbed.h"
+#include "BMP085.h"
+
+#define WEATHER_BMP085 0xee
+#define xpow(x, y) ((long)1 << y)
+
+/**
+ * @brief Initializes interface (private I2C)
+ * @param p_sda port of I2C SDA
+ * @param p_scl port of I2C SCL
+ * @param p_oss parameter of OSS
+ */
+BMP085::BMP085 (PinName p_sda, PinName p_scl, BMP085_oss p_oss) : i2c(p_sda, p_scl) {
+    init(p_oss);
+}
+
+/**
+ * @brief Initializes interface (public I2C)
+ * @param p_i2c instance of I2C class
+ * @param p_oss parameter of OSS
+ */
+BMP085::BMP085 (I2C& p_i2c, BMP085_oss p_oss) : i2c(p_i2c) { 
+    init(p_oss);
+}
+
+/**
+ * @brief Get temperature
+ * @return temperature (`C)
+ */
+float BMP085::get_temperature() {
+    return temperature;
+}
+
+/**
+ * @brief Get pressure
+ * @return pressure (hPa)
+ */
+float BMP085::get_pressure() {
+    return pressure;
+}
+
+/**
+ * @brief Update results
+ */
+void BMP085::update () {
+    long t, p, ut, up, x1, x2, x3, b3, b5, b6;
+    unsigned long b4, b7;
+
+    twi_writechar(WEATHER_BMP085, 0xf4, 0x2e);
+    wait(0.01);
+    ut = twi_readshort(WEATHER_BMP085, 0xf6);
+
+    twi_writechar(WEATHER_BMP085, 0xf4, 0x34 | (oss << 6));
+    wait(0.05);
+    up = twi_readlong(WEATHER_BMP085, 0xf6) >> (8 - oss);
+
+    x1 = (ut - ac6) * ac5 / xpow(2, 15);
+    x2 = (long)mc * xpow(2, 11) / (x1 + md);
+    b5 = x1 + x2;
+    t = (b5 + 8) / xpow(2, 4);
+    temperature = (float)t / 10.0;
+
+    b6 = b5 - 4000;
+    x1 = (b2 * (b6 * b6 / xpow(2, 12))) / xpow(2, 11);
+    x2 = ac2 * b6 / xpow(2, 11);
+    x3 = x1 + x2;
+    b3 = ((((unsigned long)ac1 * 4 + x3) << oss) + 2) / 4;
+    x1 = ac3 * b6 / xpow(2, 13);
+    x2 = (b1 * (b6 * b6 / xpow(2, 12))) / xpow(2, 16);
+    x3 = ((x1 + x2) + 2) / xpow(2, 2);
+    b4 = ac4 * (unsigned long)(x3 + 32768) / xpow(2, 15);
+    b7 = ((unsigned long)up - b3) * (50000 >> oss);
+    if (b7 < (unsigned long)0x80000000) {
+        p = (b7 * 2) / b4;
+    } else {
+        p = (b7 / b4) * 2;
+    }
+    x1 = (p / xpow(2, 8)) * (p / xpow(2, 8));
+    x1 = (x1 * 3038) / xpow(2, 16);
+    x2 = (-7357 * p) / xpow(2, 16);
+    p = p + (x1 + x2 + 3791) / xpow(2, 4);
+    pressure = (float)p / 100.0;
+}
+
+void BMP085::init (BMP085_oss p_oss) {
+    ac1 = twi_readshort(WEATHER_BMP085, 0xaa);
+    ac2 = twi_readshort(WEATHER_BMP085, 0xac);
+    ac3 = twi_readshort(WEATHER_BMP085, 0xae);
+    ac4 = twi_readshort(WEATHER_BMP085, 0xb0);
+    ac5 = twi_readshort(WEATHER_BMP085, 0xb2);
+    ac6 = twi_readshort(WEATHER_BMP085, 0xb4);
+    b1 = twi_readshort(WEATHER_BMP085, 0xb6);
+    b2 = twi_readshort(WEATHER_BMP085, 0xb8);
+    mb = twi_readshort(WEATHER_BMP085, 0xba);
+    mc = twi_readshort(WEATHER_BMP085, 0xbc);
+    md = twi_readshort(WEATHER_BMP085, 0xbe);
+    oss = p_oss;
+}
+
+unsigned short BMP085::twi_readshort (int id, int addr) {
+    unsigned short i;
+
+    i2c.start();
+    i2c.write(id);
+    i2c.write(addr);
+
+    i2c.start();
+    i2c.write(id | 1);
+    i = i2c.read(1) << 8;
+    i |= i2c.read(0);
+    i2c.stop();
+
+    return i;
+}
+
+unsigned long BMP085::twi_readlong (int id, int addr) {
+    unsigned long i;
+
+    i2c.start();
+    i2c.write(id);
+    i2c.write(addr);
+
+    i2c.start();
+    i2c.write(id | 1);
+    i = i2c.read(1) << 16;
+    i |= i2c.read(1) << 8;
+    i |= i2c.read(0);
+    i2c.stop();
+
+    return i;
+}
+
+void BMP085::twi_writechar (int id, int addr, int dat) {
+
+    i2c.start();
+    i2c.write(id);
+    i2c.write(addr);
+    i2c.write(dat);
+    i2c.stop();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP085/BMP085.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,56 @@
+/*
+ * mbed library to use a Bosch Sensortec BMP085/BMP180 sensor
+ * Copyright (c) 2010 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+ 
+/** @file BMP085.h
+ * @brief mbed library to use a Bosch Sensortec BMP085/BMP180 sensor
+ * barometric pressure sensor BMP085/BMP180 (Bosch Sensortec)
+ * interface: I2C digital
+ */
+ 
+#ifndef BMP085_H
+#define BMP085_H
+
+#include "mbed.h"
+
+/**
+ * @brief over sampling setting
+ */
+enum BMP085_oss {
+    BMP085_oss1 = 0, ///< ultra low power (1 time)
+    BMP085_oss2 = 1, ///< standard (2 times)
+    BMP085_oss4 = 2, ///< high resolution (4 times)
+    BMP085_oss8 = 3  ///< ultra high resolution (8 times)
+};
+
+/**
+ * @brief BMP085 class
+ */
+class BMP085 {
+public:
+    BMP085(PinName p_sda, PinName p_scl, BMP085_oss p_oss = BMP085_oss1);
+    BMP085(I2C& p_i2c, BMP085_oss p_oss = BMP085_oss1);
+
+    float get_temperature();
+    float get_pressure();
+    void update();
+
+protected:
+    void init(BMP085_oss);
+    unsigned short twi_readshort (int, int);
+    unsigned long twi_readlong (int, int);
+    void twi_writechar (int, int, int);
+
+    I2C i2c;
+    float temperature;
+    float pressure;
+
+private:
+
+    short ac1, ac2, ac3, b1, b2, mb, mc, md, oss;
+    unsigned short ac4, ac5, ac6;
+};
+
+#endif
\ No newline at end of file
--- a/IM920.lib	Mon Aug 14 04:55:38 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/okini3939/code/IM920/#2fd9b1725283
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/CBuffer.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,85 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * 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.
+ */
+/*
+ * Modifyed by Suga
+ */
+
+#ifndef CIRCBUFFER_H_
+#define CIRCBUFFER_H_
+
+template <class T>
+class CircBuffer {
+public:
+    CircBuffer(int length, void *addr = NULL) {
+        write = 0;
+        read = 0;
+        size = length + 1;
+        if (addr) {
+            buf = (T *)addr;
+        } else {
+            buf = (T *)malloc(size * sizeof(T));
+        }
+        if (buf == NULL)
+            error("Can't allocate memory");
+    };
+
+    bool isFull() {
+        return (((write + 1) % size) == read);
+    };
+
+    bool isEmpty() {
+        return (read == write);
+    };
+
+    void queue(T k) {
+        if (isFull()) {
+//            read++;
+//            read %= size;
+            return;
+        }
+        buf[write++] = k;
+        write %= size;
+    }
+    
+    void flush() {
+        read = 0;
+        write = 0;
+    }
+    
+
+    uint32_t available() {
+        return (write >= read) ? write - read : size - read + write;
+    };
+
+    bool dequeue(T * c) {
+        bool empty = isEmpty();
+        if (!empty) {
+            *c = buf[read++];
+            read %= size;
+        }
+        return(!empty);
+    };
+
+private:
+    volatile uint32_t write;
+    volatile uint32_t read;
+    uint32_t size;
+    T * buf;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,68 @@
+/* Copyright (C) 2014 Suga, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * 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 "IM920.h"
+
+IM920::IM920 (PinName tx, PinName rx, PinName busy, PinName reset, int baud) : _im(tx, rx) {
+
+    memset(&_state, 0, sizeof(_state));
+    _state.data = new CircBuffer<char>(CFG_DATA_SIZE);
+
+    initUart(busy, reset, baud);
+    setReset(true);
+    wait_ms(100);
+    setReset(false);
+}
+
+int IM920::init () {
+
+    cmdRDID();
+    cmdRDNN();
+    cmdSTPO(3);  // 10dBm
+    cmdSTRT(2);  // 1.25kbps
+    return 0;
+}
+
+void IM920::poll () {
+
+    if (_state.received && _state.buf != NULL)
+      if (!_state.data->isEmpty()) {
+        _func.call();
+        if (_state.data->isEmpty()) {
+            _state.received = false;
+        }
+    }
+}
+
+int IM920::send (char *buf, int len) {
+
+    if (len > 64) len = 64;
+
+    return sendData(buf, len);
+}
+
+int IM920::recv (char *buf, int len) {
+    int i;
+
+    if (_state.data == NULL) return 0;
+    while (!_state.received && _state.mode != MODE_COMMAND);
+    _state.received = false;
+    for (i = 0; i < len; i ++) {
+        if (_state.data->dequeue(&buf[i]) == false) break;
+    }
+    return i;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,161 @@
+/* Copyright (C) 2014 Suga, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * 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 _IM920_h_
+#define _IM920_h_
+
+#include "IM920_conf.h"
+
+#include "mbed.h"
+#include "FunctionPointer.h"
+#include "CBuffer.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+//Debug is disabled by default
+#if defined(DEBUG)
+#define DBG(x, ...) std::printf("[DBG]" x "\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[WARN]" x "\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[ERR]" x "\r\n", ##__VA_ARGS__);
+#define INFO(x, ...) std::printf("[INFO]" x "\r\n", ##__VA_ARGS__);
+#else
+#define DBG(x, ...)
+#define WARN(x, ...)
+#define ERR(x, ...)
+#define INFO(x, ...)
+#endif
+
+class IM920 {
+public:
+    enum Response {
+        RES_NULL,
+        RES_RDID,
+        RES_RDNN,
+        RES_RDRS,
+    };
+
+    enum Mode {
+        MODE_COMMAND,
+        MODE_DATA_RX,
+    };
+
+    enum Status {
+        STAT_NONE,
+        STAT_SLEEP,
+    };
+
+    IM920 (PinName tx, PinName rx, PinName busy, PinName reset, int baud = IM920_BAUD);
+
+    int init ();
+    void poll ();
+    int send (char *buf, int len);
+    int recv (char *buf, int len);
+
+    void attach (void(*fptr)() = NULL) {
+        _func.attach(fptr);
+    }
+    template<typename T>
+    void attach (T* tptr, void (T::*mptr)()) {
+        if ((mptr != NULL) && (tptr != NULL)) {
+            _func.attach(tptr, mptr);
+        }
+    }
+
+    // ----- IM920_util.cpp -----
+    int setNode (int node);
+    int getNode ();
+    int setCh (int ch);
+    int setPower (int pwr);
+    int setSpeed (int spd);
+    int getRssi ();
+    int sleep ();
+    int wakeup ();
+    int test ();
+
+    // ----- IM920_cmd.cpp -----
+    int sendCommand(const char * cmd, Response res = RES_NULL, int timeout = DEFAULT_WAIT_RESP_TIMEOUT);
+    int sendData(const char * data, int len, int timeout = CFG_TIMEOUT);
+
+private:
+    RawSerial _im;
+    DigitalIn *_busy;
+    DigitalInOut *_reset;
+    int _baud;
+    FunctionPointer _func;
+
+    struct STATE {
+        int id, node, rssi;
+
+        time_t time;
+        bool initialized;
+        volatile Mode mode;
+        volatile Status status;
+        volatile bool ok, failure;
+        volatile Response res;
+        int n;
+        char buf[CFG_BUF_SIZE];
+
+        CircBuffer<char> *data;
+        volatile bool received;
+    } _state;
+
+    // ----- IM920_util.cpp -----
+    int x2i (char c);
+    char i2x (int i);
+
+    // ----- IM920_msg.cpp -----
+    void recvData (char c);
+    int parseMessage ();
+    void msgOk (const char*);
+    void msgError (const char*);
+    void msgConnect (const char*);
+    void resRDID (const char *buf);
+    void resRDNN (const char *buf);
+    void resRDRS (const char *buf);
+
+    // ----- IM920_cmd.cpp -----
+    void clearFlags ();
+    int cmdENWR ();
+    int cmdDSWR ();
+    int cmdRDID ();
+    int cmdSTNN (int n);
+    int cmdRDNN ();
+    int cmdSRID (int n);
+    int cmdERID ();
+    int cmdSTCH (int n);
+    int cmdRDRS ();
+    int cmdSTPO (int n);
+    int cmdSTRT (int n);
+    int cmdSBRT (int n);
+    int cmdDSRX ();
+    int cmdENRX ();
+    int cmdEGRX ();
+    int cmdDGRX ();
+
+    // ----- IM920_hal.cpp -----
+    void setReset (bool flg);
+    void isrUart ();
+    int getUart ();
+    void putUart (char c);
+    int lockUart (int ms);
+    void unlockUart ();
+    void initUart (PinName busy, PinName reset, int baud);
+ };
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920_cmd.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,151 @@
+#include "IM920.h"
+
+void IM920::clearFlags () {
+    _state.ok = false;
+    _state.failure = false;
+    _state.res = RES_NULL;
+    _state.n = 0;
+}
+
+int IM920::sendCommand (const char * cmd, Response res, int timeout) {
+    int i;
+    Timer t;
+
+    if (lockUart(timeout)) return -1;
+
+    clearFlags();
+    _state.res = res;
+    for (i = 0; i < strlen(cmd); i ++) {
+        putUart(cmd[i]);
+    }
+    putUart('\r');
+    putUart('\n');
+    unlockUart();
+    INFO("command: '%s'\r\n", cmd);
+
+    if (timeout) {
+        t.start();
+        for (;;) {
+            if (_state.ok && _state.res == RES_NULL) break;
+            if (_state.failure || t.read_ms() > timeout) {
+                WARN("failure or timeout\r\n");
+                _state.res = RES_NULL;
+                return -1;
+            }
+        }
+        t.stop();
+    }
+    INFO("ok\r\n");
+    _state.res = RES_NULL;
+
+    return 0;
+}
+
+int IM920::sendData(const char * data, int len, int timeout) {
+    int i;
+    Timer t;
+
+    if (lockUart(timeout)) return -1;
+
+    if (len > 64) len = 64;
+    clearFlags();
+    putUart('T');
+    putUart('X');
+    putUart('D');
+    putUart('A');
+    putUart(' ');
+    for (i = 0; i < len; i ++) {
+        putUart(i2x((data[i]>>4) & 0x0f));
+        putUart(i2x(data[i] & 0x0f));
+    }
+    putUart('\r');
+    putUart('\n');
+    unlockUart();
+    INFO("data: TXDA %d\r\n", len);
+
+    if (timeout) {
+        t.start();
+        for (;;) {
+            if (_state.ok) break;
+            if (_state.failure || t.read_ms() > timeout) {
+                WARN("failure or timeout\r\n");
+                return -1;
+            }
+        }
+        t.stop();
+    }
+
+    return i;
+}
+
+int IM920::cmdENWR () {
+    return sendCommand("ENWR");
+}
+
+int IM920::cmdDSWR () {
+    return sendCommand("DSWR");
+}
+
+int IM920::cmdRDID () {
+    return sendCommand("RDID", RES_RDID);
+}
+
+int IM920::cmdSTNN (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "STNN %02X", n);
+    return sendCommand(cmd);
+}
+
+int IM920::cmdRDNN () {
+    return sendCommand("RDNN", RES_RDNN);
+}
+
+int IM920::cmdSRID (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "SRID %04X", n);
+    return sendCommand(cmd);
+}
+
+int IM920::cmdERID () {
+    return sendCommand("ERID");
+}
+
+int IM920::cmdSTCH (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "STCH %02d", n);
+    return sendCommand(cmd);
+}
+
+int IM920::cmdRDRS () {
+    return sendCommand("RDRS", RES_RDRS);
+}
+
+int IM920::cmdSTPO (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "STPO %d", n);
+    return sendCommand(cmd);
+}
+
+int IM920::cmdSTRT (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "STRT %d", n);
+    return sendCommand(cmd);
+}
+
+int IM920::cmdSBRT (int n) {
+    char cmd[CFG_CMD_SIZE];
+    sprintf(cmd, "SBRT %d", n);
+    return sendCommand(cmd);
+}
+
+int IM920::cmdDSRX () {
+    return sendCommand("DSRX");
+}
+
+int IM920::cmdENRX () {
+    return sendCommand("ENRX");
+}
+
+int IM920::cmdEGRX () {
+    return sendCommand("EGRX");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920_conf.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,16 @@
+#ifndef _IM920_conf_h_
+#define _IM920_conf_h_
+
+//#define DEBUG
+//#define DEBUG_DUMP
+
+#define IM920_BAUD 19200
+
+#define CFG_BUF_SIZE 150
+#define CFG_DATA_SIZE 64
+#define CFG_CMD_SIZE 16
+
+#define DEFAULT_WAIT_RESP_TIMEOUT 500
+#define CFG_TIMEOUT 5000
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920_hal.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,59 @@
+#include "IM920.h"
+
+void IM920::setReset (bool flg) {
+    if (_reset) {
+        if (flg) {
+            _reset->output();
+            _reset->write(0);
+        } else {
+            _reset->input();
+            _reset->mode(PullNone);
+        }
+    }
+}
+
+void IM920::isrUart () {
+    recvData(getUart());
+}
+
+int IM920::getUart () {
+    return _im.getc();
+}
+
+void IM920::putUart (char c) {
+    _im.putc(c);
+}
+
+int IM920::lockUart (int ms) {
+    Timer t;
+
+    if (_busy && _busy->read()) {
+        // CTS check
+        t.start();
+        while (_busy->read()) {
+            if (t.read_ms() >= ms) {
+                DBG("cts timeout\r\n");
+                return -1;
+            }
+        }
+    }
+    return 0;
+}
+
+void IM920::unlockUart () {
+}
+
+void IM920::initUart (PinName busy, PinName reset, int baud) {
+    _baud = baud;
+    if (_baud) _im.baud(_baud);
+    _im.attach(this, &IM920::isrUart, Serial::RxIrq);
+
+    _busy = NULL;
+    _reset = NULL;
+    if (busy != NC) {
+        _busy = new DigitalIn(busy);
+    }
+    if (reset != NC) {
+        _reset = new DigitalInOut(reset);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920_msg.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,136 @@
+#include "IM920.h"
+
+void IM920::recvData (char c) {
+    static int sub, len, count;
+    static char chr;
+
+#ifdef DEBUG_DUMP
+    if (c < 0x20 || c >= 0x7f) {
+        std::printf("_%02x", c);
+    } else {
+        std::printf("_%c", c);
+    }
+#endif
+    switch (_state.mode) {
+    case MODE_COMMAND:
+        switch (c) {
+        case 0:
+        case 0x0a: // LF
+        case 0x0d: // CR
+            _state.buf[len] = 0;
+            len = 0;
+            parseMessage();
+            break;
+        case ':':
+            if (_state.buf[2] == ',' && _state.buf[7] == ',' && len == 10) {
+                sub = 0;
+                _state.mode = MODE_DATA_RX;
+                break;
+            }
+            /* FALLTHROUGH */
+        default:
+            if (len < sizeof(_state.buf) - 1) {
+                _state.buf[len] = c;
+                len ++;
+            }
+            break;
+        }
+        break;
+
+    case MODE_DATA_RX:
+        if (c == '\r' || c == '\n') {
+            DBG("recv %d/%d\r\n", count, len);
+            _state.received = true;
+            _state.mode = MODE_COMMAND;
+            len = 0;
+            break;
+        }
+        switch (sub) {
+        case 0:
+            chr = x2i(c) << 4;
+            sub ++;
+            break;
+        case 1:
+            chr |= x2i(c);
+            sub ++;
+            if (_state.data!= NULL) {
+                _state.data->queue(chr);
+                if (_state.data->available() >= CFG_DATA_SIZE) {
+                    _state.received = true;
+                    WARN("buf full");
+                }
+            }
+            count ++;
+            break;
+        case 2:
+            if (c == ',') {
+                sub = 0;
+            }
+            break;
+        }
+    }
+}
+
+#define RES_TABLE_NUM 4
+int IM920::parseMessage () {
+    int i;
+    static const struct RES_TABLE {
+        const Response res;
+        void (IM920::*func)(const char*);
+    } res_table[RES_TABLE_NUM] = {
+      {RES_NULL,        NULL},
+      {RES_RDID,        &IM920::resRDID},
+      {RES_RDNN,        &IM920::resRDNN},
+      {RES_RDRS,        &IM920::resRDRS},
+    };
+
+    if (_state.res != RES_NULL) {
+      for (i = 0; i < RES_TABLE_NUM; i ++) {
+        if (res_table[i].res == _state.res) {
+            DBG("parse res %d '%s'\r\n", i, _state.buf);
+            if (res_table[i].func != NULL) {
+                (this->*(res_table[i].func))(_state.buf);
+            }
+        }
+      }
+    }
+
+    if (strncmp(_state.buf, "OK", 2) == 0) {
+        _state.ok = true;
+        if (_state.status == STAT_SLEEP) {
+            _state.status = STAT_NONE;
+        }
+        return 0;
+    } else
+    if (strncmp(_state.buf, "NG", 2) == 0) {
+        _state.failure = true;
+        return 0;
+    }
+
+    return -1;
+}
+
+void IM920::resRDID (const char *buf) {
+
+    if (buf[0] < '0' || buf[0] > 'F') return;
+
+    _state.id = strtol(buf, NULL, 16);
+    _state.res = RES_NULL;
+}
+
+void IM920::resRDNN (const char *buf) {
+
+    if (buf[0] < '0' || buf[0] > 'F') return;
+
+    _state.node = strtol(buf, NULL, 16);
+    _state.res = RES_NULL;
+}
+
+void IM920::resRDRS (const char *buf) {
+
+    if (buf[0] < '0' || buf[0] > 'F') return;
+
+    _state.rssi = strtol(buf, NULL, 16);
+    _state.res = RES_NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IM920/IM920_util.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,74 @@
+#include "IM920.h"
+
+int IM920::setNode (int node) {
+    _state.node = node;
+    return cmdSTNN(_state.node);
+}
+
+int IM920::getNode () {
+    cmdRDNN();
+    return _state.node;
+}
+
+int IM920::setCh (int ch) {
+    if (ch < 1 || ch > 15) return -1;
+    return cmdSTCH(ch);
+}
+
+int IM920::setPower (int pwr) {
+    if (pwr < 1 || pwr > 3) return -1;
+    return cmdSTPO(pwr);
+}
+
+int IM920::setSpeed (int spd) {
+    if (spd < 1 || spd > 2) return -1;
+    return cmdSTRT(spd);
+}
+
+int IM920::getRssi () {
+    cmdRDRS();
+    return _state.rssi;
+}
+
+int IM920::sleep () {
+    if (_state.status != STAT_NONE) return -1;
+
+    _state.status = STAT_SLEEP;
+    return cmdDSRX();
+}
+
+int IM920::wakeup () {
+    if (_state.status != STAT_SLEEP) return -1;
+
+    putUart('\r');
+    putUart('\n');
+    return cmdENRX();
+}
+
+int IM920::test () {
+    return cmdEGRX();
+}
+
+
+int IM920::x2i (char c) {
+    if (c >= '0' && c <= '9') {
+        return c - '0';
+    } else
+    if (c >= 'A' && c <= 'F') {
+        return c - 'A' + 10;
+    } else
+    if (c >= 'a' && c <= 'f') {
+        return c - 'a' + 10;
+    }
+    return 0;
+}
+
+char IM920::i2x (int i) {
+    if (i >= 0 && i <= 9) {
+        return i + '0';
+    } else
+    if (i >= 10 && i <= 15) {
+        return i - 10 + 'A';
+    }
+    return 0;
+}
--- a/L3GD20.lib	Mon Aug 14 04:55:38 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/bclaus/code/L3GD20/#b45dbca259f8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/L3GD20/L3GD20.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2011 Pololu Corporation.  For more information, see
+ * 
+ * http://www.pololu.com/
+ * http://forum.pololu.com/
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * 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 "mbed.h"
+ #include "L3GD20.h"
+
+
+// Defines ////////////////////////////////////////////////////////////////
+
+// The Arduino two-wire interface uses a 7-bit number for the address, 
+// and sets the last bit correctly based on reads and writes
+// mbed I2C libraries take the 7-bit address shifted left 1 bit
+// #define GYR_ADDRESS (0xD2 >> 1)
+#define GYR_ADDRESS 0xD6
+
+
+// Public Methods //////////////////////////////////////////////////////////////
+
+// Constructor
+L3GD20::L3GD20(PinName sda, PinName scl):
+    _L3GD20(sda, scl)
+{
+    char reg_v;
+    _L3GD20.frequency(200000);
+    
+    reg_v = 0;          
+    write_reg(GYR_ADDRESS,L3GD20_LOW_ODR,reg_v);
+    
+  // 0x6F
+  // DR = 01 (200 Hz ODR); BW = 10 (50 Hz bandwidth); PD = 1 (normal mode); Zen = Yen = Xen = 1 (all axes enabled)
+    reg_v = 0;    
+    reg_v |= 0x6F;       
+    write_reg(GYR_ADDRESS,L3GD20_CTRL_REG1,reg_v);
+    
+
+
+}
+
+
+
+bool L3GD20::read(float *gx, float *gy, float *gz) {
+    char gyr[6];
+ 
+    if (recv(GYR_ADDRESS, L3GD20_OUT_X_L, gyr, 6)) {
+    //scale is 8.75 mdps/digit
+        *gx = float(short(gyr[1] << 8 | gyr[0]))*0.00875;  
+        *gy =  float(short(gyr[3] << 8 | gyr[2]))*0.00875;
+        *gz =  float(short(gyr[5] << 8 | gyr[4]))*0.00875;
+
+ 
+        return true;
+    }
+ 
+    return false;
+}
+
+
+
+
+bool L3GD20::write_reg(int addr_i2c,int addr_reg, char v)
+{
+    char data[2] = {addr_reg, v}; 
+    return L3GD20::_L3GD20.write(addr_i2c, data, 2) == 0;
+}
+
+bool L3GD20::read_reg(int addr_i2c,int addr_reg, char *v)
+{
+    char data = addr_reg; 
+    bool result = false;
+    
+    __disable_irq();
+    if ((_L3GD20.write(addr_i2c, &data, 1) == 0) && (_L3GD20.read(addr_i2c, &data, 1) == 0)){
+        *v = data;
+        result = true;
+    }
+    __enable_irq();
+    return result;
+}
+
+
+bool L3GD20::recv(char sad, char sub, char *buf, int length) {
+    if (length > 1) sub |= 0x80;
+ 
+    return _L3GD20.write(sad, &sub, 1, true) == 0 && _L3GD20.read(sad, buf, length) == 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/L3GD20/L3GD20.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,104 @@
+/* Copyright (c) 2011 Pololu Corporation.  For more information, see
+ * 
+ * http://www.pololu.com/
+ * http://forum.pololu.com/
+ * 
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * 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 __L3GD20_H
+#define __L3GD20_H
+
+#include "mbed.h"
+
+// register addresses
+
+#define L3GD20_WHO_AM_I      0x0F
+
+#define L3GD20_CTRL_REG1     0x20
+#define L3GD20_CTRL_REG2     0x21
+#define L3GD20_CTRL_REG3     0x22
+#define L3GD20_CTRL_REG4     0x23
+#define L3GD20_CTRL_REG5     0x24
+#define L3GD20_REFERENCE     0x25
+#define L3GD20_OUT_TEMP      0x26
+#define L3GD20_STATUS_REG    0x27
+
+#define L3GD20_OUT_X_L       0x28
+#define L3GD20_OUT_X_H       0x29
+#define L3GD20_OUT_Y_L       0x2A
+#define L3GD20_OUT_Y_H       0x2B
+#define L3GD20_OUT_Z_L       0x2C
+#define L3GD20_OUT_Z_H       0x2D
+
+#define L3GD20_FIFO_CTRL_REG 0x2E
+#define L3GD20_FIFO_SRC_REG  0x2F
+
+#define L3GD20_INT1_CFG      0x30
+#define L3GD20_INT1_SRC      0x31
+#define L3GD20_INT1_THS_XH   0x32
+#define L3GD20_INT1_THS_XL   0x33
+#define L3GD20_INT1_THS_YH   0x34
+#define L3GD20_INT1_THS_YL   0x35
+#define L3GD20_INT1_THS_ZH   0x36
+#define L3GD20_INT1_THS_ZL   0x37
+#define L3GD20_INT1_DURATION 0x38
+#define L3GD20_LOW_ODR       0x39 // D20H
+
+/** Interface library for the ST L3GD20 3-axis gyro
+ *
+ * Ported from Pololu L3GD20 library for Arduino by
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "L3GD20.h"
+ * L3GD20 gyro(p28, p27);
+ * ...
+ * int g[3];
+ * gyro.read(g);
+ * @endcode
+ */
+class L3GD20
+{
+    public:
+        /** Create a new L3GD20 I2C interface
+         * @param sda is the pin for the I2C SDA line
+         * @param scl is the pin for the I2C SCL line
+         */
+        L3GD20(PinName sda, PinName scl);
+        
+        /** Read gyro values
+         * @param g Array containing x, y, and z gyro values
+         * @return g Array containing x, y, and z gyro values
+         */
+        bool read(float *gx, float *gy, float *gz);
+        
+    private:
+            I2C _L3GD20;
+        float gx, gy, gz;
+
+        bool write_reg(int addr_i2c,int addr_reg, char v);
+        bool read_reg(int addr_i2c,int addr_reg, char *v);
+        bool recv(char sad, char sub, char *buf, int length);
+};
+
+#endif
\ No newline at end of file
--- a/LSM303DLHC.lib	Mon Aug 14 04:55:38 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-https://mbed.org/users/jk1lot/code/LSM303DLHC/#e5bf52560a0c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM303DLHC/LSM303DLHC.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,108 @@
+#include "LSM303DLHC.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+LSM303DLHC::LSM303DLHC(I2C *obj) : i2c(obj)
+{
+    write(ACCEL_SAD, CTRL_REG1_A, 0x57);
+
+    write(MAGNET_SAD, CRA_REG_M, 0x90);
+    write(MAGNET_SAD, CRB_REG_M, 0x20);
+    write(MAGNET_SAD, MR_REG_M, 0x00);
+}
+
+float LSM303DLHC::orientation(void)
+{
+        /* 加速度センサ未使用版
+        float ans = atan2(float(magneticY()), float(magneticX()));
+        if (ans < 0) ans += 2*M_PI ;
+        if (ans > 2*M_PI) ans -= 2*M_PI;
+        ans = ans * 180/M_PI ;
+        if (ans > 360.0) ans = ans - 360.0 ;
+        return ans ;
+        */
+        //加速度センサ使用版
+        return heading((vector){0,-1,0});
+}
+
+float LSM303DLHC::temperature(void)
+{
+    char data[2];
+    read(MAGNET_SAD, TEMP_OUT_M, data, 2);
+    //マルツにあるサンプルをみたら25を足している
+    //データシートにはそんな記述はないが
+    //確かにそれで、それらしい値になる
+    return ((data[0]<<8)|data[1])/256.0+25;
+}
+
+void LSM303DLHC::write(char sad, char reg, char data)
+{
+    char rw[2];
+    rw[0] = reg;
+    rw[1] = data;
+    i2c->write(sad, rw, 2);
+}
+
+void LSM303DLHC::read(char sad, char reg, char *data, int length)
+{
+    reg |= 0x80; //MSB of register address means auto increment mode
+    i2c->write(sad, &reg, 1);
+    i2c->read(sad, data, length);
+}
+
+
+void LSM303DLHC::vector_cross(const vector *a,const vector *b, vector *out)
+{
+  out->x = a->y*b->z - a->z*b->y;
+  out->y = a->z*b->x - a->x*b->z;
+  out->z = a->x*b->y - a->y*b->x;
+}
+
+float LSM303DLHC::vector_dot(const vector *a,const vector *b)
+{
+  return a->x*b->x+a->y*b->y+a->z*b->z;
+}
+
+void LSM303DLHC::vector_normalize(vector *a)
+{
+  float mag = sqrt(vector_dot(a,a));
+  a->x /= mag;
+  a->y /= mag;
+  a->z /= mag;
+}
+
+float LSM303DLHC::heading(vector from)
+{
+    vector a, m;
+    a.x = accelX();
+    a.y = accelY();
+    a.z = accelZ();
+    m.x = magnetX();
+    m.y = magnetY();
+    m.z = magnetZ();
+    
+    ////////////////////////////////////////////////
+    // compute heading       
+    ////////////////////////////////////////////////
+
+    vector temp_a = a;
+    // normalize
+    vector_normalize(&temp_a);
+    //vector_normalize(&m);
+
+    // compute E and N
+    vector E;
+    vector N;
+    vector_cross(&m,&temp_a,&E);
+    vector_normalize(&E);
+    vector_cross(&temp_a,&E,&N);
+    
+    // compute heading
+    float heading = atan2(vector_dot(&E,&from), vector_dot(&N,&from)) * 180/M_PI;
+    if (heading < 0) heading += 360;
+    
+    return heading;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM303DLHC/LSM303DLHC.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,95 @@
+#ifndef LSM303DLHC_H
+#define LSM303DLHC_H
+
+#include "mbed.h"
+
+//! LSM303DLHC 3D accelerometer and 3D magnetometer
+class LSM303DLHC {
+    typedef struct vector {float x, y, z;} vector;
+    static void vector_cross(const vector *a, const vector *b, vector *out);
+    static float vector_dot(const vector *a,const vector *b);
+    static void vector_normalize(vector *a);
+public:
+    //! @param obj pointer to I2C object
+    LSM303DLHC(I2C *obj);
+    //! measure accelerometer value
+    void getAccel(void) {read(ACCEL_SAD, OUT_A, _accel, 6);}
+    //! extract X-axis value from mesured accelerometer
+    int16_t accelX(void) {return (_accel[1]<<8)|_accel[0];}
+    //! extract Y-axis value from mesured accelerometer
+    int16_t accelY(void) {return (_accel[3]<<8)|_accel[2];}
+    //! extract Z-axis value from mesured accelerometer
+    int16_t accelZ(void) {return (_accel[5]<<8)|_accel[4];}
+
+    //! mesure magnetometer value
+    void getMagnet(void) {read(MAGNET_SAD, OUT_M, _magnet, 6);}
+    //accelと magnetでは Highと Lowの順序が逆になってる変な仕様
+    //しかもMagnetは X,Z,Y の順番
+    //! extract X-axis value from mesured magnetometer
+    int16_t magnetX(void) {return (_magnet[0]<<8)|_magnet[1];}
+    //! extract Z-axis value from mesured magnetometer
+    int16_t magnetZ(void) {return (_magnet[2]<<8)|_magnet[3];}
+    //! extract Y-axis value from mesured magnetometer
+    int16_t magnetY(void) {return (_magnet[4]<<8)|_magnet[5];}
+
+    float heading(vector from);
+    //! @return orientation(direction) value, expressed in degrees(0~360)
+    float orientation(void);
+    //! @return Temperature value, expressed in degrees Celsius
+    float temperature(void);
+protected:
+    //! write 1byte
+    //! @param sad I2C address
+    //! @param reg register address
+    //! @param data data
+    void write(char sad, char reg, char data);
+    //! read data
+    //! @param sad I2C address
+    //! @param reg register address start from here and auto incriment
+    //! @param data pointer to data storage
+    //! @param length how many bytes to read
+    void read(char sad, char reg, char *data, int length=1);
+
+    I2C *i2c;
+    static const int8_t ACCEL_SAD = 0x32;
+    static const int8_t MAGNET_SAD = 0x3C;
+    enum accel_regs {
+        CTRL_REG1_A=0x20,
+        CTRL_REG2_A=0x21,
+        CTRL_REG3_A=0x22,
+        CTRL_REG4_A=0x23,
+        CTRL_REG5_A=0x24,
+        CTRL_REG6_A=0x25,
+        REFERENCE_A=0x26,
+        STATUS_REG_A=0x27,
+        OUT_A=0x28, //6bytes
+        FIFO_CTRL_REG_A=0x2E,
+        FIFO_SRC_REG_A=0x2F,
+        INT1_A=0x30, //4bytes
+        INT2_A=0x34, //4bytes
+        CLICK_A=0x38, //3bytes
+        TIME_LIMIT_A=0x3B,
+        TIME_LATENCY_A=0x3C,
+        TIME_WINDOW_A=0x3D
+    };
+    static const int INT_CFG=0;
+    static const int INT_SRC=1;
+    static const int INT_THS=2;
+    static const int INT_DURATION=3;
+    enum magnet_regs {
+        CRA_REG_M=0x00,
+        CRB_REG_M=0x01,
+        MR_REG_M=0x02,
+        OUT_M=0x03, //6bytes
+        SR_REG_M=0x09,
+        IRA_REG_M=0x0A,
+        IRB_REG_M=0x0B,
+        IRC_REG_M=0x0C,
+        TEMP_OUT_M=0x31 //2bytes
+    };
+private:
+    char _accel[6];
+    char _magnet[6];
+};
+
+#endif
\ No newline at end of file
--- a/Servo.lib	Mon Aug 14 04:55:38 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/simon/code/Servo/#36b69a7ced07
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Servo/Servo.cpp	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,74 @@
+/* mbed R/C Servo Library
+ *  
+ * Copyright (c) 2007-2010 sford, cstyles
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * 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 "Servo.h"
+#include "mbed.h"
+
+static float clamp(float value, float min, float max) {
+    if(value < min) {
+        return min;
+    } else if(value > max) {
+        return max;
+    } else {
+        return value;
+    }
+}
+
+Servo::Servo(PinName pin) : _pwm(pin) {
+    calibrate();
+    write(0.5);
+}
+
+void Servo::write(float percent) {
+    float offset = _range * 2.0 * (percent - 0.5);
+    _pwm.pulsewidth(0.0015 + clamp(offset, -_range, _range));
+    _p = clamp(percent, 0.0, 1.0);
+}
+
+void Servo::position(float degrees) {
+    float offset = _range * (degrees / _degrees);
+    _pwm.pulsewidth(0.0015 + clamp(offset, -_range, _range));
+}
+
+void Servo::calibrate(float range, float degrees) {
+    _range = range;
+    _degrees = degrees;
+}
+
+float Servo::read() {
+    return _p;
+}
+
+Servo& Servo::operator= (float percent) { 
+    write(percent);
+    return *this;
+}
+
+Servo& Servo::operator= (Servo& rhs) {
+    write(rhs.read());
+    return *this;
+}
+
+Servo::operator float() {
+    return read();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Servo/Servo.h	Mon Aug 14 04:56:52 2017 +0000
@@ -0,0 +1,98 @@
+/* mbed R/C Servo Library
+ * Copyright (c) 2007-2010 sford, cstyles
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * 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 MBED_SERVO_H
+#define MBED_SERVO_H
+
+#include "mbed.h"
+
+/** Servo control class, based on a PwmOut
+ *
+ * Example:
+ * @code
+ * // Continuously sweep the servo through it's full range
+ * #include "mbed.h"
+ * #include "Servo.h"
+ * 
+ * Servo myservo(p21);
+ * 
+ * int main() {
+ *     while(1) {
+ *         for(int i=0; i<100; i++) {
+ *             myservo = i/100.0;
+ *             wait(0.01);
+ *         }
+ *         for(int i=100; i>0; i--) {
+ *             myservo = i/100.0;
+ *             wait(0.01);
+ *         }
+ *     }
+ * }
+ * @endcode
+ */
+class Servo {
+
+public:
+    /** Create a servo object connected to the specified PwmOut pin
+     *
+     * @param pin PwmOut pin to connect to 
+     */
+    Servo(PinName pin);
+    
+    /** Set the servo position, normalised to it's full range
+     *
+     * @param percent A normalised number 0.0-1.0 to represent the full range.
+     */
+    void write(float percent);
+    
+    /**  Read the servo motors current position
+     *
+     * @param returns A normalised number 0.0-1.0  representing the full range.
+     */
+    float read();
+    
+    /** Set the servo position
+     *
+     * @param degrees Servo position in degrees
+     */
+    void position(float degrees);
+    
+    /**  Allows calibration of the range and angles for a particular servo
+     *
+     * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds
+     * @param degrees Angle from centre to maximum/minimum position in degrees
+     */
+    void calibrate(float range = 0.0005, float degrees = 45.0); 
+        
+    /**  Shorthand for the write and read functions */
+    Servo& operator= (float percent);
+    Servo& operator= (Servo& rhs);
+    operator float();
+
+protected:
+    PwmOut _pwm;
+    float _range;
+    float _degrees;
+    float _p;
+};
+
+#endif