Arduino Project: Weather station (小型氣象站)

Arduino 連接 DHT11感測空氣中的溫濕度,以光敏電阻感測是否有人經過,再以LCD顯示目前空氣溫濕度。

Arduino:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <dht.h>

#define dht_dpin 2
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, NEGATIVE);  // 設定 LCD I2C 位址
dht DHT;
int newPhotoValue, oldPhotoValue, diff;
bool flag=false;

void setup() {
  lcd.begin(16, 2);      // 初始化 LCD,一行 16 的字元,共 2 行,預設開啟背光
  lcd.clear();
  lcd.backlight();
  lcd.noCursor();
  delay(1000);

  lcd.setCursor(0, 0); // 設定游標位置在第一行行首
  lcd.print(“Hello, world!”);
  lcd.setCursor(0, 1); // 設定游標位置在第二行行首
  lcd.print(“Shrimp”);
  delay(1000);
  lcd.clear();
}

void loop() {
  //lcd.clear();
  newPhotoValue = analogRead(A0);
  //lcd.print(newPhotoValue);
  if(flag){
    lcd.setCursor(0,0);
    lcd.print(“Welcome to RS’s”);
    lcd.setCursor(0,1);
    lcd.print(“Weather Station”);
    flag = false;
  }
  diff= oldPhotoValue-newPhotoValue;
  if(abs(diff)>15){
    unsigned long time = millis();
    while(millis() – time < 1000){
      lcd.clear();
      DHT.read11(dht_dpin);
      
      lcd.setCursor(0,0);
      lcd.print(“Humi: “);
      lcd.print(DHT.humidity);
      lcd.print(“%”);
      
      lcd.setCursor(0,1);
      lcd.print(“temp: “);
      lcd.print(DHT.temperature);
      lcd.print(“oC”);
      delay(500);
    }
    flag= true;
  }
  delay(1000);
  oldPhotoValue= newPhotoValue;
}

library:

DHT11, LCD:
https://drive.google.com/folderview?id=0B9fmfEayrYvMRU0wejUyNUFGMkk&usp=sharing

參考:
1. 以arduino uno 燒錄 arduino pro mini:
http://sky4s.blogspot.tw/2014/04/arduino-unoarduino-pro-mini-use-arduino.html
補充: 燒錄時,板子記得選arduino pro mini
2. LCD I2C- G.T.WANG:
http://sky4s.blogspot.tw/2014/04/arduino-unoarduino-pro-mini-use-arduino.html
3. DHT11- 聰明人求知心切:
http://alex9ufoexploer.blogspot.tw/2013/04/arduino-humidity-sensor-dht11-tutorial_6.html

Arduino: Serial

以Serial方式,傳送指令給arduino,若收到A,LED亮,收到B,LED暗

PS. 可以把LED換成繼電器(Relay)(可控制電器)
繼電器上的
NC: Normal Close,
C: Common,
NO: Normal Open

code:
int led = 2;
char incomingByte;   // for incoming serial data

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  if(Serial.available())
  {
    incomingByte = Serial.read();
   Serial.print(“I received: “);
     Serial.println(incomingByte);
    if(incomingByte== ‘A’){
      digitalWrite(led, HIGH);
    }
    if(incomingByte== ‘B’){
      digitalWrite(led, LOW);
    }
    
  }
}


– 在putty上讀取特殊鍵盤值:

int led = 2;
int incomingByte;   // for incoming serial data

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  if(Serial.available())
  {
    incomingByte = Serial.read();
   Serial.print(“received!:  “);
     Serial.println(incomingByte);
    if(incomingByte== 65){
      Serial.println(“catch up”);
    }
    if(incomingByte== 66){
      Serial.println(“catch down”);
    }
    if(incomingByte== 67){
      Serial.println(“catch right”);
    }
    if(incomingByte== 68){
      Serial.println(“catch left”);
    }
    
  }
}
參考:
1. http://www.rebol.com/docs/core23/rebolcore-18.html


Arduino: 光敏電阻

若亮度有一定變化就會讓LED亮
code:
int led = 2;
static int oldValue = 0;
// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  int value = analogRead(A0);
  int a = abs(value-oldValue);
  Serial.println(a);
  if(a > 50){
    digitalWrite(led, HIGH);
  }else{
    digitalWrite(led, LOW);
  }
  delay(50);
  oldValue = value;

}

Arduino: 7 segment display (七段顯示器)

若要顯示3,則讓abgcd,五支腳位通電
=> 把全部腳位接線,以2~10接上控制線,再以function形式呈現1234567890
=> 接好控制線後,不做任何控制(HIGH or LOW),預設是全亮,所以會顯示8

– 為什麼當我們 digitalWrite(a, HIGH) 時,a卻是暗掉的呢?
=>
七段顯示器有共陽or共陰兩種,

此例就是共陽
所以當我們想要哪支腳位不亮,就把那支腳位設為HIGH,使他與高電位同電位,就不會有電流通過,即斷路,自然不會亮。
example:

int dp = 2;
int c = 3;
int d = 4;
int e = 5;
int b = 6;
int a = 7;
int f = 8;
int g = 9;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
}

void show0(){
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}
void show1(){
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}
void show2(){
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}
void show3(){
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}
void show4(){
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void show5(){
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void show6(){
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void show7(){
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}
void show8(){
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
void show9(){
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void setNumber(int number){
  switch(number){
  case 0: show0(); break;
  case 1: show1(); break;
  case 2: show2(); break;
  case 3: show3(); break;
    case 4: show4(); break;
    case 5: show5(); break;
    case 6: show6(); break;
    case 7: show7(); break;
    case 8: show8(); break;
    case 9: show9(); break;
  default: Serial.println(“Error”);
  }
}

// the loop routine runs over and over again forever:
void loop() {
  setNumber(1);
  delay(1000);
  setNumber(2);
  delay(1000);
  setNumber(3);
  delay(1000);
  setNumber(4);
  delay(1000);
  setNumber(5);
  delay(1000);
  setNumber(6);
  delay(1000);
  setNumber(7);
  delay(1000);
  setNumber(8);
  delay(1000);
  setNumber(9);
  delay(1000);
}



————————-

兩位數七段顯示器
 

Arduino Buzzer

int buzz= 13;
int low[]= {0, 1908, 1701, 1515, 1433, 1276, 1136, 1012};
int middle[]= {0, }
int high[]= {0, }

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(buzz, OUTPUT);
}

void play(int tone, unsigned long howlong){
  unsigned long time= millis();
  
  while(millis() – time < howlong){
    digitalWrite(buzz, HIGH);
    delayMicroseconds(low[tone]);
    digitalWrite(buzz, LOW);
    delayMicroseconds(low[tone]);
  }
  delay(10);
};

void play_little_apple(){
  play(1, 250);
  play(1, 250);
  play(5, 250);
  play(5, 250);
  play(6, 250);
  play(6, 250);
  play(5, 250);


  play(4, 250);
  play(4, 250);
  play(3, 250);
  play(3, 250);
  play(2, 250);
  play(2, 250);
  play(1, 250);

  
}

void loop() {
  // put your main code here, to run repeatedly:
  play_little_apple(); 
}


excel 算音階對應到的頻率
=ROUND(1/E2/2*1000000,0)

Arduino practice: 小型打地鼠

1. 以arduino實做一個打地鼠小遊戲,Serial序列顯示分數(可用七段顯示器或LCD替換顯示分數方式),每3秒隨機一個LED發亮,玩家需要在三秒內按到該發亮LED對應的按鈕才算得分,成功得一分,失敗則扣一分。

2. 電路圖:

3. 程式碼:

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led1 = 2;
int led2= 3;
int led3= 4;
int led4= 5;
int led5= 6;
int button1 = 8;
int button2 = 9;
int button3 = 10;
int button4 = 11;
int button5 = 12;
static int score=0;
int keyValue=0;

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);
  // initialize the digital pin as an output.
  pinMode(led1,OUTPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);
  pinMode(led4 ,OUTPUT);
  pinMode(led5 ,OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(button5, INPUT);
  initial();
}
void initial(){
 digitalWrite(led1,LOW); 
 digitalWrite(led2,LOW); 
 digitalWrite(led3,LOW); 
 digitalWrite(led4,LOW); 
 digitalWrite(led5,LOW); 
 Serial.println(“—–Welcome to Whack-a-mole Game!—–“);
}


// the loop routine runs over and over again forever:
void loop() {
  
  int a = random(2,7);      //隨機選取五個LED之一發亮
  digitalWrite(a, HIGH);  

  unsigned long time = millis();
  while( millis()-time < 3000){    // 三秒換一次LED發亮
    keyValue= digitalRead(a+6);
    if(keyValue){
    break;
    }
  //Serial.println(keyValue);
  delay(10);
  }
  
  if(keyValue){
      score++;
  }else{
      score–;
  }
  digitalWrite(a, LOW);
  Serial.print(“Score: “);
  Serial.println(score);
}


參考:
1. Autodesk circuit: (提供接線、coding模擬,功能完整,使用上方便,不會有爆炸危險XD)
https://circuits.io/circuits/

試燒 Arduino pro mini / 用終端機讀UART

剛買到的pro mini什麼都沒有
第一個念頭就是用usb to part的PL2303  (TX,RX,GND,VCC)
但是悲劇的是燒不進去
查了一下 看到這篇


1. 接DTR

雄Arduino : Pro Mini 以 CP 2102 USB to TTL 上載程式
http://gsyan888.blogspot.tw/2014/10/arduino-cp2102-dtr-pin.html
雖然不是同一顆
但是上面寫說要接上DTR (RS232有 ?
只是我這顆PL2303沒有DTR…
查了一下是有 只是沒有拉出來
google一下就有腳位圖
DTR在第二腳
至於怎麼判斷哪邊開始是1呢
通常IC上都會有小圈圈當記號
有小圈圈那邊就是1
但是!!
接上去DTR後還是不行…
只好換別的方法了
google: arduino pro mini 燒錄
就找到別篇

2. 接RESET

忘記看到哪一篇說要在燒錄的時候 出現Uploading的時候把Reset按下去!
反正在我這個case是成功的 耶耶

3. 用Arduino Uno燒pro mini 

google一下應該也蠻多人這樣做的
好像要把ATmega328p拔下來 把pro mini裝上去
還沒試過

參考:
1. 葉難(Arduino與AVR微控制器相關詞彙):http://yehnan.blogspot.tw/2013/01/arduinoterms.html
=> 裡面有SPI、I2C、UART等解釋名詞
2. 小狐狸事務所(Arduino pro mini動了):http://yhhuang1966.blogspot.tw/2015/03/arduino-pro-mini.html
=> 用SPI來燒錄

———————————————————————————————————————–

用終端機讀UART

在terminal上

ls /dev*

看一下我們的裝置是哪一個
最簡單的判斷方法就是
不要插先查
之後插完再查一次
對照一下哪個多出來的
插入PL2303的話是 tty.usbserial 和 cu.usbserial
但是用tty才可以
tty和cu的差別看這篇
MAC電腦連接埠:http://arduino.tw/articlesindex/electricity/293-devcudevtty.html

screen tty.usbserial 9600

Arduino練習題

1.  居家安全系統-簡單:
偵測按鈕是否被按壓,是->亮LED警告,否->沒事

/*
  Program1- Home Security System-simple
  This program is made by CCU COMM RongSon.
  Only for SERVICE-LEARNING use.
*/

int buttonInput=7;
int ledOutput=8;
int warning=0;

void setup(){
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println(“setup!”);
  pinMode(ledOutput,OUTPUT);
  pinMode(buttonInput,INPUT);
}

void loop() {
  warning= digitalRead(buttonInput);
  if(warning==0){
    Serial.println(“nothing happen”);
  }else{
    Serial.print(“Warning!!!!!!:”);
    Serial.println(warning);
    digitalWrite(ledOutput,HIGH);
    delay(1000);
    digitalWrite(ledOutput,LOW);
  }
  delay(500);
}

next->
1. 換四腳按鈕

2. debounce (?

3. 加光敏電阻

4. 按鈕架構換成 按著光敏電阻+麥克風