顯示具有 Arduino 標籤的文章。 顯示所有文章
顯示具有 Arduino 標籤的文章。 顯示所有文章

2017年5月3日 星期三

Arduino MQ-3 MQ-4 MQ-8 氣體感測器

     MQ 系列感測器又稱為半導體式感測器一般都是用二氧化錫(SnO2) 為基材,二氧化錫在清潔空氣中(含80的氮氣20%的氧氣與少許CO2)導電率非常低,氧化物特點就是本身的活性常低,可長時間保持在同一種狀態,MQ系列感測器壽命可超過20年,二氧化錫(SnO2) 在可燃氣體的催化導電率會升高。MQ系列的結構如下 H 是加溫結構,在加溫後活性氣體通過二氧化錫(SnO2) 時就會改變導電率,只要監測導電率就能判別氣體濃度。

   這是Winsensor 出品的 MQ8 感測器的導電率曲線,MQ8是針對氫氣開發出來的感測器,這圖表能看到紅色的空氣不管濃度多高都不會影響MQ8的導電率,氫氣濃度增加時導電率也會跟著升高,其他顏色是所謂的干擾氣體,也就是乙醇、一氧化碳、甲烷等都會干擾到MQ8的導電率。

下圖是MQ8的溫溼度與導電率的曲線,由此表可看出溫度濕度會影響MQ8的導電率。


   這張圖表是指出當氣體濃度增加時感測器輸出的電壓值,在這張圖表可發現當氣體濃度增加到300ppm後曲線開始平緩到1500ppm時幾乎快成直線。


這是反應時間曲線。

   這是時間變化曲線,把MQ8放在300ppm濃度的氫氣下的輸出電壓變化,由此圖再配合輸出電壓曲線可知MQ8的在300ppm後幾乎不可使用。
 MQ 系列雖然在高濃度時超級不準確但是還有以下優點

1.壽命超長
2.使用簡單
3.價格便宜

     也就是有以上這些優點MQ系列感測器大量應用在氣體洩漏、煙霧感測警報器,這些本來自然界就不該存在的氣體一但洩漏在空氣中超過200ppm~300ppm就發出警報很多人都能接受,只是要拿來當定量使用幾乎不太可能,以下的程式還是照著Datasheet 的曲線期望解出MQ系列的濃度曲線,注意這只是理論!!在上圖MQ8的輸出曲線可得知當超過1500ppm後的電壓變化輸入到只有10bit A/D 轉換器的Arduino根本沒意義。


// 載入 LCD  Library
#include <LiquidCrystal.h>

//      LCD 接腳:  rs, enable, d4, d5, d6, d7
LiquidCrystal  lcd(13, 12, 11, 10 , 9, 8);

/********************* 硬體設定  *************************************/

#define         MQ_3_PIN                         (0)     // MQ_3 輸入腳
#define         MQ_8_PIN                         (1)     // MQ_8 輸入腳
#define         MQ_4_PIN                         (2)     // MQ_4 輸入腳
#define         RL_VALUE                         (5)    // RL電阻為 10K歐姆
#define         MQ_3_Ro_CLEAN_AIR_FACTOR         (1)    //MQ_3在乾淨空氣中的電阻/MQ_3_Ro,
#define         MQ_8_Ro_CLEAN_AIR_FACTOR         (1)    //MQ_8在乾淨空氣中的電阻/MQ_8_Ro,
#define         MQ_4_Ro_CLEAN_AIR_FACTOR         (1)    //MQ_4在乾淨空氣中的電阻/MQ_4_Ro,
                                                   

/*********************** 軟體設定  ************************************/

#define         CALIBARAION_SAMPLE_TIMES     (50)    //設定校準時樣品讀取次數
#define         CALIBRATION_SAMPLE_INTERVAL  (100)   //設定較準時每次讀取採樣的時間間隔(ms)
                                                   
#define         READ_SAMPLE_INTERVAL         (50)    //測試時用幾次的檢測值的平均值
#define         READ_SAMPLE_TIMES            (5)         //測試時每次取樣的間隔時間(ms)
                                         
#define         GAS_Alcohol                  (0)
#define         GAS_H2                       (1)
#define         GAS_CH4                      (2)

/*****************************Globals***********************************************/

float           AlcoholCurve[3]   =  {1.7, -0.77,-1};      // 這斜率參考MQ-3的 Datasheet
                                                                                 
float           MQ_3_Ro           =  10;                           //MQ_3_Ro 的預設值

float           H2Curve[3]        =  {2, -0.6,-1};         // 這斜率參考MQ-8的 Datasheet
                                                                         
float           MQ_8_Ro           =  10;                       //MQ_8_Ro 的預設值

float           CH4Curve[3]       =  {2.48, -0.62,-0.4};   // 這斜率參考MQ-4的 Datasheet
                                                         

float           MQ_4_Ro           =  10;                    //MQ_4_Ro 的預設值


void setup()
{
  lcd.begin(20, 4);                                   //設定 LCM 為 20*4
  lcd.print("Calibrating..");                         //LCM 輸出 Calibrating...
  MQ_3_Ro = MQ_3Calibration(MQ_3_PIN);                //開機校正要確保這段時間內為乾淨空氣
  MQ_8_Ro = MQ_8Calibration(MQ_8_PIN);                //開機校正要確保這段時間內為乾淨空氣
  MQ_4_Ro = MQ_4Calibration(MQ_4_PIN);                //開機校正要確保這段時間內為乾淨空氣
}

void loop()
{
lcd.setCursor(0, 0);                                                 // LCM 游標移到位置 0,0
   lcd.print("Alcohol: ");                                           //顯示文字 Alcohol
   lcd.setCursor(8,0);                                               //LCM 游標移到位置 8,0
   lcd.print(MQ_3GetGasPercentage(MQ_3Read(MQ_3_PIN)/MQ_3_Ro,GAS_Alcohol )); //顯示測到的Alcohol值
   lcd.print(" ppm     ");                                           //LCM 顯示 PPm
   lcd.setCursor(0, 1);                                                 // LCM 游標移到位置 0,0
   lcd.print("  H2  :  ");                                           //顯示文字 H2
   lcd.setCursor(8,1);                                             //LCM 游標移到位置 8,0
   lcd.print(MQ_8GetGasPercentage(MQ_8Read(MQ_8_PIN)/MQ_8_Ro,GAS_H2 )); //顯示測到的H2值
   lcd.print(" ppm     ");                                           //LCM 顯示 PPm
   lcd.setCursor(0, 2);                                                 // LCM 游標移到位置 0,0
   lcd.print("  CH4 :  ");                                           //顯示文字 CH4
   lcd.setCursor(8,2);                                               //LCM 游標移到位置 8,0
   lcd.print(MQ_4GetGasPercentage(MQ_4Read(MQ_4_PIN)/MQ_4_Ro,GAS_CH4 )); //顯示測到的CH4值
   lcd.print(" ppm     ");                                           //LCM 顯示 PPm
   delay(1000);
}

/****************** MQ_Sensor 電阻值換算 ****************************************/



 float MQ_3ResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}

float MQ_8ResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));

}

float MQ_4ResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}

/***************************** MQ_Sensor 校正 ****************************************/

float MQ_3Calibration(int MQ_3_pin)
{
  int i;
  float val=0;

  for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {          
    val += MQ_3ResistanceCalculation(analogRead(MQ_3_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBARAION_SAMPLE_TIMES;                

  val = val/MQ_3_Ro_CLEAN_AIR_FACTOR;                      

  return val;
}

float MQ_8Calibration(int MQ_8_pin)
{
  int i;
  float val=0;

  for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {          
    val += MQ_8ResistanceCalculation(analogRead(MQ_8_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBARAION_SAMPLE_TIMES;                

  val = val/MQ_8_Ro_CLEAN_AIR_FACTOR;                      

  return val;
}

float MQ_4Calibration(int MQ_4_pin)
{
  int i;
  float val=0;

  for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {          
    val += MQ_4ResistanceCalculation(analogRead(MQ_4_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBARAION_SAMPLE_TIMES;                

  val = val/MQ_4_Ro_CLEAN_AIR_FACTOR;                      

  return val;
}


/*****************************  MQ_Sensor 讀取*********************************************/


 float MQ_3Read(int MQ_3_pin)
{
  int i;
  float rs=0;

  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQ_3ResistanceCalculation(analogRead(MQ_3_pin));
    delay(READ_SAMPLE_INTERVAL);
  }

  rs = rs/READ_SAMPLE_TIMES;

  return rs;
}

float MQ_8Read(int MQ_8_pin)
{
  int i;
  float rs=0;

  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQ_8ResistanceCalculation(analogRead(MQ_8_pin));
    delay(READ_SAMPLE_INTERVAL);
  }

  rs = rs/READ_SAMPLE_TIMES;

  return rs;
}

float MQ_4Read(int MQ_4_pin)
{
  int i;
  float rs=0;

  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQ_4ResistanceCalculation(analogRead(MQ_4_pin));
    delay(READ_SAMPLE_INTERVAL);
  }

  rs = rs/READ_SAMPLE_TIMES;

  return rs;
}

/*****************************  MQ_Sensor 換算ppm **********************************/


int MQ_3GetGasPercentage(float rs_MQ_3_Ro_ratio, int gas_id)
{
  if ( gas_id == GAS_Alcohol) {
     return MQ_3GetPercentage(rs_MQ_3_Ro_ratio,AlcoholCurve);
  }
  return 0;
}

int MQ_8GetGasPercentage(float rs_MQ_8_Ro_ratio, int gas_id)
{
  if ( gas_id == GAS_H2) {
     return MQ_8GetPercentage(rs_MQ_8_Ro_ratio,H2Curve);
  }
  return 0;
}


int MQ_4GetGasPercentage(float rs_MQ_4_Ro_ratio, int gas_id)
{
  if ( gas_id == GAS_CH4) {
     return MQ_4GetPercentage(rs_MQ_4_Ro_ratio,CH4Curve);
  }
  return 0;
}

/*****************************   計算RS MQ_Ro 百分比  **********************************/


int  MQ_3GetPercentage(float rs_MQ_3_Ro_ratio, float *pcurve)
{
  return (pow(10,( ((log(rs_MQ_3_Ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}

int  MQ_8GetPercentage(float rs_MQ_8_Ro_ratio, float *pcurve)
{
  return (pow(10,( ((log(rs_MQ_8_Ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}


int  MQ_4GetPercentage(float rs_MQ_4_Ro_ratio, float *pcurve)
{
  return (pow(10,( ((log(rs_MQ_4_Ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}


上傳後就會顯示個感測器的值,注意這是沒校正過的只能當參考 !!


     當然還有其他氣體感測器可選擇,比如有比較好的高濃度曲線的平面半導體製程MP系列,催化燃燒的MC系列,幾乎可線性輸出的電化學系列,還有使元紅外線的NDIR技術。會常用來半定量使用的是電化學與NDIR技術,只是電化學感測器(NT$ 1500~4000 )壽命只有兩年!!不管有沒有使用出廠後就只有兩年壽命,NDIR技術雖然貴一點(NT$ 3000~5000 ) 可用5年,MQ售價只要 NT$ 50~3002。

2017年4月15日 星期六

Arduino MH-Z14 NDIR CO2 Sensor 測試

MH-Z14 原廠介紹

      MH-Z14二氧化碳氣體傳感器(以下簡稱傳感器)是一個智能通用型、小型傳感器,利用非色散紅外(NDIR)原理對空氣中存在的CO2進行探測,具有很好的選擇性和無氧氣依賴性,壽命長。內置溫度補償;同時具有數字輸出與模擬電壓輸出,方便使用。該傳感器是將成熟的紅外吸收氣體檢測技術與精密光路設計、精良電路設計緊密結合而製作出的高性能傳感器。

傳感器特點

高靈敏度、高分辨率、低功耗
提供UART、模擬電壓信號、PWM波形等多種輸出方式
響應時間快
溫度補償,卓越的線性輸出                        
優異的穩定性
使用壽命長
抗水汽干擾、不中毒

產品型號MH-Z14
檢測氣體二氧化碳
工作電壓4.5~5.5 V DC
平均電流< 85 mA
接口電平3.3 V
測量範圍0~5%VOL範圍內可選(詳見表2)
輸出信號0.4~2 V DC
UART
PWM
預熱時間3 min
響應時間T90 < 90 s
工作溫度0~50 ℃
工作濕度0~95% RH (無凝結)
外形尺寸57.5 mm×34.7 mm×17 mm(L×W×H)
重 量15 g
壽 命> 5年



這程式是使用 URAT 接口,板子使用 Arduino Mega2560 LCD 使用 2004 (4 *20)。


// 載入 LCD  Library
#include <LiquidCrystal.h>

//      LCD 接腳:  rs, enable, d4, d5, d6, d7 
LiquidCrystal  lcd(13, 12, 11, 10 , 9, 8);

// MH-Z14 初始化指令

byte QueqyPkt[]={0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};  
char ResponsePkt[9]; 

void setup() {
 //設定 LCM 為 20*4
lcd.begin(20, 4);         

//設定Serial2
Serial2.begin(9600);
}

void loop() {
  
//寫入MH-Z14 指令 
Serial2.write(QueqyPkt,9);
//讀取MH-Z14
Serial2.readBytes(ResponsePkt, 9);

// 轉成十進位數值 要使用unsigned int 才不會變成負值

unsigned int responseHigh = (int) ResponsePkt[2];
unsigned int responseLow = (int) ResponsePkt[3];
unsigned int ppm = (256*responseHigh)+responseLow;

//在LCD上顯示CO2 濃度
lcd.setCursor(0, 0);  
lcd.print("CO2 = ");
lcd.setCursor(8,0); 
lcd.print(ppm);
lcd.print(" ppm     ");
delay(2000);
}




2016年5月10日 星期二

Parallax 雷射測距儀 + Arduino 範例

Parallax 雷射測距儀 

     使用的雷射測具裝置是 Parallax 的 Laser Range Finder - 2m偵測範圍是15CM~122CM解析度是1mm詳細規格請參閱原廠說明

https://www.parallax.com/product/28044

外觀長這樣

 顯示部分一樣是用 Nokia-5110-LCD  Library在這裡下載

https://github.com/adafruit/Adafruit-GFX-Library
https://github.com/adafruit/Adafruit-PCD8544-Nokia-5110-LCD-library

        Parallax 的這光學測距裝置簡稱 LRF 是用雷射光束加上CMOS 影像感測器作為測距引擎,除了可直接輸出距離數據外還可輸出相對位置的數據供使用者自行計算也可以輸出捕捉到的完整圖像

  初步測試結果LRF在深色的場合幾乎100%可以正確測出距離白色的表面錯誤率較高透明表面非常困難超作.

      LRF 的指令都是 ASCII 可在一般終端機(Terminal)操作 LRF 是Open Source 的在 Parallax的網站可下載Schematic  PCB  Firmware等..設計資料,不過CPU 是用 Parallax 的 Propeller P8X32A,開發環境是用 Parallax 自己的 可自行下載



Arduino 程式碼

#include <SoftwareSerial.h>
#include <SPI.h>
#include <Adafruit_GFX.h>                                          //LCM 定義程式!!這三個要擺一起!!!
#include <Adafruit_PCD8544.h>
Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);        //LCD 的腳位定義

#define rxPin    10  // Pin10 軟體串列埠輸入(這要連接到 LRF 的 SOUT pin)
#define txPin    11  // Pin11 軟體串列埠輸出  (這要連接到 LRF 的 SOUT pin)

#define BUFSIZE  16  // 設定緩衝區為16 Byte

// 重新命名軟體串列埠

SoftwareSerial lrfSerial =  SoftwareSerial(rxPin, txPin);

void setup()
{
  display.begin();                                 //這是 Adafruit_PCD8544  Library 定義的
  display.setContrast(60);                    //LCD 對比
  delay(1000);
  display.clearDisplay();                      // 清除LCD內容
  display.setTextSize(1);                      // 設定LCD自形大小
  display.setTextColor(BLACK);        //定義LCD顏色顏色

  // 設定 Pin

  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

  //設定 Arduino Serial Monitor

  Serial.begin(9600);

  // 設定軟體串列埠

  lrfSerial.begin(9600);

  delay(2000);                        // 延遲2秒等 LRF啟動
  lrfSerial.print('U');               // 送出"U"字元
  while (lrfSerial.read() != ':');    // 等待 LRF回復 ':'    字元
  delay(10);                          // 延遲10mS
  lrfSerial.flush();                  // 清除緩衝區

  }

void loop()
{

  lrfSerial.print('R');         //送出 " R" 字元


  char lrfData[BUFSIZE];     // 資料數據緩衝區
  char offset = 0;                   // 偏移緩衝區
  lrfData[0] = 0;                    // 清除緩衝區  
  while(1)
  {
    if (lrfSerial.available() > 0) // 等待 LRF 寫資料
    {
      lrfData[offset] = lrfSerial.read();  // 將資料傳入緩衝區
      if (lrfData[offset] == ':')          // 如果收到字元 ":" 代表資料已經傳完,LRF 等待下一個命令
      {
        lrfData[offset] = 0;
        break;               // 跳出循環
      }
       
      offset++;
      if (offset >= BUFSIZE) offset = 0;
    }
  }

  display.display();
  display.clearDisplay();                             // 清除LCD內容
  display.print(lrfData);                              // 顯示測到的距離

  Serial.println(lrfData);                            // 送出距離資料到 Serial Monitor
  Serial.flush();                      
   
 }

成果


2016年1月20日 星期三

Arduino DS18S20 + Nokia 5110 溫度計

Arduino  DS18S20 + Nokia 5110 溫度計

   DS18S20是一個數位化的溫度感測器不僅感測溫度還把溫度轉換為數位信號DS18 xx系列最大的特點就是One-Wire(單線傳輸),下指令與資料傳輸都只靠一條線DS18 XX 系列每個IC都有一個唯一的序號可在同一條線上接多個DS18 xx  IC。

  DS18S20Datasheet
https://datasheets.maximintegrated.com/en/ds/DS18S20.pdf

  單線傳輸的資料庫在
https://github.com/PaulStoffregen/OneWire

 DS18 xx 資料庫在這
 https://github.com/milesburton/Arduino-Temperature-Control-Library

這兩個資料庫都是在Github 都直接按旁邊Download ZIP 這樣一次就能下載整個目錄


下載後解壓縮放在 C:\Program Files (x86)\Arduino\libraries

開啟Arduino 填入以下程式碼


/*

這是用 Adafruit LCD 驅動程式是在 Adafruit 下載
https://www.adafruit.com/products/338
雖然是 BSD License 還是呼籲多買 Adafruit 的產品
Adafruit 老闆是美女喔!!
LCD 腳位定義
pin 7 - Serial clock out (SCLK)
pin 6 - Serial data out (DIN)
pin 5 - Data/Command select (D/C)
pin 4 - LCD chip select (CS)
pin 3 - LCD reset (RST)

單線傳輸 One-Ware驅動是在這
https://github.com/PaulStoffregen/OneWire
DS18x20 驅動在這這
https://github.com/milesburton/Arduino-Temperature-Control-Library
*/

#include "Adafruit_GFX.h"                                           //LCM 定義程式!!這三個要擺一起!!!
#include "Adafruit_PCD8544.h"
Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);        //LCD 的腳位定義

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10    //  DS18S20輸入腳接在Arduino Pin 10
OneWire oneWire(ONE_WIRE_BUS); //啟動單線程式庫
DallasTemperature sensors(&oneWire); //啟動DS18S20程式庫

void setup(void){
  
  display.begin();                 //這是 Adafruit_PCD8544  Library 定義的
  display.setContrast(60);         //LCD 對比
  delay(1000);
  display.clearDisplay();             // 清除LCD內容
  display.setTextSize(2);            // 設定LCD自形大小
  display.setTextColor(BLACK);        //定義LCD顏色顏色
  Serial.begin(9600);             //設定串列監視埠

  sensors.begin();        // 初始化DS18S20

}

void loop(void)

{

sensors.requestTemperatures();               // DS18S20開始轉換

    Serial.print(sensors.getTempCByIndex(0));    // 串列埠列印重DS18S20取得的資料
    Serial.println(" C");                        // 列印字元 " C " 後換行
    
    display.clearDisplay();                                      // 清除LCD內容
    display.print(sensors.getTempCByIndex(0));                                 // 顯示測到的溫度 度C
    display.println("C");                                        // 顯示字串 "C" 然後換行
    
    Serial.print(DallasTemperature::toFahrenheit(sensors.getTempCByIndex(0)));   //串列埠列印 (度 C 轉換為度 F )
    Serial.println(" F");                                                           // 列印字元 " F " 後換行

     display.print(DallasTemperature::toFahrenheit(sensors.getTempCByIndex(0)));      // 顯示測到的溫度 度F
     display.println("F");                                        // 顯示字串 "F" 然後換行
     display.display();
    
    delay(1000);

}

//

選好版子後上傳序列埠監視視窗就會每1秒輸出一次目前溫度


LCD 也會每秒更新一次溫度

     DS18 S 20 第一腳是GND第3腳是5V第三腳跟第2腳間要接一個4.7K,第二腳是資料輸出要接到Arduino        Pin 10




2016年1月9日 星期六

Arduino TMP36 + Nokia 5110 溫度計

       今天偷懶一下,幾本上TMP36 跟LM35一樣每度C會多10mV的輸出,不一樣的是TMP36有偏移500mV的電壓,也就是25度C時電壓輸出是750mV要記得轉換時扣掉.


 



/*

這是用 Adafruit LCD 驅動程式是在 Adafruit 下載
https://www.adafruit.com/products/338
雖然是 BSD License 還是呼籲多買 Adafruit 的產品
Adafruit 老闆是美女喔!!

LCD 腳位定義
pin 7 - Serial clock out (SCLK)
pin 6 - Serial data out (DIN)
pin 5 - Data/Command select (D/C)
pin 4 - LCD chip select (CS)
pin 3 - LCD reset (RST)

*/

#include "Adafruit_GFX.h"                                           //LCM 定義程式!!這三個要擺一起!!!
#include "Adafruit_PCD8544.h"
Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);        //LCD 的腳位定義

#define aref_voltage 3.3                //指定基準電壓
int tempPin = 0;                        //指定TMP36輸入到Arduino的腳位                          
int tempReading;    
void setup(void) {

  display.begin();                 //這是 Adafruit_PCD8544  Library 定義的
  display.setContrast(60);         //LCD 對比
  delay(1000);
  display.clearDisplay();             // 清除LCD內容
  display.setTextSize(2);            // 設定LCD自形大小
  display.setTextColor(BLACK);        //定義LCD顏色顏色

  Serial.begin(9600);
  analogReference(EXTERNAL);              
}
void loop(void) {
  tempReading = analogRead(tempPin);           //讀電LM35輸出壓值
   float voltage = tempReading * aref_voltage;  //基準電壓與ADC後的值轉換
   voltage /= 1024.0;
    float temperatureC = (voltage - 0.5)   * 100 ;  // TMP36有500mV的偏移電壓要先扣除,在把電壓轉成溫度,每10mV 1度
                                           
    Serial.print(temperatureC); Serial.println(" degrees C");     //串列埠輸出溫度C
    display.clearDisplay();                                      // 清除LCD內容
    display.print(temperatureC);                                 // 顯示測到的溫度 度C
    display.println("C");                                        // 顯示字串 "C" 然後換行

     float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;      //將度C轉成度F
     Serial.print(temperatureF); Serial.println(" degrees F");      //串列埠輸出溫度C
     display.print(temperatureF);                                 // 顯示測到的溫度 度F
     display.println("F");                                        // 顯示字串 "F" 然後換行
     display.display();
   
  delay(1000);
}



2016年1月7日 星期四

Arduino + LM35 溫度計 Nokia 5110 LCD 顯示

Arduino + LM35 溫度計 Nokia 5110 LCD 顯示 

         LM35 是類比溫度感測IC,使用5V電源 溫度每增加 1度C輸出增加 10mV,在25度C時輸出是250mV,是一個很方便的感溫零件.
      Arduino ADC是10位元,也就是會把電壓分時1024等份,而這1024等份怎麼分就是用基準電壓在分,Arduino 在沒指定的狀況下基準是5V,所以每位元電表的電壓是5/1024=0.00488V,LM35每度是0.01V 所以LM35經Arduino轉換後能得到的解析度約為0.5度,如果基準電壓降為2.5V那Arduino轉換後解析度會是0.25度C,但是Arduino並無2.5V的電源,所以就用Aeduino上有的3.3V做為基準,3.3V為基準能得到的解析度為 3.3/1024=0.00322V約為0.33度C.

  這回一樣是用 Noika 5510 LCD 做演示.

程式碼


/*

這是用 Adafruit LCD 驅動程式是在 Adafruit 下載
https://www.adafruit.com/products/338
雖然是 BSD License 還是呼籲多買 Adafruit 的產品
Adafruit 老闆是美女喔!!

LCD 腳位定義

pin 7 - Serial clock out (SCLK)
pin 6 - Serial data out (DIN)
pin 5 - Data/Command select (D/C)
pin 4 - LCD chip select (CS)
pin 3 - LCD reset (RST)


*/

#include "Adafruit_GFX.h"                                           //LCM 定義程式!!這三個要擺一起!!!
#include "Adafruit_PCD8544.h"
Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);        //LCD 的腳位定義

#define aref_voltage 3.3                //指定基準電壓
int tempPin = 0;                        //指定LM35輸入到Arduino的腳位                             
int tempReading;      
void setup(void) {

  display.begin();                 //這是 Adafruit_PCD8544  Library 定義的
  display.setContrast(60);         //LCD 對比
  delay(1000);
  display.clearDisplay();             // 清除LCD內容
  display.setTextSize(2);            // 設定LCD自形大小
  display.setTextColor(BLACK);        //定義LCD顏色顏色

  Serial.begin(9600);   
  analogReference(EXTERNAL);                
}
void loop(void) {
  tempReading = analogRead(tempPin);           //讀電LM35輸出壓值
   float voltage = tempReading * aref_voltage;  //基準電壓與ADC後的值轉換
   voltage /= 1024.0; 
    float temperatureC = voltage  * 100 ;  // 把電壓轉成溫度,每10mV 1度
                                              
    Serial.print(temperatureC); Serial.println(" degrees C");     //串列埠輸出溫度C
    display.clearDisplay();                                      // 清除LCD內容
    display.print(temperatureC);                                 // 顯示測到的溫度 度C
    display.println("C");                                        // 顯示字串 "C" 然後換行
  
     float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;      //將度C轉成度F
     Serial.print(temperatureF); Serial.println(" degrees F");      //串列埠輸出溫度C
     display.print(temperatureF);                                 // 顯示測到的溫度 度F
     display.println("F");                                        // 顯示字串 "F" 然後換行
     display.display();
     
  delay(1000);
}


上傳後 串列埠也會有輸出




2016年1月6日 星期三

Arduino MLX90614 紅外線溫度感測器 + Nokia 5110 LCD display

Arduino  MLX90614  紅外線溫度感測器 + Nokia 5110 LCD display


  MLX90614 有分5V跟3.3V的要注意!!! 以下是共通規格
  • Factory calibrated
  • -40°C to +125°C for sensor temperature
  • -70°C to +380°C for object temperature
  • ±0.5°C accuracy around room temperatures
  • High accuracy of 0.5°C over wide temperature
  • 90° Field of view
  • I2C interface, 0x5A is the fixed 7-bit address
 開啟Arduino IDE 貼上這段程式碼


/*************************************************** 
  This is a library example for the MLX90614 Temp Sensor

  Designed specifically to work with the MLX90614 sensors in the
  adafruit shop
  ----> https://www.adafruit.com/products/1748
  ----> https://www.adafruit.com/products/1749

這是用 Adafruit LCD &  MLX90614   驅動程式都是在 Adafruit 下載

https://www.adafruit.com/products/1748
https://www.adafruit.com/products/1749
https://www.adafruit.com/products/338

雖然是 BSD License 還是呼籲多買 Adafruit 的產品
Adafruit 老闆是美女喔!!

MLX90614 sensors 腳位定義
Pin A4             I2C data  SDA
Pin A5             I2C clock   SCL

LCD 腳位定義
Pin 11 for contrast on the Nokia 5110
pin 7 - Serial clock out (SCLK)
pin 6 - Serial data out (DIN)
pin 5 - Data/Command select (D/C)
pin 4 - LCD chip select (CS)
pin 3 - LCD reset (RST)
*/

#include "Adafruit_GFX.h"                                           //LCM 定義程式!!這三個要擺一起!!!
#include "Adafruit_PCD8544.h"
Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);

// Pin 4 Pin 3 的腳位要注意,我的是反過來的!!


#include <Wire.h>                                                  //MLX90614 定義程式!!這三個要擺一起!!!
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();


void setup() {
  
  mlx.begin();                                       // 啟動 MLX90614
  
  display.begin();                 //這是 Adafruit_PCD8544  Library 定義的
  display.setContrast(60);   //LCD 對比
  delay(1000);
  display.clearDisplay();             // 清除LCD內容
  display.setTextSize(2);            // 設定自形大小
  display.setTextColor(BLACK);  //定義顏色顏色

}

void loop() { 

  display.clearDisplay();                                // 清除LCD內容
  display.print(mlx.readObjectTempC());      // 顯示測到的溫度 度C
  display.println("C");                                   // 顯示字串 "C" 然後換行
  display.print(mlx.readObjectTempF());       // 顯示測到的溫度 度F
  display.println("F");                                    // 顯示字串 "F" 然後換行
  display.display();

  delay(1000);                   // 等一秒

}


上傳 然後就OK了



腳位在說明都有定義,

Nokia 5110 LCD 接地就好不用接電源


要特別注意的是

#include "Adafruit_GFX.h"                                           //LCM 定義程式!!這三個要擺一起!!!
#include "Adafruit_PCD8544.h"
Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);

#include <Wire.h>                                                  //MLX90614 定義程式!!這三個要擺一起!!!
#include <Adafruit_MLX90614.h>
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

這些不要為了整齊順序互相調換!!!

2016年1月5日 星期二

Arduino + Nokia 5110 簡單的5通道電表


   Nokia 5110/3110 LCD 是一個簡單又省電使用方便的圖形LCD , 84 X 48 的解析度一般文字表達使用都已經足夠.
    Nokia 5110/3110 LCD沒背光的使用狀況下,不接電源都還能正常使用,靠信號傳過來的脈波就足以讓他動作.

 使用材料如下 :

      Nokia 5110/3110 相容 LCD  X 1
      Arduino Leonardo                  X 1

     軟體
      Arduino  1.6.7
     Adafruit_PCD8544  Library

    首先要到這裡下載Adafruit_PCD8544  Library

      https://www.adafruit.com/products/338

Adafruit-GFX-Library-master &  Adafruit-PCD8544-Nokia-5110-LCD-library-master 都下載 , 可以的話常去Adafruit 購物,Adafruit是美女老闆喔!!

    下載好後解壓縮放在    安裝目錄\Arduino\libraries , 為什麼變成要解壓縮我也不知道 ,記得以前好像不用....

      把這一段程式貼在Arduino 草稿碼上.

/*

這是用 Adafruit LCD 區動程式,可在 Adafruit 下載
https://www.adafruit.com/products/338
雖然是 BSD License 還是呼籲多買 Adafruit 的產品

LCD 腳位定義
Pin 11 for contrast on the Nokia 5110
pin 7 - Serial clock out (SCLK)
pin 6 - Serial data out (DIN)
pin 5 - Data/Command select (D/C)
pin 4 - LCD chip select (CS)
pin 3 - LCD reset (RST)
*/

#include "Adafruit_GFX.h"
#include "Adafruit_PCD8544.h"

Adafruit_PCD8544 display = Adafruit_PCD8544 (7, 6, 5, 4, 3);

// Pin 4 Pin 3 的腳位要注意,我的是反過來的!!

void setup() {

   display.begin();                 //這是 Adafruit_PCD8544  Library 定義的
   display.setContrast(60);    //LCD 對比
  delay(1000);
  display.clearDisplay();                 // 清除LCD內容
  display.setTextSize(1);                 // 設定自形大小
  display.setTextColor(BLACK);   //定義顏色顏色

}

void loop() {

   float volt0;    //定義名稱
   float volt1;
   float volt2;
   float volt3;
   float volt4;
 
  int vin0 = analogRead(A0);  //讀取信號
  int vin1 = analogRead(A1);
  int vin2 = analogRead(A2);
  int vin3 = analogRead(A3);
  int vin4 = analogRead(A4);

   volt0=(float)vin0/1024*5.0;  //轉換數字
   volt1=(float)vin1/1024*5.0;
   volt2=(float)vin2/1024*5.0;
   volt3=(float)vin3/1024*5.0;
   volt4=(float)vin4/1024*5.0;
 
  display.clearDisplay();    // 清除LCD內容
  display.print("V0= ");     // 顯示字串 "V0="
  display.print(volt0);        // 顯示測到的電壓值
  display.println("V");       // 顯示字串 "V" 然後換行
  display.print("V1= ");
  display.print(volt1);
  display.println("V");
  display.print("V2= ");
  display.print(volt2);
  display.println("V");
  display.print("V3= ");
  display.print(volt3);
  display.println("V");
  display.print("V4= ");
  display.print(volt4);
  display.println("V");
  display.println("Story Chen");
  display.display();

  delay(1000);                   // 等一秒

}

然後上傳就好了,A0~A4 沒接時會亂跳,輸入不可接超過5V~~~


 背光很暗?因為被我燒了!!!!!


LCM 沒接電源一樣工作的很好.


 

2016年1月2日 星期六

Arduino 電子琴

目標板為Arduino Leonardo

開啟Arduino IDE
輸入以下程式碼

const int speaker=2;     //蜂鳴器接在Pin2
const int sw[8]={4,5,6,7,8,9,10,11};     //按件接在Pin4~11
const int frequency[8]={261,293,329,349,392,440,493,523};    //要產生的音符頻率
int i;              // 紀錄迴圈執行次數
int val;            //取得變數的整數值

void setup()        // 初始化副程式
{
  for(i=0;i<8;i++)      // 此迴圈執行8次
    pinMode(sw[i],INPUT_PULLUP);        //設定輸入內接拉升電阻
}
 
void loop() {           //重複不斷執行
  for(i=0;i<8;i++)  
  {
    val=digitalRead(sw[i]);        //讀取開關是否被按下
    if(val==0)                    //
      tone(speaker,frequency[i],10);  //播放i值的頻率於Spearker,i=0=261Hz

  }
}


接著上傳至Arduino   草稿碼 --> 上傳


就完成了


這是Do的波形


這是Re的波形