LCD и BMP180 по шине I2C

Nike_com
Offline
Зарегистрирован: 20.02.2015

Народ, такое дело, есть экран, работает через переходник по шине I2C, когда висит один, то все хорошо работает. Есть BMP180, датчик давления и температуры, тестовые скейчи отлично работают, выводят даннтые в порт. При попытке объединить два скейча что-бы выводить данные с датчика на дисплей, ардуиноIDE выдает кучу ошибок. Подозреваю что из-за того что нет адресации, не знаю куда прописывать эти адреса. Гугл ни чего мне интересного не говорит, помогите разобраться.

З.Ы.Код выложу вечером и того что работает и того что не работает.

З.Ы.Ы. Прошу сильно не пинать я тольько учусь...

bwn
Offline
Зарегистрирован: 25.08.2014

Ну без кода тяжеловато ответить.

Nike_com
Offline
Зарегистрирован: 20.02.2015

bwn пишет:

Ну без кода тяжеловато ответить.

просьбу уловил, код дома, а я на работе, доберусь и выложу

 

Nike_com
Offline
Зарегистрирован: 20.02.2015
// DS1302:  CE   (RST) pin    -> Arduino Digital 5
//          I/O  (DAT) pin   -> Arduino Digital 6
//          SCLK (CLK) pin  -> Arduino Digital 7

// LCD I2C:    SDA       -> Arduino A4
//             SCL       -> Arduino A5      
// DS18B20:  Датчик температуры на 9 пине


#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DS1302.h>
#include <DallasTemperature.h>
#include <BMP085.h>

// Init the DS1302
DS1302 rtc(5, 6, 7);

// Обьявляем датчик давления
BMP085 dps = BMP085();

#define ONE_WIRE_BUS 12         // Датчик температуры на 9 пине
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(0x27,16,2);

//void set_time()
//{
//  rtc.setDOW(MONDAY); // Set Day-of-Week to FRIDAY
//  rtc.setTime(21,33, 00); // Set the time to 12:00:00 (24hr format)
//  rtc.setDate(03, 03, 2015); // Set the date to August 6th, 2010
//}
// Init a Time-data structure

Time t;

void setup()
{
  Serial.begin(9600);
  // Set the clock to run-mode, and disable the write protection
  rtc.halt(false);
  rtc.writeProtect(false);

  lcd.init();                      // Инициализация LCD
  lcd.backlight();

  sensors.begin();  //DS18D20 температурный датчик
   
  Wire.begin(); // инициализация
  delay(1000);  // датчика 
  dps.init();   // давления
 }

void loop()
{
  //sensors.requestTemperatures();    // получили температуру с ДС18Б20
  
  dps.getPressure(&Pressure);       //  получили давление в паскалях
  dps.getTemperature(&Temperature); // полусили температуру х.з. в каких единицах
  
  // Get data from the DS1302
 // t = rtc.getTime();
  
  //Read first sensor
  float temp = sensors.getTempCByIndex(0);
  
  //Print first sensor results
  lcd.print("T=");
  if (temp >= 0) {                          //выбираем место для курсора температуры
                  lcd.setCursor (4, 0 );    // если больше 0, то со 1 места,
                  } 
  else {
        lcd.setCursor (3, 0 );             // иначе с нулевого
       }             
  
  lcd.print(temp);  // пишем температуру 
  // lcd.print("   ");
 
 lcd.setCursor (0, 1 );
 lcd.print("mm Hg");  lcd.print(Pressure/133.3);      //Выводим давление в мм.рт ст
 lcd.setCursor (8, 1 );  
 lcd.print("T="); lcd.print(Temperature*0.1);        // Температуру в градусах Цельсия
 
  }

Вот код, который отказывается работать, у дисплея адрес по умолчанию стоит (0х27), у датчика ВМР180 - видел в тестовом скейче 0х77 кажись...

bwn
Offline
Зарегистрирован: 25.08.2014

Из за неправильной адресации ругаться не будет, там просто не работает. По отдельности все примеры работают (Dallas, BMP, RTC) правильно? Скиньте, что в ошибках выдает.

Nike_com
Offline
Зарегистрирован: 20.02.2015

В стандартных примерах все то-же самое, но ни кто не ругается и все работает:

This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
DS1302_LCD_DS18B20.ino: In function 'void loop()':
DS1302_LCD_DS18B20:59: error: 'Pressure' was not declared in this scope
DS1302_LCD_DS18B20:60: error: 'Temperature' was not declared in this scope

вот код датчика BMP180:

// BMP085_output
// by Filipe Vieira
// Simple example of library usage with almost every BMP085 and lib features being used.

#include <Wire.h>
#include <BMP085.h>

BMP085 dps = BMP085();
long Temperature = 0, Pressure = 0, Altitude = 0;

void setup(void) {
  Serial.begin(9600);
  Wire.begin();
  delay(1000);
	
  dps.init();   
  
  showall();
  
  Serial.println("Registers dump");
  Serial.println("==========================================================");
  dumpRegisters();
  Serial.println("Calibration data");
  Serial.println("==========================================================");
  dps.dumpCalData();
  
  delay(5000);
}
 

void loop(void) {
  dps.getTemperature(&Temperature); 
  dps.getPressure(&Pressure);
  dps.getAltitude(&Altitude);
  
  Serial.print("Temp(C):");
  Serial.print(Temperature);
  Serial.print("  Alt(cm):");
  Serial.print(Altitude);
  Serial.print("  Pressure(Pa):");
  Serial.println(Pressure);
}

void showall(void) { 
  Serial.println("Current BMP085 settings");
  Serial.println("==========================================================");
  Serial.print("device address                  = 0x");
  Serial.println(dps.getDevAddr(), HEX);
  Serial.print("Mode                            = ");
  switch (dps.getMode()) {
    case MODE_ULTRA_LOW_POWER: 
      Serial.println("MODE_ULTRA_LOW_POWER");
      break;
    case MODE_STANDARD: 
      Serial.println("MODE_STANDARD");
      break;    
    case MODE_HIGHRES: 
      Serial.println("MODE_HIGHRES");
      break;    
    case MODE_ULTRA_HIGHRES:     
      Serial.println("MODE_ULTRA_HIGHRES");
      break; 
  }  
}

void dumpRegisters() {
  byte ValidRegisterAddr[]={0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xF6,0xF7,0xF8,0xF9}; 
  byte _b, i, totregisters = sizeof(ValidRegisterAddr);
  Serial.println("---dump start---");
  Serial.println("Register address|Register data");
  Serial.println("Reg.address(hex,dec) Reg.data(bin,hex,dec)");
  for (i=0;i<totregisters;i++){    
    Serial.print("0x");
    Serial.print(ValidRegisterAddr[i], HEX);
    Serial.print(",");
    Serial.print(ValidRegisterAddr[i], DEC);
    Serial.print(",");
    dps.readmem(ValidRegisterAddr[i], 1, &_b);
    Serial.print("b");
    print_bits(_b);
    Serial.print(",0x");
    Serial.print(_b,HEX);
    Serial.print(",");
    Serial.println(_b,DEC);  
  }
  Serial.println("---dump end---");
}

void print_bits(byte val){
  int i;
  for(i=7; i>=0; i--) 
    Serial.print(val >> i & 1, BIN);
}
/* void print_unit16(uint16_t val){
  int i;
  for(i=15; i>=0; i--) 
    Serial.print(val >> i & 1, BIN);
} 
*/

Если в первоначальном закоментировать все что касается датчика, то все прекрасно компилится и работает.

bwn
Offline
Зарегистрирован: 25.08.2014

А куда у вас пропала строка 9 из кода BMP?

Nike_com
Offline
Зарегистрирован: 20.02.2015

Упс, как-то порпустил... Вечером внесу изменения и буду пробовать...

А как происходит адресация команд?

bwn
Offline
Зарегистрирован: 25.08.2014

Nike_com пишет:

Упс, как-то порпустил... Вечером внесу изменения и буду пробовать...

А как происходит адресация команд?

У них адреса не изменяемые и забиты жестко в библиотеку.

Nike_com
Offline
Зарегистрирован: 20.02.2015

Всем спаибо, дело было в этой строке инициалиации переменных, поправил, все прекрасно работает.

осталось разобраться с DS1302, то это уже другая тема.

OdinochkA
Offline
Зарегистрирован: 05.07.2015

Доброго времени. Подскажите пожалуйста, пытаюсь совместить DHT11 и LCD 128*64. Ничего не получается. По отдельности оба ингридиента работают. DHT в мониторе все данные выдает, дисплей картинки крутит. Но чтобы данные с датчика выводились на дисплейчик не получается. Пытался корректировать код приведённый здесь, но компиляция постоянно с ошибками.  Брал куски от тестовых и пытался их совместить. Опять же безрезультатно.

В сети много примеров, но для обычного дисплея 16*2. А для 128*64 не подходит.

Помогите кодом.

Привожу своё творение. Только сильно не смейтесь я только начал учиться.



#include "DHT.h"
#define DHTPIN 2     // what pin we're connected to

#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);
#include <OLED_I2C.h>
byte degree[8] =         // Битовая маска символа градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};    
 
OLED  myOLED(SDA, SCL, 8);   // Задаем адрес и размерность дисплея

extern uint8_t SmallFont[];

void setup() {
  myOLED.begin(); 
  myOLED.setFont(SmallFont);
 
  dht.begin();
}

//void loop() // потом поменять местами

//{
  // 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();
//  float t = dht.readTemperature();
//
  // check if returns are valid, if they are NaN (not a number) then something went wrong!
//  if (isnan(t) || isnan(h)) {
//    myOLED.println("Failed to read from DHT");
//  } else {
//    myOLED.println("Humidity: "); 
//    myOLED.println(h);
////    myOLED.println(" %\t");
 //   myOLED.println("Temperature: "); 
//    myOLED.println(t);
//    myOLED.println(" *C");
//  }


void loop() //потом перепроверить
{

float h = dht.readHumidity();
  float t = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  
  } 
 
    myOLED.print("Humidity: "); 
    myOLED.print(h);
    myOLED.print(" %\t");
    myOLED.print("Temperature: "); 
    myOLED.print(t);
    myOLED.println(" *C");
  
}
  
  //myOLED.clrScr();
  
  //myOLED.print("Humidity:" , LEFT, 0);     // Выводим текст
  //myOLED.print(DHT.humidity);
  //myOLED.print("Temp", CENTER, 8);    // Выводим текст, \1 - значок градуса
  //myOLED.print(DHT.temperature);  
  //myOLED.update();
  delay(1000);                     
}



PS не смог спрятать под спойлер

 

zugni
Offline
Зарегистрирован: 14.06.2015

попробуй вот этот   там с дисплем тебе придется повозится или заменить на свой 

#include <DS1302.h>
#include <Wire.h>        // Добавляем необходимые библиотеки
#include <LiquidCrystal_I2C.h>
#include <dht11.h>
dht11 DHT;               // Объявление переменной класса dht11
#define DHT11_PIN 7      // Датчик DHT11 подключен к цифровому пину номер 4

byte degree[8] =         // Битовая маска символа градуса
{
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
};    
 
LiquidCrystal_I2C lcdbig(0x27,16,2);   // Задаем адрес и размерность дисплея
LiquidCrystal_I2C lcdsmall(0x27,8,10);   // Задаем адрес и размерность дисплея

DS1302 rtc(2, 3, 4);    // (RST, DAT, CLK)

Time t;



void setup(){
  
  rtc.halt(false);
  rtc.writeProtect(false);
  rtc.setTime(12, 12, 00);
  
  lcdbig.init();                       // Инициализация lcdbig             
  lcdbig.backlight();                  // Включаем подсветку
  lcdbig.createChar(1, degree);        // Создаем символ под номером 1]
 
  
  lcdsmall.init();                       // Инициализация lcdbig             
  lcdsmall.backlight();                  // Включаем подсветку
  lcdsmall.createChar(1, degree);        // Создаем символ под номером 1
}

void loop(){
  
  t = rtc.getTime(); 
  lcdbig.print(rtc.getTimeStr());  
 
  
  // Выводим показания влажности и температуры
  lcdbig.setCursor(0, 0);              // Устанавливаем курсор в начало 1 строки
  lcdbig.print(" % ");                 // Выводим текст
  lcdbig.setCursor(3, 0); 
  lcdbig.print(DHT.humidity, 1);
  lcdbig.setCursor(0, 1);              // Устанавливаем курсор в начало 2 строки
  lcdbig.print("\1C ");                // Выводим текст, \1 - значок градуса
  lcdbig.setCursor(3, 1);             
  lcdbig.print(DHT.temperature,1);  
  lcdbig.setCursor(8, 1);
  lcdbig.print(rtc.getTimeStr());
  


    /*/Отображение текущего дня недели
  lcdsmall.setCursor(5,8); //указываем место печати дня недели
  switch (t.dow)// в зависимости от номера дня недели выводим на экран
  {
    case 1: lcdsmall.print("/Su/");    break;
    case 2: lcdsmall.print("/Mo/");    break;
    case 3: lcdsmall.print("/Tu/");    break;
    case 4: lcdsmall.print("/We/");    break;
    case 5: lcdsmall.print("/Th/");    break;
    case 6: lcdsmall.print("/Fr/");    break;
    case 7: lcdsmall.print("/Sa/");    break;
  }
  */

 int chk; // Мониторинг ошибок
  chk = DHT.read(DHT11_PIN);    // Чтение данных
  switch (chk){
  case DHTLIB_OK:  
    break;
  case DHTLIB_ERROR_CHECKSUM:  
    lcdbig.clear(); 
    lcdbig.print("Checksum error");  
    break;
  case DHTLIB_ERROR_TIMEOUT:
    lcdbig.clear(); 
    lcdbig.print("Time out error");
    break;
  default:
    lcdbig.clear(); 
    lcdbig.print("Unknown error");
    break;
  }
  delay(500);                     
}

 

Kolchugin
Offline
Зарегистрирован: 15.12.2013

OdinochkA, у вас нет понимания того что вы делаете.
Зачем нужны скобки в 58 и 67 строке? В какое место экрана вы выводите надписи? Ещё и градус...
Да и пример похоже, изначально с дисплеем и датчиком  был рабочий, но вы там зачем-то закомментировали.
 

OdinochkA
Offline
Зарегистрирован: 05.07.2015

Ну я же говорил что только учусь. У меня есть понимание того, что я хочу увидеть в железе. Я это делаю и в приниципе представляю взаимосвязь и работоспособность. Но я не могу кодить. Это к сожалению не моё. Я насмотрелся примеров кодов, пытался из одного сделать другое, как-то объеденить, чтобы это работало так как я себе это представил. НО увы.

Пример был сделан под стандартный экран 16*2 и соответсвующие библиотеки. Я пытался переделать на основе этого кода своё. Мои библиотеки #include <OLED_I2C.h> вот и начал заменять и временно вырезать то что казалось не подходит

58 и 67 незнаю ((. Наверное недоглядел.

OdinochkA
Offline
Зарегистрирован: 05.07.2015

zugni пишет:
попробуй вот этот   там с дисплем тебе придется повозится или заменить на свой 

Спасибо попробую. Хотя это похоже на пример с диспом 16*2.

И вопрос по 6-й строке. Указано что DHT11_PIN 7, а в коментах что он на пине 4. Где правда?

Завтра попробую. Связка и код на работе остались. попробую и отпишусь

zugni
Offline
Зарегистрирован: 14.06.2015

да не доглядел но скетч же работает и то что я там за каментировал я еще не как не могу их акуратно над часами написать вот так как то

zugni
Offline
Зарегистрирован: 14.06.2015

7пин  я использовал под себя а вы делайте 4 пин 

zugni
Offline
Зарегистрирован: 14.06.2015
Radjah
Offline
Зарегистрирован: 06.08.2014

Два дисплея на одном адресе? УПРЛС?

На расширителе есть контакты для задания одного из 8 возможных адресов (0x20 - 0x27). Замкни любуюб посмотри с помощью i2cscanner, что получилось, и исправь скетч.

zugni
Offline
Зарегистрирован: 14.06.2015

он прикрасно работает и это не мишает работе моего термометра )))

OdinochkA
Offline
Зарегистрирован: 05.07.2015

to zugni подскажи что не так с твоим кодом. или с моими библиотеками. Вроде жалуется на DHT, но как видно по менеджеру у меня они все стоят

https://yadi.sk/i/hLf9SjCBhnNBo

OdinochkA
Offline
Зарегистрирован: 05.07.2015

Дабы закрыть самим же открытый вопрос. Нашел код. В нём была совсем другая библиотека для диспа.

Сборка работает. 

 







// Read DHT11 humidity/temperature sensors
// display on 0.96 inch 128X64 I2C OLED

#include "DHT.h"
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

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


#define DHTTYPE DHT11   // DHT 11 

DHT dht(DHTPIN, DHTTYPE, 6);

char str[10];

void drawTest(void) {
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 20, "DHTxx test!");
}

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
  u8g.firstPage();  
  do {
    drawTest();
  } while( u8g.nextPage() );
}

void loop() {

  delay(2000);


  float h = dht.readHumidity();

  float t = dht.readTemperature();

  float f = dht.readTemperature(true);
  

  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }


  float hi = dht.computeHeatIndex(f, h);

  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(hi);
  Serial.println(" *F");
  

  u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_helvB08);
    
    u8g.drawStr( 0, 15, "Humidity:");
    u8g.drawStr( 80, 15, dtostrf(h, 5, 2, str));
    u8g.drawStr( 120, 15, "%");
    
    u8g.drawStr( 0, 30, "Temperature:");
    u8g.drawStr( 80, 30, dtostrf(t, 5, 2, str));
    u8g.drawStr( 120, 30, "\260C");
    
    u8g.drawStr( 80, 45, dtostrf(f, 5, 2, str));
    u8g.drawStr( 120, 45, "\260F");
    
    u8g.drawStr( 0, 60, "Heat index:");
    u8g.drawStr( 80, 60, dtostrf(hi, 5, 2, str));
    u8g.drawStr( 120, 60, "\260F");
    
  } while( u8g.nextPage() );
}

Спасибо всем кто откликнулся.

meridian86
Offline
Зарегистрирован: 09.11.2019

Приветствую форумчане! Собираю свой первый проект на ардуино - метеостанцию. В качестве датчика атмосферного давления использую bmp180. С ним на шине I2C также висит дисплей 1602. И все вроде замечательно, кроме одного. Через случайный промежуток времени от нескольких минут до нескольких часов показания давления становятся вместо 630 мм.рт.ст 1700 мм.рт.ст., помогает только перезагрузка платы. Куда копать? Да и в принципе по коду буду рад "грамотным пинкам"!

#include "DHT.h"                //Подключаем библиотеку для датчиков типа DHT11/DHT22     
#include "MsTimer2.h"           //Подключаем библиотеку для аппаратных прерываний
#include "Button.h"             //Подключаем библиотеку для обработки кнопки
#include <LiquidCrystal_I2C.h>  //Подключение библиотеки для LCD
#include <Adafruit_BMP085.h>    //Подключаем библиотеку для датчика BMP-180

//------Объявляем имена и значения констант------//
#define DHT_INDOOR_PIN A0               //Пин датчика температуры и влажности в помещении
#define DHT_OUTDOOR_PIN A1              //Пин датчика температуры и влажности уличного
#define BUTTON_1_PIN A2                 //Пин 1 кнопки
#define CYCLE_MEAS 1000                 //Время цикла измерений температуры и влажности * период прерывания по таймеру
#define CYCLE_BACKLIGHT 7500            //Время работы подсветки lcd

//------Создаем объекты------//
Button button1(BUTTON_1_PIN, 15);           //Создали кнопку с периодом антидребезга 15х2мс
DHT indoorSensor(DHT_INDOOR_PIN, DHT11);    //Создали датчик температуры и влажности в помещении
DHT outdoorSensor(DHT_OUTDOOR_PIN, DHT22);  //Создали датчик температуры и влажности уличный
LiquidCrystal_I2C lcd(0x27, 16, 2);         //Создаем дисплей. Указываем I2C адрес (наиболее распространенное значение), а также параметры экрана (в случае LCD 1602 - 2 строки по 16 символов в каждой
Adafruit_BMP085 bmp;                        //Создаем датчик атмосферного давления

//------Объявляем переменные------//
//переменные для работы с данными с датчиков
byte hIndoor;                                   //влажность в помещении
int tIndoor;                                    //температура в помещении
byte hOutdoor;                                  //влажность уличная
int tOutdoor;                                   //температура уличная
float pressure;                                 //атмосферное давление
//переменные для работы с таймерами
unsigned int timerMeas;                         //таймер измерений температуры и влажности
boolean flagTimerMeas = false;                  //флаг таймера измерений температуры и влажности
unsigned int timerBacklight = CYCLE_BACKLIGHT ; //таймер lcd подсветки
boolean flagTimerBacklight = true;              //флаг таймера lcd подсветки
//переменные основного цикла
byte mode;                                      //перменная определяющая режим работы
byte flagUpdateMode;                            //флаг смены режима

//------Создаем нужные символы для дисплея------//
byte deg[8]       = {B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000,}; // градус
byte up[8]        = {B00000, B00100, B01110, B10101, B00100, B00100, B00100, B00000,}; // вверх
byte down[8]      = {B00000, B00100, B00100, B00100, B10101, B01110, B00100, B00000,}; // вниз
byte outdoor[8]   = {B00011, B00001, B00000, B00100, B01010, B11111, B01010, B01110,}; // снаружи
byte indoor[8]    = {B00010, B00011, B00000, B00100, B01010, B11111, B01010, B01110,}; // внутри
byte hum[8]       = {B00100, B01010, B01010, B10001, B10001, B01110, B00000, B00000,}; // капля
byte term[8]      = {B01100, B01110, B01100, B01110, B01100, B10010, B10010, B01100,}; // термометр
byte press[8]     = {B00100, B00100, B01000, B01000, B00100, B10101, B01110, B00100,}; // давление
byte mr[8]        = {B10001, B11011, B10101, B10001, B01100, B01010, B01100, B01001,}; // мр
byte ms[8]        = {B10001, B11011, B10101, B10001, B01100, B10000, B10000, B01101,}; // мc
//byte bukva_B[8]   = {B11110, B10000, B10000, B11110, B10001, B10001, B11110, B00000,}; // Буква "Б"
byte bukva_G[8]   = {B11111, B10001, B10000, B10000, B10000, B10000, B10000, B00000,}; // Буква "Г"
byte bukva_D[8]   = {B01111, B00101, B00101, B01001, B10001, B11111, B10001, B00000,}; // Буква "Д"
//byte bukva_ZH[8]  = {B10101, B10101, B10101, B11111, B10101, B10101, B10101, B00000,}; // Буква "Ж"
//byte bukva_Z[8]   = {B01110, B10001, B00001, B00010, B00001, B10001, B01110, B00000,}; // Буква "З"
byte bukva_I[8]   = {B10001, B10011, B10011, B10101, B11001, B11001, B10001, B00000,}; // Буква "И"
//byte bukva_IY[8]  = {B01110, B00000, B10001, B10011, B10101, B11001, B10001, B00000,}; // Буква "Й"
//byte bukva_L[8]   = {B00011, B00111, B00101, B00101, B01101, B01001, B11001, B00000,}; // Буква "Л"
byte bukva_P[8]   = {B11111, B10001, B10001, B10001, B10001, B10001, B10001, B00000,}; // Буква "П"
//byte bukva_Y[8]   = {B10001, B10001, B10001, B01010, B00100, B01000, B10000, B00000,}; // Буква "У"
//byte bukva_F[8]   = {B00100, B11111, B10101, B10101, B11111, B00100, B00100, B00000,}; // Буква "Ф"
byte bukva_TS[8]  = {B10010, B10010, B10010, B10010, B10010, B10010, B11111, B00001,}; // Буква "Ц"
//byte bukva_CH[8]  = {B10001, B10001, B10001, B01111, B00001, B00001, B00001, B00000,}; // Буква "Ч"
//byte bukva_Sh[8]  = {B10101, B10101, B10101, B10101, B10101, B10101, B11111, B00000,}; // Буква "Ш"
//byte bukva_Shch[8] = {B10101, B10101, B10101, B10101, B10101, B10101, B11111, B00001,}; // Буква "Щ"
//byte bukva_Mz[8]  = {B10000, B10000, B10000, B11110, B10001, B10001, B11110, B00000,}; // Буква "Ь"
//byte bukva_IYI[8] = {B10001, B10001, B10001, B11001, B10101, B10101, B11001, B00000,}; // Буква "Ы"
//byte bukva_Yu[8]  = {B10010, B10101, B10101, B11101, B10101, B10101, B10010, B00000,}; // Буква "Ю"
byte bukva_Ya[8]  = {B01111, B10001, B10001, B01111, B00101, B01001, B10001, B00000,}; // Буква "Я"

//------Установки и прочее------//
void setup() {
  MsTimer2::set(2, timerInterupt); 	//задаем период прерывания по таймеру 2 мс
  MsTimer2::start();				        //запускаем таймер
  indoorSensor.begin();			      	//запускаем датчик внутренний
  outdoorSensor.begin();            //запускаем датчик уличный
  Serial.begin(9600);				        //запускаем серийный порт
  lcd.begin();                      //запускаем дисплей
  bmp.begin();                      //запускаем датчик давления
  onOffBacklight();                 //включаем подсветку дисплея
  hello();                          //выводим приветствие
}

//------Основной цикл------//
void loop() {
  if (button1.flagClick == true) {    //был "клик" кнопкой
    button1.flagClick = false;        //сброс флага "клик" кнопкой
    timerBacklight = CYCLE_BACKLIGHT; //установка таймера подсветки lcd
    flagTimerBacklight = true;        //установить флаг включения подсветки lcd
    flagUpdateMode = true;            //установить флаг смены режима
    mode++;
    if (mode > 1) {
      mode = 0;
    }
  }

  if (flagTimerMeas == true) measureTHP(); //измеряем параметры окр. среды

  switch (mode) {
    //режим по умолчанию(показания уличные)
    case 0:
      if (flagUpdateMode == true) {     //если была смена режима
        lcd.createChar(1, outdoor);     //создаем значек снаружи
        flagUpdateMode = false;         //сбросываем флаг смены режима
        updateLcdOutdoorTHP();          //обновляем показания дисплея
      }
      if (flagTimerMeas == true) {      //если получили новые данные
        updateLcdOutdoorTHP();          //обновляем показания дисплея
        flagTimerMeas = false;          //сбрасываем флаг таймера измерений
      }
      break;
    //режим показаний в помещении
    case 1:
      if (flagUpdateMode == true) {    //если была смена режима
        lcd.createChar(1, indoor);     //создаем значек внутри
        flagUpdateMode = false;        //сбросываем флаг смены режима
        updateLcdIndoorTH();           //обновляем показания дисплея
      }
      if (flagTimerMeas == true) {     //если получили новые данные
        updateLcdIndoorTH();           //обновляем показания дисплея
        flagTimerMeas = false;         //сбрасываем флаг таймера измерений
      }
      break;
  }

  //  onOffBacklight();               //управление подсветкой
}

//------Обработчик прерываний------//
void timerInterupt() {
  button1.scanState();            //проверяем нажатие кнопки

  //Таймер измерений и обновления lcd
  timerMeas++;                    //инкремент таймера измерений
  if (timerMeas >= CYCLE_MEAS) {  //проверка таймера измерений
    timerMeas = 0;                //сброс таймера измерений
    flagTimerMeas = true;         //выставление флага таймера измерений
  }

  //Таймер подсветки lcd
  if (timerBacklight > 0) {       //проверка таймера подсветки
    timerBacklight--;             //декремент таймера подсветки
    if (timerBacklight == 0) {
      flagTimerBacklight = false; //выставление флага таймера подсветки
    }
  }
}

//------Измерение параметров окр.среды------//
void measureTHP() {
  tIndoor = indoorSensor.readTemperature() * 100.0;     //измеряем температуру в помещении
  hIndoor = indoorSensor.readHumidity();                //измеряем влажность в помещении
  tOutdoor = outdoorSensor.readTemperature() * 100.0;   //измеряем температуру уличную
  hOutdoor = outdoorSensor.readHumidity();              //измеряем влажность уличную
  pressure = bmp.readPressure();                        //измеряем давление
}

//------Управление подсветкой lcd------//
void onOffBacklight() {
  if ( flagTimerBacklight == true) {
    lcd.backlight();
  }
  else {
    lcd.noBacklight();
  }
}

//------Вывод текущих уличных значений на дисплей------//
void updateLcdOutdoorTHP() {
  char _tOutdoorStr[4];
  char _hOutdoorStr[4];
  char _pressureStr[4];
  float _tOutdoor = tOutdoor / 100.0;
  dtostrf(_tOutdoor, 4, 1, _tOutdoorStr);
  lcd.setCursor(0, 0);
  lcd.print("\1 ");
  lcd.print("\6 ");
  lcd.print(_tOutdoorStr);
  lcd.print("\3C");
  lcd.print(" \5");
  dtostrf(hOutdoor, 2, 0, _hOutdoorStr);
  lcd.print(_hOutdoorStr);
  lcd.print("%");
  dtostrf((pressure*0.0075), 4, 1, _pressureStr);
  lcd.setCursor(2, 1);
  lcd.print("\4\4 ");
  lcd.print(_pressureStr);
  lcd.print(" \2\7");
}

//------Вывод текущих значений в помещении на дисплей------//
void updateLcdIndoorTH() {
  char _tIndoorStr[4];
  char _hIndoorStr[4];
  float _tIndoor = tIndoor / 100.0;
  dtostrf(_tIndoor, 4, 1, _tIndoorStr);
  lcd.setCursor(0, 0);
  lcd.print("\1 ");
  lcd.print("\6 ");
  lcd.print(_tIndoorStr);
  lcd.print("\3C");
  lcd.print(" \5");
  dtostrf(hIndoor, 2, 0, _hIndoorStr);
  lcd.print(_hIndoorStr);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("                ");
}

//------Приветствие------//
void hello() {
  //  Serial.println("Погодная станция v.01.20");
  lcd.createChar(1, bukva_P);
  lcd.createChar(2, bukva_G);
  lcd.createChar(3, bukva_D);
  lcd.createChar(4, bukva_Ya);
  lcd.createChar(5, bukva_TS);
  lcd.createChar(6, bukva_I);
  lcd.setCursor(4, 0);             // Установка курсора в 5ю позицию первой строки
  lcd.print("\1O\2O\3HA\4");       // Набор текста на первой строке
  lcd.setCursor(0, 1);             // Установка курсора в начало второй строки
  lcd.print("CTAH\5\6\4 v.01.20"); // Набор текста на второй строке
  delay(2000);
  lcd.clear();
  lcd.createChar(1, outdoor);     // Создаем значек снаружи
  lcd.createChar(2, mr);          // Создаем значек мр
  lcd.createChar(3, deg);         // Создаем значек градуса
  lcd.createChar(4, press);       // Создаем значек давления
  lcd.createChar(5, hum);         // Создаем значек влажность
  lcd.createChar(6, term);        // Создаем значек влажность
  lcd.createChar(7, ms);          // Создаем значек мс
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

Для начала, копайте в сторону отмывки флюса и проверки надежности соединений.

meridian86
Offline
Зарегистрирован: 09.11.2019

Тоже на это дело грешил, однако видимых проблем нет. И пока в режиме тестирования датчик стабильно работает. В одном тесте 8 часов, теперь в другом уже часа 4 стоит. Пока есть предположение о проблеме в запросах данных у датчика - если смотреть пример библиотеки SFE_BMP180, то там всегда есть задержка между измерением и запросом данных, плюс всегда(не только в этом примере) обмен начинается с температуры... может в этом есть проблема. Пока ищу решение. Вот выдержка из datasheet:

Чтение давления: (некомпенсированное значение) Записываем в регистр «Measurement Control» значение: 0x34 + (OSS<<6); Ожидаем спад флага состояния «CSO» в «0»; Читаем результат из регистров «Out MSB», «Out LSB» и «Out xLSB»; long UP = («Out MSB»<<16 + «Out LSB»<<8 + «Out xLSB») >> (8-OSS);

-NMi-
Offline
Зарегистрирован: 20.08.2018

А в протеусе как работает?

meridian86
Offline
Зарегистрирован: 09.11.2019

В протеусе не моделировал, в принципе им не пользовался никогда, только слышал о нем.

Пока попробовал отключать прерывания на время измерения давления - не помогло. Сейчас в тестировании стоит скетч с "полным" опросом датчика:

//------Измерение параметров окр.среды------//
void measureTHP() {
  float temp;
  tIndoor = indoorSensor.readTemperature() * 100.0;     //измеряем температуру в помещении
  hIndoor = indoorSensor.readHumidity();                //измеряем влажность в помещении
  tOutdoor = outdoorSensor.readTemperature() * 100.0;   //измеряем температуру уличную
  hOutdoor = outdoorSensor.readHumidity();              //измеряем влажность уличную
  temp = bmp.readTemperature();
  Serial.print ("Температура = ");
  Serial.println (temp);
  pressure = bmp.readPressure();                       //измеряем давление
  Serial.print ("Давление = ");
  Serial.println (pressure);
  temp = bmp.readSealevelPressure();
  Serial.print ("Давление над уровнем моря = ");
  Serial.println (temp);
  temp = bmp.readAltitude(101500);
  Serial.print ("Высота = ");
  Serial.println (temp);
  Serial.println ("");
}

 

meridian86
Offline
Зарегистрирован: 09.11.2019

В общем, все упирается в замер температуры, если я правильно понял даташит на английском и файлик Adafruit_BMP085.cpp т.к. она используется при расчете давления. А потому хочешь или нет, а температуру считывать надо. Более подробно и глубоко вникать, нет особого желания.

Скетч с опросом температуры и прочей херни уже отработал 9 часов - полет нормальный.