Hallo,
ich habe mir von Pollin eine billige »Wetterstation« für 5,95€ geholt,
die die Raumtemperatur anzeigt und über eine Funk-Außeneinheit die
Außentemperatur.
Mein Ziel ist es, die Empfängerplatine (auf der ein Himark RX3310A
sitzt) an einem AVR zu benutzen. Hierüber empfange ich leider auch
allerlei Störungen, weshalb ich mich erst mal an die Außeneinheit
gemacht habe. Dort hab ich die Daten, die sie sendet, direkt
abgegriffen.
Diese Daten habe ich nun einem ATMega32 geloggt und über die serielle
Schnittstelle zum PC geschickt. Jetzt steht allerdings die Analyse der
Daten an, damit ich hinter das Protokoll komme.
Dazu habe ich mir ein Perlscript geschrieben, das die Daten lesbarer
macht. Vielleicht könnte sich die jemand angucken (im Anhang) und
erkennt dabei etwas. Mag ja sein, dass es mit etwas Glück irgendein
Standardprotokoll mit einer bestimmten Fehlererkennung ist.
Zum Anhang: Die Temperatur betrug 17,5 °C.
Gruß,
Wolfgang
Es wäre wirklich hilfreicher, man hätte ein paar unterschiedliche
Temperaturen im Logfile. Kannst Du das nicht noch mal an Deinen Logger
anschließen und warten, bis es sich eingependelt hat. Dann loggen und
die Schreibtischlampe über dem Teil einschalten. Wenn es eine der
üblichen Halogenlampen ist, sollte die Temperatur dann ansteigen.
Neben jeden Binär-String bitte die Temperatur schreiben.
Die Werte 1 (0001) und 7 (0111) tauchen in dem Texfile recht häufig auf.
Es gibt auch einen Block aus vielen 1ern, der als Sync dienen könnte.
Bit Bit 120 stimmen diese Blöcke überein, dann gibt es Unterschiede.
Es gibt da leider keinen Standard, der eine Temperatur-Kodierung
beschreibt. Es könnte sein, dass es Nibbels sind, die mehrfach
übertragen werden. Es kann sein, dass man von einem Bestimmten Null-Punt
ausgeht und dazu eine binäre Differenz überträgt.
Also: 0x17 0x01 für 17.5° ist ebenso möglich, wie 0x73 für folgende
Rechnung:
0-Punkt ist -40°C, 7-Bit für 128° ab -40 aufwärz, 1 Bit für 0.5°C
Es hilft auch zu wissen, welche Auflösung das Gerät hat, dann weiß man,
ob die 1/10°C dezimal oder nur als Bit übertragen werden müssen. Leider
finde ich auch keine Wetterstation für 5,95€, ist also etwas mühsam.
Gruß, Ulrich
Wolfgang,
wenn du dir die 3 Syncblöcke anschaust, wirst du bemerken, dass die drei
Blöcke fast identische Daten enthalten. Deswegen nehme ich an, dass das
Telegramm dreimal gesendet wird.
Wie mein Vorschreiber schon sagte, ist es hilfreich, mehrere
verschiedene Telegramme zu loggen, um Gemeinsamkeiten und /unterschiede
herauszuarbeiten. Welcher Typ von WS ist es denn?
Servus,
Helmut.
Pollin bietet den Artikel leider nicht mehr an, habe ich gerade
festgestellt. Die Bestellnummer war 830 212. Im beigelegten Zettel steht
nur:
- Temperaturanzeigebereich: -50 °C bis 70 °C
- Empfohlener Temp.bereich, Sensor (außen): -20 °C bis 60 °C
- Anzeigegenauigkeit: 0,1 °C
Ich habe eine Reihe weiterer Messergebnisse angehängt. (Die Datei hat
Unix-Zeilenumbrüche.)
Bitte beachtet den Anhang aus meinem ersten Post nicht mehr: Dort
fehlten die letzten Bits (Fehler im Programmcode).
Edit:
Wie man die Temperatur daraus liest, weiß ich jetzt. :)
0111 ist eine Null, 0001 eine Eins. Das niedrigstwertige Bit ist rechts.
Der erste Abschnitt von | nach | sind die Zehner der Temperatur, der
zweite Abschnitt die Einer und der dritte die eine Nachkommastelle.
Mal ein paar andere Temperaturen messen, um noch auf negative
Temperaturen zu kommen. Momentan genau das richtige Wetter dafür.
Das Bearbeiten hat meinen Anhang gekillt. Hier ist er nochmal:
http://de.pastebin.ca/820396
Die Zehner, Einer und die Nachkommastelle sind wie bei den positiven
Temperaturen kodiert. Hier im Beispiel ergibt sich 95,5. Von diesem Wert
subtrahiert man 100 und erhält die richtige Temperatur: -4,5 °C
Die Datenübertragung erfolgt übrigens immer in Celsius. Auch wenn
Fahrenheit für die Anzeige gewählt ist.
Hallo Wolfgang
Ich habe das auch mal mit der WS-308G von Pollin versucht, aber
irgendwie kam da nur Müll raus. Wie genau hast du denn die Rohdaten des
Senders verarbeitet um an die Bitwertigkeiten zu kommen? Oder hast du
den Ausgangspegel einfach nur mit einer festen Frequenz abgetastet?
Gruß, Volker
Die 9 0 sollte die Adresse der Außenstation sein, damit sie von anderen
unterschieden werden kann.
Das letzte Nibble ist das low Nibble der Prüfsumme aller zuvor
gesendeten Nibbles:
9+0+1+7+5+0 = 0x16 -> low nibble = 0x6
Jedes Datagramm wird 3 mal gesendet, dabei wird das vorletzte Nibble in
der Reihenfolge 0 -> 2 -> 1 verändert und die Prüfsumme angepasst.
Gruß, Ulrich
Wie sieht es denn mit einer Prüfsumme aus? Ich meine, wie wird die
berechnet? Ich hatte mich damals auch mal an ein Lidl-Thermometer
gewagt, Auslesen ging gut, wenn man auf die Prüfsummensicherung
verzichtet. (also nicht ganz optimal, Daten selber senden konnte ich
somit definitiv nicht)
Gruß, Martin
Hmm... Ich vermute mal, dass Du vergessen hast die Seite neu zu laden,
denn sonst wäre Dir aufgefallen, dass Deine Frage direkt im Post über
Deinem von mir beantwortet wird...
Gruß, Ulrich
>dabei wird das vorletzte Nibble in>der Reihenfolge 0 -> 2 -> 1 verändert und die Prüfsumme angepasst.
Hm, vielleicht stehe ich jetzt auf dem Schlauch: wie wird die
Prüfsumme jetzt angepasst?
Es wird die Temperatur immer drei mal übertragen.
Im ersten Paket ist das vorletzte Nibble 0, im zweiten 2 und im dritten
1.
Die Prüfsumme ist die Summe aller Bytes hexadezimal, das zuvor
beschriebene Zähler-Nibble geht in die Prüfsumme mit ein. Die Prüfsumme
wird auf die unteren 4 bit beschränkt, die oberen fallen einfach weg
(alles HEX):
9+0+1+7+5+0 = 16 -> Prüfsumme = 6
9+0+1+7+5+2 = 18 -> Prüfsumme = 8
9+0+1+7+5+1 = 17 -> Prüfsumme = 7
Man beachte die ungerade Anzahl an Nibbles, ein Controller, der das
Protokoll als Sender emuliert, muss also vorweg ein 1111 Paket senden.
Die Anzahl der vorab gesendeten 1en ist aber in dem Trace
unterschiedlich. Ich gehe davon aus, dass es mit einem SPI einfach zu
emulieren ist. Man setzt das Interface auf ruhend = 1. Ein Datagramm
sendet man mit einem Byte Adresse ( 90), 10er 1ner Temperatur in einem
Byte, 1/10el und Counter in einem Byte und zuletzt die Prüfsumme im
high-Nibble des letztem Bytes gefolgt von einem F.
1
uint8_tTH,TD;// Temperatur, Temperatur 1/10
2
...
3
voidsend_datagramm(TH,TD)
4
{
5
uint8_ti,Dcount;// Counter, Datagramm Counter
6
uint8_tcrc;// Prüfsumme
7
8
Dcount=0x40;// Dcount mit einer zuerst unsichtbaren 1 vor laden
9
for(i=0;i<3;i++){
10
11
crc=(TH>>4)+(TH&0x0F)+(TD)+(Dcount&0x03);
12
13
spi_tx(0x90);// sende Adresse / Sync?
14
spi_tx(TH);// sende Temperatur 10er/1er
15
spi_tx((TD<<4)|(Dcount&0x03));// Temperatur 1/10 im high, counter im low-nibble
16
spi_tx((CRC<<4)|0x0F);// prüfsumme im high- F im low-nibble
17
Dcount>>=1;// schiebe Dcount um ein Bit nach rechts
18
}
19
}
Zur Berechnung von Dcount:
Zuerst is Dcount 00000100. Da wir Dcount mit & 0x03 auf die beiden
letzten Bits beschränken, bleibt für das erste Datagramm 00 übrig.
Dann ist Dcount 00000010. Also senden wir eine 10
Zuletzt ist Dcount 00000001 -> ergo senden wir eine 01 in den
zuständigen 4 Bits
So, mehr kann ich jetzt wirklich nicht mehr beschreiben.
>So, mehr kann ich jetzt wirklich nicht mehr beschreiben.
Ich danke dir! Ich werde mir heute Abend mal meine damals
mitgeschriebenen Protokolle nochmal ansehen.
Viel Erfolg. Wenn sie anders aussehen, kannst Du sie auch mal posten,
das entschlüsseln macht immer wieder Spaß :)
Ist wie Sudoku, aber halt mit Nutzeffekt.
Gruß, Ulrich
Volker wrote:
> Wie genau hast du denn die Rohdaten des> Senders verarbeitet um an die Bitwertigkeiten zu kommen?
Ich habe den von mir benutzten Code angehängt. Sehr schön ist der nicht,
aber er tut offensichtlich. Die beste Vorgehensweise damit ist, den AVR
zu resetten und dann den Sender zu resetten, damit er sendet.
Ich benutze dafür das Atmel-Evaluationsboard (die Version ohne Funk) von
Pollin. An PA0 hängt die Datenleitung des Senders, PD4 ist ein Taster,
PD5 und PD6 sind LED und PD7 ist ein Buzzer.
Wenn Daten empfangen werden, blinkt PD5. Wenn eines der Arrays (siehe
Code) 85 Elemente enthält, geht PD6 an. Wenn nach 85 gespeicherten
Werten immer noch Daten kommen, geht PD6 aus und der Buzzer piept kurz.
Die Arrays enthalten die Dauern, wie lange, gemessen in
Loop-Durchläufen, low und high auf der Datenleitung anlag.
Wenn PD6 leuchtet, kann man den Taster drücken und die Arrays werden auf
der seriellen Schnittstelle ausgegeben. Mit diesen Werten habe ich dann
mein Perlscript gefüttert, das daraus Nullen und Einsen macht. Falls
Interesse besteht, lade ich das noch hoch.
Ulrich P. wrote:
> Die 9 0 sollte die Adresse der Außenstation sein, damit sie von anderen> unterschieden werden kann.
Die 0 dient bereits zur Erkennung von Minustemperaturen. Ob die 9 als
Kennung des Senders dient, werde ich überprüfen. Habe zwei solcher
Stationen.
Großes Danke für die Aufschlüsselung der Prüfsumme!
@Wolgang
Ja, danke - habe deinen Code mal kurz überflogen. Du pollst also den
Datenausgang welcher direkt den Sender moduliert - hattest du ja auch in
deinem 1. Posting so geschrieben :-)
Gruß, Volker