• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Датчик давления воды i2c

pvvx

Активный участник сообщества
Из всего что есть в данном архиве, информация только тут (авто-перевод с китайского):
C:
#include "MyDefine.h"
#include "JHM1200.h"
#include "JHM1200_IIC.h" 
// Определить верхний и нижний пределы калибровочного давления
#define CAL_L 20000  //20Kpa
#define CAL_H 120000 //120Kpa

// 7-битный адрес IIC JHM 1200 — 0x78.
//uchar Device_Address = 0x78 << 1;
uchar Device_Address;// = 0xf0;
//Необходимо определить функцию задержки
void DelayMs(uchar shu) // Демонстрационная программа 8 МГц/1 мс
{
    uchar j;
    uchar i;
    _clrwdt();
    for(i=0; i<shu; i++)
        for(j=0; j<120; j++)
        {
            _nop();_nop();
        }
}

// Прочтите статус IIC, чтобы определить, занят ли IIC.
uchar JHM1200_IsBusy(void)
{
    uchar status;
    _clrwdt();
    BSP_IIC_Read(Device_Address, &status, 1);
    status = (status >> 5) & 0x01;
    return status;
}

/**
 * @Используйте команду 0xAC для расчета фактического давления и температуры с использованием внутреннего алгоритма JHM 1200.
 * @Обратите внимание на отправку 0xAC, чтение статуса IIC до тех пор, пока IIC не будет занят.
 * @Обратите внимание, что общий размер возвращаемых данных составляет 6 байтов, расположенных по порядку: слово состояния, трехбайтовое значение давления, двухбайтовое значение температуры.
 * @Обратите внимание, что возвращаемое трехбайтовое значение давления пропорционально максимальному 24-битному значению 16777216. На основе этого соотношения фактическое значение давления снова преобразуется в соответствии с диапазоном калибровки.
 * @Обратите внимание, что возвращаемое двухбайтовое значение температуры пропорционально 16-битному максимальному значению 65536. На основе этого соотношения фактическое значение давления снова преобразуется в соответствии с диапазоном калибровки.
 * @Примечание Точка нулевого давления и точка полного давления калибровочного давления составляют 20 кПа и 120 кПа соответственно.
 * @Обратите внимание, что нулевая точка температуры калибровки равна -40°C, а полная точка – 150°C.
 * @Примечание: Рассчитайте измеренное значение давления на основе единицы измерения давления Па и измеренного значения температуры 0,01°C.
 */
void JHM1200_get_cal()
{
    uchar buffer[6] = {0};
    ulong press_raw = 0;
    uint temp_raw = 0;
    double press = 0.0, temp = 0.0;
    _clrwdt();
    // Отправляем команду 0xac и читаем возвращенные шестибайтовые данные
    buffer[0] = 0xAC;
    BSP_IIC_Write(Device_Address, buffer, 1);// Запишите один байт данных через IIC
    DelayMs(5);
    while (1)
    {
        if (JHM1200_IsBusy())// Прочтите статус IIC, чтобы определить, занят ли IIC.
        {
            DelayMs(1);
        }
        else
            break;
    }
    BSP_IIC_Read(Device_Address, buffer, 6);//Чтение байтов данных через IIC

    // Преобразование возвращаемых значений давления и температуры в фактические значения на основе диапазона калибровки.
    press_raw = ((ulong)buffer[1] << 16) | ((ulong)buffer[2] << 8) | buffer[3];
    temp_raw = ((ulong)buffer[4] << 8) | (buffer[5] << 0);
    press = (double)press_raw / 16777216;
    press = press * (CAL_H - CAL_L) + CAL_L;
    temp = (double)temp_raw / 65536;
    temp = temp * 19000 - 4000;
}
 

pvvx

Активный участник сообщества

StanislavM

New member
Да у меня задача воду измерять, на мойке сомообслуживания.

А как же PDF который в не архива с кодом, там указано что рабочие температура датчика: -20 ... +60 градусов. Остается опять вопрос, берешь датчик в руку он соответственно нагревается, а по показаниям температура падает =)

Какие будут мысли?

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

Ну вот что он мне показывает:
Update Data. Pressure: 0.01, Temperature: 27.96C
Update Data. Pressure: 0.01, Temperature: 27.97C
Update Data. Pressure: 0.01, Temperature: 27.97C

Так то получается, градусов на 5 ошибается. Стоит его подержать в руке и подуть:
Update Data. Pressure: 0.04, Temperature: 27.48C
Update Data. Pressure: 0.08, Temperature: 27.35C
Update Data. Pressure: 0.01, Temperature: 27.21C
Update Data. Pressure: 0.01, Temperature: 27.08C
Update Data. Pressure: 0.01, Temperature: 26.94C

Код:
void readSensor()
{
  //#define                     CAL_L                 20000 //20Kpa
  //#define                     CAL_H                 120000 //120Kpa
  #define                     CAL_L                 -125000 //0-1MPA
  #define                     CAL_H                 1125000 //0-1MPA
  #define                     CAL_D                 -2000 //-20°С
  #define                     CAL_U                 6000 //60°С
  //#define                     CAL_D                 -4000 //-40°С
  //#define                     CAL_U                 15000 //150°С
  uint8_t                     req;
  uint8_t                     buffer[6];
  uint32_t                    rawPressure;
  uint16_t                    rawTemperature;
  Wire.beginTransmission(I2C_device_address);
  Wire.write(0xAC);
  Wire.endTransmission();
  do {
      req=Wire.requestFrom(I2C_device_address, byte(1));
      buffer[0] = Wire.read();             
  } while (buffer[0]>>5 & 0x01);
  req=Wire.requestFrom(I2C_device_address, byte(6));
  for (byte i=0;i<req;i++) {buffer[i]=0;buffer[i]=Wire.read();}

  rawPressure     = ((ulong)buffer[1] << 16)  | ((ulong)buffer[2] << 8) | buffer[3];
  rawTemperature  = ((ulong)buffer[4] << 8)   | (buffer[5] << 0);
  pressure = (double)rawPressure / 16777216;
  pressure = pressure * (CAL_H - CAL_L) + CAL_L;
  pressure = pressure / 100000;
  temperature = (double)rawTemperature / 65536;
  temperature = temperature * (CAL_U - CAL_D) + CAL_D;
  temperature = temperature / 100;
}
 

pvvx

Активный участник сообщества
Под каждый датчик вам придется подбирать поправочный коэффициент от температуры. А так же уровни нуля и коэффициенты множителя, если характеристика линейная. Если нет - тогда таблицы...
А она не может быть линейной из-за принципов построения датчика.
В итоге подбор зависит от желаемой точности.
Для Arduno и так пойдет... :)
 

lynxchat

New member
Никто не поделится результатами? А то прошло уже не мало времени, а всё равно Tasmota и ESPhome его не видят нормально. Может есть у кого готовое решение по экспорту данных с этих датчиков в MQTT или HA сразу???
Лично мне то от них только давление нужно, для системы против утечек.
 

pvvx

Активный участник сообщества
Никто не поделится результатами? А то прошло уже не мало времени, а всё равно Tasmota и ESPhome его не видят нормально. Может есть у кого готовое решение по экспорту данных с этих датчиков в MQTT или HA сразу???
Лично мне то от них только давление нужно, для системы против утечек.
Не видел реализаций описываемого датчика в HA.
Есть только другие...
 
Сверху Снизу