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;
46 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
47 #define min(a, b) ((a) < (b) ? (a) : (b))
48 #define max(a, b) ((a) > (b) ? (a) : (b))
50 int register_event_handler(struct bme280 *bme, struct event_handler *handler)
52 struct epoll_event ev;
55 bzero(&ev, sizeof(ev));
57 if (handler->ev.data.fd <= 0) {
58 printf("Invalid file descriptor of %d\n", handler->ev.data.fd);
62 if (!handler->handle_event) {
63 printf("Handler callback missing\n");
67 printf("Registering handler for %s, fd %d\n",
68 handler->name, handler->ev.data.fd);
70 ev.data.fd = handler->ev.data.fd;
71 ev.data.ptr = handler;
72 ev.events = handler->ev.events;
73 ret = epoll_ctl(bme->epollfd, EPOLL_CTL_ADD, handler->ev.data.fd, &ev);
75 printf("Failed to add epoll_fd: %m\n");
82 int update_event_handler(struct bme280 *bme, struct event_handler *handler)
84 struct epoll_event ev;
87 bzero(&ev, sizeof(ev));
88 ev.data.fd = handler->ev.data.fd;
89 ev.data.ptr = handler;
90 ev.events = handler->ev.events;
91 ret = epoll_ctl(bme->epollfd, EPOLL_CTL_MOD, handler->ev.data.fd, &ev);
93 printf("Failed to add epoll_fd: %m\n");
100 struct connection_state {
101 struct event_handler ev;
106 time_t min_timestamp;
109 static int handle_connection_state(struct event_handler *ptr)
111 struct connection_state *conn = (struct connection_state *)ptr;
112 struct bme280 *bme = conn->bme;
116 if (conn->min_timestamp == -1) {
117 if (!conn->ev.ev.events & EPOLLIN) {
118 printf("%s: No incoming data\n", __func__);
122 ret = read(conn->fd, conn->buf + conn->len, sizeof(conn->buf) - conn->len);
124 printf("%s: read: %m\n", __func__);
128 conn->buf[min((signed)sizeof(conn->buf) - 1, ret)] = '\0';
133 for (i = 0; i < ret; i++)
134 if (conn->buf[i] == '\n')
137 /* Did we get newline? */
139 return 0; /* Not yet */
141 if (i == sizeof(conn->buf)) {
142 printf("%s Data overflow\n", __func__);
146 printf("%s: Got %s", __func__, conn->buf);
148 conn->min_timestamp = atoi(conn->buf);
151 /* Switch to sending data only mode only */
152 conn->ev.ev.events = EPOLLOUT;
153 conn->ev.ev.data.fd = conn->fd;
154 update_event_handler(bme, &conn->ev);
156 for (i = 0; i < (signed)ARRAY_SIZE(bme->data); i++) {
157 pthread_mutex_lock(&bme->lock);
160 if (!bme->data[i].time) {
161 pthread_mutex_unlock(&bme->lock);
165 /* Skip non-interesting or already sent items */
166 if (bme->data[i].time <= conn->min_timestamp) {
167 pthread_mutex_unlock(&bme->lock);
171 len = snprintf(conn->buf, sizeof(conn->buf),
172 "%ld:%0.4lf:%0.4lf:%0.4lf:%.4lf\n",
174 bme->data[i].temperature,
175 bme->data[i].pressure,
176 bme->data[i].humidity,
177 bme->data[i].dew_point);
179 ret = send(conn->fd, conn->buf, len, MSG_NOSIGNAL);
181 if (errno == EAGAIN || errno == EWOULDBLOCK) {
182 pthread_mutex_unlock(&bme->lock);
186 printf("%s: send(): %m\n", __func__);
187 pthread_mutex_unlock(&bme->lock);
191 conn->min_timestamp = bme->data[i].time;
192 pthread_mutex_unlock(&bme->lock);
196 printf("%s: Closing socket %d\n", __func__, conn->fd);
203 struct listening_socket {
204 struct event_handler ev;
209 static int handle_incoming_connection(struct event_handler *ptr)
211 struct sockaddr_in peer;
212 socklen_t peerlen = 0;
213 struct listening_socket *listener = (struct listening_socket *)ptr;
214 struct connection_state *conn;
215 struct bme280 *bme = listener->bme;
218 bzero(&peer, sizeof(peer));
220 fd = accept4(listener->fd, (struct sockaddr *)&peer, &peerlen, SOCK_NONBLOCK);
222 printf("Error while accept(): %m\n");
226 conn = calloc(sizeof(*conn), 1);
227 conn->ev.ev.data.fd = fd;
229 conn->ev.ev.events = EPOLLIN;
230 conn->ev.handle_event = handle_connection_state;
231 conn->ev.name = "socket";
233 conn->min_timestamp = -1;
236 register_event_handler(bme, &conn->ev);
241 static void *event_handler(void *arg)
243 struct bme280 *bme = arg;
244 struct sockaddr_in addr;
245 struct listening_socket incoming;
248 bzero(&addr, sizeof(addr));
249 bzero(&incoming, sizeof(incoming));
251 sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
253 printf("Failed to create socket: %m\n");
257 addr.sin_family = AF_INET;
258 addr.sin_port = htons(6000);
259 addr.sin_addr.s_addr = INADDR_ANY;
261 ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
263 printf("Failed to bind: %m\n");
267 ret = listen(sockfd, 5);
269 printf("Failed to listen(): %m\n");
273 bme->epollfd = epoll_create(1);
274 if (bme->epollfd == -1) {
275 printf("Failed to epoll_create(): %m\n");
280 incoming.ev.ev.data.fd = sockfd;
281 incoming.ev.ev.events = EPOLLIN;
282 incoming.ev.handle_event = handle_incoming_connection;
283 incoming.ev.name = "listener";
284 incoming.fd = sockfd;
286 ret = register_event_handler(bme, &incoming.ev);
289 struct epoll_event ev;
290 struct event_handler *h;
292 printf("%s: Waiting for events..\n", __func__);
293 ret = epoll_wait(bme->epollfd, &ev, 1, -1);
295 if (errno != EINTR) {
296 printf("epoll_wait: %m\n");
304 printf("Timed out\n");
310 printf("Handling %s %s event for %s\n",
311 ev.events & EPOLLIN ? "incoming" : "",
312 ev.events & EPOLLOUT ? "outgoing" : "",
324 static int8_t i2c_read(uint8_t reg_addr, uint8_t *data, uint32_t len, void *intf_ptr)
329 id = *((struct bme280 *)intf_ptr);
331 ret = write(id.fd, ®_addr, 1);
335 ret = read(id.fd, data, len);
342 static void delay_us(uint32_t period, void *unused)
349 static int8_t i2c_write(uint8_t reg_addr, const uint8_t *data, uint32_t len, void *intf_ptr)
354 id = *((struct bme280 *)intf_ptr);
356 buf = malloc(len + 1);
358 memcpy(buf + 1, data, len);
360 if (write(id.fd, buf, len + 1) < (uint16_t)len) {
361 return BME280_E_COMM_FAIL;
369 static double dp(double RH, double T)
373 * Constants and equation taken from:
374 * https://en.wikipedia.org/wiki/Dew_point#Calculating_the_dew_point
376 /* double a = 6.112;*/
388 gm = log(RH / 100.0 * exp((b - T / d) * (T / (c + T))));
389 dp = c * gm / (b - gm);
394 static int stream_sensor_data_forced_mode(struct bme280 *bme)
397 uint8_t settings_sel = 0;
399 struct bme280_data comp_data;
400 struct bme280_dev *dev = bme->dev;
402 double t_sum = 0, h_sum = 0, p_sum = 0;
403 int num = 0, first_run = 1, last_min;
405 /* Recommended mode of operation: Indoor navigation */
406 dev->settings.osr_h = BME280_OVERSAMPLING_1X;
407 dev->settings.osr_p = BME280_OVERSAMPLING_16X;
408 dev->settings.osr_t = BME280_OVERSAMPLING_2X;
409 dev->settings.filter = BME280_FILTER_COEFF_16;
411 settings_sel = BME280_OSR_PRESS_SEL | BME280_OSR_TEMP_SEL |
412 BME280_OSR_HUM_SEL | BME280_FILTER_SEL;
414 ret = bme280_set_sensor_settings(settings_sel, dev);
416 fprintf(stderr, "Failed to set sensor settings (code %+d).", ret);
421 printf("Temperature, Pressure, Humidity\n");
424 * Calculate the minimum delay required between consecutive
425 * measurement based upon the sensor enabled and the
426 * oversampling configuration.
428 req_delay = bme280_cal_meas_delay(&dev->settings);
434 ret = bme280_set_sensor_mode(BME280_FORCED_MODE, dev);
436 fprintf(stderr, "Failed to set sensor mode (code %+d).", ret);
440 /* Wait for the measurement to complete and print data */
441 dev->delay_us(req_delay * 1000, dev->intf_ptr);
442 ret = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
444 fprintf(stderr, "Failed to get sensor data (code %+d).", ret);
448 t_sum += comp_data.temperature;
449 p_sum += comp_data.pressure;
450 h_sum += comp_data.humidity;
456 if (first_run || now->tm_min != last_min) {
457 double temp, press, hum, dew;
462 last_min = now->tm_min;
464 temp = t_sum / (double)num;
465 press = p_sum * 0.01 / (double)num;
466 hum = h_sum / (double)num;
468 strftime(s, sizeof(s), "%Y.%m.%d %H:%M:%S", now);
471 printf("%s %0.4lf deg C, %0.4lf hPa, %0.4lf%%, dp: %.3f C\n",
472 s, temp, press, hum, dew);
474 pthread_mutex_lock(&bme->lock);
475 for (i = 0; i < ARRAY_SIZE(bme->data) - 1; i++)
476 bme->data[i] = bme->data[i + 1];
478 bme->data[i].time = t;
479 bme->data[i].temperature = temp;
480 bme->data[i].pressure = press;
481 bme->data[i].humidity = hum;
482 bme->data[i].dew_point = dew;
483 pthread_mutex_unlock(&bme->lock);
486 t_sum = p_sum = h_sum = 0;
493 int main(int argc, char *argv[])
496 struct bme280_dev dev;
500 bzero(&id, sizeof(id));
503 fprintf(stderr, "Missing argument for i2c bus and address.\n"
504 "Usage: %s /dev/i2c-0 0x76\n", argv[0]);
508 bzero(&id, sizeof(id));
510 if ((id.fd = open(argv[1], O_RDWR)) < 0) {
511 fprintf(stderr, "Failed to open the i2c bus %s\n", argv[1]);
515 id.dev_addr = strtol(argv[2], NULL, 0);
516 if (ioctl(id.fd, I2C_SLAVE, id.dev_addr) < 0) {
517 fprintf(stderr, "Failed to acquire bus access and/or talk to slave.\n");
521 dev.intf = BME280_I2C_INTF;
523 dev.write = i2c_write;
524 dev.delay_us = delay_us;
529 ret = bme280_init(&dev);
531 fprintf(stderr, "Failed to initialize the device (code %+d).\n", ret);
535 pthread_mutex_init(&id.lock, NULL);
536 pthread_create(&thread, NULL, event_handler, &id);
538 ret = stream_sensor_data_forced_mode(&id);
540 fprintf(stderr, "Failed to stream sensor data (code %+d).\n", ret);