---
# System prepended metadata

title: 物聯網

---

# 物聯網

## 報告

1. ==**Description**==
    為了隔天能夠有精神的上課，前一天睡得早
    然而上課時還是感覺昏昏欲睡，甚至有點頭暈
    導致我們沒辦法好好吸收上課內容
    寶貴的知識就這樣被浪費掉了！

    根據國內環保署所發布之室內空氣品質管理法
    在室內連續測量8小時所獲得的平均值不得高於1000ppm

    當二氧化碳的濃度達到1000 ppm時
    人們會感到沉悶，注意力開始不集中，心悸

    如果在不透氣的臥室里二氧化碳達到1000 PPM
    而即使我們連續睡覺8個小時
    早上起床時我們仍會感覺沒有休息好，不想起床

    如果辦公室的空氣中CO2含量達到1000PPM
    員工們的工作效率會下降
    ![](https://i.imgur.com/v8gbPvc.png)


    此專案將在教室置入二氧化碳濃度感測器
    監測學生上課時教室的二氧化碳濃度
    透過sensor連接arduino 再將資料上傳至OM2M

    雖然是內空氣品質管理法是以1000ppm為主
    但我們要超前部署，在濃度到達1000ppm前就先控制

    當二氧化碳濃度高於850ppm，就自動將冷氣機打開
    而低於650ppm時，就自動將冷氣機關閉

    

2. ==**Related work**==
    現在市面上的應用大多是直接將二氧化碳感測器嵌入冷氣機裡
    若感測到室內二氧化碳濃度過高，才引進外部空氣
    如此一來可以達到節能的效果
    ![](https://i.imgur.com/P2LAyk1.png)

    此專案與市面上冷氣機的差別為
    一開始不需要開冷氣，直到二氧化碳濃度過高再將冷氣機開啟
    就像老師上課說的，學校其實開銷很大的一部份便是用電
    常常沒有人在教室，但冷氣機卻是開著的
    而我們的設計可以解決這種困擾
    也不需要擔心無人卻自動開啟冷氣
    因為在無人的室內二氧化碳濃度值約在500~700ppm
    而我們設定開啟的標準為850ppm

    與此同時，若我們又使用這種冷氣機，便可以更好的達到節能節電


3. ==**Actors**==
    * **M2M Device**
        使用設備為二氧化碳感測器(型號:MG811)，它可以測量所在環境的二氧化碳濃度。
        
    * **M2M Area Network**
        連接M2M Device 和 M2M Service Platform之間的網路
        
    * **M2M Gateway**
        可以從二氧化碳感測器設備接收濃度數據並將資料傳送至OM2M
    
    
    * **M2M Service Platform**
        管理服務器所在的平台，Application Server使用該平台與M2M Gateway進行通訊
    
    * **Application Server**
       用來服務二氧化碳濃度感測器的Server

4. ==**Pre-conditions（前提）**==
    二氧化碳感測器能夠確實偵測到濃度
    並且將偵測到的資料傳送給arduino
    同時arduino要可以開關冷氣機
    
    `原本的： 健康傳感器設備能夠建立與移動設備的連接，以便將健康數據發送到M2M服務平台或應用服務器。這是第一次將移動設備與健康傳感器設備相關聯`

5. ==**Triggers**==

    系統
     當使用者購買產品部署於室內環境中並嘗試與arduino連線
    
    冷氣
    1. 當二氧化碳濃度>850，arduino開啟冷氣機
    2. 當二氧化碳濃度<650，arduino關閉冷氣機

    
6. ==**Normal flow（正常流程）**==
    
    step1. 二氧化碳濃度感測器與arduino連線
    
    step2. 二氧化碳濃度感測器每分鐘更新一次檢測資料
    並將資料傳送至arduino
    
        
    step3. 用arduino將資料傳送至OM2M做紀錄

    step4. 根據檢測結果的數值用arduino做出對應的動作
    

7. ==**Alternative flow(替代流程)**==
    
    無
    原因：
    1.一次只會有一個感測器
    2.每次都需要重新連線[](https://)
    3.除非手動結束否則不會停止




8. High level Illustration

## Arduino的程式碼
``` c
#include <SoftwareSerial.h> //libaray of I2C
#include <SimpleDHT.h>

//正常情況下的值(接5V)
//輸出電壓　1.87~2.多
//MG_PIN 600~700


#define DH11_pin 4
#define MG_PIN A0     //定義　MG811　的　Aout　是插在哪個腳位

#define BOOL_PIN 2

#define DC_GAIN 8.5   //輸出電壓/輸入電壓 = DC_GAIN
                      //也就是放大率（電壓增益）
                      //https://www.rohm.com.tw/electronics-basics/opamps/op_what3


//因為註解跟MG_READ有點衝突，所以先以註解的內容為主
#define READ_SAMPLE_INTERVAL 50   //define how many samples you are going to take in normal operation
#define READ_SAMPLE_TIMES 5       //define the time interval(in milisecond) between each samples in
                                  //normal operation


//當CO2濃度開始大於400ppm之後，其EMF（介於100-200mv）便開始與其濃度呈現線性的比例關係
//這裡寫得還不錯～～　雖然我不是很懂電動式是甚麼
//https://chtseng.wordpress.com/2016/03/04/%E7%92%B0%E6%8E%A7%E7%B3%BB%E7%B5%B1v2-%E6%84%9F%E6%B8%AC%E5%99%A8%E6%A0%A1%E6%AD%A3%EF%BC%88%E4%BA%94%EF%BC%89/

#define ZERO_POINT_VOLTAGE 0.220
//當CO2濃度為400ppm時　輸入電壓的值
//因為測出來的是放大完的電壓（輸出電壓/輸入電壓 = DC_GAIN）
//所以測出的電壓/DC_GAIN = ZERO_POINT_VOLTAGE
//這個是我們自己測完以後要調的
#define         REACTION_VOLTGAE             (0.030) //define the voltage drop of the sensor when move the sensor from air into 1000ppm CO2



SimpleDHT11 dht11;
//int time = millis(); //millisceond
float CO2Curve[3]  =  {2.602, ZERO_POINT_VOLTAGE, (REACTION_VOLTGAE/(2.602-3))};
        //官網給的數據圖的某的點　先叫他point1
        //雖然數據圖的線是曲線，但算出來的直線會跟曲線很接近
        //CO2Curve[0]: point1的x座標
        //CO2Curve[1]: point1的y座標（這裡要放你真正算出來的輸入電壓）
        //CO2Curve[2]: 取兩個點，算出來的斜率，slope = ( reaction voltage ) / (log400 –log1000)
        //point1: (log400, 0.324)，log400 = 2.602
        //point2: (log1000, ?)
        //原本註解寫point2: (lg4000, 0.280)，但這樣的話跟上面程式碼對不起來，應該是註解寫錯

        
        //官網的數據圖：http://image.dfrobot.com/image/data/SEN0159/CO2b%20MG811%20datasheet.pdf：　
        //這裡面有推倒過程，只是取的點point2跟官方給的不太一樣
        //http://a-chien.blogspot.com/2016/03/arduino-mg811.html

void setup()
{
    Serial.begin(9600);   //UART setup, baudrate = 9600bps
    //類似初始化
    
    pinMode(DH11_pin, OUTPUT);
    //設定DH11要使用的腳位
    
    pinMode(BOOL_PIN, INPUT);        //set pin to input
    digitalWrite(BOOL_PIN, HIGH);    //turn on pullup resistors
    
    Serial.print("MG-811 Demostration\n");
}

void loop()
{

  ///// DH11 /////
  byte temperature = 0;
  byte humidity = 0;
  if (dht11.read(DH11_pin, &temperature, &humidity, NULL)) {
    //Serial.println("Read DHT11 failed.");
    return;
  }
  Serial.print("DH11: \n");
  Serial.print("溫度: ");
  Serial.print(temperature);
  Serial.print(" 度C\n");
  Serial.print("濕度: ");
  Serial.print(humidity);
  Serial.println(" %\n"); 

  ///// CO2 /////
  int percentage;
  float volts;

//  Serial.print("A0的值：　");
//  Serial.print(analogRead(MG_PIN));
//  Serial.print("\n");
  volts = MGRead(MG_PIN);
  //回推電壓的值
  Serial.print( "轉回電壓: " );
  Serial.print(volts);
  Serial.print( "V\n" );

  
  percentage = MGGetPercentage(volts, CO2Curve);
  //回傳二氧化碳的濃度（單位是ppm）
  Serial.print("CO2:");
  if (percentage == -1) {
      Serial.print( "<400" );
  } else {
      Serial.print(percentage);
  }

  Serial.print( "ppm" );
  Serial.print("\n");

  if (digitalRead(BOOL_PIN) ){
      Serial.print( "=====BOOL is HIGH======" );
  } else {
      Serial.print( "=====BOOL is LOW======" );
  }
  Serial.print("\n\n\n");
  delay(500);
}


float MGRead(int mg_pin)
{
    int i;
    float v=0;

    for (i=0;i<READ_SAMPLE_INTERVAL;i++) {
        v += analogRead(mg_pin); //170+
//        Serial.print("A0的值：　");
//        Serial.print(analogRead(mg_pin));
//        Serial.print("\n");
        //analogRead
        //將5V的電壓 分成1024等分
        //也就是將0~5V的電壓 轉換成0~1023
        //0V -> 0
        //5V -> 1023
        
        delay(READ_SAMPLE_TIMES);
    }
    
    v = (v/READ_SAMPLE_INTERVAL) *5/1023 ;
    // 我們讀出來的值大約是170多，假設是175
    // 5:1023 = x:175
    // x = 175*5 / 1023
    // 轉換成公式就是　x = 讀出來的平均值*5 / 1023;
    
    return v;
}


int  MGGetPercentage(float volts, float *pcurve)
{
   if ((volts/DC_GAIN )>=ZERO_POINT_VOLTAGE) { 
      //vlots: 測到的電壓（輸出電壓）
      //DC_GAIN: 放大率
      //volts/DC_GAIN: 輸入電壓
      //ZERO_POINT_VOLTAGE: 400ppm時，輸入的電壓
      
      return -1;
      //因為電壓跟濃度成反比
      //假設400ppm時，輸入電壓為x
      //若<400ppm，輸入電壓必須>x
      //所以return -1，代表濃度<400ppm
   } else {
      return pow(10, ((volts/DC_GAIN)-pcurve[1])/pcurve[2]+pcurve[0]);
      //否則就根據公式　算出二氧化碳的濃度　並回傳
   }
}
```
MG811
![](https://i.imgur.com/SViswJ8.png)
![](https://i.imgur.com/7xJq8Nr.png)


正常來講
![](https://i.imgur.com/j0Pr3SA.png)

空無一人的空間
![](https://i.imgur.com/KA3Q3G2.jpg)

充滿二氧化碳的空氣
![](https://i.imgur.com/EMqkcHu.jpg)
