Browse Source

校准储液桶的重量

master
zhaohe 1 year ago
parent
commit
84ca40e3a5
  1. 60
      README.md
  2. 2
      iflytoplinuxsdk
  3. 121
      src/service/device_io_control_service.cpp
  4. 26
      src/service/device_io_control_service.hpp
  5. 43
      src/utils/moving_average_filter.hpp
  6. 81
      src/utils/volume_convertor.cpp
  7. 69
      src/utils/volume_convertor.hpp

60
README.md

@ -7,33 +7,7 @@
``` ```
``` ```
修改点: (OK)
1. 用户等级分为3级别(后台不限制用户等级,前台限制用户操作)OK
2. iflytop9973属于admin的超级密码
3. 修改用户密码 OK
4. 登陆时给出提示,用户不存在,或者密码错误
消毒前,如果湿度太大,不允许消毒。
添加预设参数 OK
添加预设参数配置 OK
添加审计数据库接口 OK
添加审计 OK
通过getState可以获得到log,小数 OK
数据库操作加锁 OK
--------------------------------
记录用户操作 (TODO)
添加U盘数据导出
添加审计数据导出
排液自动停止
水禁传感器测试
磁盘管理(磁盘容量不足时,弹出提示,且停止记录数据)
``` ```
@ -49,37 +23,3 @@ sudo apt-get install sqlitebrowser
https://www.sqlite.org/docs.html https://www.sqlite.org/docs.html
``` ```
```
测试指令
```
```
1. 开始消毒后
```
```
液位测量压力传感器:
设备地址:01
量程:-1~4kPa
4 kPa=407.888 毫米水柱
传感器测量精度:0.407888 毫米水柱
```
```
1. 支持调速
2. 液体容量进行滤波
3. 打印日志去掉小数点
1. 加泵写死,速度不可修改,550g/min
2. 注射泵速率限制在30g/min
```

2
iflytoplinuxsdk

@ -1 +1 @@
Subproject commit 45bd079bb5f10f36ecfd610a0de0148cafc97bb5
Subproject commit 279b7054fe46618b4084fba61bcef40763f7b269

121
src/service/device_io_control_service.cpp

@ -19,12 +19,71 @@ using namespace std;
DeviceIoControlService::DeviceIoControlService() {} DeviceIoControlService::DeviceIoControlService() {}
void DeviceIoControlService::initialize() { GET_TO_SERVICE(m_zcanHost); } void DeviceIoControlService::initialize() { GET_TO_SERVICE(m_zcanHost); }
void DeviceIoControlService::updateDisinfectantVolumeSample(float _pa) {
float pa = _pa - 100; // 100当容器中没有液体时的压强
if (pa < 0) pa = 0;
float g = m_volumeConvertor.pressurePa2VolumeG(_pa);
m_disinfectantVolumeSample_g = m_DisinfectantWeightFilter.filter(g);
logger->info("{} pa {} g", _pa, m_disinfectantVolumeSample_g);
}
void DeviceIoControlService::startScan() { void DeviceIoControlService::startScan() {
m_workThread.reset(new Thread("DeviceIoControlService", [this]() {
m_PressureSensorDataSampleThread.reset(new Thread("PressureSensorDataSampleThread", [this]() {
ThisThread thisThread; ThisThread thisThread;
uint32_t i = 0;
int readpressuresensor_id = 1;
while (!thisThread.getExitFlag()) {
/* code */
ZCanHost::huacheng_pressure_sensor_read_c1005_t sdata;
if (m_zcanHost->huacheng_pressure_sensor_read_c1005(1, sdata) == 0) {
lock_guard<recursive_mutex> lock(lock_);
m_pressure_sensor_data[1] = sdata;
}
thisThread.sleepForMs(100);
if (m_zcanHost->huacheng_pressure_sensor_read_c1005(2, sdata) == 0) {
lock_guard<recursive_mutex> lock(lock_);
m_pressure_sensor_data[2] = sdata;
}
thisThread.sleepForMs(100);
if (m_zcanHost->huacheng_pressure_sensor_read_c1005(3, sdata) == 0) {
lock_guard<recursive_mutex> lock(lock_);
m_pressure_sensor_data[3] = sdata;
}
thisThread.sleepForMs(100);
if (m_zcanHost->huacheng_pressure_sensor_read_c1005(4, sdata) == 0) {
lock_guard<recursive_mutex> lock(lock_);
m_pressure_sensor_data[4] = sdata;
}
thisThread.sleepForMs(100);
// if (m_zcanHost->huacheng_pressure_sensor_read_c1005(5, sdata) == 0) {
// lock_guard<recursive_mutex> lock(lock_);
// m_pressure_sensor_data[5] = sdata;
// }
// thisThread.sleepForMs(10);
/**
* @brief
*/
{ //
updateDisinfectantVolumeSample(m_pressure_sensor_data[1].value / 1.0 /*pa*/);
}
}
}));
m_workThread.reset(new Thread("DeviceIoControlService", [this]() {
ThisThread thisThread;
uint32_t i = 0;
int error = 0;
while (!thisThread.getExitFlag()) { while (!thisThread.getExitFlag()) {
/* code */ /* code */
@ -46,51 +105,21 @@ void DeviceIoControlService::startScan() {
lock_guard<recursive_mutex> lock(lock_); lock_guard<recursive_mutex> lock(lock_);
m_adc_2 = adcv; m_adc_2 = adcv;
} }
// m_zcanHost->readadc(1, m_adc_1);
// m_zcanHost->readadc(2, m_adc_2);
// m_zcanHost->readadc(3, m_adc_3);
// m_zcanHost->readadc(4, m_adc_4);
// m_zcanHost->readadc(5, m_adc_5);
} }
if (i % 3000 == 0) {
if (i % 3000 == 0 && error < 10) {
// m_hpp272_data_1 // m_hpp272_data_1
ZCanHost::hpp272_data_t m_hpp272_data_1_cache; ZCanHost::hpp272_data_t m_hpp272_data_1_cache;
int suc = m_zcanHost->hpp272_read_c1000(1, m_hpp272_data_1_cache); int suc = m_zcanHost->hpp272_read_c1000(1, m_hpp272_data_1_cache);
if (suc == 0) { if (suc == 0) {
lock_guard<recursive_mutex> lock(lock_); lock_guard<recursive_mutex> lock(lock_);
m_hpp272_data_1 = m_hpp272_data_1_cache; m_hpp272_data_1 = m_hpp272_data_1_cache;
error = 0;
} else {
error++;
if (error == 10) {
logger->error("hpp272_read_c1000 error:{}", suc);
}
} }
// hydrogen_peroxide_volume
// water_vapor_saturation_pressure_h2o_h2o2
// logger->info("---------hpp272_read_c1000---------");
// logger->info("hydrogen_peroxide_volume :{}", m_hpp272_data_1.hydrogen_peroxide_volume);
// logger->info("h2o_h2o2_rs :{}", m_hpp272_data_1.h2o_h2o2_rs);
// logger->info("temperature1 :{}", m_hpp272_data_1.temperature1);
// logger->info("relative_humidity :{}", m_hpp272_data_1.relative_humidity);
// logger->info("absolute_hydrogen_peroxide :{}", m_hpp272_data_1.absolute_hydrogen_peroxide);
// logger->info("h2o_h2o2dew_point_temperature :{}", m_hpp272_data_1.h2o_h2o2dew_point_temperature);
// logger->info("reserved1 :{}", m_hpp272_data_1.reserved1);
// logger->info("water_volume :{}", m_hpp272_data_1.water_volume);
// logger->info("water_vapor_pressure :{}", m_hpp272_data_1.water_vapor_pressure);
// logger->info("absolute_humidity :{}", m_hpp272_data_1.absolute_humidity);
// logger->info("water_vapor_saturation_pressure_h2o:{}", m_hpp272_data_1.water_vapor_saturation_pressure_h2o);
// logger->info("temperature2 :{}", m_hpp272_data_1.temperature2);
// logger->info("h2o2_vapor_pressure :{}", m_hpp272_data_1.h2o2_vapor_pressure);
// logger->info("water_vapor_saturation_pressure_h2o_h2o2:{}", m_hpp272_data_1.water_vapor_saturation_pressure_h2o_h2o2);
// logger->info("");
}
if (i % 300 == 0) {
if (readpressuresensor_id == 5) {
readpressuresensor_id = 1;
}
ZCanHost::huacheng_pressure_sensor_read_c1005_t sdata;
if (m_zcanHost->huacheng_pressure_sensor_read_c1005(readpressuresensor_id, sdata) == 0) {
lock_guard<recursive_mutex> lock(lock_);
m_pressure_sensor_data[readpressuresensor_id] = sdata;
}
readpressuresensor_id++;
} }
if (i % 100 == 0) { if (i % 100 == 0) {
@ -264,17 +293,7 @@ static int filter(int data) {
int DeviceIoControlService::getDisinfectantVolume_g() { int DeviceIoControlService::getDisinfectantVolume_g() {
// kpa; // kpa;
lock_guard<recursive_mutex> lock(lock_); lock_guard<recursive_mutex> lock(lock_);
float kpa = m_pressure_sensor_data[1].value / 1000.0;
int g = 2.11 * kpa * 1000 * 1.3;
if (g < 450) { /*零点*/
return 0;
} else {
g -= 450;
}
g = filter(g);
// logger->info("g {}", g);
return g;
return m_disinfectantVolumeSample_g;
} }
int DeviceIoControlService::getPressureSensorData(int index) { int DeviceIoControlService::getPressureSensorData(int index) {
lock_guard<recursive_mutex> lock(lock_); lock_guard<recursive_mutex> lock(lock_);

26
src/service/device_io_control_service.hpp

@ -17,6 +17,10 @@
#include "iflytop/components/zcanreceiver/zcanhost.hpp" #include "iflytop/components/zcanreceiver/zcanhost.hpp"
#include "iflytop/core/core.hpp" #include "iflytop/core/core.hpp"
#include "zservice_container/zservice_container.hpp" #include "zservice_container/zservice_container.hpp"
//
#include "utils/moving_average_filter.hpp"
#include "utils/volume_convertor.hpp"
// lock_guard<mutex> lock(lock_); // lock_guard<mutex> lock(lock_);
#include <mutex> #include <mutex>
@ -44,12 +48,19 @@ class DeviceIoControlService : public enable_shared_from_this<DeviceIoControlSer
unique_ptr<Thread> m_workThread; unique_ptr<Thread> m_workThread;
shared_ptr<ZCanHost> m_zcanHost; shared_ptr<ZCanHost> m_zcanHost;
unique_ptr<Thread> m_PressureSensorDataSampleThread;
// //
// std::mutex lock_; // std::mutex lock_;
std::recursive_mutex lock_; std::recursive_mutex lock_;
ZCanHost::hpp272_data_t m_hpp272_data_1 = {0}; ZCanHost::hpp272_data_t m_hpp272_data_1 = {0};
ZCanHost::huacheng_pressure_sensor_read_c1005_t m_pressure_sensor_data[5] = {0}; ZCanHost::huacheng_pressure_sensor_read_c1005_t m_pressure_sensor_data[5] = {0};
int32_t m_disinfectantVolumeSample_g; // 消毒液量采样
// 液体重量计算
VolumeConvertor m_volumeConvertor;
MovingAverageFilter m_DisinfectantWeightFilter = MovingAverageFilter(20);
// //
bool m_waterImmersionSensor1 = false; // 漏液检测 bool m_waterImmersionSensor1 = false; // 漏液检测
@ -68,11 +79,11 @@ class DeviceIoControlService : public enable_shared_from_this<DeviceIoControlSer
/******************************************************************************* /*******************************************************************************
* * * *
*******************************************************************************/ *******************************************************************************/
virtual int heatingStrip_getio1();
virtual int heatingStrip_getio2();
virtual int heatingStrip_getstate();
virtual int heatingStrip_getcurrentValue();
virtual void heartingPlate_setPower(bool val);
virtual int heatingStrip_getio1();
virtual int heatingStrip_getio2();
virtual int heatingStrip_getstate();
virtual int heatingStrip_getcurrentValue();
virtual void heartingPlate_setPower(bool val);
/******************************************************************************* /*******************************************************************************
* * * *
@ -124,7 +135,7 @@ class DeviceIoControlService : public enable_shared_from_this<DeviceIoControlSer
virtual int getWaterImmersionSensor1(); virtual int getWaterImmersionSensor1();
virtual int getWaterImmersionSensor2(); virtual int getWaterImmersionSensor2();
virtual int getDisinfectantVolume_g(); // g
virtual int getDisinfectantVolume_g(); // g
virtual int getPressureSensorData(int index); virtual int getPressureSensorData(int index);
typedef struct { typedef struct {
@ -147,5 +158,8 @@ class DeviceIoControlService : public enable_shared_from_this<DeviceIoControlSer
} all_h2o2sensor_data_t; } all_h2o2sensor_data_t;
virtual bool getAllSensorData(DeviceIoControlService::all_h2o2sensor_data_t& data); virtual bool getAllSensorData(DeviceIoControlService::all_h2o2sensor_data_t& data);
private:
void updateDisinfectantVolumeSample(float kpa);
}; };
} // namespace iflytop } // namespace iflytop

43
src/utils/moving_average_filter.hpp

@ -0,0 +1,43 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>
namespace iflytop {
using namespace std;
class MovingAverageFilter {
size_t size_;
float sum_ = 0;
std::list<float> values_;
public:
MovingAverageFilter(size_t size) : size_(size) {
if (size_ <= 0) {
throw std::invalid_argument("size must be greater than 0");
}
}
float filter(float value) {
if (values_.size() < size_) {
values_.push_back(value);
sum_ += value;
return sum_ / values_.size();
}
sum_ -= values_.front();
values_.pop_front();
values_.push_back(value);
sum_ += value;
return sum_ / size_;
}
private:
};
} // namespace iflytop

81
src/utils/volume_convertor.cpp

@ -0,0 +1,81 @@
#include "volume_convertor.hpp"
using namespace iflytop;
float VolumeConvertor::pa2high(float pa) {
/**
* @brief kpa
*
* p = h*density*g
*
* h = p/(density*g)
*
* p :, pa
* density:, kg/m^3
* g :,
* h :, m
*
* 30.5%=1.11331981022045g/cm^3 = 1113.31981022045kg/m^3
*
*/
// 计算液面高度
float h_m = pa / (density * 9.78); // 液体密度最后会被约掉,大小不影响结果
float h_dm = h_m * 10;
return h_dm;
}
/**
* @brief
*
* @param rb
* @param ru
* @param h
* @param nowh
* @return float
*/
float VolumeConvertor::computeConeVolume(float rb, float ru, float h, float nowh) {
if (nowh > h) nowh = h;
if (nowh < 0) nowh = 0;
float rb_now = rb + (ru - rb) * nowh / h;
float v = PI * nowh * (rb_now * rb_now + rb_now * ru + ru * ru) / 3;
return v;
}
float VolumeConvertor::pressurePa2VolumeG(float _pa) {
float pa = _pa - 90;
if (pa < 0) {
pa = 0;
}
// 计算液面高度
float h_dm = pa2high(pa);
float h1_dm = h_dm;
float h2_dm = h_dm - container_h1;
float h3_dm = h_dm - container_h2 - container_h1;
float h4_dm = h_dm - container_h3 - container_h2 - container_h1;
h1_dm = h1_dm < 0 ? 0 : h1_dm;
h2_dm = h2_dm < 0 ? 0 : h2_dm;
h3_dm = h3_dm < 0 ? 0 : h3_dm;
h4_dm = h4_dm < 0 ? 0 : h4_dm;
h1_dm = h1_dm > container_h1 ? container_h1 : h1_dm;
h2_dm = h2_dm > container_h2 ? container_h2 : h2_dm;
h3_dm = h3_dm > container_h3 ? container_h3 : h3_dm;
h4_dm = h4_dm > container_h4 ? container_h4 : h4_dm;
// printf("h_dm:%f h1_dm:%f, h2_dm:%f, h3_dm:%f, h4_dm:%f\n",h_dm, h1_dm, h2_dm, h3_dm, h4_dm);
float v1 = computeConeVolume(container_rb1, container_ru1, container_h1, h1_dm);
float v2 = computeConeVolume(container_rb2, container_ru2, container_h2, h2_dm);
float v3 = computeConeVolume(container_rb3, container_ru3, container_h3, h3_dm);
float v4 = computeConeVolume(container_rb4, container_ru4, container_h4, h4_dm);
// printf("v1:%f, v2:%f, v3:%f, v4:%f\n", v1, v2, v3, v4);
// h4_dm * (double)(2.1124069002737764)
float V_L = v1 + v2 + v3 + v4; // 0.001m^3
float g = V_L * density; // 1m^3 = 1000L
return g;
}

69
src/utils/volume_convertor.hpp

@ -0,0 +1,69 @@
#pragma once
#include <stdio.h>
namespace iflytop {
#define PI 3.14159265358979323846
class VolumeConvertor {
/**
* @brief
*
* | <--r4_2 -->|
* _____________
* | |
* | |
* | | h4
* | |
* | r4_1 |
* \ / h3
* | | h2
* \ _____ / h1
*
*
* | ru |
* -----------
* \ /
* \ / h
* \_____/
* |rb|
*
*/
float container_h4 = 2.2069;
float container_ru4 = 0.82;
float container_rb4 = 0.82;
float container_h3 = 0.15;
float container_ru3 = 0.82;
float container_rb3 = 0.67;
float container_h2 = 0.0845;
float container_ru2 = 0.67;
float container_rb2 = 0.67;
float container_h1 = 0.0845;
float container_ru1 = 0.67;
float container_rb1 = 0.05;
float density = 1000; // kg/m^3
public:
float pressurePa2VolumeG(float _pa);
private:
float pa2high(float pa);
/**
* @brief
*
* @param rb
* @param ru
* @param h
* @param nowh
* @return float
*/
float computeConeVolume(float rb, float ru, float h, float nowh);
};
} // namespace iflytop
Loading…
Cancel
Save