泳池深度计DIY图解

步骤1:设备背后的理论
我们生活在空气的海底。这里的压力约为1020hpa(百帕斯卡),因为空气柱在此形成的空间重量约为每平方厘米1千克。
水的密度要高得多,因为1升空气重约1.2克,1升水1千克,即约800倍。因此,当每8米高度的气压下降约1hpa时,水面下每厘米的压力增益为1hpa。在约10米的深度,压力为2000hpa,或两个大气压。
此处使用的压力传感器的测量范围介于750和1500 hpa之间,分辨率约为1 hpa。这意味着我们可以在大约1厘米的分辨率下测量高达5米的深度。
该设备将是boyle marriotte型深度计。它的组装非常简单,将在后面的步骤中介绍。传感器使用i2c协议,因此micro:bit的边缘连接器非常方便。最关键的部分是防水袋,因为任何湿度都会损坏微型钻头,传感器或电池。由于一些空气将被困在袋内,增加重量有助于补偿浮力。
步骤2:使用设备
脚本,详细信息如图所示在后面的步骤中,是我之前为压力计开发的脚本的变体。要测试设备,您可以使用那里描述的简单压力室。
对于潜水目的,它显示以压力测量计算的深度,以20 cm步长的条形图或根据要求以数字显示。
使用微型按钮a :位,您将当前压力设置为参考压力值。要确认输入,矩阵会闪烁一次。
您可以使用它来查看潜水的深度,或记录您潜水的深度。
在第一种情况下,将当前的外部气压设置为参考。在第二种情况下,将压力设置在最深处,作为压力参考,然后可以显示当您回到地面时的深度。
按钮b显示根据压差计算的深度,以米为单位的数值。
第3步:所需材料
微观:位。例如。 pimoroni uk/de以13英镑/16欧元计算。
边缘连接器(kitronic或pimoroni),5英镑。我使用了kitronic版本。
bmp/bme280传感器。我使用banggood的bmp280传感器,三个单元4.33欧元。
连接传感器和边缘连接器的跳线。
上面边缘连接器/传感器组合的一个很好的替代品可能是pimoroni enviro:bit(现在未经测试,请参见最后一步)。
用于micro:bit的电池组或lipo。
带开关的电源线(可选但有帮助) )。
明确的防水袋。我使用硅胶袋作为手机和一个或两个小拉链袋。
确保材料足够厚,因此边缘连接器上的针脚不会损坏袋子。
一些重量。我使用了用于钓鱼的铅块。
arduino ide和几个库。
第4步:汇编
安装arduino ide和所需的库。详细信息在此处描述。
(makecode脚本不需要。)
给定使用kitronik边缘连接器,将引脚连接到i2c端口19和20.
这不是必需的用于pimoroni边缘连接器。
将传感器的接头焊接到传感器上,并使用跨接电缆连接传感器和边缘连接器。
将vcc连接到3v,gnd连接到0 v,scl连接到端口19,sda连接到端口20.
或者将电缆直接焊接到分支。
通过usb电缆将micro:bit连接到我们的计算机。
打开提供的脚本并将其闪存到micro:bit。
使用串行监视器或绘图仪,检查传感器是否提供合理的数据。
从计算机上断开micro:位。
将电池或lipo连接到micro:位。
按下按钮b,读取值
按下按钮a.
按下按钮b,读取数值。
将设备放在两层密封袋中,袋中只留下很少的空气。
如果放置重物以补偿浮力。
检查一切是否都是水密的。
前往游泳池玩游戏。
第5步:micropython脚本
脚本只需从中获取压力值传感器,将其与参考值进行比较,然后根据差值计算深度。为了将值显示为条形图,采用深度值的整数和余数部分。第一个确定线的高度。其余部分分成五个箱子,它们确定了栏杆的长度。顶层为0 - 1 m,最低4 - 5 m。
如前所述,按下按钮a设置参考压力,按钮b显示“相对深度”,以米为单位,显示为数值。到目前为止,负值和正值以相同的方式显示在led矩阵上的条形图。
您可以根据需要随意优化脚本。您可以取消静音某些行以在arduino ide的串行监视器或绘图仪上显示值。要模拟该功能,您可以构建我在之前的instructable中描述的设备。
我没有写过读取传感器的脚本部分。我不确定来源,但我要感谢autors。欢迎任何更正或优化提示。
#include
#include
adafruit_microbit_matrix microbit;
#define bme280_address 0x76
unsigned long int hum_raw,temp_raw,pres_raw;
signed long int t_fine;
uint16_t dig_t1;
int16_t dig_t2;
int16_t dig_t3;
uint16_t dig_p1;
int16_t dig_p2;
int16_t dig_p3;
int16_t dig_p4;
int16_t dig_p5;
int16_t dig_p6;
int16_t dig_p7;
int16_t dig_p8;
int16_t dig_p9;
int8_t dig_h1;
int16_t dig_h2;
int8_t dig_h3;
int16_t dig_h4;
int16_t dig_h5;
int8_t dig_h6;
double press_norm = 1015; // a starting value
double depth; // calculated depth
//--------------------------------------------------------------------------------------------------------------------
void setup()
{
uint8_t osrs_t = 1; //temperature oversampling x 1
uint8_t osrs_p = 1; //pressure oversampling x 1
uint8_t osrs_h = 1; //humidity oversampling x 1
uint8_t mode = 3; //normal mode
uint8_t t_sb = 5; //tstandby 1000ms
uint8_t filter = 0; //filter off
uint8_t spi3w_en = 0; //3-wire spi disable
uint8_t ctrl_meas_reg = (osrs_t 《《 5) | (osrs_p 《《 2) | mode;
uint8_t config_reg = (t_sb 《《 5) | (filter 《《 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
pinmode(pin_button_a, input);
pinmode(pin_button_b, input);
serial.begin(9600); // set serial port speed
serial.print(“pressure [hpa] ”); // header for serial output
wire.begin();
writereg(0xf2,ctrl_hum_reg);
writereg(0xf4,ctrl_meas_reg);
writereg(0xf5,config_reg);
readtrim(); //
microbit.begin();
// microbit.print(“x”);
delay (1000);
}
//---------------------------------------------------------------------------------------------
void loop()
{
double temp_act = 0.0, press_act = 0.0, hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal, hum_cal;
int n;
int m;
double press_delta; // relative pressure
int depth_m; // depth in meters, integer part
double depth_cm; // remainder in cm
readdata();
// temp_cal = calibration_t(temp_raw);
press_cal = calibration_p(pres_raw);
// hum_cal = calibration_h(hum_raw);
// temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
// hum_act = (double)hum_cal / 1024.0;
microbit.clear(); //reset led matrix
// button a sets actual value as reference (p zero)
// button b display current value as depth in meters (calculated from pressure difference)
if (! digitalread(pin_button_a)) {
// set normal air pressure as zero
press_norm = press_act;
// microbit.print(“p0: ”);
// microbit.print(press_norm,0);
// microbit.print(“ hpa”);
microbit.fillscreen(led_on); // blink once to confirm
delay (100);
}else if (! digitalread(pin_button_b)) {
// display depth in meters
microbit.print(depth,2);
microbit.print(“m”);
// serial.println(“”);
}else{
// calculate depth from pressure difference
press_delta = (press_act - press_norm); // calculate relative pressure
depth = (press_delta/100); // depth in meters
depth_m = int(abs(depth)); // depth im meters
depth_cm = (abs(depth) - depth_m); // remainder
/* // used for development
serial.println(depth);
serial.println(depth_m );
serial.println(depth_cm);
*/
// steps for bargraph
if (depth_cm 》 0.8){ // set length of bars
(n=4);
} else if (depth_cm 》 0.6){
(n=3);
} else if (depth_cm 》 0.4){
(n=2);
} else if (depth_cm 》 0.2){
(n=1);
} else {
(n=0);
} if (depth_m == 4){ // set level == meter
(m=4);
} else if (depth_m == 3){
(m=3);
} else if (depth_m == 2){
(m=2);
} else if (depth_m == 1){
(m=1);
} else {
(m=0); // upper row
}
/* // used for development purposes
serial.print(“m: ”);
serial.println(depth_m);
serial.print(“cm: ”);
serial.println(depth_cm);
serial.print(“m: ”); serial.println(m); // for development purposes
serial.print(“n: ”); serial.println(n); // for development purposes
delay(500);
*/
// draw bargraph
microbit.drawline(0, m, n, m, led_on);
} // send value to serial port for plotter
serial.print(press_delta);
// draw indicator lines and fix displayed range
serial.print(“ ”); serial.print(0);
serial.print(“ ”); serial.print(-500);
serial.print(“ ”); serial.println(500);
delay(500); // measure twice a second
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------
// the following is required for the bmp/bme280 sensor,keep as it is
void readtrim()
{
uint8_t data[32],i=0; // fix 2014/04/06
wire.begintransmission(bme280_address);
wire.write(0x88);
wire.endtransmission();
wire.requestfrom(bme280_address,24); // fix 2014/04/06
while(wire.available()){
data[i] = wire.read();
i++;
}
wire.begintransmission(bme280_address); // add 2014/04/06
wire.write(0xa1); // add 2014/04/06
wire.endtransmission(); // add 2014/04/06
wire.requestfrom(bme280_address,1); // add 2014/04/06
data[i] = wire.read(); // add 2014/04/06
i++; // add 2014/04/06
wire.begintransmission(bme280_address);
wire.write(0xe1);
wire.endtransmission();
wire.requestfrom(bme280_address,7); // fix 2014/04/06
while(wire.available()){
data[i] = wire.read();
i++;
}
dig_t1 = (data[1] 《《 8) | data[0];
dig_p1 = (data[7] 《《 8) | data[6];
dig_p2 = (data[9] 《《 8) | data[8];
dig_p3 = (data[11]《《 8) | data[10];
dig_p4 = (data[13]《《 8) | data[12];
dig_p5 = (data[15]《《 8) | data[14];
dig_p6 = (data[17]《《 8) | data[16];
dig_p7 = (data[19]《《 8) | data[18];
dig_t2 = (data[3] 《《 8) | data[2];
dig_t3 = (data[5] 《《 8) | data[4];
dig_p8 = (data[21]《《 8) | data[20];
dig_p9 = (data[23]《《 8) | data[22];
dig_h1 = data[24];
dig_h2 = (data[26]《《 8) | data[25];
dig_h3 = data[27];
dig_h4 = (data[28]《《 4) | (0x0f & data[29]);
dig_h5 = (data[30] 《《 4) | ((data[29] 》》 4) & 0x0f); // fix 2014/04/06
dig_h6 = data[31]; // fix 2014/04/06
}
void writereg(uint8_t reg_address, uint8_t data)
{
wire.begintransmission(bme280_address);
wire.write(reg_address);
wire.write(data);
wire.endtransmission();
}
void readdata()
{
int i = 0;
uint32_t data[8];
wire.begintransmission(bme280_address);
wire.write(0xf7);
wire.endtransmission();
wire.requestfrom(bme280_address,8);
while(wire.available()){
data[i] = wire.read();
i++;
}
pres_raw = (data[0] 《《 12) | (data[1] 《《 4) | (data[2] 》》 4);
temp_raw = (data[3] 《《 12) | (data[4] 《《 4) | (data[5] 》》 4);
hum_raw = (data[6] 《《 8) | data[7];
}
signed long int calibration_t(signed long int adc_t)
{
signed long int var1, var2, t;
var1 = ((((adc_t 》》 3) - ((signed long int)dig_t1《《1))) * ((signed long int)dig_t2)) 》》 11;
var2 = (((((adc_t 》》 4) - ((signed long int)dig_t1)) * ((adc_t》》4) - ((signed long int)dig_t1))) 》》 12) * ((signed long int)dig_t3)) 》》 14;
t_fine = var1 + var2;
t = (t_fine * 5 + 128) 》》 8;
return t;
}
unsigned long int calibration_p(signed long int adc_p)
{
signed long int var1, var2;
unsigned long int p;
var1 = (((signed long int)t_fine)》》1) - (signed long int)64000;
var2 = (((var1》》2) * (var1》》2)) 》》 11) * ((signed long int)dig_p6);
var2 = var2 + ((var1*((signed long int)dig_p5))《《1);
var2 = (var2》》2)+(((signed long int)dig_p4)《《16);
var1 = (((dig_p3 * (((var1》》2)*(var1》》2)) 》》 13)) 》》3) + ((((signed long int)dig_p2) * var1)》》1))》》18;
var1 = ((((32768+var1))*((signed long int)dig_p1))》》15);
if (var1 == 0)
{
return 0;
}
p = (((unsigned long int)(((signed long int)1048576)-adc_p)-(var2》》12)))*3125;
if(p《0x80000000)
{
p = (p 《《 1) / ((unsigned long int) var1);
}
else
{
p = (p / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_p9) * ((signed long int)(((p》》3) * (p》》3))》》13)))》》12;
var2 = (((signed long int)(p》》2)) * ((signed long int)dig_p8))》》13;
p = (unsigned long int)((signed long int)p + ((var1 + var2 + dig_p7) 》》 4));
return p;
}
unsigned long int calibration_h(signed long int adc_h)
{
signed long int v_x1;
v_x1 = (t_fine - ((signed long int)76800));
v_x1 = (((((adc_h 《《 14) -(((signed long int)dig_h4) 《《 20) - (((signed long int)dig_h5) * v_x1)) +
((signed long int)16384)) 》》 15) * (((((((v_x1 * ((signed long int)dig_h6)) 》》 10) *
(((v_x1 * ((signed long int)dig_h3)) 》》 11) + ((signed long int) 32768))) 》》 10) + (( signed long int)2097152)) *
((signed long int) dig_h2) + 8192) 》》 14));
v_x1 = (v_x1 - (((((v_x1 》》 15) * (v_x1 》》 15)) 》》 7) * ((signed long int)dig_h1)) 》》 4));
v_x1 = (v_x1 《 0 ? 0 : v_x1);
v_x1 = (v_x1 》 419430400 ? 419430400 : v_x1);
return (unsigned long int)(v_x1 》》 12);
步骤6:主要简化:makecode/javascript代码
2018年5月,pimoroni发布了enviro:bit,它带有bme280压力/湿度/温度传感器,tcs3472光和颜色传感器以及mems麦克风。此外,他们还为makecode编辑器提供了一个javascript库,为这些传感器提供了一个micropython库。
我一直在使用他们的makecode库为我的设备开发脚本。附上你找到相应的十六进制文件,你可以直接复制到你的micro:bit。
下面你会找到相应的javascript代码。池中的测试与早期版本的脚本运行良好,所以我认为它们也可以正常工作。除了基本的条形图版本外,还有一个十字准线版本(x)和一个l版本,旨在使阅读更容易,特别是在光线不足的情况下。选择你喜欢的那个。
let column = 0
let meter = 0
let remain = 0
let row = 0
let delta = 0
let ref = 0
let is = 0
is = 1012
basic.showleds(`
# # # # #
# 。 . 。 #
# 。 # 。 #
# 。 . 。 #
# # # # #
`)
ref = 1180
basic.clearscreen()
basic.forever(() =》 {
basic.clearscreen()
if (input.buttonispressed(button.a)) {
ref = envirobit.getpressure()
basic.showleds(`
# 。 # 。 #
。 # 。 # 。
# # # # #
。 # 。 # 。
# 。 # 。 #
`)
basic.pause(1000)
} else if (input.buttonispressed(button.b)) {
basic.showstring(“” + row + “。” + remain + “ m”)
basic.pause(200)
basic.clearscreen()
} else {
is = envirobit.getpressure()
delta = is - ref
meter = math.abs(delta)
if (meter 》= 400) {
row = 4
} else if (meter 》= 300) {
row = 3
} else if (meter 》= 200) {
row = 2
} else if (meter 》= 100) {
row = 1
} else {
row = 0
}
remain = meter - row * 100
if (remain 》= 80) {
column = 4
} else if (remain 》= 60) {
column = 3
} else if (remain 》= 40) {
column = 2
} else if (remain 》= 20) {
column = 1
} else {
column = 0
}
for (let cola = 0; cola 《= column; cola++) {
led.plot(cola, row)
}
basic.pause(500)
}
})
第7步:enviro:位版本
与此同时,我收到了enviro:bit(20 gbp)和power:bit(6 gbp),来自pimoroni。
如前所述,enviro:bit配有bme280压力,湿度和温度传感器,还有光和颜色传感器(参见此处的应用)和mems麦克风。
power:bit是一个很好的解决方案,可以为micro:bit供电,并带有一个开/关开关。
最棒的是它只是点击和使用,没有焊接,电缆,面包板。
将enviro:bit添加到micro:bit,将代码加载到micro:bit,使用它。
在这种情况下,我使用micro,power和enviro:bit,将它们放在一个ziploc包中,放在一个透明的防水塑料袋中,用于手机,准备就绪。一个非常快速和整洁的解决方案。看图片。开关足够大,可以通过保护层使用。
它已经在水中进行了测试,运行良好。在约1.8米的深度处,测量值约为1.7米。对于快速廉价的解决方案来说并不算太糟糕,但远非完美。调整需要一段时间,因此您可能需要在一定深度停留约10-15秒。
步骤8:电缆和传感器探头版本
这实际上是第一个想法a。用于微型:位深度计,最后要构建。
在这里,我将bmp280传感器焊接到5米长的4线电缆上,并在另一端放置了母跳线。
为了保护传感器免受水的侵害,电缆穿过用过的葡萄酒软木塞。软木塞的末端用热胶密封。在我将两个切口切入软木塞之前,两者都在它周围。然后我将传感器装入海绵球中,在其周围放置一个气球,并将气球的末端固定在软木塞上(下切口)。然后我将3个40克的铅块放入第二个气球中,将其包裹在第一个气囊周围,将重物放在外侧,并将气球的末端固定在第二个凹口处。从第二个气球中取出空气,然后用胶带固定所有东西。查看图片,可能会有更详细的图片。
通过边缘连接器将跳线连接到micro:bit,打开设备并设置参考压力。然后将传感器头缓慢释放到水池底部(10米跳塔,深约4.5米)。
结果:
令我惊讶的是,即使使用这根长电缆也能正常工作。另一方面,但毫不奇怪,在较高压力下测量误差似乎变得更大,据报道估计深度为4米,约为3米。
潜在的应用程序:
通过一些错误修正,该设备可用于测量深度约为4米。
与arduino或raspberry pi配合使用,可用于测量和控制水池或水箱的灌装点,例如:如果水位高于或低于某些阈值,则发出警告。

PS5可通过AI智能调整游戏难度
小米的性价比高就是行业之弊还是是行业之福呢?
小米X1什么时候上市?小米X1最新消息:骁龙660+5.5英寸大屏,只售1999元?
ABB倒装SCARA机器人提高作业空间效率与灵活性
什么是多模光纤_多模光纤的作用
泳池深度计DIY图解
电瓶充电器的使用方法_电瓶充电器怎么看充满
赛迪顾问李珂:我国汽车智能传感器产业的发展现状、趋势与建议
为什么电磁流量计测量误差很大?原因是什么?
具有自校正功能的数模转换器AD760实现高精度波形发生器的设计
丰田和比亚迪建立合资公司,共同研发电动汽车
最新版本小米6仍无法开通公交卡,升级有何用?
!销售/收购/维修HP4286A惠谱HP4286A!小兵/李
家用血氧仪方案开发原理和功能介绍
毫米波雷达发射波的调制方式
步进驱动器的常见故障有哪些?步进电机驱动器的原理
自制空调扇
限流式保护器在地下车库充电设施电气设计中的应用
芯片加工中涉及的7nnm到底是怎么定义的
使FPGA进军ASIC级设计领域的方法步骤