C言語のプログラムにしてみる

前ページのコマンド入力に相当するものと、合わせて温度データを取得して出力するプログラムを書いてみた。無駄があるのはご勘弁を…。

下記のサンプルプログラムをコピーして、Windows PCのメモ帳にペーストして保存する。ファイル名「Get06Mago.sh」、文字コード「UTF-8」で保存しよう。保存先のフォルダはどこでもよい。保存後、Tera TermのSCP機能を使って、サンプルプログラムをRaspberry Piへ転送しよう。今回はRaspberry Pi側に「~/lps」というディレクトリを作って、そこへ転送(保存)した。一連の操作は、本連載の第2回(2ページ目)を参照してほしい。

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

#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#define LPS_ADDRESS (0x5c)
#define WHO_AM_I (0x0f)
#define CTRL_REG1 (0x20)
#define STATUS_REG (0x27)
#define PRESS_L (0x28)
#define PRESS_M (0x29)
#define PRESS_H (0x2a)
#define TEMP_L (0x2b)
#define TEMP_H (0x2c)

// 関数プロトタイプ宣言。
void I2C_write(unsigned char rs, unsigned char data, int fd);
unsigned char I2C_read(unsigned char rs, int fd);

int main(void)
{
    int lpt;
    char    *i2cFileName = "/dev/i2c-1";
    int LpsAddress = LPS_ADDRESS;
    long int    press;
    short int   temp;
    float   press_d,temp_d;
    time_t  timer;
    struct  tm *t_st;

//      printf("***** start i2c lcd test program *****\n");

// I2CポートをRead/Write属性でオープン。
    if ((lpt = open(i2cFileName, O_RDWR)) < 0)
    {
        printf("Faild to open i2c port\n");
        exit(1);
    }

// 通信先アドレスの設定。
    if (ioctl(lpt, I2C_SLAVE, LpsAddress) < 0)
    {
        printf("Unable to get bus access to talk to slave\n");
        exit(1);
    }
    if (I2C_read(WHO_AM_I,lpt) != (0xbb))
    {
        printf("Unable find LPS331:0F:%2.2x\n",I2C_read(WHO_AM_I,lpt));
        exit(1);
    }

    time(&timer);
    t_st = localtime(&timer);
    printf("%d/%02d/%02d %02d:%02d:%02d , ",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec);
    I2C_write(CTRL_REG1,0x90,lpt);      // output retio 12.5/12.5Hz
    usleep(100000);

    press = ( (I2C_read(PRESS_H,lpt) << 16) | (I2C_read(PRESS_M,lpt) << 8) | I2C_read(PRESS_L,lpt) );
    press_d = press / 4096.0 ;

    temp = ( (I2C_read(TEMP_H,lpt) << 8) | I2C_read(TEMP_L,lpt) );
    temp_d = 42.5 + (temp / 480.0);

    printf("%4.4f , ",press_d);
    printf("%3.3f\n",temp_d);

    I2C_write(CTRL_REG1,0x00,lpt);

    return 0;
}

void I2C_write(unsigned char rs, unsigned char data, int fd)
{
    unsigned char buf[2];

    buf[0] = rs;
    buf[1] = data;
    if (write(fd, buf, 2) != 2)
    {
        printf("Error writeing to i2c slave1\n");
    }
}

unsigned char I2C_read(unsigned char rs, int fd)
{
    unsigned char buf[2];

    buf[0] = rs;
    if (write(fd, buf, 1) != 1)
    {
        printf("Error writeing to i2c slave1\n");
    }
    if (read(fd, buf, 1) != 1)
    {
        printf("Error reading to i2c slave1\n");
    }
    return buf[0];
}
    #include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#define LPS_ADDRESS (0x5c)
#define WHO_AM_I (0x0f)
#define CTRL_REG1 (0x20)
#define STATUS_REG (0x27)
#define PRESS_L (0x28)
#define PRESS_M (0x29)
#define PRESS_H (0x2a)
#define TEMP_L (0x2b)
#define TEMP_H (0x2c)

// 関数プロトタイプ宣言。
void I2C_write(unsigned char rs, unsigned char data, int fd);
unsigned char I2C_read(unsigned char rs, int fd);

int main(void)
{
    int lpt;
    char    *i2cFileName = "/dev/i2c-1";
    int LpsAddress = LPS_ADDRESS;
    long int    press;
    short int   temp;
    float   press_d,temp_d;
    time_t  timer;
    struct  tm *t_st;

//      printf("***** start i2c lcd test program *****\n");

// I2CポートをRead/Write属性でオープン。
    if ((lpt = open(i2cFileName, O_RDWR)) < 0)
    {
        printf("Faild to open i2c port\n");
        exit(1);
    }

// 通信先アドレスの設定。
    if (ioctl(lpt, I2C_SLAVE, LpsAddress) < 0)
    {
        printf("Unable to get bus access to talk to slave\n");
        exit(1);
    }
    if (I2C_read(WHO_AM_I,lpt) != (0xbb))
    {
        printf("Unable find LPS331:0F:%2.2x\n",I2C_read(WHO_AM_I,lpt));
        exit(1);
    }

    time(&timer);
    t_st = localtime(&timer);
    printf("%d/%02d/%02d %02d:%02d:%02d , ",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec);
    I2C_write(CTRL_REG1,0x90,lpt);      // output retio 12.5/12.5Hz
    usleep(100000);

    press = ( (I2C_read(PRESS_H,lpt) << 16) | (I2C_read(PRESS_M,lpt) << 8) | I2C_read(PRESS_L,lpt) );
    press_d = press / 4096.0 ;

    temp = ( (I2C_read(TEMP_H,lpt) << 8) | I2C_read(TEMP_L,lpt) );
    temp_d = 42.5 + (temp / 480.0);

    printf("%4.4f , ",press_d);
    printf("%3.3f\n",temp_d);

    I2C_write(CTRL_REG1,0x00,lpt);

    return 0;
}

void I2C_write(unsigned char rs, unsigned char data, int fd)
{
    unsigned char buf[2];

    buf[0] = rs;
    buf[1] = data;
    if (write(fd, buf, 2) != 2)
    {
        printf("Error writeing to i2c slave1\n");
    }
}

unsigned char I2C_read(unsigned char rs, int fd)
{
    unsigned char buf[2];

    buf[0] = rs;
    if (write(fd, buf, 1) != 1)
    {
        printf("Error writeing to i2c slave1\n");
    }
    if (read(fd, buf, 1) != 1)
    {
        printf("Error reading to i2c slave1\n");
    }
    return buf[0];
}

C言語のサンプルプログラムを入力。Windows PC側のTera Termでは、Alt+Vキーでクリップボードに入っている文字列をペーストできるので、Raspberry Pi側のテキストエディタ「nano」で入力・保存する方法もある

Raspberry Piでサンプルプログラムを実行する

このサンプルプログラムを、Raspberry Piで動かしてみよう。本連載の第2回で実行したのはスクリプトプログラムだったので、実行属性を付ければ動作したが、今回はコンパイルという作業が必要だ。

Raspbian(Raspberry PiのOS)には「gcc」というcコンパイラが入っているので、「gcc lps_get.c」と入力、実行してコンパイル。エラーがなければ、「a.out」という名前の実行ファイルができあがる。ここで「mv a.out lps_get」とリネームするか、コンパイル時に「gcc lps_get.c -o lps_get」とオプション付きでコンパイルすればよいだろう。

実行は、出力されたファイルのファイル名(またはリネーム後のファイル名)をそのまま入力して、Enterキーを押せばよい。ただし、「sudo」を付けて実行しないとエラーが出るので注意したい。

gccでコンパイルし、出力されたプログラムをリネームして実行したところ。「ls」コマンドは、作業中のディレクトリ(カレントディレクトリ)内のファイルとディレクトリを一覧表示するものだ。プログラムの実行結果として、実行日時、気圧、温度が表示された