BeagleBoneBlack for LPS331 (i2c) driver and rrdtool setting


lps331.c
//      LPS331AP Driver Ver.0.01
//
//              Written by H.Nitobe     2015/07/06
//
// LPS331AP
// MEMS pressure sensor: 260-1260 mbar absolute digital output barometer
// http://www.st.com/web/en/resource/technical/document/datasheet/DM00036196.pdf
//

#include        <stdio.h>
#include        <stdlib.h>
#include        <fcntl.h>
#include        <errno.h>
#include        <time.h>
#include        <sys/ioctl.h>
#include        <linux/i2c-dev.h>

#define LPS331_address  0x5d

#define REF_PRESS_L     0x08
#define REF_PRESS_M     0x09
#define REF_PRESS_H     0x0a
#define WHO_AM_I        0x0f
#define RES_CONF        0x10
#define CTRL_REG1       0x20
#define CTRL_REG2       0x21
#define STATUS_REG      0x27
#define PRESS_L         0x28
#define PRESS_M         0x29
#define PRESS_H         0x2a
#define TEMP_L          0x2b
#define TEMP_H          0x2c

//#define DEBUG

#ifdef DEBUG
#define debug printf
#else
#define debug 1 ? (void) 0 : printf
#endif

typedef unsigned char   U8;
typedef unsigned long   U32;

int open_i2c(char *path_name, int flags);
int ioctl_i2c(int file_descriptor, U32 request, U8 address);
int write_i2c(int file_descriptor, U8 address, U8 data);
U8 read_i2c(int file_descriptor, U8 address);

int main(int argc, char *argv[])
{
        clock_t start, end;

        int     LPS331;

        U32     press_raw;
        short   temp_raw;

        float   press, temp;

        LPS331 = open_i2c("/dev/i2c-1", O_RDWR);

        ioctl_i2c(LPS331, I2C_SLAVE, LPS331_address);

#ifdef  DEBUG
        printf("[debug] WHO_AM_I = %x\n", read_i2c(LPS331, WHO_AM_I));
        printf("[debug] STATUS_REG = %x\n", read_i2c(LPS331, STATUS_REG));
#endif


//      write_i2c(LPS331, CTRL_REG1, 0xe0);
//      write_i2c(LPS331, CTRL_REG1, 0x00);
//      debug("", read_i2c(LPS331, CTRL_REG1));

//              RES_CONF(10h)                   Pressure resolution mode
//      |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
//      |       | Nr. internal average  |     Nr. internal average      |
//      |  RFU  | AVGT2 | AVGT1 | AVGT0 | AVGP3 | AVGP2 | AVGP1 | AVGP0 |
//      |   0   |   1   |   1   |   1   |   1   |   0   |   1   |   0   |
//      |       |          128          |              512              |

        write_i2c(LPS331, RES_CONF, 0x7a);
        debug("", read_i2c(LPS331, RES_CONF));

/*
ONE_SHOT bit is used to start a new conversion when ODR1-ODR0 bits in CTRL_REG1 
are set to "000" In this situation a single acquisition of temperature and pressure is started 
when ONE_SHOT bit is set to '1' At the end of conversion the new data are available 
in the output registers, the STAUS_REG[0] and STAUS_REG[1] bits are set to '1' 
and the ONE_SHOT bit comes back to '0' by hardware.
*/
//      Active Mode & One Shot Mode & Block Data Update
//              CTRL_REG1                       Control register 1
//      |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
//      |       |   Output data rate    |       |       |       |       |
//      |  PD   | ODR2  | ODR1  | ODR0  | DIFF  |  BDU  | DELTA |  SIM  |
//      |   1   |   0   |   0   |   0   |   0   |   1   |   0   |   0   |
//      |ACTIVE |       One Shot        |  no   |  yes  |  no   |  no   |

        write_i2c(LPS331, CTRL_REG1, 0x84);
        debug("", read_i2c(LPS331, CTRL_REG1));

//      Oneshot Trigger
//              CTRL_REG2                       Control register 2
//      |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
//      |       |           RESERVED            |       |       |       |
//      | BOOT  |                               |S RESET|A ZERO |ONESHOT|
//      |   0   |                               |   0   |   0   |   1   |
//      |Normal |                               |  no   |  no   |  yes  |

        write_i2c(LPS331, CTRL_REG2, 0x01);

#ifdef DEBUG
        start = clock();
#endif
        while((read_i2c(LPS331, CTRL_REG2) && 0x01) == 0x01){
                usleep(30000);
        }
#ifdef DEBUG
        end = clock();
#endif
        debug("[debug] wait : %f\n", (float)(end - start)/CLOCKS_PER_SEC);

        press_raw  = read_i2c(LPS331, PRESS_L);
        press_raw |= read_i2c(LPS331, PRESS_M) << 8;
        press_raw |= read_i2c(LPS331, PRESS_H) << 16;
        debug("[debug] Pdac = %08x:%06d\n", press_raw, press_raw);
        temp_raw  = read_i2c(LPS331, TEMP_L);
        temp_raw |= read_i2c(LPS331, TEMP_H) << 8;
        debug("[debug] Tdac = %4x:%6d\n", temp_raw, temp_raw);

//      Power Down Mode
//              CTRL_REG1                       Control register 1
//      |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
//      |       |   Output data rate    |       |       |       |       |
//      |  PD   | ODR2  | ODR1  | ODR0  | DIFF  |  BDU  | DELTA |  SIM  |
//      |   0   |   0   |   0   |   0   |   0   |   0   |   0   |   0   |
//      |PowDown|       One Shot        |  no   |  no   |  no   |  no   |

        write_i2c(LPS331, CTRL_REG1, 0x00);
        debug("", read_i2c(LPS331, CTRL_REG1));

        debug("[debug] close(%x);\n", LPS331);
        close(LPS331);

        press = (float) press_raw / 4096.0f;

//      temp = ((float)temp_raw / 480.0f) + 42.5f;
        temp = ((float)temp_raw / 480.0f) + 37.5f;

        printf("%f:%f\n", press, temp);

        return 0;
}

int open_i2c(char *path_name, int flags){
        int     file_descriptor;

        debug("[debug] open(%s, %x);\n", path_name, flags);
        if((file_descriptor = open(path_name, flags)) < 0){
                perror("[error] i2cbus open");
                exit(1);
        }
        debug("[debug] file_descriptor = %x;\n", file_descriptor);
        return file_descriptor;
}

int ioctl_i2c(int file_descriptor, U32 request, U8 address){
        int     status = 0;

        debug("[debug] ioctl(%x, %x, %x);\n",file_descriptor,request,address);
        if((status = ioctl(file_descriptor, request, address)) < 0){
                perror("[error] can't set request");
                debug("[debug] close(%x);\n", file_descriptor);
                close(file_descriptor);
                exit(1);
        }
        return status;
}

int write_i2c(int file_descriptor, U8 address, U8 data){
        U8      buf[2] = {address, data};

        debug("[debug] write_i2c(%x, %x, %x);\n",
                                         file_descriptor, address, data);
        if(write(file_descriptor, buf, 2) != 2){
                perror("[error] write address/data");
                debug("close(%x);\n", file_descriptor);
                close(file_descriptor);
                exit(1);
        }
        return 0;
}

U8 read_i2c(int file_descriptor, U8 address){
        U8      data;

        debug("[debug] write(%x, %x, 1);\n", file_descriptor, address);
        if((write(file_descriptor, &address, 1)) != 1){
                perror("[error] write address");
                debug("[debug] close(file_descriptor);\n");
                close(file_descriptor);
                exit(1);
        }
        debug("[debug] read(file_descriptor, &data, 1); : ");
        if((read(file_descriptor, &data, 1)) != 1){
                perror("[error] read data");
                debug("[debug] close(file_descriptor);\n");
                close(file_descriptor);
                exit(1);
        }
        debug("%02x:%03d\n", data, data);

        return data;
}

root@beaglebone:~/rrdtool# gcc -o lps331 lps331.c
root@beaglebone:~/rrdtool# ls -al
total 36
drwxr-xr-x 2 root root 4096 Jul  7 17:29 .
drwxr-xr-x 7 root root 4096 Jul  7 17:23 ..
-rwxr-xr-x 1 root root 6809 Jul  7 17:29 lps331
-rw-r--r-- 1 root root 5158 Jul  7 17:13 lps331.c
-rwxr-xr-x 1 root root  381 Jul  6 18:24 lps331_create.sh
-rwxr-xr-x 1 root root 3492 Jul  6 17:12 lps331_graph.sh
-rwxr-xr-x 1 root root  122 Jul  6 18:24 lps331_update.sh
root@beaglebone:~/rrdtool#

lps331_create.sh
#!/bin/bash

/usr/bin/rrdtool create /var/www/rrdtool/lps331.rrd \
--step 60 \
DS:LPS331_pres:GAUGE:120:260:1260 \
DS:LPS331_temp:GAUGE:120:-25:108 \
RRA:LAST:0.5:1:10080 \
RRA:AVERAGE:0.5:5:2016 \
RRA:AVERAGE:0.5:30:1536 \
RRA:AVERAGE:0.5:720:732 \
RRA:MIN:0.5:5:2016 \
RRA:MIN:0.5:30:1536 \
RRA:MIN:0.5:720:732 \
RRA:MAX:0.5:5:2016 \
RRA:MAX:0.5:30:1536 \
RRA:MAX:0.5:720:732 \

lps331_update.sh
#!/bin/sh

RRD="/usr/bin/rrdtool update"
RRA="/var/www/rrdtool/lps331.rrd"
DATA=`/root/rrdtool/lps331`

$RRD $RRA N:$DATA

lps331_graph.sh
#!/bin/bash

export LANG=C

RRD="/usr/bin/rrdtool graph"
RRA="/var/www/rrdtool/lps331.rrd"
date="/bin/date"
NOW=`$date +%s`
D=`$date +"%F"`
T=`$date +"%H\:%M"`
TODAY=`$date +%y%m%d`
TIMESTAMP00=`$date --date "$TODAY" +%s`
TIMESTAMP12=`expr $TIMESTAMP00 + 43200`

GRP="/var/www/rrdtool/lps331_daily.png"
$RRD $GRP \
--start -25hour \
--end $NOW  \
--imgformat PNG \
--title "LPS331(Daily)" \
--width 600 \
--height 200 \
--vertical-label "hPa" \
--y-grid 1:2 \
--alt-autoscale \
--units-exponent 0 \
--right-axis-label 'deg.C' \
--right-axis 1:-1000 \
--right-axis-format %4.2lf \
--x-grid MINUTE:30:HOUR:6:HOUR:1:0:%H \
HRULE:0#FF0000 \
VRULE:$TIMESTAMP00#FF0000 \
VRULE:$TIMESTAMP12#FF0000 \
DEF:pres=$RRA:LPS331_pres:LAST \
DEF:temp=$RRA:LPS331_temp:LAST \
CDEF:Temp=temp,1000,+ \
LINE1:Temp#00CC00:"temp\:" \
GPRINT:temp:MIN:"MIN\:%6.2lf  " \
GPRINT:temp:AVERAGE:"AVERAGE\:%6.2lf  " \
GPRINT:temp:MAX:"MAX\:%6.2lf  " \
GPRINT:temp:LAST:"LAST\:%6.2lf  \n" \
LINE1:pres#0000CC:"Pres\:" \
GPRINT:pres:MIN:"MIN\:%6.1lf  " \
GPRINT:pres:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:pres:MAX:"MAX\:%6.1lf  " \
GPRINT:pres:LAST:"LAST\:%6.1lf  \n" \
COMMENT:"$D $T\r" \

GRP="/var/www/rrdtool/lps331_weekly.png"
$RRD $GRP \
--start -8day \
--end $NOW  \
--imgformat PNG \
--title "LPS331(Weekly)" \
--width 600 \
--height 200 \
--vertical-label "hPa" \
--y-grid 1:2 \
--units-exponent 0 \
--alt-autoscale \
--right-axis-label 'deg.C' \
--right-axis 1:-1000 \
--right-axis-format %3.1lf \
--x-grid HOUR:4:DAY:1:DAY:1:86400:"%m/%d(%a)" \
HRULE:0#FF0000 \
DEF:pres=$RRA:LPS331_pres:AVERAGE \
DEF:temp=$RRA:LPS331_temp:AVERAGE \
CDEF:Temp=temp,1000,+ \
LINE1:Temp#00CC00:"temp\:" \
GPRINT:temp:MIN:"MIN\:%6.1lf  " \
GPRINT:temp:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:temp:MAX:"MAX\:%6.1lf  \n" \
LINE1:pres#0000CC:"pres\:" \
GPRINT:pres:MIN:"MIN\:%6.1lf  " \
GPRINT:pres:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:pres:MAX:"MAX\:%6.1lf  \n" \
COMMENT:"$D $T\r" \

GRP="/var/www/rrdtool/lps331_monthly.png"
$RRD $GRP \
--start -32day \
--end $NOW  \
--imgformat PNG \
--title "LPS331(Monthly)" \
--width 600 \
--height 200 \
--vertical-label "hPa" \
--y-grid 1:2 \
--units-exponent 0 \
--alt-autoscale \
--right-axis-label 'deg.C' \
--right-axis 1:-1000 \
--right-axis-format %3.1lf \
--x-grid DAY:1:WEEK:1:WEEK:1:604800:%U \
HRULE:0#FF0000 \
DEF:pres=$RRA:LPS331_pres:AVERAGE \
DEF:temp=$RRA:LPS331_temp:AVERAGE \
CDEF:Temp=temp,1000,+ \
LINE1:Temp#00CC00:"temp\:" \
GPRINT:temp:MIN:"MIN\:%6.1lf  " \
GPRINT:temp:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:temp:MAX:"MAX\:%6.1lf  \n" \
LINE1:pres#0000CC:"pres\:" \
GPRINT:pres:MIN:"MIN\:%6.1lf  " \
GPRINT:pres:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:pres:MAX:"MAX\:%6.1lf  \n" \
COMMENT:"$D $T\r" \

GRP="/var/www/rrdtool/lps331_yearly.png"
$RRD $GRP \
--start -366day \
--end $NOW  \
--imgformat PNG \
--title "LPS331(Yearly)" \
--width 600 \
--height 200 \
--vertical-label "hPa" \
--y-grid 1:2 \
--units-exponent 0 \
--alt-autoscale \
--right-axis-label 'deg.C' \
--right-axis 1:-1000 \
--right-axis-format %3.1lf \
--x-grid WEEK:1:MONTH:1:MONTH:1:2592000:%b \
HRULE:0#FF0000 \
DEF:pres=$RRA:LPS331_pres:AVERAGE \
DEF:temp=$RRA:LPS331_temp:AVERAGE \
CDEF:Temp=temp,1000,+ \
LINE1:Temp#00CC00:"temp\:" \
GPRINT:temp:MIN:"MIN\:%6.1lf  " \
GPRINT:temp:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:temp:MAX:"MAX\:%6.1lf\n" \
LINE1:pres#0000CC:"pres\:" \
GPRINT:pres:MIN:"MIN\:%6.1lf  " \
GPRINT:pres:AVERAGE:"AVERAGE\:%6.1lf  " \
GPRINT:pres:MAX:"MAX\:%6.1lf\n" \
COMMENT:"$D $T\r" \

/root/.ssh/config
Host mbsrv
  HostName 36.3.???.???
  User ?????
  Protocol 2
  PubkeyAuthentication yes

root@beaglebone:~/.ssh# ls -al
total 20
drwx------ 2 root root 4096 Jul  6 18:32 .                              <--- .ssh の permission は、700
drwxr-xr-x 7 root root 4096 Jul  7 17:23 ..
-rw-r--r-- 1 root root   90 Jul  6 18:31 config
-rw------- 1 root root 1676 Jul  6 18:32 id_rsa                         <--- 秘密鍵の permission は、600
-rw-r--r-- 1 root root  442 Jul  6 18:32 known_hosts

sshでさくっとログインできることを確認。
root@beaglebone:~/rrdtool# ssh mbsrv
Last login: Tue Jul  7 13:37:21 from 124.33.???.???
?????@saigyo.mbsrv.net [~]# logout
Connection to 36.3.???.??? closed.
root@beaglebone:~/rrdtool#

データ更新を1分毎に、グラフ描画とサーバへのアップロードを5分毎に。
/etc/cron.d/rrdtool
*/1 * * * *     root    /root/rrdtool/lps331_update.sh
*/5 * * * *     root    sleep 10; /root/rrdtool/lps331_graph.sh; rsync -az -e ssh /var/www/rrdtool mbsrv:www

T: Y: ALL: Online:
ThemeSwitch
  • Basic
Created in 0.0417 sec.
prev
2019.8
next
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
 
strawberry-linux geigercounter Ver.2
Sibasaki, Cyofu City, Tokyo, JAPAN
blogBar