2013年12月30日 星期一

Comparison of three kinds of soil moisture sensor

Three kinds of soil moisture sensor
Chip : Arduino Duemilanove ATmega 328
Module : Moisture Sensor

Demo
/*******************************************************
EX_07 : Soil Moisture Sensor
2013/12/24 SteveChang, PMP (sown813@gmail.com)
********************************************************/
int MoistureSensorPin1 = A0;  // select the input pin for the potentiometer
int MoistureSensorPin2 = A1;
int MoistureSensorPin3 = A2;

int SensorValue1 = 0;  // variable to store the value coming from the sensor
int SensorValue2 = 0;
int SensorValue3 = 0;

void setup()
{
  Serial.begin(57600);  
}

void loop()
{  
  // read the value from the sensor:
  SensorValue1 = analogRead(MoistureSensorPin1);
  SensorValue2 = analogRead(MoistureSensorPin2);
  SensorValue3 = analogRead(MoistureSensorPin3);
  delay(60000);
  
  Serial.print(SensorValue1);
  Serial.print(",");
  Serial.print(SensorValue2);
  Serial.print(",");
  Serial.println(SensorValue3);
}

2013年12月17日 星期二

Using an Arduino's PWM to control a DC motor

I using an Arduino's PWM to control speed of the motor.

Chip : Arduino Leonardo
Module : LCD KeyPad Shield (SKU: DFR0009)
Transistors : NPN TIP122
Motor : DC 3~6V

Demo

PWM Library
Arduino/Wiring SoftPWM Library
Code
/*******************************************************
Ex_06 : Using PWM to control a DC motor
2013/12/18 SteveChang, PMP (sown813@gmail.com)
********************************************************/

// Motor Control library
#include "SoftPWM.h"
#include "SoftPWM_timer.h"

//Sample using LiquidCrystal library
#include "LiquidCrystal.h"
 
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
 
// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;

// LCD Backlit Control
int BacklitControl = 10;
static int LCDBacklit;

// PWM Status
int PWM_Status = 0;

// Button define
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

#define fadePin 2

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor 
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 
// For V1.1 us this threshold
/*
  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 250)  return btnUP; 
  if (adc_key_in < 450)  return btnDOWN; 
  if (adc_key_in < 650)  return btnLEFT; 
  if (adc_key_in < 850)  return btnSELECT;  
*/
 
// For V1.0 comment the other threshold and use the one below:

  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 195)  return btnUP; 
  if (adc_key_in < 380)  return btnDOWN; 
  if (adc_key_in < 555)  return btnLEFT; 
  if (adc_key_in < 790)  return btnSELECT;   

  return btnNONE;  // when all others fail, return this...
}
 
void setup()
{
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0,0);
  lcd.print("Push the buttons"); // print a simple message
  pinMode(BacklitControl, OUTPUT);
  digitalWrite(BacklitControl, LOW);
    
  // Initialize
  SoftPWMBegin();
  // Create and set pin 13 to 0 (off)
  SoftPWMSet(fadePin, 0);
  // Set fade time for pin ? to 300 ms fade-up time, and 700 ms fade-down time
  SoftPWMSetFadeTime(fadePin, 300, 700);    
}
  
void loop()
{  
  lcd.setCursor(0,1);            // move to the begining of the second line
  lcd_key = read_LCD_buttons();  // read the buttons
  SoftPWMSetPercent(fadePin, PWM_Status);
  delay(15);
  
  switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
     case btnRIGHT:
       {
          lcd.print("RIGHT ");
          break;
       }
     case btnLEFT:
       {
          lcd.print("LEFT   ");
          break;
       }
     case btnUP:
       {
          PWM_Status += 20;
          if(PWM_Status > 100)
             PWM_Status = 100;
          lcd.print("Status    ");
          lcd.print(PWM_Status);
          lcd.print("%     ");
          delay(500);
          break;
       }
     case btnDOWN:
       {
          PWM_Status -= 20;
          if( PWM_Status < 0 )
              PWM_Status = 0;              
          lcd.print("Status    ");
          lcd.print(PWM_Status);
          lcd.print("%     ");
          delay(500);
          break;
       }
     case btnSELECT:
       {
          lcd.print("SELECT");
          LCDBacklit = LCDBacklit == HIGH ? LOW : HIGH;
          digitalWrite(BacklitControl, LCDBacklit);
          delay(500);
          break;
       }
       case btnNONE:
       {
          lcd.print("NONE     ");
          break;
       }
   }
}

2013年12月13日 星期五

Temperature Compared DHT11 and Thermistors with Weather Bureau (2013/12/12)

昨天凌晨因 Windows Update 所以 03:30~06:50 左右的資料是不見了。
另外, 我有試著把資料做 零時校準, 也就是大家所量到的值, 都以 00:00 齊頭, 意外的發現, 熱敏電阻 100Ω是最接近氣象局的數據。
2013/12/12 All sensors 


2013/12/12 All sensors level correction with Weather Bureau


-------------------- Detailed analysis --------------------
2013/12/12 Humidity Compared DHT11 level correction with Weather Bureau
The bottom line is the default Humidity value 45%, top line is level correction to 61%.


2013/12/12 Temperature Compared DHT11 with Weather Bureau
No uses level correction.


2013/12/12 Temperature Compared Thermistor 100Ω with Weather Bureau
The default value is 25.22℃, level correction to 19.4℃, all value add -5.82℃.


2013/12/12 Temperature Compared Thermistor 200Ω with Weather Bureau
The default value is 18.84℃, level correction to 19.4℃, all value add 0.56℃.


2013/12/12 Temperature Compared Thermistor 1KΩ with Weather Bureau
The default value is 17.04℃, level correction to 19.4℃, all value add 1.96℃.


2013/12/12 Temperature Compared Thermistor 10KΩ with Weather Bureau
The default value is 21.32℃, level correction to 19.4℃, all value add -1.92℃.


2013/12/12 Temperature Compared Thermistor 100KΩ with Weather Bureau
The default value is 16.53℃, level correction to 19.4℃, all value add 2.87℃.

2013年12月12日 星期四

Temperature Compared DHT11 and Thermistors with Weather Bureau (2013/12/11)

第一次 DHT11 量到的溫度與氣象局發佈是一樣的, 不過濕度就有些落差了,熱敏電阻則是以 200Ω 最為接近。
發覺氣象局的資格都是翌日中午過後才會發佈, 網站只保留最近 30天, 昨天半夜 3點 Windows Update, 結果重開機, 12/12 號會有幾個小時資料不見。

2013/12/11 All sensors 
-------------------- 以下細部分析 --------------------
2013/12/11 Humidity Compared DHT11 with Weather Bureau


2013/12/11 Temperature Compared DHT11 with Weather Bureau


2013/12/11 Temperature Compared  - Thermistors with Weather Bureau


2013/12/11 Temperature Compared  - Thermistor(100Ω) with Weather Bureau


2013/12/11 Temperature Compared  - Thermistor(200Ω) with Weather Bureau


2013/12/11 Temperature Compared  - Thermistor(1KΩ) with Weather Bureau


2013/12/11 Temperature Compared  - Thermistor(10KΩ) with Weather Bureau


2013/12/11 Temperature Compared  - Thermistor(100KΩ) with Weather Bureau

2013年12月10日 星期二

Temperature Compared DHT11 and Thermistors with Weather Bureau (2013/12/10)

昨日量測數據, 與氣象局發佈之數據相比較, 網站歷史資料都是每 1Hr 一筆, 即時資料約 15min一筆, 但更新時間不固定, 有時 1~2hr 才會更新。

2013/12/10 Temperature Compared DHT11 with Weather Bureau

2013/12/10 Humidity Compared DHT11 with Weather Bureau


2013/12/10 Temperature Compared Thermistors with Weather Bureau

2013年12月8日 星期日

Auto Pump

做了一個抽水馬達的實驗 情境是~ 
  1. 待機狀態時 LED 慢速閃爍。
  2. 水位過低 LED 高速閃爍 10 秒 ( 主要用於防止開關彈跳現象 )。
  3. 起動 Pump, LED 恆亮, 每次起動 5 秒鐘。
  4. 無窮迴圈。
可應用範圍
  1. 低水位偵測到 並閃爍警告 or 起動馬達加水。
  2. 土壤濕度不足警告 & 起動馬達加水。
  3. 滿水位偵測到 並閃爍警告 or 停止馬達加水。

[實驗結果]

2013年12月7日 星期六

Compared DHT11 with Thermistors

假日主要實驗了 DHT11 (兩塊模組), 及四個熱敏電阻量測, 以及改善軟體功能。
這兩天會做熱敏電阻量測, 及低水位幫浦 實驗, 當偵測水位過低時起動沈水馬達加水。

2013/12/07 All sensors
-------------------- 以下細部說明 --------------------
軟體改善功能
  1. 加入了 Auto Save 功能, 程式每1分鐘會自動儲存一次, 避免軟硬体當機, 資料流失。
  2. 加入了 Watch Dog 功能, 程式每1分鐘會去檢查連線是否正常, 如有斷線, 會自動重新連線。
  3. 修改曲線顏色, 讓圖表顯示更明顯。
  4. 加入 ini 設定功能, 可隨時修改 ColumnHeader , 以利往後隨時要量測任何東西, 可以隨時修改。
DHT11模組
兩塊模組的溫度變化差不多, 但濕度就有點差距了。
氣象局網站 2013/12/06~2013/12/07 溫度(16.8℃~26.7℃) , 濕度 (37%~74%)

2013/12/06~2013/07 Two DHT11 ( Temperature + Humidity )


2013/12/06~2013/07 Two DHT11 ( Temperature )
氣象局網站 2013/12/06~2013/12/07 溫度(16.8℃~26.7℃) 


2013/12/06~2013/07 Two DHT11 ( Humidity )
氣象局網站 2013/12/06~2013/12/07 濕度 (37%~74%)

熱敏電阻
因計算公式出了錯, 及硬體也有問題, 所以量測變化並無太大差異, 此部份問題皆已改善, 過兩天會有新的報表。
2013/12/06 Compared DHT11 with Thermistors (Before Improve)


2013/07 Compared DHT11 with Thermistors (Improved)

2013年12月4日 星期三

Improve conditions for measurements

我彷造氣象觀測箱環境,, 讓它不直接照到陽光, 並保持通風, 效果有比較好點, 以往過白天溫度會飆高到40℃~50℃,改良後,白天量測約 25℃~28℃, 與 氣象局的溫度量測值差不多, 波形也比較正常些了
  1. 亮度變化不會太快飽和。
  2. 溫度,空氣濕度變化不會太大。
  3. 土壤濕度變化也不會太大。
高雄氣象站 日期: 2013/12/04
時間 溫度(°C) 濕度(%)
01:00 18.2 66
02:00 18.0 68
03:00 17.7 68
04:00 17.3 70
05:00 16.7 72
06:00 16.7 69
07:00 16.8 69
08:00 18.0 62
09:00 20.2 59
10:00 22.0 56
11:00 23.3 54
12:00 23.3 56
13:00 23.7 52
14:00 23.6 47
15:00 23.8 38
16:00 23.1 51
17:00 22.2 55
18:00 21.6 57
19:00 21.0 53
20:00 20.3 53
21:00 19.5 56
22:00 19.1 57
23:00 19.0 56
24:00 18.8 58

Waveform comparison


Measurement Environmental

2013年12月2日 星期一

After four days of observation

經過四天的觀察, 有得到一些心得與想法
  • 土壤濕度四日無明顯差異,四天不澆水白天還會上昇,晚上則下降,似乎量到的非土壤濕度(有可能是電導度),至於白天為何會上昇,個人認為與日照昇溫有關,即鐵片吸熱後,而影響到量測的結果,固考慮之後盆栽需要遮陽。
  • DHT11溫濕度量測到,溫度與濕度的相對變化,即溫度昇,濕度降,濕度明明顯的不穩定高頻。
  • 熱敏電阻我似乎買太大了,以致於量測數據變化不明顯,不過該上昇及下降是都有變化,應該要找合適形號再量測一次。
  • 溫度方面,DHT11白天量到近50℃高溫,似乎麵包下面的鐵板吸熱,影響到整體量測數據,想打造一個 氣象觀測箱,來做量測。
  • 四天內軟體crash一次,藍芽當一次,原因不明,不知道是否與高溫晒有關。
  • 軟體缺少 AutoSave , 及 WatchDoc 機智 ,以至於 crash 後,一段時間的記錄遺失。
目前想到的改善流程有~
  1. 打造一個合適穩定的量測環境(室外量測平台),但這部份要做的工程就比較大些,我沒有電踞....。
  2. 將所有溫濕度感測器同時接上(目前有四顆不同形號的 DHT11),並做差異分析,找出最穩定的型號。
2013/11/29~12/02 All sensors


2013/11/29~12/02 Soil moisture


2013/11/29~12/02 Temperature


2013/11/29~12/02 DHT11( Temperature + Humidity ) Sensor


2013/11/29 All sensors


2013/11/30 All sensors


2013/12/01 All sensors


2013/12/02 All sensors


2013年11月29日 星期五

The first cake comes out of the oven.

Yellow Line - Brightness
Red Line - Temperature
Blue Line - Humidity

自家頂樓量測

將量測工具架設自家頂樓陽台, 希望這幾天別下雨 XD



[量測結果]

2013年11月28日 星期四

整合多項感測器

目前準備量測 亮度, 溫度, 濕度, 並將量測數據記錄下來,透過藍芽模組,將室外盆栽的數據傳送至室內,避免電腦被雨淋或鳥屎攻擊(住家附近的鳥還滿多的)。

主機端利用 C# 寫一套 Application 來監控

[量測結果]

DHT11 溫濕度量測

DHT11 是個傳動模組,裡頭已經整合 溫度 及 空氣濕度 感測器為一體,缺點是只有2位數,所以無法量測精密的小數點變化值。

用熱敏電阻來量測並與 DHT11做交叉比對,成本會省很多。

[量測結果]
[程式碼]
// Temp and Humidity Module "DHT11"

int DHpin = A0;
byte dat[5];
byte read_data()
{
  byte data;
  for(int i=0; i<8; i++)
  {
    if(digitalRead(DHpin) == LOW)
    {
      while(digitalRead(DHpin) == LOW);   //等待50us;
      delayMicroseconds(30);              //判斷高電平的持續時間,以判定數據是'0'還是'1';
      if(digitalRead(DHpin) == HIGH) 
        data | = ( 1 << ( 7 - i ) );      //高位在前,低位在後;
      while(digitalRead(DHpin) == HIGH);  //數據‘1’,等待下一位的接收;
    }
  }
  return data;
}

void start_test()
{
  digitalWrite(DHpin,LOW);  //拉低總線,發開始信號;
  delay(30);                //延時要大於18ms,以便DHT11能檢測到開始信號;
  digitalWrite(DHpin,HIGH);
  delayMicroseconds(40);    //等待DHT11響應;
  pinMode(DHpin,INPUT);
  while(digitalRead(DHpin) == HIGH);
  delayMicroseconds(80);    //DHT11發出響應,拉低總線80us;
  if(digitalRead(DHpin) == LOW);
  delayMicroseconds(80);    //DHT11拉高總線80us後開始發送數據;
  for(int i=0;i<4;i++)      //接收溫濕度數據,校驗位不考慮;
  dat[i] = read_data();
  pinMode(DHpin,OUTPUT);
  digitalWrite(DHpin,HIGH); //發送完一次數據後釋放總線,等待主機的下一次開始信號;
}

void setup()
{
  Serial.begin(9600);
  pinMode(DHpin,OUTPUT);
}

void loop()
{
  start_test();
  Serial.print("Current humdity = ");
  Serial.print(dat[0], DEC);  //顯示濕度的整數位;
  Serial.print('.');
  Serial.print(dat[1],DEC);   //顯示濕度的小數位;
  Serial.println('%');
  Serial.print("Current temperature = ");
  Serial.print(dat[2], DEC);  //顯示溫度的整數位;
  Serial.print('.');
  Serial.print(dat[3],DEC);   //顯示溫度的小數位;
  Serial.println('C');
  delay(700);
}

2013年11月27日 星期三

土壤濕度檢測片

在網路上找 土壤濕度檢測 可以找到一些模組可用,於是自己也想來 DIY 一下。

由於量測極只能找金屬材質,但某些金屬遇水又會生鏽,所以在選材要小心,以免生鏽產生誤差值。

我選擇不鏽鋼材質,但不鏽鋼無法被焊接,所以只能夾在金屬材質,再進行讀取,另外要再與電阻分壓,再拉線到 Arduino 的 IO腳上讀取 (電路與之前相同)。




[量測結果]

[程式碼]
/*    將 DHT11 測得的 溫濕度 顯示在LCD顯示器 */ 

#include <LiquidCrystal.h>    //使用LiquidCrystal Library 
#include <dht11.h>                 //使用DHT11 Library
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);  //初始設定LCD顯示器的介面 
dht11 DHT11;     //定義DHT11 物件
#define DHT11PIN A1  //定義讀取資料的 Pin腳 

void setup() {     
   lcd.begin(16, 2);  // 設定LCD有2列16欄  
} 

void loop() {  
   lcd.setCursor(0, 0); //將游標設定在第一行第一個位置(column 0, line 1)  
   int chk = DHT11.read(DHT11PIN);  //檢查DHT感測器的回應  

   switch (chk) {     
     case 0:       
       lcd.print("Humidity:");       
       lcd.print((float)DHT11.humidity, 1);       
       lcd.print("%");       
       lcd.setCursor(0, 1);       
       lcd.print("Temp:");       
       lcd.print((float)DHT11.temperature, 0); 
       lcd.write(0xDF);     
       lcd.print("C ");
      
       lcd.print( (float)Thermister(analogRead(A0)), 1);  // display Fahrenheit
       lcd.write(0xDF);     
       lcd.print("C ");
       
       break;     
     case -1:       
       lcd.print("Checksum error"); 
       break;     
     case -2:       
       lcd.print("Time out error"); 
       break;     
     default:       
       lcd.print("Unknown error"); 
       break;   
   }  
   delay(500); 
}

float pad = 9000;                       // balance/pad resistor value, set this to the measured resistance of your pad resistor

float Thermister(int RawADC) {
  float Temp; 
  long Resistance = ( ( 1000 * pad / RawADC) - pad );   
   Temp = log(Resistance);
   Temp = 1 / ( 0.001129148 + ( 0.000234125 + ( 0.0000000876741 * Temp * Temp ) ) * Temp );
   Temp -= 273.15;            // Convert Kelvin to Celcius
   Temp = ( Temp * 9.0 ) / 5.0; // + 32.0; // Convert Celcius to Fahrenheit
   Temp /= 10.0;
   Temp += 10.0; // Offset
   return Temp;
}