Вот чего собрал на досуге: часы-метеостанцию на Ардуино Что понадобилось: Arduino UNO DS3231 (на шине i2c) DHT11 (на 11 ноге ардуино) GY-65 (BMP085) (на шине i2c) LCD1602 (на 2-3-4-5-6-7 ногах ардуино) А еще кусочек оргстекла, несколько стоек, монтажная платка. Код собрал из разных скетчей - примеров работы с датчиками. Собирал в основном ради интереса и ради попробовать. Температура берется с датчика давления и с dht11, значения совпадают.
В планах прикрутить внешний температурный датчик на ds18b20, чтоб температуру на улице измерять. Или на KTY81-200 через аналоговую ногу с ацп. Тоже интересно получается, уже пробовал... Аналоговый датчик правда менее точным будет. Либо надо было покупать DHT22 и выносить его на улицу. У него диапазон измерения температуры шире.
Часы устанавливал отдельным скетчем через эмулятор терминала, в данном варианте установку часов не предусматривал.
Я кстати переписал скетч, отказавшись от использования библиотеки bmp085 v4. Сейчас в теме новый скетч.
Сам скетч: ---------------------------------------------
#include <Wire.h> #include <dht11.h> #include <LiquidCrystal.h> LiquidCrystal lcd(7, 6, 5, 4, 3, 2); #define BMP085_ADDRESS 0x77 // I2C address of BMP085 dht11 sensor; #define DHT11PIN 11 #define DS1307_ADDRESS 0x68 const unsigned char OSS = 0; // Oversampling Setting // Calibration values int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) // so ...Temperature(...) must be called before ...Pressure(...). long b5; short temperature; long pressure; void setup() { lcd.begin(16, 2); Wire.begin(); bmp085Calibration(); } void loop() { lcd.clear(); for (int i=0; i<=100; i++){ //bmp085 temperature = bmp085GetTemperature(bmp085ReadUT()); pressure = bmp085GetPressure(bmp085ReadUP()); lcd.setCursor(0, 0); lcd.print("P="); int press=pressure/133.3; lcd.print(press); lcd.print("mm"); lcd.setCursor(8, 0); lcd.print("T1="); lcd.print(temperature/10); lcd.print("oC"); //dht-11 delay (20); int chk = sensor.read(DHT11PIN); lcd.setCursor(0, 1); lcd.print("Hum="); lcd.print(sensor.humidity); lcd.print("%"); lcd.setCursor(8, 1); lcd.print("T2="); lcd.print(sensor.temperature); lcd.print("oC"); }
//отсюда работа с часиками printDate(); delay(40); } byte bcdToDec(byte val) { // Convert binary coded decimal to normal decimal numbers return ( (val/16*10) + (val%16) ); } void printDate(){ lcd.clear(); //цикл под "живые" часики for (int i=0; i<=600; i++){ // Reset the register pointer Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); int second = bcdToDec(Wire.read()); int minute = bcdToDec(Wire.read()); int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time int weekDay = bcdToDec(Wire.read()); //0-6 -> Sunday - Saturday int monthDay = bcdToDec(Wire.read()); int month = bcdToDec(Wire.read()); int year = bcdToDec(Wire.read()); //Рисуем дату и время на lcd: День/Месяц/Год День недели lcd.setCursor(0, 0); lcd.print(monthDay); lcd.print("/"); if (month==1){lcd.print ("Jan");} if (month==2){lcd.print ("Feb");} if (month==3){lcd.print ("Mar");} if (month==4){lcd.print ("Apr");} if (month==5){lcd.print ("May");} if (month==6){lcd.print ("Jun");} if (month==7){lcd.print ("Jul");} if (month==8){lcd.print ("Aug");} if (month==9){lcd.print ("Sep");} if (month==10){lcd.print ("Oct");} if (month==11){lcd.print ("Nov");} if (month==12){lcd.print ("Dec");} lcd.print("/"); lcd.print(year+2000); if (weekDay==0){lcd.print (" Sun.");} if (weekDay==1){lcd.print (" Mon.");} if (weekDay==2){lcd.print (" Tue.");} if (weekDay==3){lcd.print (" Wed.");} if (weekDay==4){lcd.print (" Thu.");} if (weekDay==5){lcd.print (" Fri.");} if (weekDay==6){lcd.print (" Sat.");} lcd.setCursor(4, 1); if (hour<10) {lcd.print(0);lcd.print(hour);} else {lcd.print(hour);} lcd.print(":"); if (minute<10) {lcd.print(0);lcd.print(minute);} else {lcd.print(minute);} lcd.print(":"); if (second<10) {lcd.print(0);lcd.print(second);} else {lcd.print(second);} } } // Stores all of the bmp085's calibration values into global variables // Calibration values are required to calculate temp and pressure // This function should be called at the beginning of the program void bmp085Calibration() { ac1 = bmp085ReadInt(0xAA); ac2 = bmp085ReadInt(0xAC); ac3 = bmp085ReadInt(0xAE); ac4 = bmp085ReadInt(0xB0); ac5 = bmp085ReadInt(0xB2); ac6 = bmp085ReadInt(0xB4); b1 = bmp085ReadInt(0xB6); b2 = bmp085ReadInt(0xB8); mb = bmp085ReadInt(0xBA); mc = bmp085ReadInt(0xBC); md = bmp085ReadInt(0xBE); } // Calculate temperature given ut. // Value returned will be in units of 0.1 deg C short bmp085GetTemperature(unsigned int ut) { long x1, x2;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11)/(x1 + md); b5 = x1 + x2; return ((b5 + 8)>>4); } // Calculate pressure given up // calibration values must be known // b5 is also required so bmp085GetTemperature(...) must be called first. // Value returned will be pressure in units of Pa. long bmp085GetPressure(unsigned long up) { long x1, x2, x3, b3, b6, p; unsigned long b4, b7;
return Wire.read(); } // Read 2 bytes from the BMP085 // First byte will be from 'address' // Second byte will be from 'address'+1 int bmp085ReadInt(unsigned char address) { unsigned char msb, lsb;
return (int) msb<<8 | lsb; } // Read the uncompensated temperature value unsigned int bmp085ReadUT() { unsigned int ut;
// Write 0x2E into Register 0xF4 // This requests a temperature reading Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x2E); Wire.endTransmission();
// Wait at least 4.5ms delay(5);
// Read two bytes from registers 0xF6 and 0xF7 ut = bmp085ReadInt(0xF6); return ut; } // Read the uncompensated pressure value unsigned long bmp085ReadUP() { unsigned char msb, lsb, xlsb; unsigned long up = 0;
// Write 0x34+(OSS<<6) into register 0xF4 // Request a pressure reading w/ oversampling setting Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x34 + (OSS<<6)); Wire.endTransmission();
// Wait for conversion, delay time dependent on OSS delay(2 + (3<<OSS));
Добавлено (04.03.2014, 18:47) --------------------------------------------- Прилепил на 8 ногу датчик температуры ds18b20+ У каждого датчика свой, уникальный адрес. Его искать с помощью скетча из следующего сообщения (скетч под спойлером) На 9 ногу перенес DHT11 А сейчас новый код... ------------------------------------------------------------------------------------------------------
#define BMP085_ADDRESS 0x77 // I2C address of BMP085 dht11 sensor; #define DHT11PIN 9 //9 порт ардуино под dht11 #define DS1307_ADDRESS 0x68 const unsigned char OSS = 0; // Oversampling Setting // Calibration values int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) // so ...Temperature(...) must be called before ...Pressure(...). long b5; short temperature; long pressure; void setup() { lcd.begin(16, 2); lcd.createChar(1, gradus); Wire.begin(); bmp085Calibration(); sensors.begin(); sensors.setResolution(insideThermometer, 10); } void printTemperature(DeviceAddress deviceAddress) { short tempC = sensors.getTempC(deviceAddress); lcd.print(tempC); } void loop() { lcd.clear(); //bmp085 temperature = bmp085GetTemperature(bmp085ReadUT()); pressure = bmp085GetPressure(bmp085ReadUP()); lcd.setCursor(0, 0); lcd.print("P="); int press=pressure/133.3; lcd.print(press); lcd.print("mm"); lcd.setCursor(8, 0); lcd.print("T1="); lcd.print(temperature/10); lcd.print("\1C"); //dht-11 int chk = sensor.read(DHT11PIN); lcd.setCursor(0, 1); lcd.print("Hum="); lcd.print(sensor.humidity); lcd.print("%"); lcd.setCursor(8, 1); lcd.print("T2="); //ds18b20+ temp sensors.requestTemperatures(); printTemperature(insideThermometer); // lcd.print(sensor.temperature); lcd.print("\1C"); delay(3000); //отсюда работа с часиками printDate(); delay(40); } byte bcdToDec(byte val) { // Convert binary coded decimal to normal decimal numbers return ( (val/16*10) + (val%16) ); } void printDate(){ lcd.clear(); //цикл под "живые" часики for (int i=0; i<=600; i++){ // Reset the register pointer Wire.beginTransmission(DS1307_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); int second = bcdToDec(Wire.read()); int minute = bcdToDec(Wire.read()); int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time int weekDay = bcdToDec(Wire.read()); //0-6 -> Sunday - Saturday int monthDay = bcdToDec(Wire.read()); int month = bcdToDec(Wire.read()); int year = bcdToDec(Wire.read()); //Рисуем дату и время на lcd: День/Месяц/Год День недели lcd.setCursor(0, 0); if (monthDay<10) {lcd.print(0);lcd.print(monthDay);} else {lcd.print(monthDay);} lcd.print("/"); if (month==1){lcd.print ("Jan");} if (month==2){lcd.print ("Feb");} if (month==3){lcd.print ("Mar");} if (month==4){lcd.print ("Apr");} if (month==5){lcd.print ("May");} if (month==6){lcd.print ("Jun");} if (month==7){lcd.print ("Jul");} if (month==8){lcd.print ("Aug");} if (month==9){lcd.print ("Sep");} if (month==10){lcd.print ("Oct");} if (month==11){lcd.print ("Nov");} if (month==12){lcd.print ("Dec");} lcd.print("/"); lcd.print(year+2000); if (weekDay==0){lcd.print (" Sun.");} if (weekDay==1){lcd.print (" Mon.");} if (weekDay==2){lcd.print (" Tue.");} if (weekDay==3){lcd.print (" Wed.");} if (weekDay==4){lcd.print (" Thu.");} if (weekDay==5){lcd.print (" Fri.");} if (weekDay==6){lcd.print (" Sat.");} lcd.setCursor(4, 1); if (hour<10) {lcd.print(0);lcd.print(hour);} else {lcd.print(hour);} lcd.print(":"); if (minute<10) {lcd.print(0);lcd.print(minute);} else {lcd.print(minute);} lcd.print(":"); if (second<10) {lcd.print(0);lcd.print(second);} else {lcd.print(second);} } } // Stores all of the bmp085's calibration values into global variables // Calibration values are required to calculate temp and pressure // This function should be called at the beginning of the program void bmp085Calibration() { ac1 = bmp085ReadInt(0xAA); ac2 = bmp085ReadInt(0xAC); ac3 = bmp085ReadInt(0xAE); ac4 = bmp085ReadInt(0xB0); ac5 = bmp085ReadInt(0xB2); ac6 = bmp085ReadInt(0xB4); b1 = bmp085ReadInt(0xB6); b2 = bmp085ReadInt(0xB8); mb = bmp085ReadInt(0xBA); mc = bmp085ReadInt(0xBC); md = bmp085ReadInt(0xBE); } // Calculate temperature given ut. // Value returned will be in units of 0.1 deg C short bmp085GetTemperature(unsigned int ut) { long x1, x2;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11)/(x1 + md); b5 = x1 + x2; return ((b5 + 8)>>4); } // Calculate pressure given up // calibration values must be known // b5 is also required so bmp085GetTemperature(...) must be called first. // Value returned will be pressure in units of Pa. long bmp085GetPressure(unsigned long up) { long x1, x2, x3, b3, b6, p; unsigned long b4, b7;
return Wire.read(); } // Read 2 bytes from the BMP085 // First byte will be from 'address' // Second byte will be from 'address'+1 int bmp085ReadInt(unsigned char address) { unsigned char msb, lsb;
return (int) msb<<8 | lsb; } // Read the uncompensated temperature value unsigned int bmp085ReadUT() { unsigned int ut;
// Write 0x2E into Register 0xF4 // This requests a temperature reading Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x2E); Wire.endTransmission();
// Wait at least 4.5ms delay(5);
// Read two bytes from registers 0xF6 and 0xF7 ut = bmp085ReadInt(0xF6); return ut; } // Read the uncompensated pressure value unsigned long bmp085ReadUP() { unsigned char msb, lsb, xlsb; unsigned long up = 0;
// Write 0x34+(OSS<<6) into register 0xF4 // Request a pressure reading w/ oversampling setting Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x34 + (OSS<<6)); Wire.endTransmission();
// Wait for conversion, delay time dependent on OSS delay(2 + (3<<OSS));