温度で自動にサーキュレータを制御

更新日2017-07-30 (日) 16:40:29

wiringPi

wiringPiとは、Raspbery PiのGPIOをC言語で操作できるライブラリ

Installの確認

$ gpio -v
gpio version: 2.44
Copyright (c) 2012-2017 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Pi 2, Revision: 01, Memory: 1024MB, Maker: Sony
  * Device tree is enabled.
  *--> Raspberry Pi 2 Model B Rev 1.1
  * This Raspberry Pi supports user-level GPIO access.

Installされていないとき

$ git clone git://git.drogon.net/wiringPi
$ cd wiringPi
$ cd ./build
  • 確認
$ gpio -v

GPIO操作

GPIO 21を出力に設定しON/OFF

  • 出力に設定
    $ gpio -g mode 21 out
  • ON(3.3V)
    $ gpio -g write 21 1
  • OFF(0V)
    $ gpio -g write 21 0
  • 入力に設定
    $ gpio -g write 21 in
  • GPIOの状態表示
    $ gpio readall
     +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
     | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
     +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
     |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
     |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
     |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
     |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
     |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
     |  17 |   0 | GPIO. 0 |   IN | 1 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
     |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
     |  22 |   3 | GPIO. 3 |  OUT | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
     |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
     |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
     |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
     |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
     |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
     |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
     |   5 |  21 | GPIO.21 |  OUT | 1 | 29 || 30 |   |      | 0v      |     |     |
     |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
     |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
     |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
     |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
     |     |     |      0v |      |   | 39 || 40 | 1 | OUT  | GPIO.29 | 29  | 21  |
     +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
     | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
     +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
                                      Physical:物理PIN番号                  BCM:GPIOの番号

ソリッド・ステート・リレー(SSR)でサーキュレータを制御

  • 部品(AE-SH-SSR)
  • 仕様書

ソフトをC言語で作成

  • サーキュレータON:32
  • サーキュレータOFF:31度
  • 10秒ごとに評価(確認)

SSR1.jpg

SSR2.jpg

SSR3.jpg

                                  -----
                                  |   | USB電源
                                  -+-+-   
                                +5V| |GND
---------------                    | | -------------------
| AE-SH-SSR   |  +5V       USB +5V | | |  Raspberry Pi 2 |
|             +--------------------+ | |                 |
|             | GND      PIN34(GND)  | |                 |
|             +----------------------+-+                 |
|             | 信号     PIN40(GPIO 21)|                 |
|             +------------------------+                 |
|             |                        |                 |
|             |                        -------------------
|--+------+---|
   |      |       ----------------
   |      --------|ヒューズ 1.5A |-----+------+
   |              ----------------     |      |
   |                                   |      |
   |                                   ○    ---
  |                                      /  | +----
   |                               SW    /   | |  100V~コンセントへ
   |                                   ○    | +----
   |                                   |     | |
   |                                   |     ---
   |              ------------         |      |
   ---------------|  ||   || |---------+------+
                  ------------
                      |    |
                      |    |
                     ---------
                     |       |
                     |       |サーキュレータ
                     |       |
                     ---------
  • SWをONすると制御とは無関係にサーキュレータをONすることができる。

ソース

  • ssr_fan.c
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <stdio.h>
#include <stdlib.h>    // atof(charからdoubleに変換時必要

// * ============ SSR Setting=========
#define PIN_SSR  21

#define GPIO_ON  1
#define GPIO_OFF 0 

#define FAN_ON_TEMP 32
#define FAN_OFF_TEMP 31

// * ============ BME280 Setting=========

#define BME280_ADDRESS 0x76
#define TEMP_OFFSET -3

unsigned long int hum_raw,temp_raw,pres_raw;
signed long int t_fine;

unsigned int dig_T1;
int dig_T2;
int dig_T3;
unsigned int dig_P1;
int dig_P2;
int dig_P3;
int dig_P4;
int dig_P5;
int dig_P6;
int dig_P7;
int dig_P8;
int dig_P9;
char  dig_H1;
int dig_H2;
char  dig_H3;
int dig_H4;
int dig_H5;
char  dig_H6;

static int dev;

// *=============================

#define INTERVAL_TIME 10  // Seconds

static int init_dev(void)
{
  if ((dev = wiringPiI2CSetup(BME280_ADDRESS)) == -1)
  {
     return 1 ;
  }
    return 0;
}
void getRegisters(char address, int numData, unsigned char *data) {
  char adr;
  int i;

  adr = address;
  for (i = 0; i < numData; i++) {
    *data = wiringPiI2CReadReg8 (dev, adr);
//      printf("adr:%x data:%x\n",adr, *data);
    adr ++;
    data ++;
  }
}

void readTrim()
{
   unsigned char data[32],i=0;

    getRegisters(0x88, 24, &data[0]);
    i+=24;

    getRegisters(0xA1, 1, &data[i]);
    i+=1;

    getRegisters(0xE1, 7, &data[i]);
    i+=7;

    dig_T1 = (data[1] << 8) | data[0];
    dig_T2 = (data[3] << 8) | data[2];
    dig_T3 = (data[5] << 8) | data[4];
    dig_P1 = (data[7] << 8) | data[6];
    dig_P2 = (data[9] << 8) | data[8];
    dig_P3 = (data[11]<< 8) | data[10];
    dig_P4 = (data[13]<< 8) | data[12];
    dig_P5 = (data[15]<< 8) | data[14];
    dig_P6 = (data[17]<< 8) | data[16];
    dig_P7 = (data[19]<< 8) | data[18];
    dig_P8 = (data[21]<< 8) | data[20];
    dig_P9 = (data[23]<< 8) | data[22];
    dig_H1 = data[24];
    dig_H2 = (data[26]<< 8) | data[25];
    dig_H3 = data[27];
    dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
    dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
    dig_H6 = data[31];
}

void writeReg(unsigned char address, unsigned char data) {
  char adr;
  int i;

  adr = address;
  wiringPiI2CWriteReg8 (dev, adr, data);
//  printf("adr:%x data:%x\n",adr, data);
}

void readData()
{
    int i = 0;
    unsigned char data[8];

    getRegisters(0xF7, 8, &data[0]);

    temp_raw = data[3];
    temp_raw = (temp_raw<<8) | data[4];
    temp_raw = (temp_raw<<4) | (data[5] >> 4);

}


signed long int calibration_T(signed long int adc_T)
{

    signed long int var1, var2, T;
    var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
    var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;

    t_fine = var1 + var2;
    T = (t_fine * 5 + 128) >> 8;
    return T;
}


int main ( int argc, char **argv ) {

/* BME280 Initialize */

    unsigned char osrs_t = 1;             //Temperature oversampling x 1
    unsigned char osrs_p = 1;             //Pressure oversampling x 1
    unsigned char osrs_h = 1;             //Humidity oversampling x 1
    unsigned char mode = 3;               //Normal mode
    unsigned char t_sb = 5;               //Tstandby 1000ms
    unsigned char filter = 0;             //Filter off
    unsigned char spi3w_en = 0;           //3-wire SPI Disable

    unsigned char ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
    unsigned char config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en;
    unsigned char ctrl_hum_reg  = osrs_h;


    double temp_act = 0.0;
    double on_temp, off_temp;
    signed long int temp_cal;
    unsigned long int press_cal,hum_cal;
    int i;
    
    if(argc != 3){
        printf("ssr_fan Use: ssr_fan (ON-TEMP) (OFF-TEMP) \n");
        return 1;
    }
    on_temp = atof(argv[1]);
    off_temp = atof(argv[2]);
    if (off_temp >= on_temp){
        printf("ssr_fan ERROR \n");
        printf("The temperature of ON of the fan has to be higher than temperature of OFF. \n");
        printf("ON: %lf OFF: %lf \n", on_temp, off_temp);
        return 1;
    }

    if(init_dev()==1)  return;

    writeReg(0xF2,ctrl_hum_reg);
    writeReg(0xF4,ctrl_meas_reg);
    writeReg(0xF5,config_reg);
    readTrim();                    //

//========================================
  int status_sw;
  int status_sw_temp;

  /* Initialize wiringPi */
  if( wiringPiSetupGpio() == -1 ) return 1;

  /* Initialize GPIO */
  pinMode( PIN_SSR, OUTPUT );



  /* toggle LED */

  status_sw_temp = GPIO_OFF;

  while ( 1 ) {
    temp_act = 0;
    for(i = 0 ; i < 3 ; i++)
    {
        delay(1000);
        readData();
        temp_cal = calibration_T(temp_raw);
        temp_act = (double)temp_cal / 100.0 + temp_act;
    }
    temp_act = temp_act/3 + TEMP_OFFSET;

    printf("TEMP :%f  DegC Status:%d \n",temp_act,status_sw_temp);
    if (temp_act >= on_temp && status_sw_temp == GPIO_OFF){
        status_sw_temp = fan_on( PIN_SSR);
    }
    if (temp_act <= off_temp && status_sw_temp == GPIO_ON){
        status_sw_temp = fan_off( PIN_SSR);
    }

    sleep( INTERVAL_TIME );
  }

  return 0;
}

/* ================================
 * fan_on/fanoff
 *
 *   Fan On or Off.
 *
 *   + Augment
 *       pin_id ... Number of GPIO connected to SSR
 *   + Return
 *       Fan status
 * ================================
 */

int fan_on(int pin_id ) {
  int result;

    digitalWrite( pin_id, GPIO_ON );
    result = GPIO_ON;
    return result;

}

int fan_off(int pin_id ) {
  int result;

    digitalWrite( pin_id, GPIO_OFF );
    result = GPIO_OFF;
    return result;

}

//* ================================
  • コンパイル
    gcc -o ssr_fan ssr_fan.c -lwiringPi
  • 起動
    ./ssr_fan 30.0 29.0
  • 30.0でFanがON
  • 29.0でFanがOFF

参考


添付ファイル: fileSSR1.jpg 48件 [詳細] fileSSR3.jpg 53件 [詳細] fileSSR2.jpg 55件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-07-30 (日) 16:40:29 (330d)