aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGergő J. Miklós2018-09-29 01:32:11 +0200
committerGergő J. Miklós2018-09-29 01:32:11 +0200
commitab99f700bace05491919324259c9110c7f387af8 (patch)
tree699d197b204e482dfb56f8443e036ed6f740ace0
downloadi2sensors-ab99f700bace05491919324259c9110c7f387af8.tar.gz
i2sensors-ab99f700bace05491919324259c9110c7f387af8.zip
Existing code & initialcommit.
-rw-r--r--.gitignore2
-rw-r--r--Makefile.openwrt36
-rw-r--r--README.md7
-rw-r--r--build.sh9
-rw-r--r--src/hih61xx.c155
-rw-r--r--src/hih61xx.h19
-rw-r--r--src/lm75.c163
-rw-r--r--src/lm75.h20
-rw-r--r--src/main.c161
9 files changed, 572 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6f31401
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+build/
+.vscode/
diff --git a/Makefile.openwrt b/Makefile.openwrt
new file mode 100644
index 0000000..1c90cfc
--- /dev/null
+++ b/Makefile.openwrt
@@ -0,0 +1,36 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=i3ensors
+PKG_VERSION:=1.0
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+PKG_MAINTAINER:=AA <aa@aa.hu>
+PKG_LICENSE:=ISC GPL-2.0
+## PKG_BUILD_DEPENDS:=+madplay
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/i2sensors/default
+ CATEGORY:=Sensors
+ SUBMENU:=I2C Sensors
+ TITLE:=Famous I2C Sensors reader
+endef
+
+define Package/i2sensors
+ $(Package/i2sensors/default)
+ ##DEPENDS:=+uhttpd +uhttpd-mod-lua +uhttpd-mod-tls +kmod-sound-core +kmod-usb-audio +alsa-lib
+endef
+
+define Package/i2sensors/description
+ i2sensors read some i2c devices
+endef
+
+define Package/i2sensors/install
+ $(CP) ./files/* $(1)/
+endef
+
+define Build/Compile
+ true
+endef
+
+$(eval $(call BuildPackage,webclient))
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1930ba4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+
+Reader for some famous i2c sensor (LM75, HIH6121).
+It uses the Linux Kernel i2c driver.
+
+Supported devices:
+lm75
+hih61xx (ex: hih6131)
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000..1e43724
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+#cd "i2sensors/"
+
+gcc -Wall src/main.c src/hih61xx.c src/lm75.c -o build/i2sensors
+
+build/i2sensors
+
+
diff --git a/src/hih61xx.c b/src/hih61xx.c
new file mode 100644
index 0000000..b68b653
--- /dev/null
+++ b/src/hih61xx.c
@@ -0,0 +1,155 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#include "hih61xx.h"
+
+extern int file;
+extern void bus_err(int ern);
+extern void print_help(void);
+unsigned char buf[5];
+
+
+
+
+void hih61xx_list_all(void)
+{
+ printf(
+ "00: Relative Humidity [%%] (reg: 0x00)\n"
+ "01: Temperature [°C] (reg: 0x00)\n"
+ "02: Status [hex] (reg: 0x00)\n"
+ "\n");
+}
+
+
+
+void hih61xx_get_data(void)
+{
+ buf[0] = 0x00;
+
+ if(write(file, buf, 1) != 1) //Start measure
+ {
+ bus_err(errno);
+ }
+
+ usleep(60*1000); // Wait 60ms for measurement
+
+ if(read(file, buf, 4) != 4) //Read the data
+ {
+ bus_err(errno);
+ }
+}
+
+
+
+unsigned char hih61xx_read_status(void)
+{
+ return ((buf[0] & 0xc0) >> 6);
+}
+
+
+
+float hih61xx_read_humidity(float offset)
+{
+ unsigned int raw = 0;
+ float humidity;
+
+ if(hih61xx_read_status() != 0x01 )
+ {
+ raw = ((buf[0] & 0x3f) << 8) + buf[1]; // two msb status, 14bit data
+ humidity = ((float)raw/(16384 - 2))*100; // humidity = (14bit data / (2^14 -2)) * 100%
+ }
+ else
+ {
+ humidity = -1.0 ;
+ }
+
+ return (humidity + offset) ;
+}
+
+
+
+float hih61xx_read_temp(float offset)
+{
+ unsigned int raw = 0;
+ float temp;
+
+ if(hih61xx_read_status() != 0x01 )
+ {
+ raw = ((buf[2] << 8) + buf[1]) >> 2; // 14bit temp data
+ temp = ((float)raw/(16384 - 2))*165 - 40 ; // temp = ((14bit data / (2^14 -2))*165) - 40 [°C]
+ }
+ else
+ {
+ temp = -40.0 ;
+ }
+
+ return (temp + offset);
+}
+
+
+
+void hih61xx_read_all(const char *opts)
+{
+ hih61xx_get_data();
+
+ if(opts != NULL)
+ {
+ char *ptr;
+ printf("00:%f\n", hih61xx_read_humidity(strtof(opts, &ptr)));
+
+ ptr++; // One (,) character allowed for delimiter
+
+ printf("01:%f\n", hih61xx_read_temp(strtof(ptr, NULL)));
+ }
+ else
+ {
+ printf("00:%f\n", hih61xx_read_humidity(0.0));
+ printf("01:%f\n", hih61xx_read_temp(0.0));
+ }
+
+ printf("02:0x%x\n", hih61xx_read_status());
+
+}
+
+
+
+void hih61xx_read_one(const char *opts)
+{
+ int id;
+ char *ptr;
+
+ hih61xx_get_data();
+ id = strtol (opts,&ptr,0); //all format allowed
+ ptr++; //one separator allowed
+
+ switch (id)
+ {
+ case 0x00:
+ printf("00:%f\n", hih61xx_read_humidity(strtof(ptr, NULL)));
+ break;
+ case 0x01:
+ printf("01:%f\n", hih61xx_read_temp(strtof(ptr, NULL)));
+ break;
+ case 0x02:
+ printf("02:0x%x\n", hih61xx_read_status());
+ break;
+ default:
+ print_help();
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/hih61xx.h b/src/hih61xx.h
new file mode 100644
index 0000000..25842a6
--- /dev/null
+++ b/src/hih61xx.h
@@ -0,0 +1,19 @@
+
+#ifndef _HIH61XX_INCLUDED
+#define _HIH61xx_INCLUDED
+/*
+
+extern int file;
+
+void hih61xx_list_all(void);
+void hih61xx_read_all(const char *opts);
+*/
+void hih61xx_list_all(void);
+void hih61xx_get_data(void);
+unsigned char hih61xx_read_status(void);
+float hih61xx_read_humidity(float offset);
+float hih61xx_read_temp(float offset);
+void hih61xx_read_all(const char *opts);
+void hih61xx_read_one(const char *opts);
+
+#endif \ No newline at end of file
diff --git a/src/lm75.c b/src/lm75.c
new file mode 100644
index 0000000..fac61c2
--- /dev/null
+++ b/src/lm75.c
@@ -0,0 +1,163 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#include "lm75.h"
+
+extern int file;
+extern void bus_err(int ern);
+extern void print_help(void);
+unsigned char buf[5];
+
+
+void lm75_list_all(void)
+{
+ printf(
+ "00: Temperature data [°C] (reg: 0x00)\n"
+ "01: Configuration [hex] (reg: 0x01)\n"
+ "02: Tos (Overtemp) [°C] (reg: 0x03)\n"
+ "03: Thys (Hysteresis) [°C] (reg: 0x04)\n"
+ "\n");
+}
+
+
+
+void lm75_get_data(void)
+{
+ if(write(file, buf, 1) != 1)
+ {
+ bus_err(errno);
+ }
+
+ if(read(file, buf, 2) != 2)
+ {
+ bus_err(errno);
+ }
+}
+
+
+
+float lm75_read_temp(float offset)
+{
+ signed int rawtemp = 0;
+ float temp;
+
+ buf[0] = 0x00;
+
+ lm75_get_data();
+
+ rawtemp = (buf[0]*256 + buf[1]) >> 5; //(buf[0] << 8), and (>> 5), 11bit device is also supported
+
+ if((rawtemp & 0x400) == 0x400) //check if the msb(bit11) is 1 (1024 = 0x400), 2'complement negative number
+ {
+ rawtemp = rawtemp - 2048; //2^11 = 2048
+ }
+
+ temp = rawtemp * 0.125 ; //11bit->0.125°C or 9bit->0.5°C
+ return (temp + offset);
+}
+
+
+
+float lm75_read_tos(void)
+{
+ int rawtemp = 0;
+
+ buf[0] = 0x02;
+
+ lm75_get_data();
+
+ rawtemp = buf[0]*256 + buf[1];
+ rawtemp = (rawtemp) >> 7; //9bit data
+
+ if((rawtemp & 256) == 256) // check if the msb 2'complement negative number
+ {
+ rawtemp = rawtemp - 512 ; // 2^9 = 512;
+ }
+
+ return (rawtemp * 0.5); //9bit -> 0.5 celsius
+}
+
+
+
+float lm75_read_thys(void)
+{
+ int rawtemp = 0;
+
+ buf[0] = 0x03;
+
+ lm75_get_data();
+
+ rawtemp = buf[0]*256 + buf[1];
+ rawtemp = (rawtemp) >> 7; //9bit data
+
+ if((rawtemp & 256) == 256) // check if the msb 2'complement negative number
+ {
+ rawtemp = rawtemp - 512 ; // 2^9 = 512;
+ }
+
+ return (rawtemp * 0.5); //9bit -> 0.5 celsius
+}
+
+
+char lm75_read_conf(void)
+{
+
+ buf[0] = 0x01;
+
+ lm75_get_data();
+
+ return buf[0];
+}
+
+
+
+void lm75_read_all(const char *opts)
+{
+ if(opts != NULL)
+ {
+ printf("00:%f\n", lm75_read_temp(strtof(opts, NULL)));
+ }
+ else
+ {
+ printf("00:%f\n", lm75_read_temp(0.0));
+ }
+
+ printf("01:0x%x\n", lm75_read_conf());
+ printf("02:%f\n", lm75_read_tos());
+ printf("03:%f\n", lm75_read_thys());
+}
+
+
+
+void lm75_read_one(const char *opts)
+{
+ int id;
+ char *ptr;
+
+ id = strtol (opts,&ptr,0); //all format allowed
+ ptr++; //one separator allowed
+
+ switch (id)
+ {
+ case 0x00:
+ printf("00:%f\n", lm75_read_temp(strtof(ptr, NULL)));
+ break;
+ case 0x01:
+ printf("01:0x%x\n", lm75_read_conf());
+ break;
+ case 0x02:
+ printf("02:%f\n", lm75_read_tos());
+ break;
+ case 0x03:
+ printf("03:%f\n", lm75_read_thys());
+ break;
+ default:
+ print_help();
+ }
+}
+
diff --git a/src/lm75.h b/src/lm75.h
new file mode 100644
index 0000000..ff31c6a
--- /dev/null
+++ b/src/lm75.h
@@ -0,0 +1,20 @@
+
+#ifndef _LM75_INCLUDED
+#define _LM75_INCLUDED
+
+// extern int file;
+//
+// void lm75_list_all(void);
+// void lm75_read_all(const char *opts);
+//
+void lm75_list_all(void);
+void lm75_get_data(void);
+float lm75_read_temp(float offset);
+float lm75_read_tos(void);
+float lm75_read_thys(void);
+char lm75_read_conf(void);
+void lm75_read_all(const char *opts);
+void lm75_read_one(const char *opts);
+
+
+#endif \ No newline at end of file
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..c71c872
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,161 @@
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+
+#include "lm75.h"
+#include "hih61xx.h"
+
+extern void lm75_list_all(void);
+extern void lm75_read_all(const char *opts);
+extern void lm75_read_one(const char *opts);
+extern void hih61xx_list_all(void);
+extern void hih61xx_read_all(const char *opts);
+extern void hih61xx_read_one(const char *opts);
+
+
+int file;
+void (*list_all)(void) = NULL;
+void (*read_all)(const char *opts) = NULL;
+void (*read_one)(const char *opts) = NULL;
+
+
+void print_help(void)
+{
+ printf ("Usage:\n"
+ " i2sensor <op> <bus> <dev_type> <dev_addr> (<options>)\n"
+ "Aviable options: <op>\n"
+ " list_all -- list all measured parameters off device\n"
+ " read_all -- read all measured parameters from device\n"
+ " read_one -- read the selected parameters from device\n"
+ "Exmples:\n"
+ " i2sensor read_all <bus> <device> <address> <offset_for_param-01,offset_for_param-02,...>\n"
+ " i2sensor read_one <bus> <device> <address> <param-id,offset_for_param-id>\n"
+ " i2sensor read_all 1 lm75 0x4f -1.35,\n"
+ " i2sensor read_one 1 lm75 0x4f 01,-1.35\n"
+ "" "\n");
+}
+
+void bus_err(int ern)
+{
+ printf("I2C communication(rd) error. errno: %d\n",errno);
+}
+
+void preinit(const char *dev_type)
+{
+ if(!strcmp("lm75", dev_type))
+ {
+ list_all = lm75_list_all;
+ read_all = lm75_read_all;
+ read_one = lm75_read_one;
+ }
+
+ else if(!strcmp("hih61xx", dev_type))
+ {
+ list_all = hih61xx_list_all;
+ read_all = hih61xx_read_all;
+ read_one = hih61xx_read_one;
+ }
+}
+
+
+
+int main(int argc, char *argv[])
+{
+
+// >> i2sensor <op> <bus> <dev_typ> <dev_addr> (<others>)
+// >> i2sensor read_all 0 lm75 4f 1,-1.0;2,+0.2;3,+10;4,-2
+// read_all, list_all,
+// ...read_all...<dev_addr>, <param_id,offs,param_id,offs>
+// read_one...<dev_addr>, <param_id,offs>
+// ...read_reg_hex... <dev_addr>, <reg_addr,b/w/dw>
+// ...read_reg_dec... <dev_addr>, <reg_addr,b/w/dw>
+// ...set_param... <dev_addr>, <param_id,value_dec>
+// ...set_reg... <dev_addr>, <reg_addr,value_hex>
+
+
+ if(4 < argc && 7 > argc) //Minimal 5 argument passed
+ {
+
+ char filename[32];
+ int i;
+ preinit(argv[3]);
+
+ for(i=0;i<strlen(argv[2]);i++) //Some test on bus address, for safety.
+ {
+ if(!isdigit(argv[2][i]))
+ {
+ printf("\n\tThe BUS Address must be an integer\n\n");
+ print_help();
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ snprintf(filename, 31, "/dev/i2c-%s", argv[2]); //Open i2c bus
+ file = open(filename, O_RDWR);
+
+ if (file < 0)
+ {
+ printf("\n\tCan't open i2c BUS, are you root?\n\n");
+ print_help();
+ exit (EXIT_FAILURE);
+ }
+
+
+ if(argv[4][0]=='0' && argv[4][1]=='x') //?
+ {
+
+ int addr = (int)strtol(argv[4], NULL, 0); //Open i2c device
+
+ if (ioctl(file, I2C_SLAVE, addr) < 0)
+ {
+ printf("\n\tCan't open i2c DEVICE, errno: %d\n\n",errno);
+ print_help();
+ exit (EXIT_FAILURE);
+ }
+ }
+ else
+ {
+ printf("\n\tThe DEVICE address must be a hexadecimal number\n\n");
+ print_help();
+ exit (EXIT_FAILURE);
+ }
+
+
+
+ if(!strcmp("list_all",argv[1]) && list_all != NULL) // If list_all is selected.
+ {
+ list_all();
+ }
+ else if(!strcmp("read_all",argv[1]) && read_all != NULL)
+ {
+ read_all(argv[5]);
+ }
+ else if(!strcmp("read_one",argv[1]) && read_one != NULL && argc == 5)
+ {
+ read_one(argv[5]);
+ }
+ else
+ {
+ // print_help();
+ }
+
+ close(file);
+
+ }
+ else
+ {
+ print_help();
+ }
+ return 0;
+}