我将LPS331AP连接到Omega Onion2的经验

美好的一天,哈布罗夫斯克!

简短介绍


前几天,我成为了最小的单一付款人从事LEDE的快乐所有者,而我想做的第一件事(在LED闪烁后)是一个家庭气象站,可以从任何地方访问它。 第一步是获取有关温度,湿度和压力的数据。 为此,选择了较早购买的DHT11LPS3311AP传感器(切出的照片)。

那些感兴趣的照片
图片

经过短暂的搜索后,结果发现,如果第一个家族文件齐全并且有许多工作库,那么我选择的晴雨表就不那么受欢迎了,除了用于购买传感器的Arduino商店的自写库(尽管质量很高)(不是广告,只是一个致敬),什么都找不到。

还有什么选择?

  1. 收集ATmega328微控制器上的层,对其进行闪存,填写完成的代码并从中读取。 非常令人兴奋,但听起来像是试图组装自行车以备将来用作拐杖。
  2. 依靠官方数据表,通过I2C来“手动”阅读 。 我尝试过,有可能,但是我不想生成bash脚本,并且在方法上似乎不正确。
  3. 编写一个 ,以所需的方式使用传感器。

如果您对它的来历和目的感兴趣,欢迎光临。

我遇到的第一个问题是语言的选择。 不用单手鼓跳舞就能在单板上工作的东西-C ++和Python。 由于将来我想将此项目置于自己的智能家居的核心,因此选择权就在后者身上。

由于小鸭效应,我没有提出下一个问题(哪个版本),而是立即放入了轻量级python3和用于I2C总线的库。

然后是数小时的吸烟,首先是数据表 ,然后是制造商的软件指南 。 他们使快速准备运行的传感器成为可能(尽管软件指南更完整,包括有关检查测量完成和“重置”传感器以更准确收集的建议)。

我遇到的第一个困难是读取数据。 由于来自温度计的数据以两个字节传输,压力以三个字节传输,因此有必要获得几个字节并将它们组合为一个大数。 但是python默认将十六进制转换为int,并且简单的串联不起作用。 将int转换为十六进制会返回一个完美连接的字符串,但不会转换回数字。 出路? 可以连接对c类型的支持,但我不想弄乱,也不希望用其他库来阻塞内存,因此决定在7行(如果算上字典就算是8)上写一个函数来将伪字节串转换为数字。

包含要转换为int的字符串的十六进制
s_t_h = { '0' : 0, '1' : 1, '2' : 2, '3' : 3, '4' : 4, '5' : 5, '6' : 6, '7' : 7, '8' : 8, '9' : 9, 'a' : 10, 'b' : 11, 'c' : 12, 'd' : 13, 'e' : 14, 'f' : 15 } def __string_to_int(self, hex_string): l = len(hex_string) - 1 res = 0 for h in hex_string: res += s_t_h[h] * (16 ** l) l -= 1 return res 

我相信在这里可以合理地问“为什么要从字典中读取?”这个问题。 答案很简单-我没有想到要对类型转换做出明显的决定,如果专家对这个问题有答案,我将很高兴进行更改。

使我感到困惑的第二个困难是数据的解释。 以上两个文档都给出了非常简单的转换公式:

Pout(mbar)=(PRESS_OUT_H & PRESS_OUT_L & PRESS_OUT_XL)[dec] / 4096表示压力;
T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec] / 480温度和温度T(degC) = 42.5 + (Temp_OUTH & TEMP_OUT_L)[dec] / 480

令人高兴的是,他们立即提供了公制。

但是,第一种方法顽固地给了我0x2F8000结果,这意味着760毫巴或约585 mmHg。 艺术 对于海拔130米的高度来说,这显然是不够的。 重新检查代码,重新读取有关压力测量的信息,重新启动传感器并准确无误地进行操作。 但是对指南的反复研究有所帮助-稳定的760 mbar被解释为传感器有故障的信号。 仔细阅读本文开头所附照片的读者可以确保,原则上芯片上也没有传感器:)幸运的是,我很快就一次购买了其中的两个。

工作芯片和正确操作的照片


中心的黑色小方块是HCLGA-16L测量板,它是传感器的“心脏”。

图片

在发现之后,很明显应该进行健康检查。 于是函数诞生了:

working_check
 BROKEN_MARKER = 0x2f8000/4096 def __working_check(self, address): c1 = self.__read_pressure(address) c2 = self.__read_pressure(address) c3 = self.__read_pressure(address) if c1 == c2 == c3 == BROKEN_MARKER: return True else: return False 

为了避免出现罕见但仍可能发生的误报情况,需要进行三次读取,然后才发出不可操作性的裁决。 在这样的代码中可能会过度使用常量,但只要有可能,都应注意良好的音调。

我立刻想到一个想法,即在初始化期间检查总线上的地址是否正确并添加了__deviceAdressCheck函数,该函数可以检查WHO_AM_I寄存器并期望接收到珍贵的数字0xBB。

似乎没有更多有趣的观点了。 完整的代码在github上可用,并且可以使用和修改。

Source: https://habr.com/ru/post/zh-CN471232/


All Articles