Датчик давления BMP180 / Линейный стабилизатор серии xc6206 (662K)

Датчик давления BMP180Был у меня датчик давления BMP180. Честно купленный на ебее за 80 руб. Вот такой, как на картинке справа (собственно датчик BMP180 — это металлический паралелепипед с еле заметной дырочкой на углу платы, остальное — обвязка).

Я его собирался использовать как часть погодной станции — мерять атмосферное давление.

А на самом деле он оказался датчиком давления и температуры в одном флаконе. С I2C шиной. Да еще и с максимальной точностью 2 Пa (если использовать его как барометрический высотомер это соответствует погрешности измерения высоты в 17 см). Ну и до кучи — микроскопический вес и малое потребление энергии, все это на крошечной платке 21 на 18 мм.

В общем радующий душу девайс.

Но я его таки сломал. Припаял к нему сначала угловой коннектор, захотел заменить на прямой… угловой так интегрировался в плату, что ни нагрев паяльником, ни использование оплетки не помогло — разъем я вытащил вместе с куском платы и ошметками дорожек.

С новым разъемом датчик не заработал.

Убить датчик по собственной глупости было как-то исключительно обидно. Решил изготовить для него новую плату и перепаять на нее комплектующие со старой.

Даташит на датчик нашелся без проблем.

Неожиданно, деталей обвеса в даташите оказалось несколько меньше, чем было на плате. По даташиту датчику достаточно двух резисторов, подтягивающих шину I2C и двух конденсаторов по питанию (у BMP180 питание разделено на питание датчика и питание шины).
На плате же проглядывался какой-то транзисторноподобный корпус SOT-23 с плохо различимой маркировкой 662K.

Типовое подключение BMP180 (из даташита)

По маркировке и удалось найти что это. Оказалось — линейный стабилизатор Torex серии xc6206 — xc6206p332mr (даташит).

Штучка тоже совершенно замечательная в своем роде — мелкая фитюлька 6 Вольт входного напряжения превращает в 3.3 Вольта (это в данном конкретном случае, а в зависимости от конкретной микросхемы — от 1.2 до 5.0 Вольт с шагом 0.1 Вольт) и выдает 250 мА тока.

При этом падение напряжения на стабилизаторе составляет всего 250 мВ, собственное потребление — 1uA.

Из обвязки требуется два керамических конденсатора по 1uF (Вот оно счастье! Никакого дорогостоящего, труднодступного и крупногабаритного тантала!).

Типовое подключение линейного стабилизатора сери xc6206. Обратите внимание на конденсаторы!

А самое главное — на ебее 20 штук (!) таких стабилизаторов продается за 45 руб с доставкой. По 2.25 руб за стабилизатор!

То есть теперь если мне в пятивольтовом устройстве понадобится подключить что-то трехвольтовое (с учетом ограничения по току конечно — сетевая enc28j60 отпадает) я просто тут же, в том месте, в котором мне удобно, получу из 5 Вольт 3.3, причем из-за бросовой цены стабилизатора его можно ставить к каждому трехвольтовому устройству персонально! А из-за малых размеров и самого стабилизатора, и его обвеса проблем с габаритами тоже не возникнет.

Немного подумав на тему, а нафига я при наличии стабилизатора так трепетно подключал датчик к трем вольтам и заказав на ебее 20 стабиков на будущее, развел плату под восстановление датчика.

Принципиальная схема платы:

Схема платы датчика

С1 и C2 по 1uF на схеме — обвес линейного стабилизатора.
R1 и R2 по 4.7К — подтяжка к питанию линий шины I2C.
С3 100 nF — только один из двух, положенных по даташиту BMP180, конденсаторов на питание.

Только один — потому, что на исходной плате он и был только один. По всей видимости, разработчики оригинала сочли, что 1uF керамика после линейного стабилизатора послужит вполне приемлимой заменой второго из шунтирующих конденсаторов.
Я не смог отследить по плате, к какому питанию относится единственный 100nF конденсатор и решил зашунтировать питание шины I2C, исходя из того, что теоретически на шине происходят более активные перепады напряжения.

Сейчас я уже не так уверен в правильности моих рассуждений, хотя выбранная схема на работоспособности датчика не сказалось. Возможно, сказалась на точности, но вот это я проверить как раз не могу.
Собственно, я даже не уверен, что этот конденсатор (при наличии рядом с ним куда более емкого и тоже керамического собрата) вообще играет хоть какую-то роль. Или что он не служит фильтром для обоих входов, которые, в конце-концов, электрически объеденены в одной точке…

Кстати, как можно видеть на схеме, у BMP180 есть контакты CS (1) и SDO (4), что как бы намекает на наличие у датчика поддержки SPI. Увы. В даташите написано, что версии датчика с SPI доступны по запросу, стандартное же исполнение SPI не поддерживает и контакты 1 и 4 не должны быть никуда подсоединены.

Габариты платы выбрал исходя из габаритов оригинала. Из принципа. И из интереса, смогу ли в домашних условиях повторить промышленную плотность компонентов. Смог. Только долго не мог понять, куда делось место под огромную дырку, занимающую четверть площади оригинальной платы.
Когда я стал переносить комплектующие с поломанной платы на мою вопрос с исчезновением места прояснился — я по привычке развел плату под размер комплектующих 0805 а в оригинале использовались 0603!
Кстати, во-первых, я совершенно спокойно запаял вручную 0603, а во-вторых, хоть и “внатяг”, но они все-таки нормально упоялись на площадки для 0805.
В конечном итоге мне все же повезло, что площадки были под 0805, потому что один из конденсаторов 0603 я при отпайке потерял, а заменить его в мелком типоразмере было бы нечем…

Плата (файл SprintLayout-а):

Собственно плата

Белая рамка — габариты платы.

Разведена плата в предположении, что вы смотрите на плату сверху, и “сквозь” текстолит видите фольгу и, соответственно, перевернутые пузом вверх SMD-компоненты на нижней стороне платы. То есть при печати платы для ЛУТ плату зеркалить НЕ НАДО.

Изготовление платы никаких особых сюрпризов не принесло. При запайке компонетов, как и ожидалось, самым сложным было запаять сам датчик. Контакты у него на пузе и с боков не очень то и виды.
Проблема решилась так: я нанес на каждую из контактных площадок датчика капельку припоя (получились такие “ножки” в виде шариков), примостил датчик на отведенное ему место и прогрел его по периметру паяльником с небольшим количеством припоя. Расплавленный припой с паяльника по контактным площадкам на плате втянулся под корпус датчика, расплавил “ножки” из припоя на самом датчике и за пару проходов паяльником по краям датчика он вполне сносно припаялся.

Наклейку с назначением пинов (учитывая сколько всего я второпях подключил неправильно — взял в привычку подписывать все разъемы крупными буквами) нарисовал в том же SprintLayout-е, распечатал на цветном струйном принтере и приклеил на плату полоской канцелярского скотча.

Вот что получилось

Для сравнения - рядом SD карта

А, кстати. Немного про демонтаж со сломанной платы. Все детальки, кроме датчика отпаялись легко, чтобы снять датчик пришлось греть плату мелкой газовой горелкой снизу (К слову сказать, горелка эта — редкостная дрянь. Подача газа гуляет в огромных пределах при малейшем изменении ее положения в пространстве. Но я уже приноровился.). При прогреве платы снизу корпус датчика «поплыл» и легко снялся пинцетом.

Горелка

То, что осталось от старой платы после «разборки»

Останки

Все детали на новой плате, кроме одного утерянного конденсатора, про который я уже писал раньше — с оригинальной платы, сохранили работоспособность.

Для проверки датчика собрал комплект из Arduinio + LCD Shield несложный цифровой термометр, который тут же был с успехом применен на практике для замера температуры воздуха на выходе комнатного кондиционера (термометр окончательно подтвердил тот неприятный факт, что кондиционер в спальне перестал “холодить” — на выходе из него удавалось получить минимум 20 градусов, в то время как кондер в детской выдавал 8 и, похоже, это был не предел).

«Термометр»

Термометр

Потребуются библиотеки Arduino LiquidCrystal и Wire.
И, конечно же, бибилиотека датчика BMP180 от Adafruit.


#include <LiquidCrystal.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

#define TX_PIN 8
#define INTERVAL 1000

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 

Adafruit_BMP085 bmp;

// Коды кнопок
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// Считывание нажатой кнопки
int read_LCD_buttons() {
   int adc_key_in = analogRead(0);
   if (adc_key_in > 1000) return btnNONE; 
   if (adc_key_in < 50)   return btnRIGHT;  
   if (adc_key_in < 250)  return btnUP; 
   if (adc_key_in < 450)  return btnDOWN; 
   if (adc_key_in < 650)  return btnLEFT; 
   if (adc_key_in < 850)  return btnSELECT;  
   return btnNONE;
}

#define DEBOUNCE 300

#define SCREEN_COUNT 6

#define FAULT_SCREEN -1
#define HELLO_SCREEN 0
#define SUMMARY_SCREEN 1
#define PRESS_SCREEN 2
#define TEMP_SCREEN 3
#define ALT_SCREEN 4
#define PREC_SCREEN 5


unsigned long last_press= 0; // момент последнего нажатия на кнопку
unsigned long last_refresh = 0; // момент последнего обновления экрана
unsigned long refresh_rate = 500; // частота обновления экрана
int screen = 0; // Номер текущего "экрана"
int32_t prec = BMP085_ULTRAHIGHRES; // точность датчика

float temp; // температура
int32_t p; // давление
float h; // высота
float h0 = 0;
float h1 = 0;

boolean fixed = false; // режим измерения
int32_t baseP; // фиксированное давление
float baseTemp; // фиксировання температура
float baseH; // фиксированная высота



void setup() {
  Serial.begin(115200);
  Serial.println(F("[ BMP180 ]"));
  lcd.begin(16,2);
  if (!bmp.begin(prec)) {
    screen = FAULT_SCREEN;
    Serial.println("Could not find a valid BMP085 sensor, check wiring!");    
  }    
}

void loop() {
  int last_screen = screen;
  unsigned long t = millis();
  if(t - last_press > DEBOUNCE) {
    int btn = read_LCD_buttons();
    if(btn != btnNONE) last_press = t;
    switch(btn) {
      case btnDOWN: 
        if(screen != -1) screen++;
        if(screen >= SCREEN_COUNT) screen = 0;
        break;  
      case btnUP: 
        last_press = millis();
        if(screen != -1) screen--;
        if(screen < 0) screen = SCREEN_COUNT - 1;
        break;
      case btnLEFT:
        if(screen == PREC_SCREEN) {          
          if(prec == BMP085_ULTRALOWPOWER) {
            prec = BMP085_ULTRAHIGHRES;
          } else {
            prec--; 
          }  
          bmp.begin(prec);
        }
        break;
      case btnRIGHT:     
        if(screen == PREC_SCREEN) {                    
          if(prec == BMP085_ULTRAHIGHRES) {
            prec = BMP085_ULTRALOWPOWER;
          } else {
            prec++;              
          }  
          bmp.begin(prec);
        }  
        break;
      case btnSELECT:
        switch(screen) {
          case PRESS_SCREEN:
            fixed = true;
            if(fixed) baseP = p;
            break;                    
          case TEMP_SCREEN:
            fixed = true;
            if(fixed) baseTemp = temp;
            break;          
          case ALT_SCREEN:
            fixed = true;
            if(fixed) baseH = h;
            break;            
        }
        break;  
    }
    if(screen != last_screen) {
      lcd.clear();
      fixed = false;
      switch(screen) {
        case FAULT_SCREEN:
        case HELLO_SCREEN:
          refresh_rate = 500;
          break;
        default:
          refresh_rate = 200;
          break;
      }      
    }
  }
  t = millis();
  if(t - last_refresh > refresh_rate) {
    last_refresh = t;
    switch(screen) {
      case FAULT_SCREEN: 
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("*** Sensor error!");
        break;  
      case HELLO_SCREEN: 
        lcd.clear();
        lcd.print("[ BMP180 ]");
        lcd.setCursor(0,1);    
        lcd.print("up: ");
        lcd.print(millis());
        break;  
      case SUMMARY_SCREEN:
        temp = bmp.readTemperature(); 
        p = bmp.readPressure();    
        lcd.clear();
        lcd.setCursor(0,0);    
        lcd.print(screen);        
        lcd.setCursor(2,0);    
        lcd.print("T ");      
        lcd.print(temp);
        lcd.setCursor(15, 0);
        lcd.print("C");
        lcd.setCursor(2,1);
        lcd.print("P ");      
        lcd.print(p/100);
        lcd.setCursor(13,1);
        lcd.print("gPa");
        break;
      case PRESS_SCREEN: 
        p = bmp.readPressure(); 
        lcd.clear();
        lcd.setCursor(0,0);    
        lcd.print(screen);        
        lcd.setCursor(2,0);    
        lcd.print("P ");          
        lcd.print(fixed ? baseP : p);        
        if(fixed) {
          lcd.setCursor(4,1);    
          lcd.print(p - baseP);        
        }
        lcd.setCursor(14, 0);  
        lcd.print("Pa");          
        break;                  
      case TEMP_SCREEN: 
        temp = bmp.readTemperature(); 
        lcd.clear();
        lcd.setCursor(0,0);    
        lcd.print(screen);        
        lcd.setCursor(2,0);    
        lcd.print("T ");          
        lcd.print(fixed ? baseTemp: temp);        
        if(fixed) {
          lcd.setCursor(4,1);    
          lcd.print(temp - baseTemp);        
        }
        lcd.setCursor(15, 0);  
        lcd.print("C");          
        break;          
      case ALT_SCREEN: 
        h0 = h1;
        h = bmp.readAltitude();        
        lcd.clear();
        lcd.setCursor(0,0);    
        lcd.print(screen);        
        lcd.setCursor(2,0);    
        lcd.print("H ");          
        lcd.print(fixed ? baseH: h);        
        if(fixed) {
          lcd.setCursor(4,1);    
          lcd.print(h - baseH);        
        }
        lcd.setCursor(15, 0);  
        lcd.print("m");          
        break;  
      case PREC_SCREEN:
        lcd.setCursor(0,0);    
        lcd.print(screen);              
        lcd.setCursor(2,0);    
        lcd.print("Resolution:");
        lcd.setCursor(0,1);   
        lcd.print((prec == BMP085_ULTRALOWPOWER) ? "[LP]" : " LP "); 
        lcd.print((prec == BMP085_STANDARD) ? "[ST]" : " ST ");
        lcd.print((prec == BMP085_HIGHRES) ? "[HR]" : " HR ");
        lcd.print((prec == BMP085_ULTRAHIGHRES) ? "[UH]" : " UH ");
        break;        
    }
  }
}
Файлы в топике: BMP180.zip

Комментарии (40)

RSS свернуть / развернуть
Я так понял ты делаешь какую-то особенную станцию измерения климата. Расскажи про неё подробнее.
+1
Это будет не совсем погодная станция.

Это будет Ethernet-коллектор для датчиков Oregon Scientific — то есть «перехват» сообщений датчиков и их загрузка в базу данных по HTTP протоколу.
Поскольку датчики Орегона (те, которые есть у меня) не дают информацию о давлении, я хочу поставить датчик давления на сам коллектор.

Коллектор я как раз сейчас собираю, когда доделаю — планирую про него написать отдельный пост…
0
Тогда (если только коллектор не собран из ардуино и шилдов) было бы разумнее не запаивать датчик на свой аналог китайской платы, а развести под него место прямо на коллекторе.
0
Не, коллектор будет паянным.

Но!

1) Датчик то я сломал как раз в процессе его «приживления» на первую версию коллектора. То есть изначально планировалось впаивание в коллектор купленного «датчика в сборе», перебирать датчик пришлось потому, что просто «уж так получилось»
2) Первая версия коллектора меня не устроила по питанию — там было два линейных стабилизатора (на 5 на 3.3 Вольт) но с блоком питания на 12Вольт (от какой-то быттехники) грелись они не по-детский. Все-таки enc28j60 жрет 250 мА. Высадить более 2 Ватт в тепло — это перебор. Так что сейчас собираю вторую версию уже со Step-Down-ом до 5 Вольт.
И теперь гложет мысль — а ну как и эта версия не последняя…
3) Не факт, что когда-нибудь не придется коллектор разбирать — мало ли, может актуальность потеряет. Ну и если вдруг где-то позарез понадобится датчик давления его можно будет аккуратно снять вместе с его платой, а коллектор при этом сохранит весь оставшийся функционал.
4) Честно говоря был практически твердо уверен, что сам датчик тоже убит или что я его убью в процессе перепайки.
0
При этом падение напряжения на стабилизаторе составляет всего 250 мА
В этой фразе однозначно что-то не так.

При демонтаже неплохо выручает оловоотсос еще.
0
  • avatar
  • Ozze
  • 14 августа 2014, 09:00
В этой фразе однозначно что-то не так.

Спасибо, исправил!
0
Оказалось — линейный стабилизатор Torex серии xc6206 — xc6206p332mr (даташит).
Ну, что это LDO было очевидно. А вот что он такой дешевый — уже интересней. Линком не поделишься?
я совершенно спокойно запаял вручную 0603
А в этом и нет никаких проблем. Вот 0201 запаять чуть сложнее. Вот выпаять их без паяльного пинцета или фена не так просто — есть риск испортить (многослойные конденсаторы вообще очень охотно дохнут — от неравномерного нагрева, от изгиба платы, даже от удара плейсером).
чтобы снять датчик пришлось греть плату мелкой газовой горелкой
Как только люди не извращаются, лишь бы фен не покупать…
К слову сказать, горелка эта — редкостная дрянь
Она еще и недолговечная — довольно быстро дает течь. Моя уже давно сдохла и разобрана.
0
  • avatar
  • Vga
  • 14 августа 2014, 11:00
А вот что он такой дешевый — уже интересней. Линком не поделишься?

Запросто:
www.ebay.com/itm/161312805359?_trksid=p2059210.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

Кстати, там похоже только 2 уже осталось.

Как только люди не извращаются, лишь бы фен не покупать…

Ну да :-D
Вообще-то дозреваю конечно до фена, что-нить типа lukey 852d+. Вот доживу до дня рождения — и куплю :-)
0
Ну, что это LDO было очевидно. А вот что он такой дешевый — уже интересней. Линком не поделишься?
Здесь заказал 50 шт за $2.99
0
Это скорей в детальку надо запостить. Т.к. ремонта тут нет, больше про датчик.
0
А сейчас перенести еще можно? Или все рассыпиться?
0
Можно, можно.
0
Перенес…
0
Я бы еще добавил в название про LDO-шку и убрал про плату.
0
ОК
0
Да еще и с максимальной точностью 2 Пa (если использовать его как барометрический высотомер это соответствует погрешности измерения высоты в 17 см)

А Вы экспериментировали с измерением барометрической высоты? Датчик действительно обеспечивает заявленные 17 см? По моему опыту ( MS5611-01BA01 ) производители «лукавят» и заявленная в датшите точность измерения барометрической высоты отличается раза в три-пять от реальной…
0
  • avatar
  • e_mc2
  • 14 августа 2014, 23:04
А Вы экспериментировали с измерением барометрической высоты? Датчик действительно обеспечивает заявленные 17 см?
Я применяю такие. Экспериментов не требуется, все прописано в ДШ, надо только вдумчиво прочитать. :)

Просто не надо путать разрешающую способность и точность. Все характеристики, прописанные в ДШ, соответствуют реальности. Правда с небольшой оговоркой — никто вокруг не шумит (микроконтроллер уложен в спячку, питание чистое и стабильное и т.п.)



На этой картинке показаны выходные значения при oversampling_setting = 0. Это я сравнивал результату «стандартных» вычислений и Bosch BMP085 Barometer Floating Point Pressure Calculations. Процессор молотит на 72 МГц, выборки через 10 мс (температура каждую сотую выборку давления), сильно шумит общая с компом земля, поэтому такая большие разбросы значений.
+1
Просто не надо путать разрешающую способность и точность

Извиняюсь, не правильно выразился. Я понимаю разницу между разрешавшей способностью и погрешностью измерений.

Я как раз имел ввиду под «лукавят» то, что выставляют на показ чувствительность, хотя погрешность измерения намного выше этой величины.
Вот для моей микросхемы на первой странице даташита, в первой строке громко сказано «High resolution module, 10 cm». А погрешность (в самом лучшем случае, autozero at one pressure point ) +-0.5 mbar, что приблизительно равно +-40 см. Даже после фильтра (например, скользящее среднее на 500 измерений) показания плавают в пределах +-15 см.

Правда с небольшой оговоркой — никто вокруг не шумит (микроконтроллер уложен в спячку, питание чистое и стабильное и т.п.)

А вот это интересно. С питанием понятно, а на сколько усыпление МК, на практике, сказывается на точности?
0
Кстати, попробовал вчера на скорую руку и вариант с питанием от трех батареек АА (LCD правда был какой-то еле различимый) и выводом реультата измерений на LCD (разницы между минимальным и максимальным измеренным значением высоты на 1000 измерениях).
При oversampling_setting = 0 получил разброс результатов в те же два метра…

Любопытно, что в даташите отдельно указана «Relative accuracy» — «Относительная точность» +/-1м (что как бы совпадает с разбросом).
Правда, по моим понятиям — относительная точность должна быть величиной безразмерной и представлять из себя отношение погршености измерения к точному значению измерямемой величины.

А разные «accuracy mode» — «режимы точности» — по даташинту определяют «RMS Noise» — буквально врдоде «среднеквадратичный шум», а по человечески это интересно что? СКО шума? Сигма? Так все равно все измерения должны укладываться в три сигмы…

Ай, блин, они и укладываются — high resolution дает RMS Noise 0.3м, 3 симгмы — +/-0.9м. Остальные режимы еще хуже. А разница между режимами точности должна быть только в «степени разбросанности» различных измерений относительно среднего.

Попробую найти время — сделаю графики измерений в разных режимах точности. На них разница должна быть видна…
0
Ну вот, сделал.

500 измерений подряд при четырех разных режимах точности.

500 измерений при разных режимах точности

Красный график (самая высокая точность) конечно более поджат, чем синий (самая низкая), но!
Скормил по 200 первых точек каждой выборки вот сюда (намного больше 200 точек не получается запихать)

Получил:

OSR                               0           1          2          3
Минимум                         123.53      123.79     123.96     123.96
Максимум                        125.89      125.81     125.81     125.64 
Среднее арифметическое          124.6877    124.87535  124.8262   124.8465
Дисперсия                         0.146643    0.127849   0.096630   0.105574
Исправленная дисперсия            0.14738     0.128491   0.097115   0.106104
Среднеквадратическое отклонение   0.38294     0.35756    0.310853   0.324921
---
Даташит                           0.5         0.4        0.3        0.25



Т.е. при всех режимах точности среднеквадратичное отклонение по реальным измерениям
а) Практически одинаковое
б) На уровне «лучших домов Европы» — на уровне точности 2 по даташиту
в) Но самый точный режим дает результат хуже, чем должен по даташиту.

Чем это можно объяснить — я не знаю…

Даташит по поводу СКО (RMS) в разных режимах точности

P.S. Все измерения производил при датчике, прикрытым сверху непрозрачным материалом (SD-картой).
0
Сорри, забыл поставить ссылку на то, чем считал статистику — ru.numberempire.com/statisticscalculator.php
0
А вот скользящее усреднение (красная линия) по 40 и 100 точкам для самой высокой точности (OSR=3).
Шума становиться сильно меньше.

Скользящее усреднение по 40 точкам, OSR=3

Скользящее усреднение по 100 точкам, OSR=3
0
А это подъем датчика на высоту 50 см и спуск обратно.

Красная линия — скользящее среднее по 40 точкам, OSR=3

Подхем на 50 см, скользящее среднее 40 точек, OSR=3
0
С питанием понятно, а на сколько усыпление МК, на практике, сказывается на точности?
На точности при большом усреднении — никак. Сказывается только на зашумленности выходных значений. Чем меньшее количество переключений происходит тем меньше шума по цепям питания, и, соответственно меньше шумов в оцифрованных значениях.
Здесь немного подробнее про работу с датчиками LPS331 и BMP085.
0
А это вот вопрос конечно интересный.

Эксперементировал «глазами», т.е. запускал скрипт «термометра» и смотрел на экране при неподвижном датчике при разных точностях.

Что могу сказать:

а) Колбасит показания заметно сильнее чем 17 см. Кажется видел отклонения до метра (но! этому есть определенное объяснение, см. ниже).

б) Самое для меня непонятное — что на размах погрешности _визуально_ (при считывании с экрана) не влияет установка точности датчика. Но тут может быть я неправильно использую библиотеку — в ней нет отдельного метода смены точности, есть только метод инициализации begin, в котором можно указать точность. И я этот метод просто вызваю неоднократно. По коду библиотеки — вроде бы должен срабатывать, но глубоко я не анализировал.

в) Еще один нюанс — 17 см это конечно определенное лукавство. Насколько я понимаю, «железо» датчика поддерживает всего навсего один уровень точности — 6Па (50 см). А дальше датчик умеет программно усреднять несколько измерений и благодаря этому на нем можно установить четыре уровня точностu

ultra low power — одно измерение, дает точность 50 см
srandart — два измерения, 40 см
highresolution — четрые измерения, 30 см
ultra high resolution — 8 измерений, 25 см

При этом чем точнее должен быть результат, тем дольше происходит замер и тем больше тока он требует.
Насколько я понял, смысл проводить усреднение в датчике заключается в том, что при неоднократном измерении давления можно обойтись однократным измерением температуры.

Теперь, где же обещанные 17 см. Очень просто — для получения такой точности Bosch предлагает усреднить три замера точности ultra high resolution на стороне контроллера :-)
Троекратный замер с усреднением длиться 76 мс и дает точность 2 Па, 17 см.

Но вообще, Вы меня заинтриговали — попробую сейчас наваять скетч, который посчтитает разброс измерений…
0
Попробовал. Результат несколько обескураживающий.
И разборс значений очень уж большой, и от точности не зависит. Хотя при большой точности меряет дольше.

Start @ osr = 0
cnt=1000; time=13290 ms, 13 ms/smpl; min_h=190.48 m; max_h=193.11 m; avg_h=191.73 m; delta=2.63 m;
cnt=1000; time=13291 ms, 13 ms/smpl; min_h=190.05 m; max_h=193.11 m; avg_h=191.57 m; delta=3.05 m;
cnt=1000; time=13291 ms, 13 ms/smpl; min_h=189.55 m; max_h=192.94 m; avg_h=191.09 m; delta=3.39 m;
cnt=1000; time=13292 ms, 13 ms/smpl; min_h=189.55 m; max_h=192.94 m; avg_h=191.00 m; delta=3.39 m;

Start @ osr = 1
cnt=1000; time=16310 ms, 16 ms/smpl; min_h=189.88 m; max_h=192.17 m; avg_h=190.80 m; delta=2.29 m;
cnt=1000; time=16310 ms, 16 ms/smpl; min_h=189.63 m; max_h=192.43 m; avg_h=190.72 m; delta=2.80 m;
cnt=1000; time=16311 ms, 16 ms/smpl; min_h=190.31 m; max_h=192.43 m; avg_h=191.05 m; delta=2.12 m;
cnt=1000; time=16310 ms, 16 ms/smpl; min_h=189.97 m; max_h=192.43 m; avg_h=191.00 m; delta=2.46 m;

Start @ osr = 2
cnt=1000; time=22344 ms, 22 ms/smpl; min_h=189.55 m; max_h=191.83 m; avg_h=190.38 m; delta=2.29 m;
cnt=1000; time=22345 ms, 22 ms/smpl; min_h=189.55 m; max_h=192.00 m; avg_h=190.53 m; delta=2.46 m;
cnt=1000; time=22345 ms, 22 ms/smpl; min_h=189.80 m; max_h=192.17 m; avg_h=190.73 m; delta=2.37 m;
cnt=1000; time=22345 ms, 22 ms/smpl; min_h=189.55 m; max_h=191.75 m; avg_h=190.32 m; delta=2.20 m;

Start @ osr = 3
cnt=1000; time=34484 ms, 34 ms/smpl; min_h=190.22 m; max_h=192.60 m; avg_h=191.28 m; delta=2.38 m;
cnt=1000; time=34485 ms, 34 ms/smpl; min_h=190.48 m; max_h=192.77 m; avg_h=191.41 m; delta=2.29 m;
cnt=1000; time=34486 ms, 34 ms/smpl; min_h=190.48 m; max_h=192.77 m; avg_h=191.32 m; delta=2.29 m;
cnt=1000; time=34485 ms, 34 ms/smpl; min_h=190.56 m; max_h=192.68 m; avg_h=191.47 m; delta=2.12 m;


#include <Wire.h>
#include <Adafruit_BMP085.h>

#define CNT 1000

Adafruit_BMP085 bmp;
uint8_t osr = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("[ BMP180 accuracy test ]");
  //
  if (!bmp.begin(osr)) {
    Serial.println("Could not find a valid BMP085 sensor, check wiring!");    
  } else {
    Serial.print("Start @ osr = ");
    Serial.println(osr);
  }   
}
/*
первый момент, m1, он же мат. ожидание - сумма элементов выборки, поделенная на объем выборки N. m1 = sum(xi)/N
второй момент, m2, сумма квадратов элементов выборки, нормированная к объему выборки. m2 = sum(xi^2)/N
дисперсия D = m2 - (m1)^2 
*/
void loop() {
  float h;
  float min_h, max_h, avg_h = 0;
  unsigned long t0 = millis();
  for(int i = 0; i < CNT; i++) {
    h = bmp.readAltitude(); 
    if(i == 0) {
      min_h = max_h = h;
    } else {
      if(min_h > h) min_h = h;
      if(max_h < h) max_h = h;  
    } 
    avg_h += h;
  }
  unsigned long time  = millis() - t0; 
  Serial.print("cnt=");
  Serial.print(CNT);
  Serial.print("; time=");
  Serial.print(time);
  Serial.print(" ms, ");
  Serial.print(time / CNT);
  Serial.print(" ms/smpl; min_h=");
  Serial.print(min_h);
  Serial.print(" m; max_h=");
  Serial.print(max_h);
  Serial.print(" m; avg_h=");
  Serial.print(avg_h / CNT);
  Serial.print(" m; delta=");
  Serial.print(max_h - min_h);
  Serial.print(" m;");
  Serial.println();
}
+1
Результат несколько обескураживающий.

Почему, не так все плохо. Датчик шумит, но усредненное значение плавает не так сильно.
Спасибо за проделанный эксперимент.
0
Барометр полетного контроллера квадрокоптера показывает чепуху, если в отверстие попадает свет. Пробовали его в черный ящик класть?
0
Барометр полетного контроллера квадрокоптера показывает чепуху, если в отверстие попадает свет.
У меня получалось, что при освещении лампой отверстия в датчике для забора давления, показания изменяются примерно на 1 мм.рт.ст. и начинают шуметь значительно больше. Наверное, это связано с фотоэффектами на поверхности структуры датчика. При «стандартной» атмосфере это примерно 11 метров барометрической высоты.
Чепухи — не получалось. :)
0
Была мысль, что может быть дело в свете — рекомендация прятать от света в даташите есть. Закрывал листом белой бумаги, вроде ничего не изменилось…
0
Прятать от света — затенять непрозрачным. Т.е. отнюдь не белой бумагой.
0
И неотражающим. Т.е. вообще не белым.
0
Проясните мне один момент, LCD-шильд 5ти вольтовый, датчик 3х вольтовый и выводы у него не толлерантны к 5ти вольтам, каким питанием у вас запитана схема.
Второй момент, в либе от adafruit стоит адрес для датчика 0x77, а в даташите указан 0xEE, там ошибка или как это понять.
0
Ответ на оба вопроса — I2C.
Во первых, поскольку это шина с подтяжкой — пины тянут только вниз, а подтяжка к питанию датчика. Соответственно 5В на линиях данных взяться неоткуда (ну, если к 5В не подтягивать). 5В логике 3.3В в качестве высокого уровня хватает.
Во вторых, адреса у I2C семибитные, причем это 7 старших бит в адресном байте. Младший занимает R/W-бит. Т.е. в шину плюется (Addr << 1) | RW. Если сдвинуть адрес 0х77 заранее — получится именно 0хЕЕ.
0
Ну да :-)
И плюс тот самый линейный стабилизатор 662K, который я обнаружив только сломав плату :-)
Он обеспечивает 3х вольтовое питание датчика и подтяжку к трем вольтам линий I2C.

На приниципиальной схеме в посте посмотрите…
0
Да, но так наверно лучше не делать, если при сбое или ошибке на выводе появится логическая 1 с уровнем в 5 вольт прощай датчик, в модулях от адафруит стоит простейший преобразователь уровней из транзистора и двух резисторов.
0
Вроде у Atmega после рестарта на ногах Hi-Z (т.е. нога вообще никуда не подсоединена).
0
Денис, рестарт это не сбой и не ошибка.
0
Ну сбой чаще всего к рестарту приводит… или к НЕстарту. А чтобы чего-то сбойнуло так, чтобы с неположенных ног логические единицы полезли — такого у меня еще не было.
Программная ошибка — это да, это опасно.
И еще один прикол есть — сколько раз ловил себя на том, что заливаю скетч в конструкцию от предыдущих экспериментов, для того совершенно не предназначенную…
0
Для I2C единичка на шине в любом случае ахтунг — первый же девайс, попытавшийся ее придавить устроит КЗ.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.