5 #include <linux/i2c-dev.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <sys/ioctl.h>
15 #include <sys/epoll.h>
28 struct bme280_dev *dev;
31 struct data_entry data[8192];
38 typedef int (handle_event_fn_t)(struct event_handler *);
40 struct event_handler {
41 struct epoll_event ev;
42 handle_event_fn_t *handle_event;
48 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
49 #define min(a, b) ((a) < (b) ? (a) : (b))
50 #define max(a, b) ((a) > (b) ? (a) : (b))
52 int register_event_handler(struct bme280 *bme, struct event_handler *handler)
54 struct epoll_event ev;
57 bzero(&ev, sizeof(ev));
59 if (handler->ev.data.fd <= 0) {
60 printf("Invalid file descriptor of %d\n", handler->ev.data.fd);
64 if (!handler->handle_event) {
65 printf("Handler callback missing\n");
69 printf("Registering handler for %s, fd %d\n",
70 handler->name, handler->ev.data.fd);
72 ev.data.fd = handler->ev.data.fd;
73 ev.data.ptr = handler;
74 ev.events = handler->ev.events;
75 ret = epoll_ctl(bme->epollfd, EPOLL_CTL_ADD, handler->ev.data.fd, &ev);
77 printf("Failed to add epoll_fd: %m\n");
84 int update_event_handler(struct bme280 *bme, struct event_handler *handler)
86 struct epoll_event ev;
89 bzero(&ev, sizeof(ev));
90 ev.data.fd = handler->ev.data.fd;
91 ev.data.ptr = handler;
92 ev.events = handler->ev.events;
93 ret = epoll_ctl(bme->epollfd, EPOLL_CTL_MOD, handler->ev.data.fd, &ev);
95 printf("Failed to add epoll_fd: %m\n");
102 struct connection_state {
103 struct event_handler ev;
108 time_t min_timestamp;
111 static int handle_connection_state(struct event_handler *ptr)
113 struct connection_state *conn = (struct connection_state *)ptr;
114 struct bme280 *bme = conn->bme;
118 if (conn->min_timestamp == -1) {
119 if (!conn->ev.ev.events & EPOLLIN) {
120 printf("%s: No incoming data\n", __func__);
124 ret = read(conn->fd, conn->buf + conn->len, sizeof(conn->buf) - conn->len);
126 printf("%s: read: %m\n", __func__);
130 conn->buf[min((signed)sizeof(conn->buf) - 1, ret)] = '\0';
135 for (i = 0; i < ret; i++)
136 if (conn->buf[i] == '\n')
139 /* Did we get newline? */
141 return 0; /* Not yet */
143 if (i == sizeof(conn->buf)) {
144 printf("%s Data overflow\n", __func__);
148 printf("%s: Got %s", __func__, conn->buf);
150 conn->min_timestamp = atoi(conn->buf);
153 /* Switch to sending data only mode only */
154 conn->ev.ev.events = EPOLLOUT;
155 conn->ev.ev.data.fd = conn->fd;
156 update_event_handler(bme, &conn->ev);
158 for (i = 0; i < (signed)ARRAY_SIZE(bme->data); i++) {
159 pthread_mutex_lock(&bme->lock);
162 if (!bme->data[i].time) {
163 pthread_mutex_unlock(&bme->lock);
167 /* Skip non-interesting or already sent items */
168 if (bme->data[i].time <= conn->min_timestamp) {
169 pthread_mutex_unlock(&bme->lock);
173 len = snprintf(conn->buf, sizeof(conn->buf),
174 "%ld:%0.4lf:%0.4lf:%0.4lf:%.4lf\n",
176 bme->data[i].temperature,
177 bme->data[i].pressure,
178 bme->data[i].humidity,
179 bme->data[i].dew_point);
181 ret = send(conn->fd, conn->buf, len, MSG_NOSIGNAL);
183 if (errno == EAGAIN || errno == EWOULDBLOCK) {
184 pthread_mutex_unlock(&bme->lock);
188 printf("%s: send(): %m\n", __func__);
189 pthread_mutex_unlock(&bme->lock);
193 conn->min_timestamp = bme->data[i].time;
194 pthread_mutex_unlock(&bme->lock);
198 printf("%s: Closing socket %d\n", __func__, conn->fd);
205 struct listening_socket {
206 struct event_handler ev;
211 static int handle_incoming_connection(struct event_handler *ptr)
213 struct sockaddr_in peer;
214 socklen_t peerlen = 0;
215 struct listening_socket *listener = (struct listening_socket *)ptr;
216 struct connection_state *conn;
217 struct bme280 *bme = listener->bme;
220 bzero(&peer, sizeof(peer));
222 fd = accept4(listener->fd, (struct sockaddr *)&peer, &peerlen, SOCK_NONBLOCK);
224 printf("Error while accept(): %m\n");
228 conn = calloc(sizeof(*conn), 1);
229 conn->ev.ev.data.fd = fd;
231 conn->ev.ev.events = EPOLLIN;
232 conn->ev.handle_event = handle_connection_state;
233 conn->ev.name = "socket";
235 conn->min_timestamp = -1;
238 register_event_handler(bme, &conn->ev);
243 static void *event_handler(void *arg)
245 struct bme280 *bme = arg;
246 struct sockaddr_in addr;
247 struct listening_socket incoming;
250 bzero(&addr, sizeof(addr));
251 bzero(&incoming, sizeof(incoming));
253 sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
255 printf("Failed to create socket: %m\n");
259 addr.sin_family = AF_INET;
260 addr.sin_port = htons(8347);
261 addr.sin_addr.s_addr = INADDR_ANY;
263 ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
265 printf("Failed to bind: %m\n");
269 ret = listen(sockfd, 5);
271 printf("Failed to listen(): %m\n");
275 bme->epollfd = epoll_create(1);
276 if (bme->epollfd == -1) {
277 printf("Failed to epoll_create(): %m\n");
282 incoming.ev.ev.data.fd = sockfd;
283 incoming.ev.ev.events = EPOLLIN;
284 incoming.ev.handle_event = handle_incoming_connection;
285 incoming.ev.name = "listener";
286 incoming.fd = sockfd;
288 ret = register_event_handler(bme, &incoming.ev);
291 struct epoll_event ev;
292 struct event_handler *h;
294 printf("%s: Waiting for events..\n", __func__);
295 ret = epoll_wait(bme->epollfd, &ev, 1, -1);
297 if (errno != EINTR) {
298 printf("epoll_wait: %m\n");
306 printf("Timed out\n");
312 printf("Handling %s %s event for %s\n",
313 ev.events & EPOLLIN ? "incoming" : "",
314 ev.events & EPOLLOUT ? "outgoing" : "",
328 static int8_t i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t len, void *intf_ptr)
333 id = *((struct bme280 *)intf_ptr);
335 ret = write(id.fd, ®_addr, 1);
339 ret = read(id.fd, data, len);
346 static void delay_us(uint32_t period, void *unused)
353 static int8_t i2c_write(uint8_t reg_addr, const uint8_t *data, uint32_t len, void *intf_ptr)
358 id = *((struct bme280 *)intf_ptr);
360 buf = malloc(len + 1);
362 memcpy(buf + 1, data, len);
364 if (write(id.fd, buf, len + 1) < (uint16_t)len) {
365 return BME280_E_COMM_FAIL;
373 static double dp(double RH, double T)
377 * Constants and equation taken from:
378 * https://en.wikipedia.org/wiki/Dew_point#Calculating_the_dew_point
380 /* double a = 6.112;*/
392 gm = log(RH / 100.0 * exp((b - T / d) * (T / (c + T))));
393 dp = c * gm / (b - gm);
398 static int stream_sensor_data_forced_mode(struct bme280 *bme)
401 uint8_t settings_sel = 0;
403 struct bme280_data comp_data;
404 struct bme280_dev *dev = bme->dev;
406 double t_sum = 0, h_sum = 0, p_sum = 0;
407 int num = 0, first_run = 1, last_min;
409 /* Recommended mode of operation: Indoor navigation */
410 dev->settings.osr_h = BME280_OVERSAMPLING_1X;
411 dev->settings.osr_p = BME280_OVERSAMPLING_16X;
412 dev->settings.osr_t = BME280_OVERSAMPLING_2X;
413 dev->settings.filter = BME280_FILTER_COEFF_16;
415 settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL |
416 BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
418 ret = bme280_set_sensor_settings(settings_sel, dev);
420 fprintf(stderr, "Failed to set sensor settings (code %+d).", ret);
425 printf("Temperature, Pressure, Humidity\n");
428 * Calculate the minimum delay required between consecutive
429 * measurement based upon the sensor enabled and the
430 * oversampling configuration.
432 req_delay = bme280_cal_meas_delay(&dev->settings);
442 ret = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
444 fprintf(stderr, "Failed to set sensor mode (code %+d).", ret);
448 /* Wait for the measurement to complete and print data */
449 dev->delay_us(req_delay * 1000, dev->intf_ptr);
450 ret = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
452 fprintf(stderr, "Failed to get sensor data (code %+d).", ret);
456 t_sum += comp_data.temperature;
457 p_sum += comp_data.pressure;
458 h_sum += comp_data.humidity;
464 if (first_run || now->tm_min != last_min) {
465 double temp, press, hum, dew;
470 last_min = now->tm_min;
472 temp = t_sum / (double)num;
473 press = p_sum * 0.01 / (double)num;
474 hum = h_sum / (double)num;
476 strftime(s, sizeof(s), "%Y.%m.%d %H:%M:%S", now);
479 printf("%s %0.4lf deg C, %0.4lf hPa, %0.4lf%%, dp: %.3f C\n",
480 s, temp, press, hum, dew);
482 pthread_mutex_lock(&bme->lock);
483 for (i = 0; i < ARRAY_SIZE(bme->data) - 1; i++)
484 bme->data[i] = bme->data[i + 1];
486 bme->data[i].time = t;
487 bme->data[i].temperature = temp;
488 bme->data[i].pressure = press;
489 bme->data[i].humidity = hum;
490 bme->data[i].dew_point = dew;
491 pthread_mutex_unlock(&bme->lock);
494 t_sum = p_sum = h_sum = 0;
501 int main(int argc, char *argv[])
504 struct bme280_dev dev;
508 bzero(&id, sizeof(id));
511 fprintf(stderr, "Missing argument for i2c bus and address.\n"
512 "Usage: %s /dev/i2c-0 0x76\n", argv[0]);
516 bzero(&id, sizeof(id));
518 if ((id.fd = open(argv[1], O_RDWR)) < 0) {
519 fprintf(stderr, "Failed to open the i2c bus %s\n", argv[1]);
523 id.dev_addr = strtol(argv[2], NULL, 0);
524 if (ioctl(id.fd, I2C_SLAVE, id.dev_addr) < 0) {
525 fprintf(stderr, "Failed to acquire bus access and/or talk to slave.\n");
529 dev.intf = BME280_I2C_INTF;
531 dev.write = i2c_write;
532 dev.delay_us = delay_us;
537 ret = bme280_init(&dev);
539 fprintf(stderr, "Failed to initialize the device (code %+d).\n", ret);
543 pthread_mutex_init(&id.lock, NULL);
544 pthread_create(&thread, NULL, event_handler, &id);
546 ret = stream_sensor_data_forced_mode(&id);
548 fprintf(stderr, "Failed to stream sensor data (code %+d).\n", ret);