#include <Wire.h>
#include <Adafruit_AHTX0.h>
#define pwmPin A0
#define get_timing (900)
#define dsp_timing (3000)
#define bkout_segment (10)
Adafruit_AHTX0 aht;
int BH1750_addr = 0x23; // @ADD = L i2cデバイス(BH7150)のAddresse
byte buff[2];
/* 微気象変数 */
signed int dsp_temp,dsp_hum; //気温、相対湿度
float valf = 0; //日射
float ppfd; //ppfd換算
int dsp_ppfd; //表示
signed int soil_moisture = 0; //土壌水分
signed long Dsp_Co2=0; //co2
unsigned int tmr_get_soil_moisture = 0; //土壌水分センサー取得フラグ
unsigned int tmr_get_radiation = 0; //日射センサー取得フラグ
unsigned int tmr_get_temp_hum = 0; //日射センサー取得フラグ
int prevVal = LOW;
long th, tl, h, l, ppm;
char tstr[20] ;
/* 7セグ */
unsigned int scan_no;
signed int pv_dsp = 0; //表示する値 -99.9~999.9
int pinA = 2;
int pinB = 3;
int pinC = 4;
int pinD = 5;
int pinE = 11;
int pinF = 12;
int pinG = 13;
int pinDP = 6;
int D1 = 7;
int D2 = 9;
int D3 = 8;
int D4 = 10;
unsigned int disp_1000;
unsigned int disp_100;
unsigned int disp_10;
unsigned int disp_1;
unsigned int count_1000ms;
/* 表示 */
unsigned int flg_disp; //表示するもの
unsigned int count_disp; //表示カウンタ
void setup() {
/* 割り込み */
TCB2.CCMP = 250; // TOP値の設定(割り込み周期 = カウント周期(4us) * TOP値, TOP値 = 割り込み周期 / 4us)
TCB2.CTRLB = (TCB2_CTRLB & 0b10101000) + 0b00000000; //タイマーのGPIO出力ON、クロックソースを設定
TCB2.CTRLA = (TCB2_CTRLA & 0b11111000) + 0b00000101; //カウント周期を設定してカウントスタート
TCB2.INTCTRL = 1; //割り込み許可
/* CO2 */
pinMode(pwmPin, INPUT);
/* 照度BH1750 */
Wire.begin();
Wire.beginTransmission(BH1750_addr); // 指定したアドレスのI2Cスレーブに対して送信処理開始
Wire.write(0x07); // Reset Data register
Wire.endTransmission(); // I2Cデバイスとの送信を終了
Wire.beginTransmission(BH1750_addr); // 指定したアドレスのI2Cスレーブに対して送信処理開始
Wire.write(0x10); // H-resolution mode設定
Wire.endTransmission(); // I2Cデバイスとの送信を終了
delay(200); // update 120ms以上@DataSheet
/* 温湿度AHT21 */
aht.begin(); // AHT21の初期化
/* 7セグ */
pinMode(pinA, OUTPUT);
pinMode(pinB, OUTPUT);
pinMode(pinC, OUTPUT);
pinMode(pinD, OUTPUT);
pinMode(pinE, OUTPUT);
pinMode(pinF, OUTPUT);
pinMode(pinG, OUTPUT);
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
pinMode(D4, OUTPUT);
/* シリアル通信 */
Serial.begin(9600);
}
/************************************************************************/
/* 7セグ (LOW = 光る) */
/************************************************************************/
//どのセグを光らせるか
void digit1(){
digitalWrite(D1, HIGH);
digitalWrite(D2, LOW);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
}
void digit2(){
digitalWrite(D1, LOW);
digitalWrite(D2, HIGH);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
}
void digit3(){
digitalWrite(D1, LOW);
digitalWrite(D2, LOW);
digitalWrite(D3, HIGH);
digitalWrite(D4, LOW);
}
void digit4(){
digitalWrite(D1, LOW);
digitalWrite(D2, LOW);
digitalWrite(D3, LOW);
digitalWrite(D4, HIGH);
}
void all4Digits(){
digitalWrite(D1, HIGH);
digitalWrite(D2, HIGH);
digitalWrite(D3, HIGH);
digitalWrite(D4, HIGH);
}
//何を光らせるか
void bk_out(){
digitalWrite(pinA, HIGH);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
}
void zero(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, HIGH);
}
void one(){
digitalWrite(pinA, HIGH);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
}
void two(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, LOW);
digitalWrite(pinC, HIGH);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, LOW);
}
void three(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, LOW);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, LOW);
}
void four(){
digitalWrite(pinA, HIGH);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
}
void five(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, LOW);
digitalWrite(pinD, LOW);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
}
void six(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, HIGH);
digitalWrite(pinC, LOW);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
}
void seven(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, HIGH);
digitalWrite(pinG, HIGH);
}
void eight(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, LOW);
digitalWrite(pinE, LOW);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
}
void nine(){
digitalWrite(pinA, LOW);
digitalWrite(pinB, LOW);
digitalWrite(pinC, LOW);
digitalWrite(pinD, HIGH);
digitalWrite(pinE, HIGH);
digitalWrite(pinF, LOW);
digitalWrite(pinG, LOW);
}
void ( * const SegmentArray[])(void) = {
zero,
one,
two,
three,
four,
five,
six,
seven,
eight,
nine,
bk_out,
};
/********************************************************/
/* CO2(MH-Z19C) */
/********************************************************/
void co2(void)
{
long tt = millis();
//電圧を取得
int myVal = digitalRead(pwmPin);
//パルス長の計測
if (myVal == HIGH) {
if (myVal != prevVal) {
h = tt;
tl = h - l;
prevVal = myVal;
}
}
else
{
if (myVal != prevVal)
{
l = tt;
th = l - h;
prevVal = myVal;
ppm = 5000 * (th - 2) / (th + tl - 4);
Serial.println("PPM = " + String(ppm));
Dsp_Co2 = ppm;
}
}
}
/********************************************************/
/* Soil moisture */
/********************************************************/
void Soil_Moisture(void)
{
Serial.print("Moisture Sensor Value:");
noInterrupts(); //割り込み禁止
soil_moisture = analogRead(A0);
interrupts(); //割り込み許可
Serial.println(soil_moisture);
}
/********************************************************/
/* Radiation 日射 */
/********************************************************/
void get_radiation(void){
int i = 0;
Wire.beginTransmission(BH1750_addr); // 指定したアドレスのI2Cスレーブに対して送信処理開始
Wire.requestFrom(BH1750_addr, 2); // I2Cデバイスのアドレスおよびデータ量を指定
noInterrupts(); //割り込み禁止
//2byte読み取り
while(Wire.available()){
buff[i] = Wire.read();
i++;
}
interrupts(); //割り込み許可
Wire.endTransmission(); // I2Cデバイスとの送信を終了
valf=((buff[0]<<8)|buff[1]); // buff[0]を8bitシフトしてbuff[1]とor取り2byteデータに変換
valf = valf/1.2; // Measurement Accuracy 1.2倍@Typ.(@DataSheet)
if(valf<0){ Serial.print("> 65535:Overflow"); // Overflowを表示(測定範囲 1 ~ 65535 lx @DataSheet)
}
else{
Serial.print((int)valf,DEC); // 整数および10進表示←分解能は1@DataSheet
}
Serial.println(" lx");
ppfd = valf / 54; //lux → ppfd
dsp_ppfd = (int)ppfd;
}
/********************************************************/
/* 温湿度 */
/********************************************************/
void get_temp_hum(void)
{
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp); // AHT21から湿度と温度の取得
Serial.print("温度:");
Serial.println((int)temp.temperature);
dsp_temp = (int)temp.temperature;
Serial.print("相対湿度:");
Serial.println((int)humidity.relative_humidity);
dsp_hum = (int)humidity.relative_humidity;
}
/************************************************************************/
/* 表示 */
/************************************************************************/
void display()
{
switch(flg_disp)
{
case (0):
pv_dsp = dsp_temp; //気温
break;
case (1):
pv_dsp = dsp_hum; //相対湿度
break;
case (2):
pv_dsp = dsp_ppfd; //日射(lx)
break;
case (3):
pv_dsp = soil_moisture; //土壌水分
break;
case (4):
pv_dsp = Dsp_Co2; //Co2
default:
break;
}
if(pv_dsp < 1000)
{
disp_1000 = bkout_segment;
}
else
{
disp_1000 = pv_dsp / 1000;
}
if(pv_dsp < 100)
{
disp_100 = bkout_segment;
}
else
{
disp_100 = pv_dsp % 1000 /100;
}
if(pv_dsp < 10)
{
disp_10 = bkout_segment;
}
else
{
disp_10 = pv_dsp % 100 / 10;
}
disp_1 = pv_dsp % 10;
}
/********************************************************/
/* 割り込み (1ms) */
/********************************************************/
ISR(TCB2_INT_vect) {
TCB2.INTFLAGS = 1; //割り込みフラグのクリア
/* 表示 */
if(count_disp<dsp_timing)
{
count_disp++;
}
else
{
count_disp = 0;
if(flg_disp < 4)
{
flg_disp++;
}
else
{
flg_disp = 0;
}
}
if(tmr_get_soil_moisture < get_timing)
{
tmr_get_soil_moisture++;
}
if(tmr_get_radiation < get_timing)
{
tmr_get_radiation++;
}
if(tmr_get_temp_hum < get_timing)
{
tmr_get_temp_hum++;
}
if(scan_no < 4)
{
scan_no++;
}
else
{
scan_no = 0;
}
/* 7セグ */
count_1000ms++;
/*ブラックアウト*/
bk_out();
switch (scan_no)
{
/* 1000桁 */
case 0:
digit1();
SegmentArray[disp_1000]();
break;
/* 100桁 */
case 1:
digit2();
SegmentArray[disp_100]();
break;
/* 10桁 */
case 2:
digit3();
SegmentArray[disp_10]();
break;
/* 1桁 */
case 3:
digit4();
SegmentArray[disp_1]();
break;
default:
break;
}
}
/********************************************************/
/* メインループ */
/********************************************************/
void loop() {
if (tmr_get_soil_moisture > 10) //1秒に1回
{
Soil_Moisture();
tmr_get_soil_moisture = 0;
}
if (tmr_get_radiation > 10) //1秒に1回
{
get_radiation();
tmr_get_radiation = 0;
}
if (tmr_get_temp_hum > 10) //1秒に1回
{
get_temp_hum();
tmr_get_temp_hum = 0;
}
co2();
display();
}