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.
Dependencies: mbed FATFileSystem
Fork of FTE-06 by
Revision 23:9be034083282, committed 2017-08-14
- Comitter:
- mizuki_akaike
- Date:
- Mon Aug 14 04:56:52 2017 +0000
- Parent:
- 22:b2e90f18ea55
- Child:
- 24:8080c0516969
- Commit message:
- ?????????????;
Changed in this revision
--- 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, ®, 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

