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;
50 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
51 #define min(a, b) ((a) < (b) ? (a) : (b))
52 #define max(a, b) ((a) > (b) ? (a) : (b))
54 int register_event_handler(struct bme280 *bme, struct event_handler *handler)
56 struct epoll_event ev;
59 bzero(&ev, sizeof(ev));
61 if (handler->ev.data.fd <= 0) {
62 printf("Invalid file descriptor of %d\n", handler->ev.data.fd);
66 if (!handler->handle_event) {
67 printf("Handler callback missing\n");
72 printf("Registering handler for %s, fd %d\n",
73 handler->name, handler->ev.data.fd);
75 ev.data.fd = handler->ev.data.fd;
76 ev.data.ptr = handler;
77 ev.events = handler->ev.events;
78 ret = epoll_ctl(bme->epollfd, EPOLL_CTL_ADD, handler->ev.data.fd, &ev);
80 printf("Failed to add epoll_fd: %m\n");
87 int update_event_handler(struct bme280 *bme, struct event_handler *handler)
89 struct epoll_event ev;
92 bzero(&ev, sizeof(ev));
93 ev.data.fd = handler->ev.data.fd;
94 ev.data.ptr = handler;
95 ev.events = handler->ev.events;
96 ret = epoll_ctl(bme->epollfd, EPOLL_CTL_MOD, handler->ev.data.fd, &ev);
98 printf("Failed to add epoll_fd: %m\n");
105 struct connection_state {
106 struct event_handler ev;
111 time_t min_timestamp;
114 static int handle_connection_state(struct event_handler *ptr)
116 struct connection_state *conn = (struct connection_state *)ptr;
117 struct bme280 *bme = conn->bme;
121 if (conn->min_timestamp == -1) {
122 if (!conn->ev.ev.events & EPOLLIN) {
123 printf("%s: No incoming data\n", __func__);
127 ret = read(conn->fd, conn->buf + conn->len, sizeof(conn->buf) - conn->len);
129 printf("%s: read: %m\n", __func__);
133 conn->buf[min((signed)sizeof(conn->buf) - 1, ret)] = '\0';
138 for (i = 0; i < ret; i++)
139 if (conn->buf[i] == '\n')
142 /* Did we get newline? */
144 return 0; /* Not yet */
146 if (i == sizeof(conn->buf)) {
147 printf("%s Data overflow\n", __func__);
152 printf("%s: Got %s", __func__, conn->buf);
154 conn->min_timestamp = atoi(conn->buf);
157 /* Switch to sending data only mode only */
158 conn->ev.ev.events = EPOLLOUT;
159 conn->ev.ev.data.fd = conn->fd;
160 update_event_handler(bme, &conn->ev);
162 for (i = 0; i < (signed)ARRAY_SIZE(bme->data); i++) {
163 pthread_mutex_lock(&bme->lock);
166 if (!bme->data[i].time) {
167 pthread_mutex_unlock(&bme->lock);
171 /* Skip non-interesting or already sent items */
172 if (bme->data[i].time <= conn->min_timestamp) {
173 pthread_mutex_unlock(&bme->lock);
177 len = snprintf(conn->buf, sizeof(conn->buf),
178 "%ld:%0.4lf:%0.4lf:%0.4lf:%.4lf\n",
180 bme->data[i].temperature,
181 bme->data[i].pressure,
182 bme->data[i].humidity,
183 bme->data[i].dew_point);
185 ret = send(conn->fd, conn->buf, len, MSG_NOSIGNAL);
187 if (errno == EAGAIN || errno == EWOULDBLOCK) {
188 pthread_mutex_unlock(&bme->lock);
192 printf("%s: send(): %m\n", __func__);
193 pthread_mutex_unlock(&bme->lock);
197 conn->min_timestamp = bme->data[i].time;
198 pthread_mutex_unlock(&bme->lock);
203 printf("%s: Closing socket %d\n", __func__, conn->fd);
211 struct listening_socket {
212 struct event_handler ev;
217 static int handle_incoming_connection(struct event_handler *ptr)
219 struct sockaddr_in peer;
220 socklen_t peerlen = 0;
221 struct listening_socket *listener = (struct listening_socket *)ptr;
222 struct connection_state *conn;
223 struct bme280 *bme = listener->bme;
226 bzero(&peer, sizeof(peer));
228 fd = accept4(listener->fd, (struct sockaddr *)&peer, &peerlen, SOCK_NONBLOCK);
230 printf("Error while accept(): %m\n");
234 conn = calloc(sizeof(*conn), 1);
235 conn->ev.ev.data.fd = fd;
237 conn->ev.ev.events = EPOLLIN;
238 conn->ev.handle_event = handle_connection_state;
239 conn->ev.name = "socket";
241 conn->min_timestamp = -1;
244 register_event_handler(bme, &conn->ev);
249 static void *event_handler(void *arg)
251 struct bme280 *bme = arg;
252 struct sockaddr_in addr;
253 struct listening_socket incoming;
257 bzero(&addr, sizeof(addr));
258 bzero(&incoming, sizeof(incoming));
260 sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
262 printf("Failed to create socket: %m\n");
266 ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
268 printf("Error setting SO_REUSEADDR: %m\n");
270 addr.sin_family = AF_INET;
271 addr.sin_port = htons(8347);
272 addr.sin_addr.s_addr = INADDR_ANY;
274 ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
276 printf("Failed to bind: %m\n");
280 ret = listen(sockfd, 5);
282 printf("Failed to listen(): %m\n");
286 bme->epollfd = epoll_create(1);
287 if (bme->epollfd == -1) {
288 printf("Failed to epoll_create(): %m\n");
293 incoming.ev.ev.data.fd = sockfd;
294 incoming.ev.ev.events = EPOLLIN;
295 incoming.ev.handle_event = handle_incoming_connection;
296 incoming.ev.name = "listener";
297 incoming.fd = sockfd;
299 ret = register_event_handler(bme, &incoming.ev);
302 struct epoll_event ev;
303 struct event_handler *h;
306 printf("%s: Waiting for events..\n", __func__);
308 ret = epoll_wait(bme->epollfd, &ev, 1, -1);
310 if (errno != EINTR) {
311 printf("epoll_wait: %m\n");
319 printf("Timed out\n");
326 printf("Handling %s %s event for %s\n",
327 ev.events & EPOLLIN ? "incoming" : "",
328 ev.events & EPOLLOUT ? "outgoing" : "",
343 static int8_t i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t len, void *intf_ptr)
348 id = *((struct bme280 *)intf_ptr);
350 ret = write(id.fd, ®_addr, 1);
354 ret = read(id.fd, data, len);
361 static void delay_us(uint32_t period, void *unused)
368 static int8_t i2c_write(uint8_t reg_addr, const uint8_t *data, uint32_t len, void *intf_ptr)
373 id = *((struct bme280 *)intf_ptr);
375 buf = malloc(len + 1);
377 memcpy(buf + 1, data, len);
379 if (write(id.fd, buf, len + 1) < (uint16_t)len) {
380 return BME280_E_COMM_FAIL;
388 static double dp(double RH, double T)
392 * Constants and equation taken from:
393 * https://en.wikipedia.org/wiki/Dew_point#Calculating_the_dew_point
395 /* double a = 6.112;*/
407 gm = log(RH / 100.0 * exp((b - T / d) * (T / (c + T))));
408 dp = c * gm / (b - gm);
413 static int stream_sensor_data_forced_mode(struct bme280 *bme)
416 uint8_t settings_sel = 0;
418 struct bme280_data comp_data;
419 struct bme280_dev *dev = bme->dev;
421 double t_sum = 0, h_sum = 0, p_sum = 0;
422 int num = 0, first_run = 1, last_min;
424 /* Recommended mode of operation: Indoor navigation */
425 dev->settings.osr_h = BME280_OVERSAMPLING_1X;
426 dev->settings.osr_p = BME280_OVERSAMPLING_16X;
427 dev->settings.osr_t = BME280_OVERSAMPLING_2X;
428 dev->settings.filter = BME280_FILTER_COEFF_16;
430 settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL |
431 BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
433 ret = bme280_set_sensor_settings(settings_sel, dev);
435 fprintf(stderr, "Failed to set sensor settings (code %+d).", ret);
440 printf("Temperature, Pressure, Humidity\n");
443 * Calculate the minimum delay required between consecutive
444 * measurement based upon the sensor enabled and the
445 * oversampling configuration.
447 req_delay = bme280_cal_meas_delay(&dev->settings);
457 ret = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
459 fprintf(stderr, "Failed to set sensor mode (code %+d).", ret);
463 /* Wait for the measurement to complete and print data */
464 dev->delay_us(req_delay * 1000, dev->intf_ptr);
465 ret = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
467 fprintf(stderr, "Failed to get sensor data (code %+d).", ret);
471 t_sum += comp_data.temperature;
472 p_sum += comp_data.pressure;
473 h_sum += comp_data.humidity;
479 if (first_run || now->tm_min != last_min) {
480 double temp, press, hum, dew;
485 last_min = now->tm_min;
487 temp = t_sum / (double)num;
488 press = p_sum * 0.01 / (double)num;
489 hum = h_sum / (double)num;
491 strftime(s, sizeof(s), "%Y.%m.%d %H:%M:%S", now);
494 printf("%s %0.4lf deg C, %0.4lf hPa, %0.4lf%%, dp: %.3f C\n",
495 s, temp, press, hum, dew);
498 pthread_mutex_lock(&bme->lock);
499 for (i = 0; i < ARRAY_SIZE(bme->data) - 1; i++)
500 bme->data[i] = bme->data[i + 1];
502 bme->data[i].time = t;
503 bme->data[i].temperature = temp;
504 bme->data[i].pressure = press;
505 bme->data[i].humidity = hum;
506 bme->data[i].dew_point = dew;
507 pthread_mutex_unlock(&bme->lock);
510 t_sum = p_sum = h_sum = 0;
517 int main(int argc, char *argv[])
520 struct bme280_dev dev;
524 bzero(&id, sizeof(id));
527 fprintf(stderr, "Missing argument for i2c bus and address.\n"
528 "Usage: %s /dev/i2c-0 0x76\n", argv[0]);
532 bzero(&id, sizeof(id));
534 if ((id.fd = open(argv[1], O_RDWR)) < 0) {
535 fprintf(stderr, "Failed to open the i2c bus %s\n", argv[1]);
539 id.dev_addr = strtol(argv[2], NULL, 0);
540 if (ioctl(id.fd, I2C_SLAVE, id.dev_addr) < 0) {
541 fprintf(stderr, "Failed to acquire bus access and/or talk to slave.\n");
545 dev.intf = BME280_I2C_INTF;
547 dev.write = i2c_write;
548 dev.delay_us = delay_us;
553 ret = bme280_init(&dev);
555 fprintf(stderr, "Failed to initialize the device (code %+d).\n", ret);
559 pthread_mutex_init(&id.lock, NULL);
560 pthread_create(&thread, NULL, event_handler, &id);
562 ret = stream_sensor_data_forced_mode(&id);
564 fprintf(stderr, "Failed to stream sensor data (code %+d).\n", ret);