2018年5月29日 星期二

arduino心跳模組專案


暨上次挑戰完雙溫濕度計感測模組以後,最近終於下定決心要去做心跳模組了。
雖然之前上雙溫濕度計感測模組覺得沒有很成功,因為學生在裝設arduino就要花太多時間了,何況是需要串聯、插麵包板時候。
已經覺得降低很多難度與門檻了,看來還是遠遠不夠,造成計畫持續延宕。
而且每讓教學現場下降一門檻,我自己的時間成本就會拉好高好高,不斷的反思這樣是否可以真的實現在教室內呢?還是只能在延伸課程中?

  • 之前在教師研習時也覺得arduino光是插線就是一件很困難的事情,老師覺得困難,學生操作時當然也是一樣的。

    最近因為計畫死線關係,重還是必須完成arduino設計,讓下一年的課程可能可以用到這個工具,這次寫完這個專案其實滿有成就感的。

    目標是做一個可以顯示心跳數值跟圖像化表現專案
    心跳越快下面的心臟數量越多,閃爍速度也越快。
    然後超過心跳120,會有火的圖形出現,140兩個火,160三個火,表示達到燃脂運動區間

    先說說這次拼湊了那些元件與概念
    1.PulseSensor基本介紹
    https://pulsesensor.com/pages/code-and-guide

    1.LCD畫圖方式,心型,跳動的心型
    https://www.youtube.com/watch?v=jaD0dJtovwc
    謝KK偷插電資訊課的畫圖程式
    http://163.22.72.1/html5/colour_by_numbers/html5_colour_by_numbers/colour_by_numbers.html

    2.迴圈與判斷式if,else if
    http://ming-shian.blogspot.tw/2013/09/arduino.html
    http://www.86duino.com/?p=593&lang=TW

    3.燃脂心跳區間
    http://www.dreye-health.com/SingularController?service=goCheck&path=feat


    認真參考過但是後來發現自己等級還不夠的資料

    1.Arduino Based Heartbeat Monitor
    http://www.circuitstoday.com/pulse-sensor-arduino
    https://circuitdigest.com/microcontroller-projects/heartbeat-monitor-project-using-arduino

    2.arduino數學函數
    http://yhhuang1966.blogspot.tw/2015/09/arduino_23.html

    3.millis()時間函數
    http://coopermaa2nd.blogspot.tw/2011/04/millis-button.html
    http://coopermaa2nd.blogspot.tw/2011/04/millis.html
    http://yhhuang1966.blogspot.tw/2015/09/arduino_9.html
    http://rainage.blogspot.tw/2016/02/arduino.html

    需要準備的東西
    1.下載程式庫pulsesensor playground
    2.開啟範例pulsesensor playground → Getting_BPM_to_Monitor
    3.把我的檔案倒進去就可以了
    --------------以下是程式碼部分--------------

    /*  Getting_BPM_to_Monitor prints the BPM to the Serial Monitor, using the least lines of code and PulseSensor Library.
     *  Tutorial Webpage: https://pulsesensor.com/pages/getting-advanced
     *
    --------Use This Sketch To------------------------------------------
    1) Displays user's live and changing BPM, Beats Per Minute, in Arduino's native Serial Monitor.
    2) Print: "♥  A HeartBeat Happened !" when a beat is detected, live.
    2) Learn about using a PulseSensor Library "Object".
    4) Blinks LED on PIN 13 with user's Heartbeat.
    --------------------------------------------------------------------*/

    #define USE_ARDUINO_INTERRUPTS true    // Set-up low-level interrupts for most acurate BPM math.
    #include <PulseSensorPlayground.h>     // Includes the PulseSensorPlayground Library. 
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    // 設定 LCD I2C 位址
    // Set the pins on the I2C chip used for LCD connections:
    // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol

    //LED_Fundino紅色板子用
    //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    //LED_MH黑色板子用
    LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


    //  Variables
    const int PulseWire = 0;       // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
    const int LED13 = 13;          // The on-board Arduino LED, close to PIN 13.
    int Threshold = 550;           // Determine which Signal to "count as a beat" and which to ignore.
                                   // Use the "Gettting Started Project" to fine-tune Threshold Value beyond default setting.
                                   // Otherwise leave the default "550" value.
    int z,a;

    PulseSensorPlayground pulseSensor;  // Creates an instance of the PulseSensorPlayground object called "pulseSensor"

    //建立心型
    byte heart_h[8] = {
      B00000,
      B00000,
      B01010,
      B10101,
      B10001,
      B01010,
      B00100,
      B00000
    };
    byte heart_f[8] = {
      B00000,
      B00000,
      B01010,
      B11111,
      B11111,
      B01110,
      B00100,
      B00000
    };
    //建立火型
    byte fire[8] = {
      B00100,
      B10100,
      B10100,
      B11100,
      B10101,
      B10011,
      B11001,
      B01110
    };
    void setup() { 

      Serial.begin(9600);          // For Serial Monitor

      // Configure the PulseSensor object, by assigning our variables to it.
      pulseSensor.analogInput(PulseWire); 
      pulseSensor.blinkOnPulse(LED13);       //auto-magically blink Arduino's LED with heartbeat.
      pulseSensor.setThreshold(Threshold); 

      // Double-check the "pulseSensor" object was created and "began" seeing a signal.
       if (pulseSensor.begin()) {
        Serial.println("We created a pulseSensor Object !");  //This prints one time at Arduino power-up,  or on Arduino reset.
      }
      // 初始化 LCD,一行 16 的字元,共 2 行,預設開啟背光
      lcd.begin(16, 2);

      //建立心型
      lcd.createChar (1, heart_h);  // load heart_h to memory 1
      lcd.createChar (2, heart_f);  // load heart_f to memory 2
      lcd.createChar (3, fire);    // load fire to memory 3
     
      pinMode(LED13,OUTPUT);    // pin that will blink to your heartbeat!

      // 閃爍兩次
      for (int i = 0; i < 1; i++) {
        lcd.backlight(); // 開啟背光
        delay(250);
        lcd.noBacklight(); // 關閉背光
        delay(250);
      }
      lcd.backlight();

      // 輸出初始化文字
      lcd.setCursor(0, 0); // 設定游標位置在第一行行首
      lcd.print("Hello, Maker!");
      delay(500);
      lcd.setCursor(0, 1); // 設定游標位置在第二行行首
      lcd.print("heartbeat");
      delay(1000);
      lcd.clear(); //顯示清除
    }



    void loop() {

     int myBPM = pulseSensor.getBeatsPerMinute();  // Calls function on our pulseSensor object that returns BPM as an "int".
                                              // "myBPM" hold this BPM value now.
     lcd.setCursor(0, 0); // 設定游標位置在第一行行首
     lcd.print("HeartBeat=");

     if (pulseSensor.sawStartOfBeat()) {            // Constantly test to see if "a beat happened".
      Serial.println("♥  A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened".
      Serial.print("BPM: ");                        // Print phrase "BPM: "
      Serial.println(myBPM);                        // Print the value inside of myBPM.
      lcd.print(" ");
      lcd.print(myBPM);
      lcd.print("      ");

      //心型跳動
      for(z=1;z<=2;z=z+1){
        lcd.setCursor(0,1);  // 設定游標位置在第二行行首

        if(myBPM<80){       //判別心跳介於哪個區間,if,else if判斷式
          lcd.print(char(z));
          lcd.print("                ");
          delay(20000/myBPM);  //不知道為什麼這樣跟心跳頻率滿接近的,是try error得到的結果
        }
        else if(myBPM>=80 && myBPM<100){
          lcd.print(char(z)); 
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print("              ");
          delay(20000/myBPM);
        }
        else if(myBPM>=100 && myBPM<120){
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print("                ");
          delay(20000/myBPM);
        }
        else if(myBPM>=120 && myBPM<140){
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print("        ");
          lcd.print(char(3));
          delay(20000/myBPM);
        }
        else if(myBPM>=140 && myBPM<160){
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print("     ");
          lcd.print(char(3));
          lcd.print(char(3));
          delay(20000/myBPM);
        }
        else if(myBPM>=160){
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print(char(z));
          lcd.print("   ");
          lcd.print(char(3));
          lcd.print(char(3));
          lcd.print(char(3));
          delay(20000/myBPM);
        }
      }
     }
     else{
      lcd.print(" ");
      lcd.print(myBPM);
      lcd.print(" ");
      }
    }






    -------------------以下是露天網購材料與價錢-------------
    單顆18650升壓5V充電裝置,共127元
    18650電池,68元
    http://goods.ruten.com.tw/item/show?21516007891673
    電池盒,8元
    http://goods.ruten.com.tw/item/show?21514873619557
    充電保護裝置,30元
    http://goods.ruten.com.tw/item/show?21529155040880
    升壓模組,18元
    http://goods.ruten.com.tw/item/show?21513816706112
    開關,3元
    http://goods.ruten.com.tw/item/show?21645325862802

    Arduino IIC I2C 5V LCD,165元
    http://goods.ruten.com.tw/item/show?21550344478159#qa&p=1

    Arduino Pulse Sensor 脈搏 心率 感測器模組,190元
    http://goods.ruten.com.tw/item/show?21530165613441

    Arduino UNO,170元
    http://goods.ruten.com.tw/item/show?21513818850541

    以上價錢不含運也不含稅,本人也沒有收廣告費XD,請自己找更便宜或是喜歡的方式購買
    基本上淘寶價錢會更低大概一半,東西也很輕,可以考慮一下
  • 2 則留言:

    1. 請問為什麼我複製貼上後,編譯完它說POSITIVE(LCD那行)沒有宣告

      回覆刪除
      回覆
      1. //LED_Fundino紅色板子用
        //LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
        //LED_MH黑色板子用
        LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

        這兩行應該是選一種,你可以換成刪掉紅色板子的//,把黑色板子程式的前方加上//

        刪除