]> git.itanic.dy.fi Git - BME280_driver/blob - examples/bsd_userspace.c
5e32da3562fbfa24c49e3e6c0ae43f72ea8a3a69
[BME280_driver] / examples / bsd_userspace.c
1 /*\r
2  * BSD userspace test code, simple and mose code directy from the doco.\r
3  * compile like this: cc bsd_userspace.c ../bme280.c -I ../ -o bme280\r
4  * tested: NanoPi NEO.\r
5  * Use like: ./bme280 /dev/iic0\r
6  */\r
7 #include "bme280.h"\r
8 #include <string.h>\r
9 #include <stdio.h>\r
10 #include <stdlib.h>\r
11 #include <unistd.h>\r
12 #include <sys/types.h>\r
13 #include <fcntl.h>\r
14 \r
15 #include <sys/ioctl.h>\r
16 #include <dev/iicbus/iic.h>\r
17 \r
18 int fd;\r
19 \r
20 int8_t user_i2c_read(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len);\r
21 void user_delay_ms(uint32_t period);\r
22 int8_t user_i2c_write(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len);\r
23 void print_sensor_data(struct bme280_data *comp_data);\r
24 int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev);\r
25 \r
26 \r
27 int8_t user_i2c_read(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len)\r
28 {\r
29     struct iic_msg msgs[2] = {\r
30         {id << 1 | IIC_M_WR, IIC_M_WR, 1, &reg_addr},\r
31         {id << 1 | IIC_M_RD, IIC_M_RD, len, data},\r
32     };\r
33 \r
34     struct iic_rdwr_data rdwr_data = {msgs, 2};\r
35 \r
36     int error = ioctl(fd, I2CRDWR, &rdwr_data);\r
37     if (error) {\r
38         return BME280_E_COMM_FAIL;\r
39     }\r
40 \r
41     return BME280_OK;\r
42 }\r
43 \r
44 \r
45 void user_delay_ms(uint32_t period)\r
46 {\r
47     usleep(period * 1000);\r
48 }\r
49 \r
50 \r
51 int8_t user_i2c_write(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len)\r
52 {\r
53     uint8_t *buf = malloc( (1 + len) * sizeof(uint8_t) );\r
54     if (buf == NULL) {\r
55         return BME280_E_COMM_FAIL;\r
56     }\r
57 \r
58     buf[0] = reg_addr;\r
59 \r
60     for (int i = 0; i < len; i++) {\r
61         buf[i+1] = data[i];\r
62     }\r
63 \r
64     struct iic_msg msg;\r
65 \r
66     msg.slave = id << 1 | !IIC_M_RD;\r
67     msg.flags = !IIC_M_RD;\r
68     msg.len = (1 + len) * sizeof(uint8_t);\r
69     msg.buf = buf;\r
70 \r
71     struct iic_rdwr_data rdwr_data = {&msg, 1};\r
72 \r
73     int error = ioctl(fd, I2CRDWR, &rdwr_data);\r
74     if (error) {\r
75         free(buf);\r
76         return BME280_E_COMM_FAIL;\r
77     }\r
78 \r
79     free(buf);\r
80 \r
81     return BME280_OK;\r
82 }\r
83 \r
84 \r
85 void print_sensor_data(struct bme280_data *comp_data)\r
86 {\r
87     float temp, press, hum;\r
88 #ifdef BME280_FLOAT_ENABLE\r
89     temp = comp_data->temperature;\r
90     press = 0.01 * comp_data->pressure;\r
91     hum = comp_data->humidity;\r
92 #else\r
93 #ifdef BME280_64BIT_ENABLE\r
94     temp = 0.01f * comp_data->temperature;\r
95     press = 0.0001f * comp_data->pressure;\r
96     hum = 1.0f / 1024.0f * comp_data->humidity;\r
97 #else\r
98     temp = 0.01f * comp_data->temperature;\r
99     press = 0.01f * comp_data->pressure;\r
100     hum = 1.0f / 1024.0f * comp_data->humidity;\r
101 #endif\r
102 #endif\r
103     printf("%0.2lf deg C, %0.2lf hPa, %0.2lf%%\n", temp, press, hum);\r
104 }\r
105 \r
106 \r
107 int8_t stream_sensor_data_forced_mode(struct bme280_dev *dev)\r
108 {\r
109     int8_t rslt;\r
110     uint8_t settings_sel;\r
111     struct bme280_data comp_data;\r
112 \r
113     /* Recommended mode of operation: Indoor navigation */\r
114     dev->settings.osr_h = BME280_OVERSAMPLING_1X;\r
115     dev->settings.osr_p = BME280_OVERSAMPLING_16X;\r
116     dev->settings.osr_t = BME280_OVERSAMPLING_2X;\r
117     dev->settings.filter = BME280_FILTER_COEFF_16;\r
118 \r
119     settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL | BME280_OSR_HUM_SEL | BME280_FILTER_SEL;\r
120 \r
121     rslt = bme280_set_sensor_settings(settings_sel, dev);\r
122     if (rslt != BME280_OK)\r
123     {\r
124         fprintf(stderr, "Failed to set sensor settings (code %+d).", rslt);\r
125         return rslt;\r
126     }\r
127 \r
128     printf("Temperature, Pressure, Humidity\n");\r
129     /* Continuously stream sensor data */\r
130     while (1)\r
131     {\r
132         rslt = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);\r
133         if (rslt != BME280_OK)\r
134         {\r
135             fprintf(stderr, "Failed to set sensor mode (code %+d).", rslt);\r
136             break;\r
137         }\r
138         /* Wait for the measurement to complete and print data @25Hz */\r
139         dev->delay_ms(40);\r
140         rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);\r
141         if (rslt != BME280_OK)\r
142         {\r
143             fprintf(stderr, "Failed to get sensor data (code %+d).", rslt);\r
144             break;\r
145         }\r
146         print_sensor_data(&comp_data);\r
147         dev->delay_ms(1000);\r
148     }\r
149 \r
150     return rslt;\r
151 }\r
152 \r
153 \r
154 \r
155 int main(int argc, char* argv[])\r
156 {\r
157     struct bme280_dev dev;\r
158     int8_t rslt = BME280_OK;\r
159 \r
160     if (argc < 2)\r
161     {\r
162         fprintf(stderr, "Missing argument for i2c bus.\n");\r
163         exit(1);\r
164     }\r
165 \r
166     // make sure to select BME280_I2C_ADDR_PRIM\r
167     // or BME280_I2C_ADDR_SEC as needed\r
168     dev.dev_id =\r
169 #if 1\r
170         BME280_I2C_ADDR_PRIM\r
171 #else\r
172         BME280_I2C_ADDR_SEC\r
173 #endif\r
174 ;\r
175 \r
176     dev.intf = BME280_I2C_INTF;\r
177     dev.read = user_i2c_read;\r
178     dev.write = user_i2c_write;\r
179     dev.delay_ms = user_delay_ms;\r
180 \r
181 \r
182     if ((fd = open(argv[1], O_RDWR)) < 0)\r
183     {\r
184         fprintf(stderr, "Failed to open the i2c bus %s\n", argv[1]);\r
185         exit(1);\r
186     }\r
187 \r
188     rslt = bme280_init(&dev);\r
189     if (rslt != BME280_OK)\r
190     {\r
191         fprintf(stderr, "Failed to initialize the device (code %+d).\n", rslt);\r
192         exit(1);\r
193     }\r
194 \r
195     rslt = stream_sensor_data_forced_mode(&dev);\r
196     if (rslt != BME280_OK)\r
197     {\r
198         fprintf(stderr, "Failed to stream sensor data (code %+d).\n", rslt);\r
199         exit(1);\r
200     }\r
201     return 0;\r
202 }\r