До погодной станции еще далеко. Пока что просто посмотрим как получать данные с датчиков температуры, давления и влажности.
Итак, в ролях:
- Arduino Duemillanove
- BMP085 от Bosch Sensortec - датчик давления и температуры
- HIH-4030 от Honeywell - датчик влажности
Датчик влажности прост и незамысловат - подаете на него 5 вольт и получаете напряжение, линейно зависящее от влажности.
Датчик давления и температуры сложнее, он подключается по шине I2C и, кроме того, использует для питания 3.3V.
Итак собираем схему.
Датчик влажности подключаем к земле и питанию, ногу out подключаем к аналоговому входу №0 ардуино.
Датчик давления подключаем к земле и питанию 3.3 вольта, выходы SDA и SLC подключаем к аналоговым входам 4 и 5 соответственно.
Для получения значения влажности нам понадобятся некоторые константы, которые можно найти в даташите на HIH-4030:
static const int offset = 958;
static const int slope_coef = 10;
static const int slope = 307;
offset - напряжение, соответствующее нулевой относительной влажности, а slope - соотношение между напряжением и влажностью, составляющий 30.68 mV. Поскольку я собираюсь использовать только целочисленную арифметику, то slope заведем как 307 и добавим дополнительный делитель 10.
Функция получения относительной влажности будет выглядеть так:
int get_humidity() {
long voltage = analogRead(0); // получить значение 0..1023
voltage = voltage * 5000 / 1023; // преобразовать в микровольты
// вычислим относительную влажность в процентах
return ((voltage - offset) * slope / slope_coef) / 100;
}
Код для работы с BMP085 я стянул тут. Имейте в виду, у меня этот код не заработал сразу из-за путаницы с использованием типов int, unsigned int и long. Работающий код можно взять из репозитория на bitbucket.org или из zip-файла в конце статьи.
Для удобства все функции для работы с датчиками удобно собрать в библиотеку. Библиотека в IDE Arduino - это папка с файлами, лежащая в каталоге libraries в каталоге arduino. Библиотека содержит как минимум два файла - заголовочный h-файл и cpp-файл с кодом.
Я сделал такой заголовочный файл:
/*
Library of utility classes and functions for Arduino weather station
*/
#ifndef WEATHER_H
#define WEATHER_H
#include "WProgram.h"
// interface for humidity sensor HIH-4030
class Humidity {
private:
static const int offset = 958;
static const int slope_coef = 10;
static const int slope = 307;
int pin;
public:
Humidity(const int pin = 0);
// returns relative humidity in percents * 10
// to get actual humidity delete results by ten
long get_humidity();
int get_humidity_int();
};
#define I2C_ADDRESS 0x77
#define DEFAULT_OVERSAMPLING 3
class TemperaturePressure {
private:
int i2c_address;
unsigned char oversampling_setting; //oversamplig for measurement
static const unsigned char pressure_waittime[];// = { 5, 8, 14, 26 };
//taken straight from the BMP085 datasheet
int ac1, ac2, ac3;
unsigned int ac4, ac5, ac6;
int b1, b2, mb, mc, md;
int _temp;
long _pressure;
void get_calibration_data();
int read_int_register(unsigned char reg);
char read_register(unsigned char reg);
void write_register(unsigned char reg, unsigned char value);
unsigned int read_ut();
long read_up();
void read_temperature_and_pressure();
public:
TemperaturePressure();
TemperaturePressure(const int i2c_address, const int oversampling);
void read_data_from_sensor();
int get_temperature();
long get_pressure();
long get_pressure_hg();
void begin();
};
#endif
Как видно, библиотека содержит два класса - Humidity, для работы с датчиком влажности и TemperaturePressure, для работы с датчиком давления и температуры.
Для работы с датчиком давления используется библиотека Wire, которая включена в стандартный набор библиотек Arduino. К сожалению я не понял, как можно задействовать в своей библиотеке стандартные библиотеки ардуино, так что пришлось в программе включать два заголовочных файла - Wire.h и Weather.h
CPP-файл я показывать здесь не буду, чтобы не загромождать все текстом.
Ну и наконец скетч для ардуино, который использует библиотеку Weather:
#include <wire.h>
#include <weather.h>
#define HUMIDITY_PIN 0
Humidity humidity(HUMIDITY_PIN);
TemperaturePressure tempPres;
void setup() {
Serial.begin(9600);
Serial.println("Calibrating...");
tempPres.begin();
Serial.println("Calibrated");
// Light the LED when ready
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
}
void loop() {
int h = humidity.get_humidity_int();
tempPres.read_data_from_sensor();
int t = tempPres.get_temperature();
float p = tempPres.get_pressure() * 7.5006e-3; // convert to mmHg
Serial.print(t/10.0);
Serial.print(";");
Serial.print(p);
Serial.print(";");
Serial.println(h);
delay(60000);
}
Скетч получает данные о температуре, относительной влажности и давлении и передает их через последовательный порт на десктоп, где простой python-скрипт записывает их в CSV-файл. Из результирующих данных можно, к примеру, построить графики изменения параметров во времени.
Исходники библиотеки и скетча можно скачать отсюда или с помощью Mercurial забрать с bitbucket
Исходники библиотеки и скетча можно скачать отсюда или с помощью Mercurial забрать с bitbucket