Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: датчик давления HP02S

Вт май 17, 2011 20:57:21

Ser60 писал(а):Кстати, о каком датчике идет речь?

Упустил - HP03

Re: датчик давления HP02S

Вт май 17, 2011 21:46:54

Ясно. А как насчет показаний температуры у HP03? Наблюдается-ли неповторяемость показаний как я описал выше? И как насчет соответствия показаний с другими термометрами. Правда, возникает вопрос кому из них верить, если нет доступа к баро/термо-камерам. Но у меня 2 датчика SHT15 купленные в разное время из разных источников и BMP085 работают "дых в дых" (отличие не более 0.1 градуса). Я подсчитал, что отличие показаний в 1.5 градуса соответствует отличию параметра dUT (в примере данных констант из даташита сенсора) на 254 единицы. Это в свою очередь приведет к показаниям давления в 996.3 hpa вместо 991.8 hpa в примере из даташита, что соответствует разнице в 4 mmHg.

В Радио за 6/2010 была статья с использованием HP03SA. Там автор тоже сетует на невысокую точность датчика температуры в этом сенсоре, но к сожалению не приводит детали. Поэтому мне интересен Ваш опыт. Может стоит для повышения точности обработки давления измерять температуру другим сенсором, затем пересчитывать ее в dUT (см. алгорит сенсора) и использовать эту величину для обработки "сырых" показаний давления?

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

Re: датчик давления HP02S

Ср май 18, 2011 08:01:58

Результаты проверки за ~8 часов:
20000 измерений
Максимальная разница температур между соседними измерениями 0.34 град (визуально, пока не лень пялиться в экран, температура "скачет" в среднем на 0.11)
В начале измерений (ночью) в комнате было 25 град - мерил двумя датчиками DS1820, HP03 показывал ~26,5 (к сожалению точных цифр не записал).
В 8:30 утра: в комнате 22.5 град, а HP03 показывает 27.7.

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

Re: датчик давления HP02S

Ср май 18, 2011 09:02:51

У меня так:

Код:
//----------

//Модуль обслуживания датчика давления HP02S

//----------

#include "Main.h"
#include "HP02S.h"
#include "I2C.h"

//---------- Используемые модулем аппаратные ресурсы: ----------

//Датчик давления использует тактовую частоту, которую формирует таймер 1
//на выходе OC1A. Для обмена данными с датчиком используется порт I2C,
//реализованный программно.

//---------- Константы: ----------

#define F_MCLK 32768 //тактовая частота датчика, Гц
#define TADC      50 //время преобразования АЦП, мс
#define TIDLE    900 //время ожидания следующего преобразования, мс

#define T1VAL (F_CLK * 5E5 / F_MCLK + 0.5)

enum {      //коды состояний измерителя
  HP_IDLE,  //измеритель в состоянии ожидания
  HP_MEASD, //измерение давления
  HP_MEAST, //измерение температуры
  HP_CALC   //вычисление давления
};

//---------- Переменные: ----------

static char State;         //состояние измерителя
static unsigned int Hp_D0; //калибровочный коэффициент D0
static unsigned int Hp_T0; //калибровочный коэффициент T0
static unsigned int Hp_P0; //калибровочный коэффициент P0
static unsigned int Hp_S;  //калибровочный коэффициент S
static unsigned int Hp_C;  //калибровочный коэффициент C

static unsigned int Hp_D1; //измеренный код давления D1
static unsigned int Hp_T1; //измеренный код температуры T1

static int Pressure;       //текущее значение давления

//---------- Инициализация подсистемы измерителя: ----------

void HP02S_Init(void)
{
  TCCR1A = (1 << COM1A0);              //toggle OC1A on compare
  TCCR1B = (1 << WGM12) | (1 << CS10); //CTC, CK/1
  OCR1A = T1VAL - 1;
 
  //чтение калибровочных коэффициентов:
 
  I2C_Start();                 //start
  I2C_Wr(0xA0);                //address
  I2C_Wr(2);                   //subaddress
  I2C_Stop();                  //stop
 
  I2C_Start();                 //start
  I2C_Wr(0xA0 | I2C_RD);       //address + read
  Hp_D0 = I2C_RdAck() << 8;    //D0 (MSB)
  Hp_D0 = Hp_D0 | I2C_RdAck(); //D0 (LSB)
  Hp_T0 = I2C_RdAck() << 8;    //T0 (MSB)
  Hp_T0 = Hp_T0 | I2C_RdAck(); //T0 (LSB)
  Hp_P0 = I2C_RdAck() << 8;    //P0 (MSB)
  Hp_P0 = Hp_P0 | I2C_RdAck(); //P0 (LSB)
  Hp_S = I2C_RdAck() << 8;     //S (MSB)
  Hp_S = Hp_S | I2C_RdAck();   //S (LSB)
  Hp_C = I2C_RdAck() << 8;     //C (MSB)
  Hp_C = Hp_C | I2C_RdNak();   //C (LSB) + NAK
  I2C_Stop();                  //stop

  State = HP_IDLE;
}

//---------- Процесс измерения: ----------

void HP02S_Exe(bool t)
{
  static int Interval = 0;     //измерительный интервал
  if(t)
  {
    if(Interval)
    {
      Interval--;
    }
    else
    {
      switch(State)
      {
      case HP_IDLE:
        {
          //запуск измерения давления:
          Port_XCLR_1;
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFF);
          I2C_Wr(0xF0);
          I2C_Stop();
          Interval = ms2sys(TADC);
          State = HP_MEASD;
          break;
        }
      case HP_MEASD:
        {
          //чтение измеренного кода давления:
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFD);
          I2C_Stop();
          I2C_Start();
          I2C_Wr(0xEE | I2C_RD);
          Hp_D1 = I2C_RdAck() << 8;
          Hp_D1 = Hp_D1 | I2C_RdNak();
          I2C_Stop();
          //запуск измерения температуры:
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFF);
          I2C_Wr(0xE8);
          I2C_Stop();
          Interval = ms2sys(TADC);
          State = HP_MEAST;
          break;
        }
      case HP_MEAST:
        {
          //чтение измеренного кода температуры:
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFD);
          I2C_Stop();
          I2C_Start();
          I2C_Wr(0xEE | I2C_RD);
          Hp_T1 = I2C_RdAck() << 8;
          Hp_T1 = Hp_T1 | I2C_RdNak();
          I2C_Stop();
          Port_XCLR_0;
          State = HP_CALC;
          break;
        }
      case HP_CALC:
        {
          //вычисление давления:
          long dUP = (long)Hp_D1 - (long)Hp_D0;
          long dT = (long)Hp_T1 - (long)Hp_T0;
          long dUT = (((dT * 29L) / 50L - (dT * dT) / 76666L) * (long)Hp_S) / (long)Hp_C;
          Pressure = (long)Hp_P0 + ((dUP + dUT) * 100L) / (long)Hp_S;
          Interval = ms2sys(TIDLE);
          State = HP_IDLE;
          break;
        }
      }
    }
  }
}

//---------- Считывание текущего значения давления: ----------

int HP02S_GetP(void)
{
  return(Pressure);
}

//----------

Re: датчик давления HP02S

Ср май 18, 2011 18:36:41

Спасибо [b]md5sum[/b] за экспериментальные данные. 20000 измерений за 8 часов - значит интервал между измерениями около 0.7 секунды. Я думаю это может быть слишком быстро и сенсор может от такой скорости прогреваться и показывать завышенную температуру. К сожалению в даташите не указана максимальная частота проведения измерений, но попробуйте ее снизить хотя-бы до 1 измерения в 2 сек. Судя по даташиту (хотя явно
это и не указано), в интервале между измерениями сенсор должен автоматически переходить в спящий режим, где его токопотребление снизится с 500 мка до 1 мка и это должно способствовать его остыванию для следующего измерения. Кстати, вы сняли с него защитную пленку?

Конечно, датчик температуры в сенсоре показывает температуру сенсора, но я не думаю что разработчики имели ее в виду для коррекции показаний давления. Для последних небходимо учитывать скорее температуру окружающего воздуха. Кроме того, зачем-бы они привели в даташите формулу как пересчитать "сырую" температуру в "реальную". Форнулы коррекции давления учитывают лишь "сырую" температуру. Кому нужна температура сенсора? Единственное, что причодит на ум - если при быстром проведении серии измерений будет значительное отличие температуры сенсора с температурой среды, показываемой другим датчиком в системе, то пора дать сенсору поостыть. Хотя, гадать тут можно много...

Я сделал видео своего эксперимента с HP03SA и BMP085 (извиняюсь за качество):
http://www.youtube.com/watch?v=UF8LgLuc1ag
Там показываются данные от HP03SA (с буквой А в начале) и BMP085 с букжой "б" в начале. Числа в диапазоне около 700 - это давление в mmHg, остальные в районе 18-19 - температура. Черная коробка содетжит самодельный датчик температуры и влажности на SHT15 (если на нем видно "H" - то это влажность). Я пробовал подключать дополнительно еше один SHT15, поместив его рядом с сенсорами давления на макетку, но ошутимое отличие с HP03SA по температуре все-равно имеется.

Re: датчик давления HP02S

Ср май 18, 2011 20:20:22

Ковыряю исходник....
Где-то закралась ГРУБАЯ ошибка...
Выкинул датчик на балкон, при температуре на улице +19 датчик показывает +32 и давление РЕЗКО подскочило на 14 мм.рт.ст
:shock: :kill:

Re: датчик давления HP02S

Чт май 19, 2011 04:06:57

Советую почитать документацию на свой компилятор. У меня, например, был в начале затык в том, что компилятор C18 из MPLAB (тестовая схема собрана на PIC18) при делении на степени двойки путем сдвига вправо не мультиплицировал знаковый разряд, а просто посылал туда 0 :shock: Это приводило к тому, что отрицательные числа при делении на степени двойки становились положительными! Для положительных чисел все работает нормально. Хотя это отличие от стандартного ANSI C и описано в документации, здесь Microchiip проявил себя как другая "Micro"- организация, непонятно зачем поперев существующие стандарты. Короче, я не нашел ничего лучшего для борьбы с этим безобразием, как внедрить в C-код ассемблерные вставки везде, где может быть сдвиг вправо отрицательных чисел. Если интересно, можете посмотреть мой непричесанный исходник.

Кроме того, т.к. я использую свободную версию C18, которая не производит оптимизацию кода, при делении 4-байтных чисел типа long на 2^16 компилятор тупо перемалывал биты вместо того, чтобы просто переставить 3 байта. Подчеркиваю, что код может не работать с другими компиляторами (и заведомо не будет работать с микроконтроллерами других семейств), т.к. у них может быть другая схема организации поинтеров на стек данных и система размещения переменных в банках памяти.

Успеха в отладке! Напишите потом в чем была проблема.
Вложения
HP03SA.c
Подорограммы для HP03SA
(4.2 KiB) Скачиваний: 295

Re: датчик давления HP02S

Чт май 19, 2011 22:55:23

Ser60 писал(а):Успеха в отладке! Напишите потом в чем была проблема.

Спасибо, ошибка была вызвана скорее невнимательностью: не привел тип unsigned к signed до вычислений, оставив это компилятору (avr-gcc). :)) И самое удивительное, что при комнатной температуре ошибка почти не проявляла себя....

24000 измерений, с интервалом 1.5 сек.
Максимальная разница температуры между соседними измерениями 0.34.
Относительно DS1820 - HP03m меряет на 1 градус меньше.

Давление относительно уровня моря на 14 мм ниже.
Где найти высоту места по GPS координатам? Сам GPS вычислил 115 м над морем, но у GPS точность по высоте небольшая.

Re: датчик давления HP02S

Чт май 19, 2011 23:05:51

Спасибо за репорт. Попробуйте Google Earth для определения высоты.

Re: датчик давления HP02S

Пт май 20, 2011 09:22:01

Ser60 писал(а):Кстати, вы сняли с него защитную пленку?

сама отвалилась :) Зацепил случайно...
Но на сайте хопер нашел касательно HP03M:
"The gel protection of the sensor provides a water protection sufficient for 100 m waterproof watches without any additional protection"
Раз до 100 м воды,то... :dont_know:

Re: датчик давления HP02S

Пт май 20, 2011 16:44:53

Мдааа... Сильно сказано. Как говорится, нет слов, одни выражения...

Я все-таки думаю, что пленка нужна для предохранения начинки сенсора
внутри трубы от пыли, в том числе при хранении и транспортировке. Мой пришел
(по почте) просто завернутым в пластиковый мешок. Интересно, как они на складе
хранятся, хотя лучше наверное это не знать. То, что пленка предохранит
его даже от капли воды я сомневаюсь, т.к. в моем там дырка (см. фото). Я
пленку снять так и не решился.

Еще может быть она предохраняет его в какой-то мере от света. Некоторые
сенсоры по даташиту не терпят света. Интересно, если вы внутрь трубы направите
прямой солнечный свет, изменятся-ли показания? Я свою тестовую плату
разобрал.

Интересно, что у моего HP03SA тоже заниженные показания температуры и
давления и примерно на столько-же. Учитывая Ваши данные, создается
впечатление, что сенсоры не дотягивают. Может в даташите опечатки в
формулах? Разница по температуре в 1 градус приемлима, а вот в плане давления
разница больше чем я ожидал. Вчера приобрел еще один BMP085 для своего
устройства. На днях впаяю его на плату и отпишусь насчет совпадения или
несовпадения показаний с другими сенсорами.
Вложения
hp03sa.jpg
Фото сенсора HP03SA
(27.86 KiB) Скачиваний: 386

Re: датчик давления HP02S

Пт май 20, 2011 18:24:37

Внутри трубы - что-то геле образное, как и писал производитель. Видно по бликам внутри трубы... Да и сама форма конструкции вызвана тем, что в трубу что-то наливают :beer:
Изображение
По ДШ максимальное давление, которое выдерживает датчик - 15 бар.
100 м воды это примерно 9,8 бар...
Думаю пленка не нужна... но хозяин-барин.

Точность по давлению можно проверить только в барокамере.
Данным аэропортов можно верить, но с учетом того, что они передают в инет (раз в полчаса) -"нельзя использовать для предполетной подготовки" (взято с какого-то сайта аэропорта).
Данные передаваемые Домодедово приведены к уровню моря, и с учетом моей высоты 160 м - точность составила 1 мм.рт.ст

Мне на самом деле такая точность ненужна т.к. интересует только динамика за последние 48 часов.

Ser60: СПАСИБО, за то, что сподвигнули меня на тесты, иначе при комнатной температуре я бы нескоро баг в софте обнаружил :))
Вложения
hp03m.jpg
(10.42 KiB) Скачиваний: 1999

Re: датчик давления HP02S

Сб май 28, 2011 19:56:56

Да пожалуйста, рад был посодействовать.

Я наконец-то написал в каком-то виде программу своей метеостанции на BMP085 и
сравнил ее показания с показаниями друго экземпляра сенсора BMP085 на
макетке. Они в точности совпадают (после пересчета в mmHg)! То есть два
разных сенсора одной модели показывают в точности одно и то-же значение
давления. Весьма впечатляюще для сенсоров.
Вложения
sv400199.jpg
Тестовая плата с BMP085
(170.35 KiB) Скачиваний: 601
sv400200.jpg
Метеостанция на BMP085 и SHT15
(90.98 KiB) Скачиваний: 592

Re: датчик давления HP02S

Вт ноя 22, 2011 18:35:35

Ничегонеработает писал(а):У меня так:

Код:
//----------

//Модуль обслуживания датчика давления HP02S

//----------

#include "Main.h"
#include "HP02S.h"
#include "I2C.h"

//---------- Используемые модулем аппаратные ресурсы: ----------

//Датчик давления использует тактовую частоту, которую формирует таймер 1
//на выходе OC1A. Для обмена данными с датчиком используется порт I2C,
//реализованный программно.

//---------- Константы: ----------

#define F_MCLK 32768 //тактовая частота датчика, Гц
#define TADC      50 //время преобразования АЦП, мс
#define TIDLE    900 //время ожидания следующего преобразования, мс

#define T1VAL (F_CLK * 5E5 / F_MCLK + 0.5)

enum {      //коды состояний измерителя
  HP_IDLE,  //измеритель в состоянии ожидания
  HP_MEASD, //измерение давления
  HP_MEAST, //измерение температуры
  HP_CALC   //вычисление давления
};

//---------- Переменные: ----------

static char State;         //состояние измерителя
static unsigned int Hp_D0; //калибровочный коэффициент D0
static unsigned int Hp_T0; //калибровочный коэффициент T0
static unsigned int Hp_P0; //калибровочный коэффициент P0
static unsigned int Hp_S;  //калибровочный коэффициент S
static unsigned int Hp_C;  //калибровочный коэффициент C

static unsigned int Hp_D1; //измеренный код давления D1
static unsigned int Hp_T1; //измеренный код температуры T1

static int Pressure;       //текущее значение давления

//---------- Инициализация подсистемы измерителя: ----------

void HP02S_Init(void)
{
  TCCR1A = (1 << COM1A0);              //toggle OC1A on compare
  TCCR1B = (1 << WGM12) | (1 << CS10); //CTC, CK/1
  OCR1A = T1VAL - 1;
 
  //чтение калибровочных коэффициентов:
 
  I2C_Start();                 //start
  I2C_Wr(0xA0);                //address
  I2C_Wr(2);                   //subaddress
  I2C_Stop();                  //stop
 
  I2C_Start();                 //start
  I2C_Wr(0xA0 | I2C_RD);       //address + read
  Hp_D0 = I2C_RdAck() << 8;    //D0 (MSB)
  Hp_D0 = Hp_D0 | I2C_RdAck(); //D0 (LSB)
  Hp_T0 = I2C_RdAck() << 8;    //T0 (MSB)
  Hp_T0 = Hp_T0 | I2C_RdAck(); //T0 (LSB)
  Hp_P0 = I2C_RdAck() << 8;    //P0 (MSB)
  Hp_P0 = Hp_P0 | I2C_RdAck(); //P0 (LSB)
  Hp_S = I2C_RdAck() << 8;     //S (MSB)
  Hp_S = Hp_S | I2C_RdAck();   //S (LSB)
  Hp_C = I2C_RdAck() << 8;     //C (MSB)
  Hp_C = Hp_C | I2C_RdNak();   //C (LSB) + NAK
  I2C_Stop();                  //stop

  State = HP_IDLE;
}

//---------- Процесс измерения: ----------

void HP02S_Exe(bool t)
{
  static int Interval = 0;     //измерительный интервал
  if(t)
  {
    if(Interval)
    {
      Interval--;
    }
    else
    {
      switch(State)
      {
      case HP_IDLE:
        {
          //запуск измерения давления:
          Port_XCLR_1;
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFF);
          I2C_Wr(0xF0);
          I2C_Stop();
          Interval = ms2sys(TADC);
          State = HP_MEASD;
          break;
        }
      case HP_MEASD:
        {
          //чтение измеренного кода давления:
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFD);
          I2C_Stop();
          I2C_Start();
          I2C_Wr(0xEE | I2C_RD);
          Hp_D1 = I2C_RdAck() << 8;
          Hp_D1 = Hp_D1 | I2C_RdNak();
          I2C_Stop();
          //запуск измерения температуры:
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFF);
          I2C_Wr(0xE8);
          I2C_Stop();
          Interval = ms2sys(TADC);
          State = HP_MEAST;
          break;
        }
      case HP_MEAST:
        {
          //чтение измеренного кода температуры:
          I2C_Start();
          I2C_Wr(0xEE);
          I2C_Wr(0xFD);
          I2C_Stop();
          I2C_Start();
          I2C_Wr(0xEE | I2C_RD);
          Hp_T1 = I2C_RdAck() << 8;
          Hp_T1 = Hp_T1 | I2C_RdNak();
          I2C_Stop();
          Port_XCLR_0;
          State = HP_CALC;
          break;
        }
      case HP_CALC:
        {
          //вычисление давления:
          long dUP = (long)Hp_D1 - (long)Hp_D0;
          long dT = (long)Hp_T1 - (long)Hp_T0;
          long dUT = (((dT * 29L) / 50L - (dT * dT) / 76666L) * (long)Hp_S) / (long)Hp_C;
          Pressure = (long)Hp_P0 + ((dUP + dUT) * 100L) / (long)Hp_S;
          Interval = ms2sys(TIDLE);
          State = HP_IDLE;
          break;
        }
      }
    }
  }
}

//---------- Считывание текущего значения давления: ----------

int HP02S_GetP(void)
{
  return(Pressure);
}

//----------

С?
Я на МК ничего не собирал объясните пожалуйста как разговаривать с HP03-02

Re: датчик давления HP02S

Вт ноя 22, 2011 18:59:43

Макс электронщик писал(а):С?


Да, Си.

Макс электронщик писал(а):объясните пожалуйста как разговаривать с HP03-02


Так исходник же перед Вами. Что конкретно не понятно?

Re: датчик давления HP02S

Ср ноя 23, 2011 15:57:49

Ничегонеработает писал(а):
Макс электронщик писал(а):
Макс электронщик писал(а):объясните пожалуйста как разговаривать с HP03-02


Так исходник же перед Вами. Что конкретно не понятно?

Что такое исходник!
И I2C

Просто Arduino не имеет библиотеки I2С
Последний раз редактировалось Макс электронщик Сб ноя 26, 2011 10:03:19, всего редактировалось 2 раз(а).

Re: датчик давления HP02S

Ср ноя 23, 2011 16:01:53

http://ru.wikipedia.org/wiki/%D0%98%D1% ... 0%BE%D0%B4
http://ru.wikipedia.org/wiki/I%C2%B2C

Re: датчик давления HP02S

Ср ноя 23, 2011 20:47:33

urry писал(а):http://ru.wikipedia.org/wiki/%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4
http://ru.wikipedia.org/wiki/I%C2%B2C

Как красиво послал! :))

Re: датчик давления HP02S

Чт ноя 24, 2011 14:42:03

urry писал(а):http://ru.wikipedia.org/wiki/%D0%98%D1%81%D1%85%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4
http://ru.wikipedia.org/wiki/I%C2%B2C

Спасибо.

Re: датчик давления HP02S

Вс дек 18, 2011 18:08:16

куда все делись???
Ответить