英文:
Strange date/time protocol, need help solving
问题
I'm trying to reverse engineer the data sent from a very old temperature/humidity device and decode the date/time and other data from serial communication.
This are some of the older registers of the device:
and this are more recent registers, device is out of date:
At the moment I've discovered a very weird format for the hour:
In the last byte of the registers is where the hour stands in the following manner:
For example, in one of the last registers of the 2022 table:
0000 0000 001D B360 0A10 6343
0x43 is the hour 13:00:00
In binary: 01000011
If you take the bits 7 and 6 (01) and insert them to the right of the bit 0: 00001101
Which is 13 in decimal.
This, in my opinion, extremely weird format checks for all hours.
This took me a few days, it's amazing.
What I'm asking to anyone who will take the challenge is if you could help me figuring out the rest of the date format.
I really appreciate if you could help.
I tried epoch from year 2000, both endianness, float format, messing around with bits, and xor-ing some bytes in a drowned attempt to figure it out but to no positive results.
Today I discovered the hour and I got really excited!
EDIT: Here is the excel file with the entire device data base: meter database
英文:
I'm trying to reverse engineer the data sent from a very old temperature/humidity device and decode the date/time and other data from serial communication.
This are some of the older registers of the device:
and this are more recent registers, device is out of date:
At the moment I've discovered a very weird format for the hour:
In the last byte of the registers is where the hour stands in the following manner:
For example, in one of the lasts registers of the 2022 table:
0000 0000 001D B360 0A10 6343
0x43 is the hour 13:00:00
In binary: 01000011
If you take the bits 7 and 6 (01) and insert them to the right of the bit 0: 00001101
Which is 13 in decimal.
This, in my opinion, extremely weird format checks for all hours.
This took me a few days, it's amazing.
What I'm asking to anyone who will take the challenge is if you could help me figuring out the rest of the date format.
I really appreciate if you could help.
I tried epoch from year 2000, both endianness, float format, messing around with bits, and xor-ing some bytes in a drowned attempt to figure it out but to no positive results.
Today I discovered the hour and I got really excited!
EDIT: Here is the excel file with the entire device data base: meter database
答案1
得分: 1
最终,我弄清楚了!
原来关键在于字节序,但要考虑到半字节。
在寄存器0000 0000 001D B360 0A10 6343
中:
如果我们按照以下的位置来看待它:abcd efgh ijkl mnop qrst uvwx
那么这是:
温度:mlk
,以开尔文 * 10 表示
压力:qpon
,以百分之一巴表示
日期:vutsr
,以十进制表示(日期10/12/2022用221210十进制或3601A
十六进制表示)
小时:wx
,这部分的位数排列有点奇怪:01234567
到23456701
表示小时。
以下是我编写的代码,将寄存器的值解析为每个数值:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
uint8_t registro[12] = {0x18, 0x00, 0x75, 0x10, 0x00, 0x91, 0xB8, 0x01, 0x06, 0x3E, 0x53, 0x41};
/*
寄存器数据:
修正后消耗: 12.9
未修正消耗: 34.3
温度: 10.9
压力: 2.64
日期: 2022年7月26日
时间: 05:00:00
*/
int main()
{
printf("寄存器信息\n");
//时间
uint8_t hora_parte_1 = registro[11] & 0xC0;
uint8_t hora_parte_2 = registro[11] & 0x3F;
hora_parte_1 = hora_parte_1 >> 6;
hora_parte_2 = hora_parte_2 << 2;
uint8_t hora = hora_parte_1 + hora_parte_2;
printf("寄存器时间:%d\n", hora);
//日期
uint32_t fecha_parte_1 = registro[8] & 0x0F;
uint32_t fecha_parte_2 = registro[9] & 0xF0;
uint32_t fecha_parte_3 = registro[9] & 0x0F;
uint32_t fecha_parte_4 = registro[10] & 0xF0;
uint32_t fecha_parte_5 = registro[10] & 0x0F;
fecha_parte_3 = fecha_parte_3 << 8;
fecha_parte_4 = fecha_parte_4 << 8;
fecha_parte_5 = fecha_parte_5 << 16;
uint32_t fecha = fecha_parte_1 + fecha_parte_2 + fecha_parte_3 + fecha_parte_4 + fecha_parte_5;
printf("日期(十进制):%d\n", fecha);
uint8_t day = fecha % 100;
fecha /= 100;
uint8_t month = fecha % 100;
fecha /= 100;
uint8_t year = fecha;
printf("寄存器日期:%02d-%02d-%02d\n", day, month, year);
//压力
uint8_t presion_parte_1 = registro[6] & 0x0F;
uint8_t presion_parte_2 = registro[7] & 0xF0;
uint16_t presion_parte_3 = registro[7] & 0x0F;
presion_parte_3 = presion_parte_3 << 8;
float presion = (presion_parte_1 + presion_parte_2 + presion_parte_3);
presion /= 100;
printf("寄存器压力:%.2f\n", presion);
//温度
uint8_t temperatura_parte_1 = registro[5] & 0x0F;
uint8_t temperatura_parte_2 = registro[5] & 0xF0;
uint16_t temperatura_parte_3 = registro[6] & 0xF0;
temperatura_parte_1 = temperatura_parte_1 << 4;
temperatura_parte_2 = temperatura_parte_2 >> 4;
temperatura_parte_3 = temperatura_parte_3 << 4;
float temperatura = (temperatura_parte_1 + temperatura_parte_2 + temperatura_parte_3);
temperatura /= 10;
temperatura -= 273.2;
printf("寄存器温度:%.1f\n", temperatura);
//未修正消耗
uint8_t no_corregido_parte_1 = registro[0] & 0x0F;
uint8_t no_corregido_parte_2 = registro[0] & 0xF0;
uint16_t no_corregido_parte_3 = registro[1] & 0x0F;
uint16_t no_corregido_parte_4 = registro[1] & 0xF0;
no_corregido_parte_1 = no_corregido_parte_1 << 4;
no_corregido_parte_2 = no_corregido_parte_2 >> 4;
no_corregido_parte_3 = no_corregido_parte_3 << 12;
no_corregido_parte_4 = no_corregido_parte_4 << 4;
float no_corregido = (no_corregido_parte_1 + no_corregido_parte_2 + no_corregido_parte_3 + no_corregido_parte_4);
no_corregido /= 10;
printf("未修正消耗:%.2f\n", no_corregido);
//修正消耗
uint8_t corregido_parte_1 = registro[2] & 0x0F;
uint8_t corregido_parte_2 = registro[2] & 0xF0;
uint16_t corregido_parte_3 = registro[3] & 0x0F;
uint16_t corregido_parte_4 = registro[3] & 0xF0;
corregido_parte_1 = corregido_parte_1 << 4;
corregido_parte_2 = corregido_parte_2 >> 4;
corregido_parte_3 = corregido_parte_3 << 12;
corregido_parte_4 = correg
<details>
<summary>英文:</summary>
So finally I figured it out!!<br>
Turns out that the key was in the endianness, but taking nibbles in account.<br>
In register `0000 0000 001D B360 0A10 6343`<br>
If we think of it in positions like this : `abcd efgh ijkl mnop qrst uvwx`<br>
So this is:<br>
Temperature : `mlk` , in Kelvin * 10<br>
Pressure : `qpon`, in Bar * 100<br>
Date : `vutsr`, in decimal (date 10/12/2022 is 221210 decimal or `3601A` hexadecimal)<br>
Hour : `wx` , this has a weird arrange of bits: `01234567` to `23456701` this is the hour.<br>
<br>
This is the code I made to decifer the register into each value:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
uint8_t registro[12] = {0x18, 0x00, 0x75, 0x10, 0x00, 0x91, 0xB8, 0x01, 0x06, 0x3E, 0x53, 0x41};
/*
Datos del registro:
Consumo Corregido : 12.9
Consumo sin Corregir : 34.3
Temperatura : 10.9
Presion : 2.64
Fecha : 26/07/2022
Hora : 05:00:00
*/
int main()
{
printf("Registro flashero\r\n");
//HORA
uint8_t hora_parte_1 = registro[11] & 0xC0;
uint8_t hora_parte_2 = registro[11] & 0x3F;
hora_parte_1 = hora_parte_1 >> 6;
hora_parte_2 = hora_parte_2 << 2;
uint8_t hora = hora_parte_1 + hora_parte_2;
printf("Hora de Registro : %d\r\n", hora);
//FECHA
uint32_t fecha_parte_1 = registro[8] & 0x0F;
uint32_t fecha_parte_2 = registro[9] & 0xF0;
uint32_t fecha_parte_3 = registro[9] & 0x0F;
uint32_t fecha_parte_4 = registro[10] & 0xF0;
uint32_t fecha_parte_5 = registro[10] & 0x0F;
fecha_parte_3 = fecha_parte_3 << 8;
fecha_parte_4 = fecha_parte_4 << 8;
fecha_parte_5 = fecha_parte_5 << 16;
uint32_t fecha = fecha_parte_1 + fecha_parte_2 + fecha_parte_3 + fecha_parte_4 + fecha_parte_5;
printf("Fecha en decimal : %d\r\n", fecha);
uint8_t dia = fecha % 100;
fecha /= 100;
uint8_t mes = fecha % 100;
fecha /= 100;
uint8_t anio = fecha;
printf("Fecha de Registro : %02d-%02d-%02d\r\n", dia, mes, anio);
//PRESION
uint8_t presion_parte_1 = registro[6] & 0x0F;
uint8_t presion_parte_2 = registro[7] & 0xF0;
uint16_t presion_parte_3 = registro[7] & 0x0F;
presion_parte_3 = presion_parte_3 << 8;
float presion = (presion_parte_1 + presion_parte_2 + presion_parte_3);
presion /= 100;
printf("Presion de Registro : %.2f\r\n", presion);
//TEMPERATURA
uint8_t temperatura_parte_1 = registro[5] &0x0F;
uint8_t temperatura_parte_2 = registro[5] &0xF0;
uint16_t temperatura_parte_3 = registro[6] &0xF0;
temperatura_parte_1 = temperatura_parte_1 << 4;
temperatura_parte_2 = temperatura_parte_2 >> 4;
temperatura_parte_3 = temperatura_parte_3 << 4;
float temperatura = (temperatura_parte_1 + temperatura_parte_2 + temperatura_parte_3);
temperatura /= 10;
temperatura -= 273.2;
printf("Temperatura de Registro : %.1f\r\n", temperatura);
//CONSUMO SIN CORREGIR
uint8_t no_corregido_parte_1 = registro[0] &0x0F;
uint8_t no_corregido_parte_2 = registro[0] &0xF0;
uint16_t no_corregido_parte_3 = registro[1] &0x0F;
uint16_t no_corregido_parte_4 = registro[1] &0xF0;
no_corregido_parte_1 = no_corregido_parte_1 << 4;
no_corregido_parte_2 = no_corregido_parte_2 >> 4;
no_corregido_parte_3 = no_corregido_parte_3 << 12;
no_corregido_parte_4 = no_corregido_parte_4 << 4;
float no_corregido = (no_corregido_parte_1 + no_corregido_parte_2 + no_corregido_parte_3 + no_corregido_parte_4);
no_corregido /= 10;
printf("Consumo no corregido : %.2f\r\n", no_corregido);
//CONSUMO CORREGIDO
uint8_t corregido_parte_1 = registro[2] &0x0F;
uint8_t corregido_parte_2 = registro[2] &0xF0;
uint16_t corregido_parte_3 = registro[3] &0x0F;
uint16_t corregido_parte_4 = registro[3] &0xF0;
corregido_parte_1 = corregido_parte_1 << 4;
corregido_parte_2 = corregido_parte_2 >> 4;
corregido_parte_3 = corregido_parte_3 << 12;
corregido_parte_4 = corregido_parte_4 << 4;
float corregido = (corregido_parte_1 + corregido_parte_2 + corregido_parte_3 + corregido_parte_4);
corregido /= 10;
printf("Consumo corregido : %.2f\r\n", corregido);
return 0;
}
Result:
Registro flashero
Hora de Registro : 5
Fecha en decimal : 220726
Fecha de Registro : 26-07-22
Presion de Registro : 2.64
Temperatura de Registro : 10.9
Consumo no corregido : 12.90
Consumo corregido : 34.30
Process returned 0 (0x0) execution time : 0.037 s
Press any key to continue.
Sorry, I code in spanish.<br>
Thank you for you help everyone!<br>
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论