2017년 8월 8일 화요일

RTC 모듈로 릴레이 작동시키기

http://cafe.naver.com/diymaker/11 에 사용한 RTC 모듈을 간단하게 릴레이를 작동시키는 타이머로 사용하는 방법입니다.

Blynk 앱으로는 간단하게 되는데 웹으로 지원하는 IoT 사이트에서는 원격으로 타이머처리를 할려니 안되는 곳도 있고 

설정이 복잡하더군요.


#include <Wire.h>
#include "RTClib.h"

// PIN definitions
#define RELAY_PIN 2

// FSM states
#define STATE_OFF  0
#define STATE_ON   1

// Timer settings
#define START_TIME  2144
#define END_TIME    2146

// variables
RTC_DS1307 RTC;
int fsm_state;

void setup() {
  
  Serial.begin(57600);
  Serial.println("SimpleTimer running...");
  Serial.println();

  Wire.begin();
  RTC.begin();  

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);
  fsm_state = STATE_OFF;
}

void loop() {

  DateTime now = RTC.now();
  int nowHourMinute = now.hour() * 100 + now.minute();

  // FSM states
  switch(fsm_state) {
    
    case STATE_OFF:
      if(nowHourMinute > START_TIME && nowHourMinute < END_TIME) {
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.println(", it's time to wake up!");
        digitalWrite(RELAY_PIN, HIGH);
        fsm_state = STATE_ON;
      }
      break;
    
    case STATE_ON:
      if(nowHourMinute > END_TIME) {
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);        
        Serial.println(", it's time to go to sleep!");
        digitalWrite(RELAY_PIN, LOW);
        fsm_state = STATE_OFF;
      }    
      break;
  }
}


유량센서 사용하기 - 인터럽트 이용

유량센서 작동방식이 홀센서가 내부에 있어서 1회전에 할때마다 트리거가 발생하는 원리이므로

트리거 신호를 인터럽트에 연결시켜서 회전수를 카운트 해서 유량을 계산하는 코드입니다.

신호선에는 10K 저항을 연결해서 풀업저항으로 만들어 줍니다. 

1회전시 유량은 유량센서 용량에 따라 다르므로 스펙에 맞게 공식을 수정해야 할 것 같습니다.

제가 구한 유량센서는 The frequency calculation = constant flow rate (L/min) 7.5 * unit time (in seconds)

분당 7.5 리터니깐 초당 계산하니깐 60을 더 곱해줍니다.

인터럽트를 사용하니 SoftSerial은 사용할 수 없을것 같네요. 같이 인터럽트를 사용하니 WiFi을 연결하려면

하드웨어 시리얼을  이용해야 할 듯 합니다.

flow meter arduino

아래 사이트를 코드를 참고하였습니다.


// Reading liquid flow rate using an Arduino 
// Code adapted by Charles Gantt from PC Fan RPM code written by Crenn@thebestcasescenario.com
// http:/themakersworkbench.com http://thebestcasescenario.com 

volatile int NbTopsFan;            //measuring the rising edges of the signal
int Calc; 
int hallsensor = 2;                //The pin location of the sensor

void rpm ()                        //This is the function that the interupt calls
{
  NbTopsFan++;                     //This function measures the rising and falling edge of signal
}                                  //The setup() method runs once, when the sketch starts

void setup() 

{
 pinMode(hallsensor, INPUT);       //initializes digital pin 2 as an input
 Serial.begin(9600);               //This is the setup function where the serial port is initialised
 attachInterrupt(0, rpm, RISING);  //and the interrupt is attached
}
                                   // the loop() method runs over and over again
                                   // as long as the Arduino has power
void loop () 
{
 NbTopsFan = 0;                    //Set NbTops to 0 ready for calculations
 sei();                            //Enables interrupts
 delay (1000);                     //Wait 1 second
 cli();                            //Disable interrupts
 Calc = (NbTopsFan * 60 / 7.5);    //(Pulse frequency x 60) / 7.5Q = flow rate in L/hour
 Serial.print (Calc, DEC);         //Prints the number calculated above
 Serial.print (" L/hour\r\n");     //Prints "L/hour" and returns a new line
}

초음파 센서 이용하기

초음파 센서로 간단하게 거리를 측정하는 코드입니다.

Trig핀으로 신호를 보내고 Echo핀으로 측정값을 받습니다.

측정된 값을 왕복이니깐 2로 나누고, 소리는 초당 343m를 이동하므로, 1cm를 이동하는데 29.155ms가 소요되므로 29.1을

나누어 줍니다.

/*
HC-SR04 Ping distance sensor]
VCC to arduino 5v GND to arduino GND
Echo to Arduino pin 13 Trig to Arduino pin 12
Red POS to Arduino pin 11
Green POS to Arduino pin 10
560 ohm resistor to both LED NEG and GRD power rail
More info at: http://goo.gl/kJ8Gl
Original code improvements to the Ping sketch sourced from Trollmaker.com
Some code and wiring inspired by http://en.wikiversity.org/wiki/User:Dstaub/robotcar
*/

#define trigPin 13
#define echoPin 12
#define led 11
#define led2 10

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(led, OUTPUT);
  pinMode(led2, OUTPUT);
}

void loop() {
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(1000); - Removed this line
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1; // 소리는 초당 343m를 이동하므로, 1cm를 이동하는데 29.155ms가 소요됨
  if (distance < 4) {  // This is where the LED On/Off happens
    digitalWrite(led,HIGH); // When the Red condition is met, the Green LED should turn off
  digitalWrite(led2,LOW);
}
  else {
    digitalWrite(led,LOW);
    digitalWrite(led2,HIGH);
  }
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
  }
  delay(500);
}


MQ-2 가스센서 사용하기

가스센서중에 MQ-2 센서는 메탄, 알콜, CO, 1프로판, LPG 가스는 물론 연기까지 감지가 가능해서 가스 누출 경보기, 화재경보기로

응용이 가능할 듯 합니다. 

다음 링크에 설명이 잘되어 있는데요. http://www.seeedstudio.com/wiki/Grove_-_Gas_Sensor%28MQ2%29

 처음에 자기 집의 깨끗한 환경에서 먼저 센서 평균 R0 값을 구합니다.

void setup() {
  Serial.begin(9600);
}
 
void loop() {
  float sensor_volt; 
  float RS_air; //  Get the value of RS via in a clear air
  float R0;  // Get the value of R0 via in H2
  float sensorValue;
 
/*--- Get a average data by testing 100 times ---*/   
    for(int x = 0 ; x < 100 ; x++)
  {
    sensorValue = sensorValue + analogRead(A0);
  }
  sensorValue = sensorValue/100.0;
/*-----------------------------------------------*/
 
  sensor_volt = sensorValue/1024*5.0;
  RS_air = (5.0-sensor_volt)/sensor_volt; // omit *RL
  R0 = RS_air/10.0; // The ratio of RS/R0 is 10 in a clear air
 
  Serial.print("sensor_volt = ");
  Serial.print(sensor_volt);
  Serial.println("V");
 
  Serial.print("R0 = ");
  Serial.println(R0);
  delay(1000);
 
}
그 다음에 아래 코드의 R0 값을 위에서 구한 값으로 대치합니다.

제 방에서 구한 값이 평균 1.5 정도 나와서 그 값으로 교체했습니다.
void setup() {
  Serial.begin(9600);
}
 
void loop() {
  float R0 = 1.5;//미리 측정한 값
  float sensor_volt;
  float RS_gas; // Get value of RS in a GAS
  float ratio; // Get ratio RS_GAS/RS_air
  int sensorValue = analogRead(A0);
  sensor_volt=(float)sensorValue/1024*5.0;
  RS_gas = (5.0-sensor_volt)/sensor_volt; // omit *RL
 
  /*-Replace the name "R0" with the value of R0 in the demo of First Test -*/
  ratio = RS_gas/R0;  // ratio = RS/R0 
  /*-----------------------------------------------------------------------*/
 
  Serial.print("sensor_volt = ");
  Serial.println(sensor_volt);
  Serial.print("RS_ratio = ");
  Serial.println(RS_gas);
  Serial.print("Rs/R0 = ");
  Serial.println(ratio);
 
  Serial.print("\n\n");
 
  delay(1000);
 
}
센서에는 아나로그 값과 디지털값이 둘다 출력가능하며 아나로그 값은 데이타시트의 아래 그래프처럼 일반적인 공기는 10 언저리를 유지하다가

가스가 감지되면 값이 내려 갑니다.  디지털값은 처음에는  HIGH 값이다가 감지되면 LOW 값이 출력됩니다. 감도는 센서의 저항을 조정하여

조절 가능합니다.





NeoPixel RGB LED 제어하기

NeoPixel RGB LED는 각각의 RGB을 하나의 라인으로 제어할 수 있습니다. 그래서 옥외 광고용으로 유용하지요.

처음 데이타 입력핀을 스파크 방지차원에서 500옴 정도되는 저항으로 연결하는게 좋다는군요. 

입력되는 핀이 하나뿐이라 간단합니다. 6번핀에 연결하고 아래와 같이 하면 간단히 테스트가 가능합니다.

테스트차원에서 2개만 연결해서 각각 테스트 해봤습니다.

// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN            6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      2

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int delayval = 1000; // delay for half a second

void setup() {
  pixels.begin(); // This initializes the NeoPixel library.
  pixels.setBrightness(64);
}

void loop() {

  // For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.

  for(int i=0;i<NUMPIXELS;i++)
  {

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(0,250,0)); // Moderately bright green color.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(delayval); // Delay for a period of time (in milliseconds).

  }
}

조도 센서 사용하기

빛의 세기에 따라 저항값이 변하는 조도센서인 LDR (light dependent resistor) 에 대해서 알아 보겠습니다.

빛이 세면 저항이 낮아져서 측정값이 낮게나오고, 빛이 약하면 저항이 높아져서 측정값이 높게 나오는 특성이 있습니다.

비교할 고정 저항 10K을 아나로그 핀에 연결해 줍니다.



코드는 초간단합니다.

int LDR_Pin = A0; //analog pin 0

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

void loop(){
  int LDRReading = analogRead(LDR_Pin); 

  Serial.print("sensor = ");
  Serial.println(LDRReading);
  delay(250); //just here to slow down the output for easier reading
}

습기 센서 사용하기

흙 습기를 측정할 수 있는 센서를 이용해 보겠습니다.

화분에 꽂아서 값이 어느 이하로 나오면 LED가 들어 오게 하면 사무실에서 화분키우다가 

말려 죽이는 일은 적어지지 않을까 싶네요.


위에 링크를 보니 센서값이 300 이하면 마른 것이고 700 이상은 물이 너무 많은 것이다고 하는데

화분에 키우는 식물에 맞게 체크 값은 조정하면 될 것 같습니다.

계속 센서를 화분에 끼워 높으면 오염될수 있다고 하는데요.

해결책은 센서에 전류를 사용할때만 통하면 좀 나은듯 합니다. 그래서 위 링크에서는 TR을 사용했는데,

집에 화분에 테스트해보니 그냥 아두이노 디지털 핀을 사용해도 어느 정도 비슷한 값이 나오네요.

그런데 1분 정도되어야 값이 안정화 되는 것 같습니다. 그 전까지는 값이 조금씩 증가하네요.

int sensorPin = 0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
 
void setup() {
  // declare the ledPin as an OUTPUT:
  pinMode(12, OUTPUT); //LED
  pinMode(13, OUTPUT); //Sensor Power
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
   Serial.begin(9600);  
}
 
void loop() {
  // read the value from the sensor:
  digitalWrite(13, HIGH);
  delay(2000);
  sensorValue = analogRead(sensorPin);  
  delay(1000);  
  Serial.print("sensor = " );                       
  Serial.println(sensorValue);  
  digitalWrite(13, LOW);

  if(sensorValue < 300)
      digitalWrite(12, HIGH);
  else
     digitalWrite(12, LOW);
  delay(5000);                    
}

지자계 센서 사용하기

핸드폰에도 들어 있는 콤파스 역할을 하는 지자계 센서를 다뤄 보겠습니다.

드론에도 GPS 와 같이 지자계 센서가 들어 있어 웨이포인트를 설정하여 자동비행에 이용되기도 합니다.

지자계 센서로 HMC5883L 을 이용해 보겠습니다. 이 모듈도 I2C 포트를 이용합니다.

라이브러리를 첨부된 파일을 압축을 푼후 직접 복사해서 넣으면 됩니다.

이건 I2Cdev 라이브러리도 필요하네요. 

// I2C device class (I2Cdev) demonstration Arduino sketch for HMC5883L class
// 10/7/2011 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
//     2013-05-04 - Added Heading Calculation in degrees
//     2011-10-07 - initial release

/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2011 Jeff Rowberg

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#include "Wire.h"

// I2Cdev and HMC5883L must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "HMC5883L.h"

// class default I2C address is 0x1E
// specific I2C addresses may be passed as a parameter here
// this device only supports one I2C address (0x1E)
HMC5883L mag;

int16_t mx, my, mz;

#define LED_PIN 13
bool blinkState = false;

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    Wire.begin();

    // initialize serial communication
    // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
    // it's really up to you depending on your project)
    Serial.begin(38400);

    // initialize device
    Serial.println("Initializing I2C devices...");
    mag.initialize();

    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(mag.testConnection() ? "HMC5883L connection successful" : "HMC5883L connection failed");

    // configure Arduino LED for
    pinMode(LED_PIN, OUTPUT);
}

void loop() {
    // read raw heading measurements from device
    mag.getHeading(&mx, &my, &mz);

    // display tab-separated gyro x/y/z values
    Serial.print("mag:\t");
    Serial.print(mx); Serial.print("\t");
    Serial.print(my); Serial.print("\t");
    Serial.print(mz); Serial.print("\t");
    
// To calculate heading in degrees. 0 degree indicates North
    float heading = atan2(my, mx);
    if(heading < 0)
      heading += 2 * M_PI;
    Serial.print("heading:\t");
    Serial.println(heading * 180/M_PI);

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
    delay(500);
}




자이로/가속도 센서 사용하기

자이로와 가속도 센서가 한칩에 들어 있는 MPU6050 센서를 다뤄 보겠습니다.
핸드폰이나 드론에 꼭 들어 있는 센서이죠. 

드론의 자세를 스스로 잡을수 있도록 하여 조종하기 쉽도록 도와주죠.


위에 글에 잘 정리되어 있네요. 이 모듈도 I2C 포트를 이용합니다.

라이브러리를 첨부된 파일을 압축을 푼후 직접 복사해서 넣으면 됩니다.

// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

출력  데이타는 움직여야 변화하니 동영상도 같이 보여 드리겠습니다.




기압센서 사용하기

만약 weather center를 만든다면 기압센서를 추가하면 데이타가 더 그럴싸 하겠죠? ^^

기압, 고도, 온도를 측정할 수 있는 BMP180 센서를 이용하면 되는데 제가  집에 굴러다니는 것이 

이전 모델인 BMP085 센서라 이걸로 먼저 테스트해 보겠습니다. 

라이브러리가 호환이 되고 BMP180 이 개선 버전이라고 하네요.

단위별 변환값은 아래와 같습니다.

1 hPa = 100 Pa = 1 mbar = 0.001 bar
1 hPa = 0.75006168 Torr
1 hPa = 0.01450377 psi (pounds per square inch)
1 hPa = 0.02953337 inHg (inches of mercury)
1 hpa = 0.00098692 atm (standard atmospheres)
#BMP180 스펙
  • Vin: 3 to 5VDC
  • Logic: 3 to 5V compliant
  • Pressure sensing range: 300-1100 hPa (9000m to -500m above sea level)
  • Up to 0.03hPa / 0.25m resolution
  • -40 to +85°C operational range, +-2°C temperature accuracy
  • This board/chip uses I2C 7-bit address 0x77.
온도 오차는 좀 커서 온도 센서는 따로 이용해야 겠네요.
습기에 민감하므로 센서에 구멍이 있는데 여기로 물이 들어가지 않도록 주의해야 하고 
바람에 오차가 발생할 수 있으니 야외에 사용할때는 스펀지를 대주는 것도 한가지 방법이
되겠습니다.
/* SFE_BMP180 altitude example sketch
This sketch shows how to use the Bosch BMP180 pressure sensor
as an altimiter.
Like most pressure sensors, the BMP180 measures absolute pressure.
Since absolute pressure varies with altitude, you can use the pressure
to determine your altitude.
Because pressure also varies with weather, you must first take a pressure
reading at a known baseline altitude. Then you can measure variations
from that pressure
Hardware connections:
- (GND) to GND
+ (VDD) to 3.3V
(WARNING: do not connect + to 5V or the sensor will be damaged!)
You will also need to connect the I2C pins (SCL and SDA) to your
Arduino. The pins are different on different Arduinos:
Any Arduino pins labeled:  SDA  SCL
Uno, Redboard, Pro:        A4   A5
Mega2560, Due:             20   21
Leonardo:                   2    3
Leave the IO (VDDIO) pin unconnected. This pin is for connecting
the BMP180 to systems with lower logic levels such as 1.8V
Have fun! -Your friends at SparkFun.
The SFE_BMP180 library uses floating-point equations developed by the
Weather Station Data Logger project: http://wmrx00.sourceforge.net/
Our example code uses the "beerware" license. You can do anything
you like with this code. No really, anything. If you find it useful,
buy me a beer someday.
V10 Mike Grusin, SparkFun Electronics 10/24/2013
V1.1.2 Updates for Arduino 1.6.4 5/2015
*/
// Your sketch must #include this library, and the Wire library.
// (Wire is a standard library included with Arduino.):
#include <SFE_BMP180.h>
#include <Wire.h>
// You will need to create an SFE_BMP180 object, here called "pressure":
SFE_BMP180 pressure;
double baseline; // baseline pressure
void setup()
{
  Serial.begin(9600);
  Serial.println("REBOOT");
  // Initialize the sensor (it is important to get calibration values stored on the device).
  if (pressure.begin())
    Serial.println("BMP180 init success");
  else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.
    Serial.println("BMP180 init fail (disconnected?)\n\n");
    while(1); // Pause forever.
  }
  // Get the baseline pressure:
  baseline = getPressure();
  Serial.print("baseline pressure: ");
  Serial.print(baseline);
  Serial.println(" mb");  
}
void loop()
{
  double a, P;
  // Get a new pressure reading:
  P = getPressure();
  Serial.print("Pressure: ");
  Serial.print(P);
  Serial.println("hPa");
  // Show the relative altitude difference between
  // the new reading and the baseline reading:
  a = pressure.altitude(P,baseline);
  Serial.print("relative altitude: ");
  if (a >= 0.0) Serial.print(" "); // add a space for positive numbers
  Serial.print(a,1);
  Serial.print(" meters, ");
  if (a >= 0.0) Serial.print(" "); // add a space for positive numbers
  Serial.print(a*3.28084,0);
  Serial.println(" feet");
  delay(2000);
}
double getPressure()
{
  char status;
  double T,P,p0,a;
  // You must first get a temperature measurement to perform a pressure reading.
  // Start a temperature measurement:
  // If request is successful, the number of ms to wait is returned.
  // If request is unsuccessful, 0 is returned.
  status = pressure.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);
    // Retrieve the completed temperature measurement:
    // Note that the measurement is stored in the variable T.
    // Use '&T' to provide the address of T to the function.
    // Function returns 1 if successful, 0 if failure.
    status = pressure.getTemperature(T);
    if (status != 0)
    {
      // Start a pressure measurement:
      // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
      // If request is successful, the number of ms to wait is returned.
      // If request is unsuccessful, 0 is returned.
      Serial.print("Temp: ");
      Serial.print(T);
      Serial.println("C");
      status = pressure.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);
        // Retrieve the completed pressure measurement:
        // Note that the measurement is stored in the variable P.
        // Use '&P' to provide the address of P.
        // Note also that the function requires the previous temperature measurement (T).
        // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
        // Function returns 1 if successful, 0 if failure.
        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          return(P);
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");
}

캐릭터 LCD 16x2 I2C로 출력하기

캐릭터 LCD 16X2 디스플레이의 장점은 저렴하게 출력장치를 구현할  수 있다는 것인데요.

단점은 필요한 핀이 너무 많다는 거죠. 그래서 I2C 포트를 이용할 수 있게 해주는

I2C 컨버터를 연결해서 I2C 포트로 전에 이용해본 RTC 모듈로 시간을 출력해 보겠습니다.

아두이노의 SCL, SDA 핀에 연결합니다. I2C 통신을 위해 Wire 라이브러리가 필요한데

아두이노 스케치 프로그램내에 기본 라이브러리로 포함되어 있습니다.

I2C 모듈은 각자 자기 고유의 주소값이 있는데 확인하는 방법은 http://cafe.naver.com/diymaker/15 글을 확인하세요.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

RTC_DS1307 RTC;
 
void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
    lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
 
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__)); //현재 시간설정
  }
 
}
 
void loop () {
    DateTime now = RTC.now();

    lcd.clear();
    lcd.home(); //첫행
    lcd.print(now.year(), DEC);
    lcd.print('/');
    lcd.print(now.month(), DEC);
    lcd.print('/');
    lcd.print(now.day(), DEC);
    
    lcd.setCursor(0, 1); //다음 행
   lcd.print(getTimeStr(now.hour()));
    lcd.print(':');
    lcd.print(getTimeStr(now.minute()));
    lcd.print(':');
    lcd.print(getTimeStr(now.second()));
 
    delay(1000);
}

String getTimeStr(int time)
{
    String str;
    if (time < 10) { str = "0" + String(time); } 
    else { str = String(time); }
    return str;
}


온습도 측정하기 - DHT22 센서이용

DHT11 센서 업그레이드 버전인 DHT22 센서로 테스트 해보았습니다.

DHT11은 파란색인데 DHT22는 흰색 케이스이네요. 

DHT 센서용 라이브러리를 찾아보니 종류가 여러가지가 있더군요.

그런데 아래 라이브러리가 Heat Index 출력 기능이 있네요. 이게 뭔가 찾아보니 대략 체감 온도 같습니다.


센서 핀에 표시가 없네요. 왼쪽부터 1번핀이 5V이고 2번핀이 데이타핀으로 5V와 10K 저항을 연결해줍니다. 

3번핀은 연결안하고 4번핀을 GND에 연결해줍니다.



// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 5     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");

  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
 // float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.print(" *C ");
  //Serial.print(hif);
  //Serial.println(" *F");
}