- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,对于令人困惑的标题感到抱歉。现在已经很晚了,我无法想出更好的方案。
所以,我有一个 I2C 温度传感器,它以 16 位字的形式输出当前温度。从左到右读取,第 1 位是 MSB,第 13 位是 LSB,因此 13 位是有效负载,最后 3 位是零。我想用 Raspberry Pi 读取该传感器并转换数据。
第一个字节(8 位)是当前温度的整数部分。当且仅当温度为负时,才必须构建整个单词的补码。
第二个字节是小数部分,必须乘以0.03125。
所以,仅举几个示例(TEMP DIGITAL OUTPUT(二进制)/DIGITAL OUTPUT(十六进制),取自此处的数据表 http://datasheets.maximintegrated.com/en/ds/DS1624.pdf)
+125˚C | 01111101 00000000 | 7D00h
+25.0625˚C | 00011001 00010000 | 1910h
+½˚C | 00000000 10000000 | 0080h
0˚C | 00000000 00000000 | 0000h
-½˚C | 11111111 10000000 | FF80h
-25.0625˚C | 11100110 11110000 | E6F0h
-55˚C | 11001001 00000000 | C900h
由于字节顺序的差异,读取传感器时字节顺序会颠倒,这不是问题。 例如,第一行将变为 0x007D 而不是 0x7D00,0xE6F0 变为 F0E6,依此类推...
但是,一旦我构建了负值的补码,我就无法得出正确的转换。
我想出的(不适用于负值)是:
import smbus
import time
import logging
class TempSensor:
"""
Class to read out an DS1624 temperature sensor with a given address.
DS1624 data sheet: http://datasheets.maximintegrated.com/en/ds/DS1624.pdf
Usage:
>>> from TempSensor import TempSensor
>>> sensor = TempSensor(0x48)
>>> print "%02.02f" % sensor.get_temperature()
23.66
"""
# Some constants
DS1624_READ_TEMP = 0xAA
DS1624_START = 0xEE
DS1624_STOP = 0x22
def __init__(self, address):
self.address = address
self.bus = smbus.SMBus(0)
def __send_start(self):
self.bus.write_byte(self.address, self.DS1624_START);
def __send_stop(self):
self.bus.write_byte(self.address, self.DS1624_STOP);
def __read_sensor(self):
"""
Gets the temperature data. As the DS1624 is Big-endian and the Pi Little-endian,
the byte order is reversed.
"""
"""
Get the two-byte temperature value. The second byte (endianness!) represents
the integer part of the temperature and the first byte the fractional part in terms
of a 0.03125 multiplier.
The first byte contains the value of the 5 least significant bits. The remaining 3
bits are set to zero.
"""
return self.bus.read_word_data(self.address, self.DS1624_READ_TEMP)
def __convert_raw_to_decimal(self, raw):
# Check if temperature is negative
negative = ((raw & 0x00FF) & 0x80) == 0x80
if negative:
# perform two's complement
raw = (~raw) + 1
# Remove the fractional part (first byte) by doing a bitwise AND with 0x00FF
temp_integer = raw & 0x00FF
# Remove the integer part (second byte) by doing a bitwise AND with 0XFF00 and
# shift the result bits to the right by 8 places and another 3 bits to the right
# because LSB is the 5th bit
temp_fractional = ((raw & 0xFF00) >> 8) >> 3
return temp_integer + ( 0.03125 * temp_fractional)
def run_test(self):
logging.basicConfig(filename='debug.log', level=logging.DEBUG)
# Examples taken from the data sheet (byte order swapped)
values = [0x7D, 0x1019, 0x8000, 0, 0x80FF, 0xF0E6, 0xC9]
for value in values:
logging.debug('value: ' + hex(value) + ' result: ' + str(self.__convert_raw_to_decimal(value)))
def get_temperature(self):
self.__send_start();
time.sleep(0.1);
return self.__convert_raw_to_decimal(self.__read_sensor())
如果您运行 run_test() 方法,您就会明白我的意思。所有负值都是错误的。
我得到的结果是:
DEBUG:root:value: 0x7d result: 125.0
DEBUG:root:value: 0x1019 result: 25.0625
DEBUG:root:value: 0x8000 result: 0.5
DEBUG:root:value: 0x0 result: 0.0
DEBUG:root:value: 0x80ff result: 1.46875
DEBUG:root:value: 0xf0e6 result: 26.03125
DEBUG:root:value: 0xc9 result: 55.96875
所以,我已经在这个问题上绞尽脑汁了几个小时,但似乎我缺乏按位运算的基础知识。我认为问题在于当值为负数时逻辑 AND 的屏蔽。
编辑:网络上有一些实现。它们都不适用于负温度。我实际上将传感器放入冰水中进行了尝试。我还没有尝试过 Arduino C++ 版本,但从源代码来看,它似乎根本无法构建两者的补码,因此也没有负温度 ( https://github.com/federico-galli/Arduino-i2c-temperature-sensor-DS1624/blob/master/DS1624.cpp )。
最佳答案
有两件事,你已经把你的掩码反过来了,raw & 0x00ff 是小数部分,而不是整数部分,第二,这是我的解决方案,考虑到表中的输入,这似乎对我有用:
import struct
def convert_temp (bytes):
raw_temp = (bytes & 0xff00) >> 8
raw_frac = (bytes & 0x00ff) >> 3
a, b = struct.unpack('bb', '{}{}'.format(chr(raw_temp), chr(raw_frac)))
return a + (0.03125 * b)
struct 模块在处理更基本的数据类型(例如有符号字节)时非常有用。希望这有帮助!
编辑:忽略对你的面具的评论,我现在看到了我自己的错误。你可以切换字节,应该没问题。
结构解释:Struct.(un)pack 都采用 2 个参数,第一个是指定结构体属性的字符串(以 C 语言的角度思考)。在 C 中,结构只是一堆字节,带有一些有关其类型的信息。第二个参数是需要解码的数据(需要是一个字符串,解释了讨厌的 format())。
我似乎无法进一步解释它,我想如果你阅读了 struct 模块和 C 中的结构,并意识到结构只不过是一堆字节,那么你应该没问题:)。
至于二进制补码,这是有符号字节的常规表示,因此不需要转换。你遇到的问题是Python不理解8位整数和符号。例如,您可能有一个有符号字节 0x10101010,但如果您在 Python 中对其进行 long(),它不会将其解释为有符号 8 位 int。我的猜测是,它只是将其放入 32 位 int 中,在这种情况下,符号位将被解释为第八位。
struct.unpack('b', ...) 的作用实际上是将这些位解释为 8 位有符号整数。不确定这是否会让它更清晰,但我希望它有所帮助。
关于python - 将 I2C 传感器 (DS1624) 读数转换为数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18504753/
我想使用两个适配器,具体取决于路线。目前我有以下商店: if (window.USE_FIXTURES) { var my_adapter = 'DS.FixtureAdapter'; } else
Joomla 3.0 DS 不工作。它已被删除。我明白了 Notice: Use of undefined constant DS - assumed 'DS' in 我该如何解决这个问题? Simi
我正在尝试通过一键单击事件从 2 个不同的表中提取数据。我已经检查了所有内容,似乎没有任何拼写错误或任何其他内容,但不断收到此错误。 下面是我的按钮点击事件的代码 Protected Sub btnF
我希望预先填充定制库组件中的选定值,以便执行编辑功能。我尝试了所有可能的方法,但不知道该组件的任何预定义属性可以帮助我实现这一点。该HTML代码如下所示。。.TS代码。选定ID的JSON数据。Avai
目前我正在学习 x86 汇编,因为我喜欢微 Controller 编程,所以我对汇编很熟悉。 目前我一直在到处寻找这个问题的答案,但似乎找不到它...... DS寄存器,我知道它应该指向我程序中的全局
在 bundle 启动和停止时按什么顺序调用带注释的方法? 我使用aQute.bnd.annotation的注释。 有这方面的文档吗? 我的猜测是: bundle 启动时: 设置A onStartUp
我正在尝试让我之前在 Windows 上编写的一些 Python 代码在我的 DS 上运行。我正在使用 ( DSPython ),当我尝试导入数学时,失败并显示“ImportError: No mod
我对 XML 文件进行数字签名,但需要签名标签包含命名空间前缀“ds”。我在谷歌上进行了大量研究,发现了很多相同的问题,但没有令人满意的答案。 我试图将“ds”手动放入文件中,但签名无效。标签“Sig
本文分享自华为云社区《GaussDB(DWS) 《DWS之TPCD-DS&TPC-H与查询性能的那些事儿》》,作者: 一剑战八荒 。 1 综述 本文目标在于,详细讲述使用GaussDB(DWS)时,如
据我所知,在 DS 上运行的代码必须加载到 RAM 中,从而从已经受到限制的 4M 中获取。有没有办法直接从图像运行 DS 代码? 最佳答案 简短的回答:没有。 Nintendo DS 的内存映射不包
我正在尝试覆盖 DS 以在我的 Windows 开发机器中使用“/”而不是“\”。原因是在某些 javascript 上,它使用 cake 的 DS 进行一些 ajax 调用。 例如: var dat
我只是汇编语言的初学者,可能有一些愚蠢的问题。这两行有什么区别? 3e 8b 06 mov eax,DWORD PTR ds:[esi] 8b 06 mov eax,DWORD PTR [esi
我需要在同一云服务中创建两个 DS 虚拟机。在现有门户中,这非常容易,但是在预览门户中,创建虚拟机时似乎没有设置云服务的选项。 问题是现有门户无法创建 DS 虚拟机或具有高级存储的虚拟机。虽然预览门户
0040103A CALL DWORD PTR DS:[40207A] USER32.MessageBoxA DS: 是什么意思? 最佳答案 该指令正在从内存 ds:
这个问题在这里已经有了答案: Scheduler is not scheduling Pod for DaemonSet in Master node (1 个回答) 关闭 4 年前。 我正在运行一
我反汇编了某些二进制文件(Linux elf)。 我找到了这个代码: movsl %ds:(%esi),%es:(%edi) 有两个寄存器“ds”和“es”。 我知道这些被命名为“段寄存器”。 但是,
我正在研究内核开发。我有一个引导加载程序,可以将二进制文件加载到内存并运行它。二进制文件由C语言生成,构建过程如下: i686-elf-gcc -c main.c -o main.o -std=gnu
考虑这种情况: 在完全基于 OSGi 并大量采用服务层 SOA 概念的网络管理系统中,决定将 NE 管理模块转换为 DS 组件。 在跟踪网络资源的配置子代理角色中有一个 DS 组件,在适当的时候,它会
我需要的是每次当某些消费者需要此服务时 + 使用 CDI 时获取新的服务实例。我已经阅读了很多文章,但找不到 2 个问题的答案。 如果我们使用工厂,为什么在服务消费者中我们调用工厂 ( http://
我在 postgres 和对称 ds 的默认配置中使用对称 ds。 我总是收到以下错误。 2017-12-20 09:59:53,372 INFO [SymmetricLauncher] [Wrap
我是一名优秀的程序员,十分优秀!