Tchibo Wetterstation 433 MHz - Dekodierung mal ganz einfach

titus75:
Dieser Sketch hat mir echt geholfen. Danke!!!

:open_mouth: Oh, endlich mal ein Feedback zum Sketch aus Reply #19 - Danke für die Rückmeldung!
(Dann weiß ich, dass es wenigstens einer sinnvoll verwenden konnte. )

Hallo ich habe hier einen KW 9010 TH
http://www.ebay.de/itm/261136672627?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649
Ich empfange folgend Werte bei 22,7 C 58%

Start!

Start Bit L: 8850   H: 552
Data Bits: 36
L: 3988 1896 1900 3984 1928 4004 4012 1924 1924 1916 4016 4016 4008 4004 1936 1940 1944 4028 4012 4008 1944 1948 1956 1960 1956 4016 4016 1960 4040 1960 4020 4016 4032 4036 4032 4136 
H: 524 544 544 536 516 512 504 512 520 524 508 500 500 516 508 500 500 492 492 512 504 492 492 484 484 484 504 496 476 480 480 500 500 480 480 492 
100101100011110001110000011010111111

Start Bit L: 8900   H: 504
Data Bits: 36
L: 4028 1964 1944 4028 1960 4040 4036 1952 1944 1956 4032 4036 4036 4012 1932 1948 1960 4032 4020 4016 1940 1960 1960 1960 1964 4024 4016 1952 4036 1960 4028 4012 4032 4032 4028 4144 
H: 488 480 484 500 484 476 476 484 496 492 484 480 480 488 512 504 484 484 484 504 500 492 480 484 476 480 500 500 484 480 480 496 500 480 488 484 
100101100011110001110000011010111111

Start Bit L: 8900   H: 504
Data Bits: 36
L: 4032 1964 1952 4028 1952 4036 4036 1960 1956 1956 4032 4036 4036 4012 1932 1952 1956 4032 4028 4012 1936 1956 1960 1956 1960 4032 4020 1952 4036 1964 4040 4020 4028 4028 4032 4140 
H: 484 476 484 496 484 484 480 480 484 488 484 480 476 492 508 504 484 488 484 492 508 500 480 484 480 484 488 500 480 480 476 480 500 488 484 484 
100101100011110001110000011010111111

Start Bit L: 8900   H: 508
Data Bits: 36
L: 4028 1964 1960 4028 1956 4040 4036 1960 1956 1956 4036 4036 4032 4016 1932 1936 1952 4036 4032 4016 1932 1948 1960 1960 1960 4036 4016 1944 4040 1960 4036 4020 4020 4036 4036 4148 
H: 488 480 480 484 492 476 480 480 480 488 484 480 480 488 508 508 500 484 480 488 508 504 488 480 480 480 488 500 488 480 480 480 504 488 480 480 
100101100011110001110000011010111111

Start Bit L: 8900   H: 500
Data Bits: 36
L: 4028 1960 1964 4028 1952 4032 4036 1960 1960 1964 4032 4036 4040 4020 1932 1936 1952 4032 4032 4016 1936 1948 1956 1960 1960 4036 4016 1940 4028 1960 4032 4028 4016 4032 4036 4148 
H: 492 480 480 484 492 484 480 480 484 484 480 476 480 480 504 508 504 484 484 484 504 504 492 484 480 480 484 504 500 484 480 484 496 496 480 484 
100101100011110001110000011010111111

Start Bit L: 8900   H: 492
Data Bits: 36
L: 4032 1960 1964 4024 1948 4032 4036 1964 1964 1956 4032 4036 4036 4020 1936 1932 1940 4028 4032 4016 1932 1936 1956 1960 1960 4036 4024 1932 4032 1956 4032 4028 4020 4028 4032 4156 
H: 488 480 480 484 496 488 480 480 476 480 488 480 480 484 500 508 508 496 488 484 508 508 500 480 484 480 480 504 500 484 484 480 496 496 484 484 
100101100011110001110000011010111111

Start Bit L: 8900   H: 484
Data Bits: 29
L: 4036 1964 1960 4028 1936 4032 4040 1960 1968 1964 4032 4032 4032 4032 1944 1936 1932 4028 4028 4032 1940 1932 1948 1956 1964 4040 4028 1940 4024 
H: 488 476 480 480 500 500 476 480 476 476 480 484 484 484 488 500 512 500 488 484 488 508 504 488 484 476 476 496 504 
10010110001111000111000001101

Aber ich erkenne da jetzt keinen Zusammenhang mit der Temperatur und der Luftfeuchte. Stehe da irgendwie auf dem schlauch, habt ihr eine Idee?

Vielen Dank

tror:
Aber ich erkenne da jetzt keinen Zusammenhang mit der Temperatur und der Luftfeuchte. Stehe da irgendwie auf dem schlauch, habt ihr eine Idee?

Also die Temperatur sehe ich eindeutig da stehen, die ist ganz simpel binär codiert.
Hinweis: Invertiere mal die Bitfolge, bevor Du die Temperatur suchst!

Die Luftfeuchte ist vermutlich etwas anders (komplizierter) codiert, aber eine Idee habe ich auch dafür.

Findest Du die Temperatur, wenn Du die Bitfolge zuerst invertierst, oder brauchst Du weitere Hilfestellung?

tror:
Also die Temperatur sehe ich eindeutig da stehen, die ist ganz simpel binär codiert.
Hinweis: Invertiere mal die Bitfolge, bevor Du die Temperatur suchst!

Die Luftfeuchte ist vermutlich etwas anders (komplizierter) codiert, aber eine Idee habe ich auch dafür.

Findest Du die Temperatur, wenn Du die Bitfolge zuerst invertierst, oder brauchst Du weitere Hilfestellung?

Erstmal Danke, weiß aber nicht genau wie ich die Bit`s so aufteilen soll, in vierer schritten oder ist die Temperatur breiter als 4 bititge Einzel-Ziffern und muss dann umgerechnet werden?

Danke

Edit---

Ah ok nen bissel weiter bin ich gerade gekommen
Der Invertierte mittlere 12 Bit String wäre 227 in Dez probiere jetzt mal weiter rum, aber für einen Tipp bei der Feuchte wäre ich auch dankbar.

Super Arbeit hier im Forum

tror:
Erstmal Danke, weiß aber nicht genau wie ich die Bit`s so aufteilen soll, in vierer schritten oder ist die Temperatur breiter als 4 bititge Einzel-Ziffern und muss dann umgerechnet werden?

Ja, so ist das, wenn Du nur Bits bekommst und keine technische Dokumentation des Bit-Stroms. Das mußt Du Dir bei unbekannten Sensoren alles selbst herausfinden und austüfteln. Wenn Du es kannst.

Da mußt Du möglichst die Fähigkeiten eines Kryptografie-Experten haben, und eine gehörige Portion Phantasie, um es herauszufinden, welches Bit was bedeutet.

tror:
Ah ok nen bissel weiter bin ich gerade gekommen
Der Invertierte mittlere 12 Bit String wäre 227 in Dez

Korrekt, da in der Mitte steckt die 227, wenn man die Bitfolge invertiert:

100101100011110001110000011010111111 Bitfolge
011010011100001110001111100101000000 invertierte Bitfolge
          xxxx11100011 = 227         Temperatur in Zehntelgrad binär codiert

Allerdings steckt die 227 auch drin, wenn man die Bitfolge nur rückwärts aufschreibt:

100101100011110001110000011010111111 Bitfolge
111111010110000011100011110001101001 Bitfolge rückwärts
            xxxx11100011 = 227       Temperatur in Zehntelgrad binär codiert

Welche der beiden Möglichkeiten die richtige ist, um die Temperatur abzulesen, kann man anhand eines einzigen Datensatzes nicht sagen. Man braucht mehrere exakt erfasste Datensätze, die Bitfolge und die dazugehörigen decodierten Werte, um tatsächlich definitiv entschlüsseln zu können, welche Bits wie und als was decodiert werden können.

Die vier Stellen davor gehören dann jeweils bestimmt auch noch zur Temperatur, denn es müssen ja auch noch betragsmäßig deutlich höhere Temperaturen darstellbar sein.

Interessant dürfte noch sein, wie es mit dem Vorzeichen gehandhabt wird, d.h. Du müßtest auch mal einen Wert unterhalb 0°C auswerten, wie das Bitmuster dann aussieht.

probiere jetzt mal weiter rum, aber für einen Tipp bei der Feuchte wäre ich auch dankbar. 
Super Arbeit hier im Forum

Bei der Luftfeuchte geht meine Vermutung dahin, dass sich dessen Codierung unmittelbar rechts/links an den Code der Temperatur anschließt. Um die Codierung zu verifizieren wäre es allerdings erforderlich, nochmal (mindestens) zwei oder drei Bitfolgen bei anderen bekannten Temperatur- und Luftfeuchtewerten zu haben, also ein wenig abweichend von 22,7C/58% rF.

jurs:
Feedback erwünscht!

1000 Dank für das tolle Werkzeug. Ich habe vorher studenlang Datenmüll produziert um die richtigen Parameter für den PEARL Aussensensor Nr. NC-7159-912 PEARL Funk-Außensensor für Wetterstation FWS-90 zu finden.
Mit dem Tool war es eine Sache von wenigen Minuten !!

Ich baue hier auf der Arbeit von tror und jurs auf und habe dann gleich noch Fragen...
Zuerst aber mal ganz herzlichen Dank an jurs für den Arduino-Sketch!

Hier ein paar mehr Messwerte aus dem o.g. Conrad KW9010:

Kanal 2:
100010100011101111110000111000111000 25,3 43
100010100011001111110000111000110000 25,2 43
100010100011110111110000000100110000 25,1 44
100010100011100111110000100100111111 25,0 44
100010100011001111110000111000110000 24,9 43
100010100011100111110000011000110011 24,9 42
100010100011000111110000011000111101 24,8 42
100010100011000111110000011000111101 24,8 42
100010100011111011110000101000111001 24,7 41
100010100011011011110000101000110001 24,6 41
100010100011101011110000101000111110 24,5 41
100010100011001011110000101000110110 24,4 41
100010100011110011110000101000111010 24,3 41
100010100011010011110000101000110010 24,2 41
100010100011010011110000001000111100 24,2 40
100010100011100011110000001000110100 24,1 40
100010100011100011110000001000110100 24,1 40
100010100010100011110000001000110101 24,1 40 nicht-manuell
100010100011100011110000101000111100 24,1 41
100010100010100011110000101000111101 24,1 41 nicht-manuell
100010100010111101110000101000110001 23,9 41 nicht-manuell (?)
100010100011111101110000101000110000 23,9 41
100010100010111101110000001000111110 23,9 40 nicht-manuell
100010100010011101110000101000111110 23,8 41
100010100010011101110000101000111110 23,8 41 nicht-manuell
100010100011011101110000101000111111 23,8 41 

100001100101111101110000011000110000 23,9 42 Kanal 1
100010100101111101110000011000111111 23,9 42 Kanal 2
100011100101111101110000011000111000 23,9 42 Kanal 3
100001100101000011110000101000111000 24,0 41 Kanal 1
100010100101000011110000101000110000 24,0 41 Kanal 2
100011100101000011110000101000110100 24,0 41 Kanal 3
100001100101111101110000101000111111 23,9 41 Kanal 1 (manuell)
100010100101111101110000101000110111 23,9 41 Kanal 2 (manuell)
100011100101111101110000101000110000 23,9 41 Kanal 3 (manuell)

Und noch ein höherer Wert von Kanal 3:
100011100100011111101000000011011101 38,2 20%

manuell/nicht-manuell: ganz sicher bin ich mir nicht immer, aber es gibt offensichtlich einen Unterschied ob ich die Taste zum Senden hinten drücke oder ob er von selber intervallgesteuert sendet. Wenn dazu nix dahinter steht, habe ich keine Ahnung, ob ich den Messwert getriggert habe, oder nicht.

Was man erkennen kann: Es wird nicht invertiert, sondern die Rückwärts-Methode ist die richtige. Ich teile vorläufig so auf:

Struktur des Telegramms:
AAAABBCCCCDDEEEEEEEEEEEEFFFFFFFGHHHH

AAAA = ???; bei mir bislang immer 1000
BB = Kanal: 01 = 1, 10 = 2, 11 =3
CCCC = ???; bei mir bislang immer 1000
DD = ???; könnte natürlich auch mit CCCC zusammenhängen.
EEEEEEEEEEEE = von hinten zu lesen: Temperatur in Zehntelgrad binär (also z.B. 240 für 24°C); Von den Stellen her ginge das bis über 200°C, da die Anzeige aber nur zwei Stellen vor dem Komma hat, weiß ich nicht, ob da nicht noch Padding oder was weiß ich was am Ende kommt. Nachdem es bei mir immer Nullen waren, die vor dem FFFFFFF stehen, ist das auch egal.
FFFFFFF = enthält die Luftfeuchtigkeit; auch wieder von hinten zu lesen. Allerdings ist das bei mir bislang Luftfeuchtigkeit plus 28. Hier der Ausschnitt aus den Messdaten:
empfangen  dezimal  abgelesen
0001001    72       44
1110001    71       43
0110001    70       42
1010001    69       41
0010001    68       40
G = ???; bei mir bislang konstant 1; wenn es zu FFFFFFF gehört, dann sind die Werte nochmal 128 höher, d.h. bei 44% Luftfeuchtigkeit wäre der Wert in dezimal 200.
HHHH = ???; scheint mir eine Checksumme zu sein, da sie sich ziemlich krass ändert. Hier wird m.E. reincodiert, ob die Tx-Taste gedrückt wurde oder ob es intervallgesteuert gesendet wird. Bin mir aber nicht sicher, wie.

Also prinzipiell komme ich jetzt glaub' ich zurecht. Kann sich jemand auf die unklaren Stellen einen Reim machen? Oder weiß jemand, warum Luftfeuchtigkeit plus 28 verwendet wird?

Ansonsten viel Spaß mit dem Sensor! Meines Erachtens Preis/Leistungsmäßig momentan einer der interessantesten am Markt.

Viele Grüße
gurkensalat

Auch von mir ein Danke für den Sketch!
Habe eine Wetterstation von Hofer/Aldi und zwar die Krippl AB1-WS-9/W210-5.
Der Außensensor liefert die Daten ähnlich den der hier im Thread behandelten.
Hier eine tlw. Aufschlüsselung:

Empfangenes Telegramm bei 43.7° und 27% Luftfeuchte im Display:
111101010010101011011000111001000001
Dieses Muss umgedreht werden, was dann so aussieht:
100000100111000110110101010010101111
AABBCCCCCCCCDEEEEEEEEEEEFGGGGGHHIIII
AA Bei TX gedrückt 01, meistens 11, manchmal auch 10, keine Ahnung warum
  BB Dürfte mit dem Kanal zusammenhängen (01=Ch1,10=Ch2,00=Ch3)
    CCCCCCCC ist die Luftfeuchte in HEX. Der binäre Wert hier (00100111) muss nach Hex gewandelt werden (27) und ist dann gleich dem angezeigten Wert
            D Vorzeichen der Temperatur (0=Plus, 1=Minus), Wenn Minus, dann muss Temp (E) Invertiert werden!
             EEEEEEEEEEE ist Die Temperatur in 1/10 Grad (hier 437)
                        F TX gedrückt
                         GGGGG kein Ahnung
                              HH Kanal (10=Ch1,01=Ch2,11Ch3)
                                IIII keine Ahnung, evtl. Checksumme?[/font][/font]

Das Wichtigste (Temp/Luftfeuche) kann ich lesen, das andere Zeugs brauche ich eigentlich nicht.
Nun das Ganze noch coden und per Script afragen und in eine DB schreiben lassen.

gurkensalat:
Was man erkennen kann: Es wird nicht invertiert, sondern die Rückwärts-Methode ist die richtige. Ich teile vorläufig so auf:

Struktur des Telegramms:

AAAABBCCCCDDEEEEEEEEEEEEFFFFFFFGHHHH

AAAA = ???; bei mir bislang immer 1000
BB = Kanal: 01 = 1, 10 = 2, 11 =3
CCCC = ???; bei mir bislang immer 1000
DD = ???; könnte natürlich auch mit CCCC zusammenhängen.
EEEEEEEEEEEE = von hinten zu lesen: Temperatur in Zehntelgrad binär (also z.B. 240 für 24°C); Von den Stellen her ginge das bis über 200°C, da die Anzeige aber nur zwei Stellen vor dem Komma hat, weiß ich nicht, ob da nicht noch Padding oder was weiß ich was am Ende kommt. Nachdem es bei mir immer Nullen waren, die vor dem FFFFFFF stehen, ist das auch egal.
FFFFFFF = enthält die Luftfeuchtigkeit; auch wieder von hinten zu lesen. Allerdings ist das bei mir bislang Luftfeuchtigkeit plus 28.

Ich habe inzwischen auch so einen Sensor für die Conrad KW9010.

AAAA scheint eine Zufalls-Sender-ID zu sein, die sich jedesmal beim Batteriewechsel zufällig ändert, dann aber bis zum nächsten Batteriewechsel konstant bleibt.

Diese Zufalls-ID verhindert Probleme, wenn Dein Nachbar zufällig dieselbe Wetterstation hat, und er bei sich z.B. mit den Sensoren die Temperatur im Wohnzimmer (Kanal 1) und Schlafzimmer (Kanal 2) mißt, Du aber bei Dir lieber die Temperatur im Wohnzimmer (Kanal 1) und draußen (Kanal 2) messen möchtest.

Die Systeme arbeiten mit dieser Zufalls-Sender-ID wie folgt:

  • Beim Einsetzen der Batterien setzt der Sender eine zufällige Zufalls-ID und sendet z.B. 10 Minuten lang sehr oft
  • Die zum System gehörende Basisstation lauscht nach dem Einsetzen der Batterien auf jeweils das erste eintreffende Datenpaket mit jeder Kanalnummer. Danach werden nur noch Datenpakete ausgewertet, die sowohl in der Kanalnummer als auch der Zufalls-Sender-ID übereinstimmen.

gurkensalat:
Also prinzipiell komme ich jetzt glaub' ich zurecht. Kann sich jemand auf die unklaren Stellen einen Reim machen?

Von den unklaren Stellen könnten zwei Bits für folgende Funktionen dienen:

  1. Unterscheidung ob manuell (durch Drücken der Taste am Sender) oder automatisch gesendet wurde
  2. "Low Battery Bit", also ein Bit, das wechselt, wenn die Batteriespannung unter einen bestimmten Wert fällt

Dass die letzten 4 Bits irgendeine Prüfsumme oder CRC-Wert darstellen, glaube ich auch.
Ich habe aber noch nicht die Zeit gefunden, das näher zu testen.

gurkensalat:
Oder weiß jemand, warum Luftfeuchtigkeit plus 28 verwendet wird?

Das kann man nicht so genau wissen und wird irgendwie systembedingt sein.

Hallo jurs,

vielen Dank für die Rückmeldung! Ich habe inzwischen eine Implementierung des Protokolls der KW 9010 gefunden, wo anscheinend sogar die Checksummen geprüft werden (stand da irgendwo). Schau doch mal hier:
http://www.fhemwiki.de/wiki/FHEMduino

(Das besteht aus einem Arduino-Sketch und Perl-Modulen für fhem, die das weiterverarbeiten.)

Viele Grüße
gurkensalat

gurkensalat:
Schau doch mal hier:
FHEMduino – FHEMWiki

Oh ja, danke für den Link! Da ist ein Quellcode eines größeren Projekts abrufbar, in dem die einzelnen Bits eines KW9010 Sensors ausgewertet werden. Es ist zwar keine ausführliche Protokollbeschreibung abrufbar, aber im Quellcode steht eigentlich alles notwendige drin.

Wenn man mal davon absieht, dass dort die ersten 8 Bit des Telegramms als "Sender ID" angesehen werden und nicht unterschieden wird zwischen "Sender Zufalls ID" (ändert sich zufällig bei jedem Batteriewechsel) und "Sender Kanalnummer" (einstellbar am Sensor), sind dort alle Bits dekodiert. Wenn ich mal zusätzlich zwischen Zufalls-ID beim Batteriewechsel und Kanalnummer unterscheide, haben die Bits dann folgende Bedeutung:

Struktur des Telegramms aus 36 Bits:
IIIIKKIILTTMEEEEEEEEEEEEFFFFFFFFSSSS

I: Zufalls-Bits als Sender-ID (ändern sich beim Batteriewechsel, sonst konstant)
K: Kanalnummer (hinten am Sensor einstellbar)
L: Low-Battery Warnung (1 bei schwacher Batteriespannung)
TT: Temperaturtrend (gleichbleibend, steigend, fallend)
M: Manuelles "Forced send" (wenn mit der Sendetaste am Sensor gesendet wird)
E: 12-bit Temperatur in Zehntelgrad
F: 8-bit Luftfeuchte, (Luftfeuchte = Wert-156)
SSSS: Prüfsumme (32 Bits in acht 4-Bit Blöcke zerlegt, aufsummiert, davon die unteren 4 Bit)

Das gesendete Protokoll ist immer in °C, auch wenn am Sensor auf °F Anzeige umgeschaltet wurde.

Damit sollte einem Einsatz des Sensors zusammen mit eigenen Arduino-Projekten nichts im Wege stehen. Hier bei mir müßte ich nur nochmal mit Minustemperaturen testen, ob auch die Auswertung bei Minusgraden stimmt.

Falls jemand Probleme hat, das Protokoll oder den FHEMduino-Quellcode in eigenen Code umzusetzen, könnte ich mal einen Arduino-Minimalsketch erstellen und hier posten, der die Werte empfängt und auf Serial anzeigt. Nur falls jemand Bedarf hat.

Also ich würde Bedarf anmelden, ich schaue da überhaupt nicht durch. Vielleicht finden sich ja noch ein paar Leute damit sich der Aufwand auch lohnt. 8)

Gruß

Frank

Scherheinz:
Also ich würde Bedarf anmelden, ich schaue da überhaupt nicht durch. Vielleicht finden sich ja noch ein paar Leute damit sich der Aufwand auch lohnt. 8)

Ich poste mal, was ich habe.

// Arduino sketch to receive KW9010 temperature/humidity RF sensor telegrams
// Written by 'jurs' for German Arduino Forum

#define RX433DATA 2       // receive pin for hardware interrupts
#define RX433INTERRUPT 0  // interrupt number for receive pin

#define KW9010_SYNC 9000  // length in µs of starting pulse
#define KW9010_ONE 4000   // length in µs of ONE pulse
#define KW9010_ZERO 2000  // length in µs of ZERO pulse
#define KW9010_GLITCH 500 // pulse length variation for ONE and ZERO pulses
#define KW9010_MESSAGELEN 36  // number of bits in one message

void setup()
{
  Serial.begin(9600);
  pinMode(RX433DATA, INPUT);
  attachInterrupt(RX433INTERRUPT, rx433Handler, CHANGE);
  Serial.println();
  Serial.print(F("Free RAM: "));Serial.println(freeRam());
  Serial.println();
  Serial.println(F("Seconds\tCRC\tID\tChannel\tTemp C\tTrend\trH %\tLowBat\tForced send"));
 
}

void loop()
{
  if (fifoAvailable())
  {
    unsigned long dataReceived=fifoRead();
    Serial.print(millis()/1000);
    if (dataReceived!=0)
    {
      Serial.print(F("\tOK"));
      printResults(dataReceived);
    }  
    else  
      Serial.print(F("\tFAIL"));
    Serial.println();  
  }  
}


void printResults(unsigned long value)
{
  // Sensor ID 
  byte id = value & 0b11001111; // bit 0, 1, 2, 3, 6, 7, random change bits when battery is changed
  Serial.print('\t');Serial.print(id);
  // Channel (as set on sensor)
  byte channel = 2*bitRead(value,4)+bitRead(value,5); // bit 4, 5 are channel number
  Serial.print('\t');Serial.print(channel);
  // Temperature 
  int temperature = value>>12 & 0b111111111111;  // bit 12..23
  // if sign bit is set, adjust two's complement to fit a 16-bit number
  if (bitRead(temperature,11)) temperature= temperature | 0b1111000000000000;
  Serial.print('\t');Serial.print(temperature/10.0,1);
  // temperature tendency
  byte trend = value>>9 &0b11; // bit 9, 10
  Serial.print('\t');
  if (trend==0) Serial.print('=');       // temp tendency steady
  else if (trend==1) Serial.print('-');  // temp tendency falling
  else if (trend==2) Serial.print('+');  // temp tendency rising
  // Humidity
  byte humidity = (value>>24 & 0b11111111) - 156; // bit 24..31
  Serial.print('\t');Serial.print(humidity);
  // Battery State
  bool lowBat = value>>8 & 0b1;      // bit 8 is set if battery voltage is low
  Serial.print('\t');Serial.print(lowBat);
  // Trigger
  bool forcedSend = value>>11 &0b1;  // bit 11 is set if manual send button was pressed
  Serial.print('\t');Serial.print(forcedSend);
}

boolean crcValid(unsigned long value, byte checksum)
// check if received crc is correct for received value
{
  byte calculatedChecksum = 0;
  for (int i = 0 ; i < 8 ; i++) calculatedChecksum +=(byte)(value >> (i*4));
  calculatedChecksum &= 0xF;
  return calculatedChecksum == checksum;
}

void rx433Handler()
{
  static long rx433LineUp, rx433LineDown;
  static unsigned long rxBits=0;
  static byte crcBits=0;
  static byte bitsCounted=0;
  long LowVal, HighVal;
  byte rx433State = digitalRead(RX433DATA); // current pin state
  if (rx433State) // pin is now HIGH
  {
    rx433LineUp=micros(); // line went HIGH after being LOW at this time
    LowVal=rx433LineUp - rx433LineDown; // calculate the LOW pulse time
    if (LowVal>KW9010_SYNC-2*KW9010_GLITCH && LowVal<KW9010_SYNC+2*KW9010_GLITCH)
    {
      rxBits=0;
      crcBits=0;
      bitsCounted=0;
    }
    else if (LowVal>KW9010_ONE-KW9010_GLITCH && LowVal<KW9010_ONE+KW9010_GLITCH)
    { // set the one bits
      if (bitsCounted<32)
        bitSet(rxBits,bitsCounted);
      else  
        bitSet(crcBits,bitsCounted-32);
      bitsCounted++;
    }
    else if (LowVal>KW9010_ZERO-KW9010_GLITCH && LowVal<KW9010_ZERO+KW9010_GLITCH)
    { // setting zero bits is not necessary, but count them
      bitsCounted++;
    }
    else // received bit is not a SYNC, ONE or ZERO bit, so restart
    {
      rxBits=0;
      crcBits=0;
      bitsCounted=0; 
    }
    if (bitsCounted>=KW9010_MESSAGELEN) // all bits received
    {
      if (crcValid(rxBits,crcBits)) fifoWrite(rxBits); // write valid value to FIFO buffer
      else fifoWrite(0);  // write 0 to FIFO buffer (0 = invalid value received)
      rxBits=0;
      crcBits=0;
      bitsCounted=0;
    }
  }
  else 
  { // High values have no information with them
    rx433LineDown=micros(); // line went LOW after being HIGH
    HighVal=rx433LineDown - rx433LineUp; // calculate the HIGH pulse time
  }
}


#define FIFOSIZE 8  // Fifo Buffer size 8 can hold up to 7 items
volatile long fifoBuf[FIFOSIZE]; // ring buffer
volatile byte fifoReadIndex,fifoWriteIndex;  // read and write index into ring buffer

void fifoWrite(long item)
// write item into ring buffer
{
  fifoBuf[fifoWriteIndex]=item; // store the item
  if (!(fifoWriteIndex+1==fifoReadIndex || (fifoWriteIndex+1>=FIFOSIZE && fifoReadIndex==0)))
    fifoWriteIndex++;  // advance write pointer in ringbuffer
  if (fifoWriteIndex>=FIFOSIZE) fifoWriteIndex=0; // ring buffer is at its end
} 


unsigned long fifoRead()
// always check first if item is available with fifoAvailable()
// before reading the ring buffer using this function
{ 
  unsigned long item;
  item=fifoBuf[fifoReadIndex];
  cli(); // Interrupts off while changing the read pointer for the ringbuffer
  fifoReadIndex++;
  if (fifoReadIndex>=FIFOSIZE) fifoReadIndex=0;
  sei(); // Interrupts on again
  return(item);
}  

boolean fifoAvailable()
// item is available for reading if (fifoReadIndex!=fifoWriteIndex)
{
  return (fifoReadIndex!=fifoWriteIndex);
} 

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Zum Testen mit Minustemperaturen mußte ich den Sensor in der Tiefkühltruhe kühlen, draussen im Freien sind wir heute mal wieder zweistellig im Plusbereich.

Der Sensor sendet offenbar mit 32 Sekunden Abstand immer sechs Datentelegramme a 36 Bit raus, bestehend aus 32 Bits Daten und vier Bits Prüfsumme. Die 32 Datenbits speichere ich in "unsigned long" Variablen. Die Prüfsumme wird noch innerhalb der Interrupt-Routine überprüft. Falls die Prüfsumme korrekt ist, werden die Daten in einen FIFO-Puffer geschoben, bei falscher Prüfsumme anstelle der Daten eine 0.

So dass man innerhalb der loop nur "unsigned long" Variablen aus dem FIFO-Puffer ziehen und auf 0 prüfen muss: Ist der Wert ungleich Null, wurde ein Wert mit korrekter Prüfsumme empfangen. Eine absolute Garantie für korrekte Daten ist das natürlich nicht, da eine 4-Bit Prüfsumme natürlich kein 100% Test ist. Zur Verbesserung der Datensicherheit müßte man wahrscheinlich testen, ob zwei aufeinanderfolgende Datentelegramme mit korrekter Prüfsumme denselben Wert haben.

Die Datentelegramme werden pro Aussendung immer sechsmal identisch gesendet.

Die Sender-ID in den ersten 8 Bits des Datentelegramms habe ich aufgeteilt in

  • eine Zufalls-Sender-ID, die sich beim Batteriewechsel ändert
  • eine Kanalnummer, die hinten am Sensor per Schiebeschalter im Batteriefach einstellbar ist

Leider scheint die mit diesem Sensor erzielbare Reichweite recht gering zu sein. Extrem gering sogar.
Aber das müßte ich mit verschiedenen Antennen nochmal genau austesten.

Wow, verstehe deine Erklärung abre den Code nicht ganz. Aber mein KW9010 müsste in 2-3 Tagen da sein, dann wird sofort getestet! 8) 8)

Vielen Dank!!!!

Gruß
Frank

Hallo

ich habe mir auch die KW9010 gehöhlt um damit ein raspberry pi Projekt zu bauen. Schonmal vielen dank an alle die hier code und Anregungen zusammen getragen haben. Vieles davon hat mir bereits geholfen bzw einiges habe ich parallel selbst erarbeitet.
Meine Frage zielt nun eher auf eure Hardware Setups ab.
Welche 433 MHz Empfänger nutz ihr?
Ich habe einen billigen von ebay probiert, der war nur auf 3,3v nutzbar, da er bei 5v schon zu viel rauscht.
dann habe ich einen Empfänger aus einem Conrad 433mhz sender / Empfänger set probiert. Hier ist weniger rauschen auf 5V
allerdings bleibt die Reichweite geringe, aber immerhin bin ich von 5cm jetzt schon auf 30cm gekommen. Aber für ein Wohnung reicht das noch lange nicht.
Könnt ihr Empfänger empfehlen? Was nutz ihr? oder liegt es wirklich am Conrad Sender? Ich kann mir nicht vorstelle, das dieser wirklich so schlecht senden

Cheers
BastardOp

bastardop:
immerhin bin ich von 5cm jetzt schon auf 30cm gekommen.

30 cm? Doch so viel?

Hört sich an, als wenn Du versuchst, ganz ohne Antenne Empfang zu bekommen.
So schlecht, dass die Reichweite nur 30 cm ist, kann eigentlich überhaupt keine Antenne sein.
Ohne Antenne geht nix.

Die billigste Antenne ist ein nicht zu dünner Draht, abgeschnitten auf 17,5 cm Länge und am "Ant" Lötauge des Empfängers angelötet.

Und wenn Du eine Antenne dran hast: Die ganz billigen "Super-Regenerativempfänger" brauchen einen Mindestabstand von ca. 50cm zum Sender. Sonst werden diese Empfänger selbst zu Sendern und empfangen nichts. Teste mal mit Antenne und mindestens einem halben Meter Abstand!

Antenne hab ich schon dranne, aber das mit dem halben Meter wusste ich nicht.
Am billigen hat mir halt eher das massive rauschen so sehr dazwischen "gefunkt" dass ich den eigentlichen sender nicht mehr erkennen konnte. Den Conrad sender habe ich heute erst von nem bekannten bekommen mit einer falsch bemessenen Antenne, das wird nochmal korrigiert und ausprobiert.

Hallo,
ich habe einige dieser http://www.ebay.de/itm/Conrad-Thermo-Hygro-Funksensor-KW-9010-TH-433MHz-/261367592277 Sensoren gekauft, um damit eine Messwerterfassung mit Arduino und Raspberry aufzubauen.
Leider hat dieses Modell (alle 5 Geräte) eine extrem schlechte Reichweite. Bei Sichtverbindung komme ich gerade mal 5-7 Meter weit. Durch eine Mauer oder Scheibe geht gar nichts mehr. Am Empfänger kanns nicht liegen, der empfängt meinen Tchibo Außensensor noch durch 2 Wände. Von diesem Sensor kann ich nur abraten.
Ich habe das eingebaute Sendemodul mal gegen ein anderes ausgetauscht, damit war die Reichweite immerhin schonmal etwas besser.
Jemand hier unterwegs, der bessere Erfahrungen gemacht hat?
Gruß
Reinhard

Nochmal Danke an Jurs, das Program funktioniert tadelos!!!
Was die Sendeleistung angeht geb ich den anderen Recht, aber ich denke das kann man optimieren. Die originale Antenne ist wirlich nicht der Brüller obwohl im Gehäuse noch genug Platz wäre für was Größeres bzw Genaueres. Oder man tauscht das ganze Sendemodul aus, dürfe auch kein größeres Problem sein.
Siehe Anhang!

Gruß

Hallo,

Die originale Antenne ist wirlich nicht der Brüller obwohl im Gehäuse noch genug Platz wäre für was Größeres bzw Genaueres. Oder man tauscht das ganze Sendemodul aus, dürfe auch kein größeres Problem sein.

Hab ich schon ausprobiert. Eine andere Antenne (lambda/4 Draht) brachte gar nichts. Ein anderes Sendemodul (Billig China Ware) brachte nur wenig. Vielleicht liegt das dann auch an den 3V, mit denen der Sender betrieben wird.
Ich habe jetzt einen RFM12B als OOK Empfänger im Einsatz. Damit ist die Reichweite ganz gut, zumindest komme ich schon mal quer durch die Wohnung. Das ganze ist aber ziemlich empfindlich auf Störungen (Netzteil, USB Leitung, ...). Wenn ich den seriellen Ausgang mit dem Raspberry verbinde geht es gar nicht mehr.
Vielleicht sollten wir mal einen neuen Threat aufmachen für den KW9010 Sensor?
Gruß
Reinhard