LÖSUNG:Dekodieren Temperatur Feuchte T/H sensor von PEARL NC7427(NC7415) 433MHz

Begonnen von maxtox, 25 September 2016, 19:37:33

Vorheriges Thema - Nächstes Thema

juergs

Hier mein aktueller Stand:

hatte doch etwas zu kämpfen um auf Stand zu kommen.

Meine Vorgehensweise:

1.) Pulse-Erkennung des Telegramms funktioniert sehr gut.
Die einzelnen bits werden in ein Byte-Array mit Länge 42 als Wert 0 oder 1 gespeichert.
Hier habe ich die Telegrammbits byteweise zur Verfügung, in der Reihenfolge, wie sie reinkommen.

2.) Um die Daten elegant aus einer Struktur bzw. Union lesen zu können, muss ich dann aber einiges "richten":
Hier die Definition, die das Protokoll wiederspiegelt, dafür (Grundlage dafür ist ein 64Bit-Integer):
union proto_union
{
    unsigned long long raw;   
    struct proto_struct
    {
        unsigned long dummy : 22;
        byte lead : 2;
        byte id : 8;
        byte bat : 2;
        byte chan : 2;
        unsigned short temp : 12;
        byte hum : 8;
        byte crc : 8;
    } d;
} p;


damit die Wertigkeiten dafür passen, muss ich die jeweiligen Wertigkeiten für ID+CH+Temp+Hum+Crc
binär im Byte-Array swappen.  Dann steht alles richtig bzw. lesbar in den einzelnen Strukt-Elementen aus der Umwandlung des int64-Wertes.
Dann werden 15 Telegramme in einem Ringpuffer gehalten bzw. zwischengespeichert.

Das Ergebnis daraus, aus dem Seriell-Log des Arduinos:
Zitat------------------------------------------------------------
buffer.read: [4]    
0_________10________20________30________40________50________60
0123456789012345678901234567890123456789012345678901234567890123
0000110101100010011110100110000010111101000000000000000000000000
ld:   0
id:   189
id_c:   61
bat:   0
ch:   0
tempF:    0x6A7
tempC:    26.83
hum:   98
crc:   13
raw:   964467826117050368
------------------------------------------------------------
FUNC    ID: 61 [61]   T: 26.83   H: 98.00
TX    ID: 61   T: 26.83   H: 98.00
------------------------------------------------------------

Da LaCrosse nur Ids bis 127 zulässt, subtrahiere ich bei größeren IDs einfach 128 ab,
bzw. setze das 7te Bit der ID auf 0 (id/id_c).   

Mein Problem besteht im Moment noch aus:

a.) der falsche HUM-Wert
b.) die "passgenaue" Einbindung der CRC-Unterroutine.

Den int64-Wert für den CRC-Aufruf habe ich, vermute aber, nach der Anpassung mit der Bit-Tauscherei passt das nicht mehr ... 
Oder ist nur die Anzahl der Einsen und Nullen relevant, egal in welcher Kombination? (... sah für mich so aus, muss ich noch Testen) 
Da ich den Struct und die Union vor den eigentlichen Werten definiert hatte, ist die Bitorder des Telegramms
zu allem Überfluss noch im int64 gedreht, was aber nicht unbedingt stört (aber der Wert der im FHEM-EventMonitor angezeigt wird, passt dann leider nicht zusammen).
Mal schauen, ob das heute noch in Griff zu bekommen ist ...

Grüße,
Jürgen

juergs

Zitat------------------------------------------------------------
buffer.read: [1]    
0         10        20        30        40        50        60
0123456789012345678901234567890123456789012345678901234567890123
1000001001100010000110100110000010111101000000000000000000000000
ld:   0
id:   189
id_c:   61
bat:   0
ch:   0
tempF:    0x6A1
tempC:    26.50
hum:   98
crc:   130
crc_2:   0
raw:   805166183438352384
------------------------------------------------------------
FUNC    ID: 61 [61]   T: 26.50   H: 98.00
TX    ID: 61   T: 26.50   H: 98.00
------------------------------------------------------------

Ein Versuch die CRC-Routine mit dem Raw-Wert aufzurufen,liefrt immer 0. (CRC Bits sind aber noch dabei und noch nicht ausmaskiert) .
uint_64t musste ich in "unsigned long long" setzen, da der Atmel-Compiler einen 32Bit-Datentyp daraus macht.

//-------------------------------------------------------------
//uint8_t CRC(uint64_t bits)
uint8_t CRC(unsigned long long bits)
{
    uint8_t crc; int i;
    for (i = 0; i < 64; i++) {
        crc <<= 1;
        if (bits & (1UL << 63)) crc |= 1;
        if (crc & 0x10) crc ^= 0x3;
        bits <<= 1;
    }
    return (crc & 0xf);
}

FHEm2005

Zu meinem größten Bedauern funktioniert es nicht so, wie ich es mir vorstelle. Es kommen zwar keine Fehlermeldungen, aber der 7415 wird immer noch als 'Unknown' erkannt. Ein Status wird auch angezeigt, und zwar das richtige 12 Byte lange Datentelegramm, welches ja als UserReading gut verarbeitet werden kann. Mal sehen ob Björn ein Erbarmen mit uns hat und die 14_CUL_TCM97001.pm ergänzt. ....

@Jürgen
obwohl wir hier nicht ein Arduino-Forum sind ;)....

1. Ich finde die Berechnung der Hum in der .ino-Datei  nicht
2. Gibt es beim 7415 keinen Kanal 0 (die Bitfolge 00 ist bereits Kanal 1)
3. Ich habe die Hum mal nachgerechnet (ausgehend vom 2F41E9988340in Deinem Bild) komme ich auf "38"
4. Wenn ich 2F41E9988340 in binär umsetze bekomme ich 0010 1111 0100 0001 1110 1001 1001 1000 1000 0011 0100 0000. Das weicht stark von der auf Deinem Zettel enthaltenen Bitfolge ab.

Bei der Größe ist es schwer sich in die Gedankengänge eines anderen Programmierers einzufräsen. Auf welchem Board soll es denn laufen?.


Gruß
Eberhard
Raspi3: FHEM, CULV3 (V1.61), EnOcean Pi 868, nanoCUL433, HUE-Bridge; Raspi4: Node-red, MQTT, Gaszähler auslesen mit ESP32-CAM

juergs

Zitat@Jürgen
obwohl wir hier nicht ein Arduino-Forum sind
Ja, werde meinen Teil in die Bastelecke verlegen ...  ;)
Wobei man die Telegrammerfassung auf für den "CUL-Hard- und Firmware"-Bereich nutzen kann. (aculfw?)  :D

Zitat1. Ich finde die Berechnung der Hum in der .ino-Datei  nicht
Durch den Aufbau der Struktur und der Union ist der Speicherbereiche der gleiche.
So dass man einen Wert an den 64bittigen Raw-Wert übergibt, dann enthalten die anderen Struct-Variablen automatich
die Bitweise Zuweisung. Sofern Endianness und Padding stimmen.

Zitat3. Ich habe die Hum mal nachgerechnet (ausgehend vom 2F41E9988340in Deinem Bild) komme ich auf "38"
Stimmt wird bei mir so angezeigt. Habe 2 aktive Sensoren.
Da habe ich noch ein System-/Denkfehler drin, den ich noch finden muss.

ZitatBei der Größe ist es schwer sich in die Gedankengänge eines anderen Programmierers einzufräsen. Auf welchem Board soll es denn laufen?.
Ja. Auf jedem Arduino. Zu berücksichtigen ist nur die INT-Nummer für D2, die bei den Modellen unterschiedlich sein kann.
Die Eigentliche Verarbeitung erfolgt im Interrupt, die Loop-Routine wertet dann nur fertig empfangene Telegramme aus.

Grüße,
Jürgen


FHEm2005

Hallo Jürgen,

offensichtlich stimmt das bitpos swapping nicht richtig. Wäre es nicht sinnvoller, das gesamte Telegramm in einem Schritt umzusetzen und dann nur noch auf die umgesetzten Daten zuzugreifen? 

Gruß Eberhard
Raspi3: FHEM, CULV3 (V1.61), EnOcean Pi 868, nanoCUL433, HUE-Bridge; Raspi4: Node-red, MQTT, Gaszähler auslesen mit ESP32-CAM

juergs

#include <stdio.h>
#include <stdint.h>

uint8_t CRC(unsigned long long bits);

int main()
{
   
/*                     #    F    F    0    0    F    9    5    5    F   
# 1111 1111 0000 0000 1111 1001 0101 0101 1111
#    A    B    C    D    E    F    G    H    I
# A+B = Zufällige Code wechelt beim Batteriewechsel
# C Bit 4 Battery, 3 Manual, 2+1 Channel
# D+E+F Temperatur, wenn es negativ wird muss man negieren und dann 1 addieren, wie im ersten Post beschrieben.
# G+H Hum - bit 0-7
# I CRC?   
*/
   unsigned long long value = 0xFF00F955F ; //0x19C6CDA08040;
   printf("CRC:\t%d\n" , CRC(value) );
   
   return 0;
}

//-------------------------------------------------------------
//uint8_t CRC(uint64_t bits)
uint8_t CRC(unsigned long long bits)
{
    uint8_t crc; int i;
    for (i = 0; i < 64; i++) {
        crc <<= 1;
        if (bits & (1UL << 63)) crc |= 1;
        if (crc & 0x10) crc ^= 0x3;
        bits <<= 1;
    }
    return (crc & 0xf);
}


Mit dem Ergebnis:
ZitatCRC:    15

Also muss mit allen Bits (inkl. CRC?) berechnet werden..

Deswegen bin ich noch mal auf das übertragene Protokoll zurückgegangen
und glaube die Problematik zumindest mal darstellen zu können ...

Die 42 Bits des Protokolls ergeben  nur 10,5 Nibble (4er Bitfolgen), es müssen also noch 0-Bits  bis auf die 64Bit (QWord) aufgefüllt werden.

Gebe ich obiges mit zwei Nullen komplettiertes Beispiel hier, im Simulator ein (mit compile+execute):
#include <stdio.h>
#include <stdint.h>

uint8_t CRC(unsigned long long bits);

int main()
{
   
   unsigned long long value = 0x2F4119A4C3C;
   printf("CRC:\t%d\n" , CRC(value) );
   
   return 0;
}

//-------------------------------------------------------------
uint8_t CRC(unsigned long long bits)
{
    uint8_t crc; int i;
    for (i = 0; i < 64; i++) {
        crc <<= 1;
        if (bits & (1UL << 63)) crc |= 1;
        if (crc & 0x10) crc ^= 0x3;
        bits <<= 1;
    }
    return (crc & 0xf);
}


Kommt 15 als CRC heraus. Passt also jetzt (..auch mit anderen Werten).

Muss jetzt also nur noch die Zuordnung + Reihenfolge der empfangenen Bits prüfen.
Die ersten Bits beginnend mit der Id usw. sind entgegen meiner Annahme die höherwertigsten
in der uint64-Zuweisung aus der ich dann die Einzelinfos herausziehen.
Hier muss ich morgen die Zuordnung innerhalb der uint64_t-Variablen noch richtig setzen, dann sollte es passen.

Was ich nicht verstehe, warum FHEM 12 Nibbles liefert:
Zitat2017-07-25 20:20:03 CUL_TCM97001 Unknown Code: 2F4295ACC1C0

FHEm2005

Hallo Jürgen,

ZitatWas ich nicht verstehe, warum FHEM 12 Nibbles liefert:
..weil das richtig ist! :)

Vor dem eigentlichen Datenblock liegen noch zwei Bits ( 0 und 1) deren Wert immer Null ist.  Danach folgen von Bit 2 bis 33 die eigentlichen Daten. Zwischen den Daten der Hum (26 bis 33) und den 4 Bits der Prüfsumme (38 bis 41) liegen 4 Bits (34 bis 37), deren Bedeutung unklar ist. Am Schluss folgen sechs Bits (42 bis 47) die fast immer Null sind und nicht in die Berechnung einbezogen werden. Das macht zusammen 48 bits = 12 Nibbles.

Deine Betrachtung, dass die Prüfziffer in Bit 34-41  liegt, stimmt nur deshalb, weil die Bits 34-37 Null sind. Der CRC Wert über 33-41 ist also identisch mit dem WErt wenn er über Bit 38 bis 40 gebildet wird. Sie müssen aber nicht immer Null sein, dann passt DEINE Prüfziffernberechnung nicht mehr.

rmax berechnet die Prüfsumme über die Bits 0 bis 37; sie schließt die eigenen Bits (38 bis 41)  nicht mit ein. Macht auch keinen Sinn.

... aus dem o.a. Grund liefert FHEM 12 Nibbles.

Gruß Eberhard
Raspi3: FHEM, CULV3 (V1.61), EnOcean Pi 868, nanoCUL433, HUE-Bridge; Raspi4: Node-red, MQTT, Gaszähler auslesen mit ESP32-CAM

juergs

Hallo Eberhard,
Zitatrmax berechnet die Prüfsumme über die Bits 0 bis 37; sie schließt die eigenen Bits (38 bis 41)  nicht mit ein...
Danke, das werde ich so implementieren.
Jürgen

erotikbaer

Hi,
Gibts denn schon etwas Neues zu dem Thema NC7427?

Gruß Christian

FHEm2005

... ich schließe mich den Ausführungen meines Vorredners an. ;D ;D

Dürfen wir uns was wünschen, obwohl Weihnachten vorbei ist? Ich meine wir haben gute Vorarbeit geleistet und wollen nun die Früchte unserer Mühen auch ernten (Teufel, hört sich das gut an!!!) 8) 8) 8)

Viele Grüße
Eberhard
Raspi3: FHEM, CULV3 (V1.61), EnOcean Pi 868, nanoCUL433, HUE-Bridge; Raspi4: Node-red, MQTT, Gaszähler auslesen mit ESP32-CAM

juergs

Hallöchen,

war mit dem BME680 - den "four in one" - Sensor doch zu stark beschäftigt, um hier weiterzumachen.
Aber, wenn wirklich Interesse besteht können wir das noch in die Todo-Queue setzen. ;) ;)

Der Sensor sendet alle 10 Sekunden ca. ca Repetitions, verseucht also die 433 MHz-Welt ganz gehörig ....
und der BME680 hat Temp/Hum/Press und Luftgüte ....

Leider hab ich auch noch zwei von den NCS hier rumliegen ....

Grüße,
Jürgen

erotikbaer

Ich muss gestehen... der BME680 ist mir persönlich zu teuer... mit 3D-Druckgehäuse etc. ist man ganz schnell bei 40-50€ und das dann pro Raum...

juergs

Mehr als 3 NCS würde ich auch nicht empfehlen.
Nur, wenn sonst keine anderen Sensoren im Umfeld sind...  ;)

FHEm2005


Hallo Jürgen,
ZitatLeider hab ich auch noch zwei von den NCS hier rumliegen ....
Willkommen im Club. Ich habe hier genau 3 mit Übergangslösung in Betrieb.

ZitatAber, wenn wirklich Interesse besteht können wir das noch in die Todo-Queue setzen.
Wenn wir kein Interesse hätten, gäbe es diesen Thread nicht. ;) ;)

ZitatMehr als 3 NCS würde ich auch nicht empfehlen.
Da bin ich absolut bei Dir, und dann aufpassen, dass jeder in einem eigenen Kanal läuft. Wenn ich mich an das letzte Öffnen erinnere, hat der drei einstellbare Kanäle.

Freue mich schon auf die Integration in CUL_TCM97001. Das erspart mir 100 Zeilen in der fhem.cfg ;D ;D
Gruß Eberhard
Raspi3: FHEM, CULV3 (V1.61), EnOcean Pi 868, nanoCUL433, HUE-Bridge; Raspi4: Node-red, MQTT, Gaszähler auslesen mit ESP32-CAM

FHEm2005

Darf ich mich als Interessent an der Lösung zu diesem Thema noch einmal in Erinnerung bringen?

Helau, Alaaf und was man/frau sonst noch zu den tollen Tagen ruft.
Eberhard
Raspi3: FHEM, CULV3 (V1.61), EnOcean Pi 868, nanoCUL433, HUE-Bridge; Raspi4: Node-red, MQTT, Gaszähler auslesen mit ESP32-CAM