О поведении датчика давления BMP180

dhog1
Offline
Зарегистрирован: 01.03.2016

Замеряю время вызова функции опроса BMP180, температура, потом давление в одном флаконе (опросе). Для различных разрешений (точностей). МК ATMega328P, 16 МГц, 5 В. Замер времени по Timer1, 2000 кГц, 1 тик 0.5 мкс, начало измерения при вызове функции опроса, окончание - при возврате из функции. Помимо собственно измерений, там (в функции) и обсчет, чтение калибровочных коэффициентов и т.п.

Собственно измерения (температуры и затем давления) начинаются командой начала измерения и прекращаются при сбросе бита CSO в контрольном регистре 0xF4. Все по документации.

Вот результаты. Между сериями около 30 с, между измерениями 3 с.

О достоверности измерений. Температура совпадает +/- 0.1*С с одновременно работающими датчиками DS1621 и DS18B20 (ну и DHT22 близок). Давление проконтроллировать нечем, но высота (ALT, производная от измеренного давления) очень хорошо совпадает с определенной на глаз. (Выбор на карте высот города своей улицы + поправка на лапоть (зачеркнуто) этаж обиталища. Расхождение 2 м.)

Да, BMP180 из братского Китая, по фотографии не отличим от рассово правильных Adafruit. Каким напряжением его и его выводы питать в курсе.

Значения времени измерения, как видно из картинки, на порядок меньше ожидаемого. Да, растут с ростом точности, но тоже не так резко, как ожидается.

Или как говорил товарищ О.Бендер - "Вас обманули. Вам дали гораздо лучший мех. Это шанхайские барсы."

После этого моего удивления не хватает на то, что BMP180 работает по I2C на 100 кГц и отказывается работать на 400 кГц.

Кто-нибудь может прокомментировать и не дать остаться в неведении?

tyshkevich10088...
Offline
Зарегистрирован: 18.03.2016

Привет! кто может подсказать, какая распиновка при подключении arduino leonardo и датчика освещенности BH 1750? 

dhog1
Offline
Зарегистрирован: 01.03.2016

Понимаю, что времени нет, все дела, всякое такое...

Собственно SDA к SDA(2), SCL к SCL(3), о чем на этом же сайте и написано. Какие-то проблемы?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Пасибки за информацию, если ещё опубликуете скетчик работы с датчиком - народ будет признателен. По заданному вопросу скорости I2C железяка может быть просто заточена под эту скорость втупую. А вот то, что он работает настолько шустро - приятненько. Лежит, тоже ждет своего часа..

alexvs
Offline
Зарегистрирован: 22.07.2014

А пример, идущий в комплекте с библиотекой к датчику, самому слабо открыть?

dhog1
Offline
Зарегистрирован: 01.03.2016

Arhat109-2

Подозрение вызывает скорость считывания, которая существенно отличается от приведенной в документации. Данные же представляются правдоподобными. Результат устойчив.

Не умею писать скетчи, вот полный текст функции опроса.

_bmp180.h

#ifndef bmp180_h
#define bmp180_h

#include <avr035.h>
#include <delay.h>
#include <math.h>

#define BMP180_ADDR         0x77

#define sealevelPressure    101325

#define BMP180_CTRL_REG     0xF4
#define BMP180_CSO_BIT      5

#define BMP180_T_CMD        0x2E
#define BMP180_P0_CMD       0x34       // low cmd
#define BMP180_P1_CMD       0x74
#define BMP180_P2_CMD       0xB4
#define BMP180_P3_CMD       0xF4       // ultrahigh cmd

#define BMP180_CONSTS       0xAA
#define BMP180_OUT          0xF6
#define BMP180_SOFT_RESET   0xE0    // <-- 0xB6

#define _TWI_INIT  { TWSR &= 0xFC; TWBR = 0x48; }   // @16Mhz MCU twi 100kHz TWBR = 0x48;
                                                    //            twi 400kHz TWBR = 0x0C
                                                    // @8Mhz MCU  twi 100kHz TWBR = 0x20;

                                                    // return altitude in m
uint16_t bmp180_read(int16_t *tm, uint16_t *p, unsigned char cmd);



#endif

_bmp180.c

#include <_bmp180.h>

#define BMP180_CONST(cnst)  { twi_master_trans(BMP180_ADDR, buf, 1, &buf[1], 2); \
                              (cnst) = buf[1] << 8 | buf[2]; \
                              buf[0] += 2; }

void twi_master_trans(uint8_t twi_addr, unsigned char *outdata, uint8_t outlen, unsigned char *indata, uint8_t inlen) {

uint8_t i;
                                            // send START condition
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
    while (!(TWCR & (1<<TWINT)));

    if (outlen) {                           // if there are data to be sent

        TWDR = twi_addr << 1;               // twi slave bus address + Write (SLA+W)
        TWCR = (1<<TWINT)|(1<<TWEN);
        while (!(TWCR & (1<<TWINT)));

        for (i=0; i<outlen; i++) {          // send data bytes
            TWDR = *(outdata+i);
            TWCR = (1<<TWINT)|(1<<TWEN);
            while (!(TWCR & (1<<TWINT)));
        };
    };

    if (inlen) {                            // if there are data to be received

        if (outlen) {                       // send Repeated Start after TX to switch in MR mode
            TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
            while (!(TWCR & (1<<TWINT)));
        }

        TWDR = (twi_addr << 1) | 0x01;      // twi slave bus addr + Read (SLA+R)
        TWCR = (1<<TWINT)|(1<<TWEN);
        while (!(TWCR & (1<<TWINT)));

        for (i=0; i<inlen-1; i++) {
            TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);   // send ACK
            while (!(TWCR & (1<<TWINT)));
            *(indata+i) = TWDR;
        };

        TWCR = (1<<TWINT)|(1<<TWEN);            // last data byte w/o ACK
        while (!(TWCR & (1<<TWINT)));
        *(indata+inlen-1) = TWDR;
    };

    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);     // STOP condition
}

								// tm - temperature in 0.1*C
								// p  - pressure in mm Hg
								// return altitude in m
uint16_t bmp180_read(int16_t *tm, uint16_t *p, unsigned char cmd) {

unsigned char buf[3], OSS;

int16_t AC1, AC2, AC3, B1, B2 , MB, MC, MD;
uint16_t AC4, AC5, AC6;
int32_t  X1, X2, X3, B3, B5, B6, P, T;
uint32_t B4, B7, UT, UP;

uint16_t msb=0;

    _TWI_INIT;
						// read calibration constants
    buf[0] = BMP180_CONSTS;
    BMP180_CONST(AC1);
    BMP180_CONST(AC2);
    BMP180_CONST(AC3);
    BMP180_CONST(AC4);
    BMP180_CONST(AC5);
    BMP180_CONST(AC6);
    BMP180_CONST(B1);
    BMP180_CONST(B2);
    BMP180_CONST(MB);
    BMP180_CONST(MC);
    BMP180_CONST(MD);
    OSS = (cmd & 0xC0) >> 6;
						// start temperature measurement
    buf[0] = BMP180_CTRL_REG;
    buf[1] = BMP180_T_CMD;
    twi_master_trans(BMP180_ADDR, buf, 2, 0, 0);

    do {
        delay_us(4);
        twi_master_trans(BMP180_ADDR, buf, 1, &buf[1], 1);
    } while (buf[1] & (1<<BMP180_CSO_BIT));
						// get row temperature
    buf[0] = BMP180_OUT;
    twi_master_trans(BMP180_ADDR, buf, 1, &buf[1], 2);
    msb = buf[1] << 8 | buf[2];
    UT  = msb;
    						// start pressure measurement
    buf[0] = BMP180_CTRL_REG;
    buf[1] = cmd;
    twi_master_trans(BMP180_ADDR, buf, 2, 0, 0);

    do {
        delay_us(4);
        twi_master_trans(BMP180_ADDR, buf, 1, &buf[1], 1);
    } while (buf[1] & (1<<BMP180_CSO_BIT));
						// get row pressure
    buf[0] = BMP180_OUT;
    twi_master_trans(BMP180_ADDR, buf, 1, buf, 3);
    msb  = buf[0] << 8 | buf[1];
    UP = msb;
    UP <<= 8;
    UP |= buf[2];
    UP >>= (8 - OSS);
						// long way to calculate all
    X1 = (UT - (int32_t)AC6) * (int32_t)AC5 >> 15;
    X2 = ((int32_t)MC << 11) / (X1 + (int32_t)MD);
    B5 = (int32_t)(X1 + X2);
    T  = (B5 + 8) >> 4;     		// temperature in 0.1C

    *tm = (int16_t)T;   

    B6 = B5 - 4000U;
    X1 = ((int32_t)B2*(B6*B6) >> 12) >> 11;
    X2 = (int32_t)AC2*B6 >> 11;
    X3 = X1 + X2;
    B3 = ((((int32_t)AC1 *4 + X3) << OSS) + 2) >> 2;

    X1 = (int32_t)AC3*B6 >> 13;
    X2 = ((int32_t)B1*(B6*B6) >> 12) >> 16;
    X3 = ((X1 + X2) + 2) >> 2;
    B4 = (uint32_t)AC4*(uint32_t)(X3 + 32768) >> 15;
    B7 = ((uint32_t)UP - B3)*(uint32_t)(50000UL >> OSS);
    if (B7 < 0x80000000) { P = (B7*2)/B4; } else { P = (B7/B4)*2; };

    X1 = (P >> 8) * (P >> 8);
    X1 = (X1 * 3038) >> 16;
    X2 = (-7357 * P) >> 16;
    P  += ((X1 + X2) + 3791) >> 4;

    *p = (uint32_t)((float)P*0.0075006375541921);

    return (uint16_t)(44330.0 * (1.0 - pow( (float)P / sealevelPressure,0.1903)));
}

Смотрел как кодируют другие, там просто ставится временнАя задержка между началом измерения и считыванием данных. Так тоже работает, результаты такие же.

alexvs

Мне даже подобные комментарии получать не слабо.

Пришла с Али россыпь датчиков. По виду BMP180. По программированию тоже. В упаковке библиотека не обнаружилась. В документации Bosh вежливо отсылают к региональным авторизованным поставщикам. Ссылку на библиотеку, идущую в комплекте с датчиком, предоставите? А пример сам постараюсь открыть.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Спасибо за скетчик, посмотрю и, если не возражаете - добавлю в свою библиотеку arhat .. может кому пригодится.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

 

После этого моего удивления не хватает на то, что BMP180 работает по I2C на 100 кГц и отказывается работать на 400 кГц.

Кто-нибудь может прокомментировать и не дать остаться в неведении?

[/quote]

Не могу понять что Вы желаете узнать, а вообще в правом верхнем углу форума  есть срока "поиск" набираете там BMP 180 и узнаете много интересного.

dhog1
Offline
Зарегистрирован: 01.03.2016

oleg_kazakof

Кроме ваших же советов всем обращаться в поиск ничего интересного не обнаружил. Вы понимаете, на что я жалуюсь?

Нет проблем с подключениями, хоть одного, хоть нескольких датчиков, нет проблем со считыванием данных.  Есть смутное подозрение, что я где-то лажаю. Лажа в том, что считывание внешне достоверных данных происходит слишком быстро. По технике из документации, разумеется. Вот с этим кто-нибудь заморачивался? (Ну может там CSO нужно OSS раз дожидаться или еще что-то).

Ну и дополнительно, это уже мелочи. Кто-нибудь работал с BMP180 в режимах I2C шины выше standart (100 kHz)?

oleg_kazakof, вы уж лучше сразу ссылку на даташит приводите, если пост достает вас своей глупостью.

tyshkevich10088...
Offline
Зарегистрирован: 18.03.2016

dhog1 пишет:

Понимаю, что времени нет, все дела, всякое такое...

Собственно SDA к SDA(2), SCL к SCL(3), о чем на этом же сайте и написано. Какие-то проблемы?

спасибо я просто еще зеленый совсем ,все что находил это на UNO там 4 , 5 вывод.и не получалось был неизменный коивицент покозаний.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Конкретно по этому дачтику - не подскажу, сам ещё его не ковырял.. пока лежит без надобности.

Но вот по опыту снятия показаний с датчика цвета TCS3200, могу сказать что почитав его даташит и посчитав обратную матрицу восстановления цветности и переведя её в целочисленную арифметику со сдвигами до точности в 0.5%, да прокалибровав его светодиоды на предмет восстановления баланса белого и тоже сдвигами до 0.5%, а также учтя фоновые засветки и подняв цветоделение на 12% .. получил вполне точный прибор с погрешностью около 2% определения RGB цветов в диапазоне освещенностей от 300 люкс до 12000люкс и чуствительностью от 7лк., да и скорость съема показаний в районе 1-16мсек (автоподстройка по яркости) .. а вот народ пишет, что "фигня, а не датчик" .. а по мне так очень хороший приборчик. :)

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

А вот по поводу скоростей шины I2C, могу предположить что в самом датчике нестандартная скорость просто не предусмотрена .. ну не ловит он частоту выше и всё тут.

Или Вы где-то находили решения с этой микросхемой и иной скоростью I2C?

dhog1
Offline
Зарегистрирован: 01.03.2016

Arhat109-2

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

Наверное пора (мне) прекращать нытье с BMP180.  Что касается частоты по I2C, то она до 3.4 МГц заявлена, но тут скорее мои замороки - длина проводов, сопли на макетках, еще что-то. Протоколы обмена всегда пишу сам, это просто интересно. На высоких скоростях бывают нюансы, видимо с twi на мегагерце еще не справился.

Благодарю за адекватные ответы.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну .. сейчас уже да, TWI (он же I2C) значительно расширен по спецификации .. но, косоглазые (а зачастую и косорукие мастера поднебесной) ставят в такие шилды "что подешевше" и достаточно старые микрухи .. вот они запросто могут иметь "фикс" по скорости шины.

С теми же датчиками цвета: чуть не пожег свою дуньку. На шилде есть нога !OE которая типа "выбор датчика" .. сделал расширитель и поставил 2 датчика (предварительно закрыв в корпус, изолировав трубкой приемник от собственных светиков .. разъёмчик, лего детальки для крепления .. "как надо" .. и внезапно обнаруцжил, что этот вход на шилде .. ага, тупо сидит на земле. Какое-то время не мог понять почему все время работает один из 2-х дачтиков .. все искал программную ошибку, пока не доперло. Хорошо что ничего не погорело.