Fedor Chervyakov / Mbed OS bme280-ble-sensor
Committer:
fedorc
Date:
Sat Aug 10 22:25:46 2019 +0000
Revision:
0:22a4f6c99d74
Child:
1:667b9825e7ee
Initial commit; Proof of concept, code is ugly af

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fedorc 0:22a4f6c99d74 1 /* mbed Microcontroller Library
fedorc 0:22a4f6c99d74 2 * Copyright (c) 2018 ARM Limited
fedorc 0:22a4f6c99d74 3 * SPDX-License-Identifier: Apache-2.0
fedorc 0:22a4f6c99d74 4 */
fedorc 0:22a4f6c99d74 5
fedorc 0:22a4f6c99d74 6 #include "mbed.h"
fedorc 0:22a4f6c99d74 7 #include "bme280.h"
fedorc 0:22a4f6c99d74 8
fedorc 0:22a4f6c99d74 9
fedorc 0:22a4f6c99d74 10
fedorc 0:22a4f6c99d74 11 I2C sensor(I2C_SDA, I2C_SCL);
fedorc 0:22a4f6c99d74 12
fedorc 0:22a4f6c99d74 13 void user_delay_ms(uint32_t period)
fedorc 0:22a4f6c99d74 14 {
fedorc 0:22a4f6c99d74 15 wait_ms(period);
fedorc 0:22a4f6c99d74 16 }
fedorc 0:22a4f6c99d74 17
fedorc 0:22a4f6c99d74 18
fedorc 0:22a4f6c99d74 19 int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
fedorc 0:22a4f6c99d74 20 {
fedorc 0:22a4f6c99d74 21 int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
fedorc 0:22a4f6c99d74 22 int addr8bit = dev_id << 1;
fedorc 0:22a4f6c99d74 23
fedorc 0:22a4f6c99d74 24 char cmd[2];
fedorc 0:22a4f6c99d74 25 cmd[0] = (char) reg_addr;
fedorc 0:22a4f6c99d74 26
fedorc 0:22a4f6c99d74 27 rslt = sensor.write(addr8bit, cmd, 1);
fedorc 0:22a4f6c99d74 28 rslt = sensor.read( addr8bit, (char *) reg_data, (int) len);
fedorc 0:22a4f6c99d74 29
fedorc 0:22a4f6c99d74 30 /*if (sizeof(reg_data)/8 < len)
fedorc 0:22a4f6c99d74 31 return BME280_E_COMM_FAIL;
fedorc 0:22a4f6c99d74 32 */
fedorc 0:22a4f6c99d74 33 /*
fedorc 0:22a4f6c99d74 34 * The parameter dev_id can be used as a variable to store the I2C address of the device
fedorc 0:22a4f6c99d74 35 */
fedorc 0:22a4f6c99d74 36
fedorc 0:22a4f6c99d74 37 /*
fedorc 0:22a4f6c99d74 38 * Data on the bus should be like
fedorc 0:22a4f6c99d74 39 * |------------+---------------------|
fedorc 0:22a4f6c99d74 40 * | I2C action | Data |
fedorc 0:22a4f6c99d74 41 * |------------+---------------------|
fedorc 0:22a4f6c99d74 42 * | Start | - |
fedorc 0:22a4f6c99d74 43 * | Write | (reg_addr) |
fedorc 0:22a4f6c99d74 44 * | Stop | - |
fedorc 0:22a4f6c99d74 45 * | Start | - |
fedorc 0:22a4f6c99d74 46 * | Read | (reg_data[0]) |
fedorc 0:22a4f6c99d74 47 * | Read | (....) |
fedorc 0:22a4f6c99d74 48 * | Read | (reg_data[len - 1]) |
fedorc 0:22a4f6c99d74 49 * | Stop | - |
fedorc 0:22a4f6c99d74 50 * |------------+---------------------|
fedorc 0:22a4f6c99d74 51 */
fedorc 0:22a4f6c99d74 52
fedorc 0:22a4f6c99d74 53 return rslt;
fedorc 0:22a4f6c99d74 54 }
fedorc 0:22a4f6c99d74 55
fedorc 0:22a4f6c99d74 56 int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
fedorc 0:22a4f6c99d74 57 {
fedorc 0:22a4f6c99d74 58 int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
fedorc 0:22a4f6c99d74 59
fedorc 0:22a4f6c99d74 60 /*
fedorc 0:22a4f6c99d74 61 * The parameter dev_id can be used as a variable to store the I2C address of the device
fedorc 0:22a4f6c99d74 62 */
fedorc 0:22a4f6c99d74 63
fedorc 0:22a4f6c99d74 64 int addr8bit = dev_id << 1;
fedorc 0:22a4f6c99d74 65 char cmd[2*len];
fedorc 0:22a4f6c99d74 66
fedorc 0:22a4f6c99d74 67 int n;
fedorc 0:22a4f6c99d74 68 for (int i=0; i<len; i++) {
fedorc 0:22a4f6c99d74 69 n = 2*i;
fedorc 0:22a4f6c99d74 70 cmd[n] = reg_addr+i;
fedorc 0:22a4f6c99d74 71 cmd[n+1] = reg_data[i];
fedorc 0:22a4f6c99d74 72 }
fedorc 0:22a4f6c99d74 73
fedorc 0:22a4f6c99d74 74 rslt = sensor.write(addr8bit, cmd, len*2);
fedorc 0:22a4f6c99d74 75 /*
fedorc 0:22a4f6c99d74 76 * Data on the bus should be like
fedorc 0:22a4f6c99d74 77 * |------------+----------------------|
fedorc 0:22a4f6c99d74 78 * | I2C action | Data |
fedorc 0:22a4f6c99d74 79 * |------------+----------------------|
fedorc 0:22a4f6c99d74 80 * | Start | - |
fedorc 0:22a4f6c99d74 81 * | Write | (reg_addr) |
fedorc 0:22a4f6c99d74 82 * | Write | (reg_data[0]) |
fedorc 0:22a4f6c99d74 83 * | Write | (reg_addr + 1) |
fedorc 0:22a4f6c99d74 84 * | Write | (reg_data[1]) |
fedorc 0:22a4f6c99d74 85 * | Write | (....) |
fedorc 0:22a4f6c99d74 86 * | Write | (reg_addr + len - 1) |
fedorc 0:22a4f6c99d74 87 * | Write | (reg_data[len - 1]) |
fedorc 0:22a4f6c99d74 88 * | Stop | - |
fedorc 0:22a4f6c99d74 89 * |------------+----------------------|
fedorc 0:22a4f6c99d74 90 */
fedorc 0:22a4f6c99d74 91
fedorc 0:22a4f6c99d74 92 return rslt;
fedorc 0:22a4f6c99d74 93 }
fedorc 0:22a4f6c99d74 94
fedorc 0:22a4f6c99d74 95 void print_sensor_data(struct bme280_data *comp_data)
fedorc 0:22a4f6c99d74 96 {
fedorc 0:22a4f6c99d74 97 float temp, press, hum;
fedorc 0:22a4f6c99d74 98 #ifdef BME280_FLOAT_ENABLE
fedorc 0:22a4f6c99d74 99 temp = comp_data->temperature;
fedorc 0:22a4f6c99d74 100 press = 0.01 * comp_data->pressure;
fedorc 0:22a4f6c99d74 101 hum = comp_data->humidity;
fedorc 0:22a4f6c99d74 102 #else
fedorc 0:22a4f6c99d74 103 #ifdef BME280_64BIT_ENABLE
fedorc 0:22a4f6c99d74 104 temp = 0.01f * comp_data->temperature;
fedorc 0:22a4f6c99d74 105 press = 0.0001f * comp_data->pressure;
fedorc 0:22a4f6c99d74 106 hum = 1.0f / 1024.0f * comp_data->humidity;
fedorc 0:22a4f6c99d74 107 #else
fedorc 0:22a4f6c99d74 108 temp = 0.01f * comp_data->temperature;
fedorc 0:22a4f6c99d74 109 press = 0.01f * comp_data->pressure;
fedorc 0:22a4f6c99d74 110 hum = 1.0f / 1024.0f * comp_data->humidity;
fedorc 0:22a4f6c99d74 111 #endif
fedorc 0:22a4f6c99d74 112 #endif
fedorc 0:22a4f6c99d74 113 printf("%0.2lf deg C, %0.2lf hPa, %0.2lf%%\n", temp, press, hum);
fedorc 0:22a4f6c99d74 114 }
fedorc 0:22a4f6c99d74 115
fedorc 0:22a4f6c99d74 116 // main() runs in its own thread in the OS
fedorc 0:22a4f6c99d74 117 int main()
fedorc 0:22a4f6c99d74 118 {
fedorc 0:22a4f6c99d74 119
fedorc 0:22a4f6c99d74 120 struct bme280_dev dev;
fedorc 0:22a4f6c99d74 121 struct bme280_data comp_data;
fedorc 0:22a4f6c99d74 122 uint8_t settings_sel;
fedorc 0:22a4f6c99d74 123 int8_t rslt;
fedorc 0:22a4f6c99d74 124
fedorc 0:22a4f6c99d74 125 dev.dev_id = BME280_I2C_ADDR_PRIM;
fedorc 0:22a4f6c99d74 126 dev.intf = BME280_I2C_INTF;
fedorc 0:22a4f6c99d74 127 dev.write = user_i2c_write;
fedorc 0:22a4f6c99d74 128 dev.read = user_i2c_read;
fedorc 0:22a4f6c99d74 129 dev.delay_ms = user_delay_ms;
fedorc 0:22a4f6c99d74 130
fedorc 0:22a4f6c99d74 131 bme280_init(&dev);
fedorc 0:22a4f6c99d74 132
fedorc 0:22a4f6c99d74 133 dev.settings.osr_h = BME280_OVERSAMPLING_1X;
fedorc 0:22a4f6c99d74 134 dev.settings.osr_p = BME280_OVERSAMPLING_16X;
fedorc 0:22a4f6c99d74 135 dev.settings.osr_t = BME280_OVERSAMPLING_2X;
fedorc 0:22a4f6c99d74 136 dev.settings.filter = BME280_FILTER_COEFF_16;
fedorc 0:22a4f6c99d74 137
fedorc 0:22a4f6c99d74 138 settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
fedorc 0:22a4f6c99d74 139
fedorc 0:22a4f6c99d74 140 rslt = bme280_set_sensor_settings(settings_sel, &dev);
fedorc 0:22a4f6c99d74 141 if (rslt != BME280_OK)
fedorc 0:22a4f6c99d74 142 {
fedorc 0:22a4f6c99d74 143 fprintf(stderr, "Failed to set sensor settings (code %+d).", rslt);
fedorc 0:22a4f6c99d74 144 return rslt;
fedorc 0:22a4f6c99d74 145 }
fedorc 0:22a4f6c99d74 146
fedorc 0:22a4f6c99d74 147 while (true) {
fedorc 0:22a4f6c99d74 148 rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, &dev);
fedorc 0:22a4f6c99d74 149 if (rslt != BME280_OK)
fedorc 0:22a4f6c99d74 150 {
fedorc 0:22a4f6c99d74 151 printf("Failed to set sensor mode (code %+d).\n", rslt);
fedorc 0:22a4f6c99d74 152 break;
fedorc 0:22a4f6c99d74 153 }
fedorc 0:22a4f6c99d74 154 dev.delay_ms(400);
fedorc 0:22a4f6c99d74 155 rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, &dev);
fedorc 0:22a4f6c99d74 156
fedorc 0:22a4f6c99d74 157 if (rslt != BME280_OK)
fedorc 0:22a4f6c99d74 158 {
fedorc 0:22a4f6c99d74 159 printf("Failed to get sensor data (code %+d).\n", rslt);
fedorc 0:22a4f6c99d74 160 break;
fedorc 0:22a4f6c99d74 161 }
fedorc 0:22a4f6c99d74 162 print_sensor_data(&comp_data);
fedorc 0:22a4f6c99d74 163
fedorc 0:22a4f6c99d74 164 }
fedorc 0:22a4f6c99d74 165 }