Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Am2320 #14

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ option(WITH_IN_XBEE "Enable XBee input plugin" No)
option(WITH_IN_CPU "Enable CPU input plugin" Yes)
option(WITH_IN_MEM "Enable Memory input plugin" Yes)
option(WITH_IN_KMSG "Enable Kernel log input plugin" Yes)
option(WITH_IN_AM2320 "Enable AM2320/AM2321 input plugin" No)
option(WITH_OUT_FLUENTD "Enable Fluentd output plugin" Yes)
option(WITH_OUT_TD "Enable Treasure Data output plugin" Yes)
option(WITH_OUT_STDOUT "Enable STDOUT output plugin" Yes)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ When building _Fluent-Bit_, the following options are available when running __c
------------|------------|---------------------------------------------|---------
WITH_ALL | bool | Enable all features available | off
WITH_XBEE | bool | Enable XBee support (input) | off
WITH_AM2320 | bool | Enable AM2320/2321 Sensor support (input) | off
WITH_DEBUG | bool | Include debug symbols when building targets | off
WITHOUT_BIN | bool | Do not build the fluent-bit executable | off

Expand All @@ -47,6 +48,7 @@ Once the tool have been compiled, a binary file called _Fluent-Bit_ will be foun
| Memory | mem | usage of system memory |
| Kernel Ring Buffer | kmsg | read Linux Kernel messages, same behavior as the __dmesg__ command line program |
| XBee | xbee | listen for incoming messages over a Xbee device |
| AM2320 | am2320 | read temperature and humidity from AM2320/2321 from I2C senor device |

### Output Plugins

Expand Down
1 change: 1 addition & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ REGISTER_IN_PLUGIN("in_xbee")
REGISTER_IN_PLUGIN("in_cpu")
REGISTER_IN_PLUGIN("in_mem")
REGISTER_IN_PLUGIN("in_kmsg")
REGISTER_IN_PLUGIN("in_am2320")
REGISTER_OUT_PLUGIN("out_fluentd")
REGISTER_OUT_PLUGIN("out_td")
REGISTER_OUT_PLUGIN("out_stdout")
Expand Down
4 changes: 4 additions & 0 deletions plugins/in_am2320/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set(src
in_am2320.c am2320.c)

FLB_PLUGIN(in_am2320 "${src}" "")
20 changes: 20 additions & 0 deletions plugins/in_am2320/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
AM2320/AM2321 input support for Fluent Bit
Developed and tested on Raspbian and Raspberry Pi Type B+

Remarks:
- needs i2c-dev.h in i2c-tools (or equivalent) to comple this plug-in.
- I2C device path is hard-coded to /dev/i2c-1.
- fluent-bit process needs access to /dev/i2c-1.

License:
- am2320.[ch] is licensed under LGPL.
- in_am2320.[ch] is licensed under Apache License 2.0.

Thanks to:
- original authors of am2320.c
https://github.com/takagi/am2321
https://gist.github.com/yenjoji/40d135519a0741d3718b

--
Takeshi HASEGAWA
<hasegaw at gmail dot com>
173 changes: 173 additions & 0 deletions plugins/in_am2320/am2320.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
* am2320: AM2320/2321 I2C Sensor Driver
* Copyright (C) 2015 Takeshi HASEGAWA
*
* This file is modified version of:
* https://github.com/takagi/am2321
*
* Licensed under the LGPL License.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <time.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include "in_am2320.h"
#include "am2320.h"

/*
* udelay function
*/

long timeval_to_usec(struct timeval tm) {
return tm.tv_sec * 1000000 + tm.tv_usec;
}

void udelay(long us) {
struct timeval current;
struct timeval start;

gettimeofday(&start, NULL);
do {
gettimeofday( &current, NULL);
} while(timeval_to_usec(current) - timeval_to_usec( start ) < us);
}

/*
* CRC16
*/

unsigned short crc16(unsigned char *ptr, unsigned char len) {
unsigned short crc = 0xFFFF;
unsigned char i;

while(len--) {
crc ^= *ptr++;
for(i = 0; i < 8; i++) {
if(crc & 0x01) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}

return crc;
}

unsigned char crc16_low(unsigned short crc) {
return crc & 0xFF;
}

unsigned char crc16_high(unsigned short crc) {
return crc >> 8;
}

int in_am2320_check_crc16(unsigned char* data) {
unsigned short crc_m, crc_s;

crc_m = crc16(data, 6);
crc_s = (data[7] << 8) + data[6];
if (crc_m != crc_s) {
return 0;
}

return 1;
}

int in_am2320_read(struct flb_config *config, void *in_context) {
int retries = 5;

struct flb_in_am2320_config *ctx = in_context;
int fd;
unsigned char data[8];

fd = open(IN_AM2320_I2C_DEVICE, O_RDWR);
if (fd < 0) {
flb_debug("[in_am2320] could not open I2C device: %s",
IN_AM2320_I2C_DEVICE);
return 1;
}

/* set address of I2C device in 7 bits */
int ret = ioctl( fd, I2C_SLAVE, IN_AM2320_I2C_ADDRESS);
if (ret < 0) {
flb_debug("[in_am2320] could not select I2C address: %x",
IN_AM2320_I2C_ADDRESS);
goto error;
}

/* write measurement request */
data[0] = 0x03;
data[1] = 0x00;
data[2] = 0x04;

while (retries) {
/* wake I2C device up */
write( fd, NULL, 0);

ret = write(fd, data, 3);

if (ret >= 0)
break;

flb_debug("[in_am2320] write error, retries = %d");
udelay(1000);
retries--;
}

if (ret < 0) {
flb_debug("[in_am2320] write error");
goto error;
}

/* wait for having measured */
udelay(1500);

/* read measured result */
memset(data, 0x00, 8);
ret = read(fd, data, 8);
if (ret < 0)
goto error;

/* close I2C device */
close(fd);

if (! in_am2320_check_crc16(data)) {
flb_debug("[in_am2320] CRC error");
return 0;
}

double temp = (double) ((data[4] << 8) + data[5]) / 10;
double humidity = (double) ((data[2] << 8) + data[3]) / 10;

msgpack_pack_map(&ctx->pckr, 3);
msgpack_pack_raw(&ctx->pckr, 4);
msgpack_pack_raw_body(&ctx->pckr, "time", 4);
msgpack_pack_uint64(&ctx->pckr, time(NULL));
msgpack_pack_raw(&ctx->pckr, 11);
msgpack_pack_raw_body(&ctx->pckr, "temperature", 11);
msgpack_pack_double(&ctx->pckr, temp);
msgpack_pack_raw(&ctx->pckr, 8);
msgpack_pack_raw_body(&ctx->pckr, "humidity", 8);
msgpack_pack_double(&ctx->pckr, humidity);

flb_debug("[in_am2320] temperature %f humidity %f (buffer=%i)",
temp, humidity, ctx->idx);
ctx->idx++;

return 1;
error:
/* close I2C device */
close(fd);

return 0;
}
18 changes: 18 additions & 0 deletions plugins/in_am2320/am2320.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
* am2320: AM2320/2321 I2C Sensor Driver
* Copyright (C) 2015 Takeshi HASEGAWA
*
* This file is modified version of:
* https://github.com/takagi/am2321
*
* Licensed under the LGPL License.
*/

/* I2C character device */
#define IN_AM2320_I2C_DEVICE "/dev/i2c-1"
#define IN_AM2320_I2C_ADDRESS (0xB8 >> 1)

/* I2C device access */
int in_am2320_read(struct flb_config *config, void *in_context);
108 changes: 108 additions & 0 deletions plugins/in_am2320/in_am2320.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
* in_am2320: AM2320/2321 I2C Sensor device input
* Copyright (C) 2015 Takeshi HASEGAWA
*
* Fluent Bit
* ==========
* Copyright (C) 2015 Treasure Data Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/kernel.h>

#include <time.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include "in_am2320.h"
#include "am2320.h"

int in_am2320_collect(struct flb_config *config, void *in_context);

int in_am2320_init(struct flb_config *config)
{
int ret;
struct flb_in_am2320_config *ctx;

ctx = malloc(sizeof(struct flb_in_am2320_config));
if (!ctx) {
return -1;
}
ctx->idx = 0;
msgpack_sbuffer_init(&ctx->sbuf);
msgpack_packer_init(&ctx->pckr, &ctx->sbuf, msgpack_sbuffer_write);
ret = flb_input_set_context("am2320", ctx, config);
if (ret == -1) {
flb_utils_error_c("[in_am2320] Could not set configuration for memory input plugin");
}
ret = flb_input_set_collector_time("am2320",
in_am2320_collect,
IN_AM2320_COLLECT_SEC,
IN_AM2320_COLLECT_NSEC,
config);
if (ret == -1) {
flb_utils_error_c("Could not set collector for memory input plugin");
}
return 0;
}

int in_am2320_pre_run(void *in_context, struct flb_config *config)
{
struct flb_in_am2320_config *ctx = in_context;

ctx->tag_len = snprintf(ctx->tag, sizeof(ctx->tag), "%s.am2320", config->tag);
if (ctx->tag_len == -1) {
flb_utils_error_c("Could not set custom tag on memory input plugin");
}
return 0;
}

int in_am2320_collect(struct flb_config *config, void *in_context)
{
return in_am2320_read(config, in_context);
}

void *in_am2320_flush(void *in_context, int *size)
{
char *buf;
struct flb_in_am2320_config *ctx = in_context;

if (ctx->idx == 0)
return NULL;

buf = malloc(ctx->sbuf.size);
if (!buf)
return NULL;

memcpy(buf, ctx->sbuf.data, ctx->sbuf.size);
*size = ctx->sbuf.size;
msgpack_sbuffer_destroy(&ctx->sbuf);
msgpack_sbuffer_init(&ctx->sbuf);
msgpack_packer_init(&ctx->pckr, &ctx->sbuf, msgpack_sbuffer_write);
ctx->idx = 0;
return buf;
}

struct flb_input_plugin in_am2320_plugin = {
.name = "am2320",
.description = "AM2320/AM2321 Sensor",
.cb_init = in_am2320_init,
.cb_pre_run = in_am2320_pre_run,
.cb_collect = in_am2320_collect,
.cb_flush_buf = in_am2320_flush
};
Loading