Hallo zusammen Ich habe folgendes Problem. Ein Wettersensor sendet die Windrichtung in einem Datenpaket an eine Wetterstation. Der Wert für die Richtung ist in einem Nibble enthalten. Somit sind 16 Windrichtungen möglich. Der Wert wird allerdings irgendwie kodiert versendet. Mit folgender C-Function kann der Wert entschlüsselt werden: byte decodeWindDirection(byte winddir) { b ^⁼ (b & 8) >> 1; b ^⁼ (b & 4) >> 1; b ^⁼ (b & 2) >> 1; return -b & 0xf; } Übergeben wird der Funktion ein Wert 0 bis 15 (die verschlüsselte Windrichtung). Und heraus kommt die unverschlüsselte Windrichtung mit Werten 0-15. Das Ergebnis mit 22.5° multipliziert ergibt die Windrichtung in Grad. Soviel zur Erklärung. Hat jemand eine Idee, wie man die Funktion umkehren kann? Hier eine Tabelle mit einigen Richtungen. z.B Osten ist 90° und der Binärwert unverschlüsselt 4. Nach dem Encrypten soll daraus 9 werden. Für das Decrypten kann obige Funktion verwendet werden, die auch funktioniert. Richtung | Winkel | Dec | Enc N = 0,0° = 0 = 0 NNO = 22,5° = 1 = 8 NO = 45,0° = 2 = 9 ONO = 67,5° = 3 = 11 O = 90,0° = 4 = 10 OSO = 112,5° = 5 = 14 SO = 135,0° = 6 = 15 SSO = 157,5° = 7 = 13 S = 180,0° = 8 = 12 Wäre schön, wenn jemand eine Idee hat, wie die Funktion umgekehrt werden kann. Gruß Micha.
:
Bearbeitet durch User
Wenn man es sich binäre anschaut, könnte das eine Art Gray-Code sein: Richtung | Winkel | Dec | Enc | Enc Binär N = 0,0° = 0 = 0 | 0000 NNO = 22,5° = 1 = 8 | 1000 NO = 45,0° = 2 = 9 | 1001 ONO = 67,5° = 3 = 11 | 1011 O = 90,0° = 4 = 10 | 1010 OSO = 112,5° = 5 = 14 | 1110 SO = 135,0° = 6 = 15 | 1111 SSO = 157,5° = 7 = 13 | 1101 S = 180,0° = 8 = 12 | 1100 Was spricht bei 16 Werten gegen eine Lookup-Table?
Micha R. schrieb: > byte decodeWindDirection(byte winddir) > { > b ^⁼ (b & 8) >> 1; > b ^⁼ (b & 4) >> 1; > b ^⁼ (b & 2) >> 1; > return -b & 0xf; > } woher kommt denn die Variabel b? und was soll das Zeichen nach dem ^ darstellen?
Sorry, b ist die Windrichtung, die übergeben wird So ist es vielleicht verständlicher: > byte decodeWindDirection(byte b) > { > b ^= (b & 8) >> 1; > b ^= (b & 4) >> 1; > b ^= (b & 2) >> 1; > return -b & 0xf; > } Übrigens, könnte schon sein, dass es der Greycode ist. Bleibt die Frage, wie man den umdreht.
:
Bearbeitet durch User
Sebastian: Eine Lookup Tabelle wäre die letzte Option, wenn es keine mathematische Lösung gibt. Schön wäre eine Function wie byte encodeWindDir(byte dir) { ... } die das Ergebnis berechnet.
Micha R. schrieb: > Übrigens, könnte schon sein, dass es der Greycode ist. 00: 0000 01: 0001 02: 0011 03: 0010 04: 0110 05: 0111 06: 0101 07: 0100 08: 1100 09: 1101 10: 1111 11: 1110 12: 1010 13: 1011 14: 1001 15: 1000 Richtung | Winkel | Dec | Enc | Enc Binär | Gray N = 0,0° = 0 = 0 | 0000 | 0 NNO = 22,5° = 1 = 8 | 1000 | 15 NO = 45,0° = 2 = 9 | 1001 | 14 ONO = 67,5° = 3 = 11 | 1011 | 13 O = 90,0° = 4 = 10 | 1010 | 12 OSO = 112,5° = 5 = 14 | 1110 | 11 SO = 135,0° = 6 = 15 | 1111 | 10 SSO = 157,5° = 7 = 13 | 1101 | 9 S = 180,0° = 8 = 12 | 1100 | 8
Hier gibts Code für Hin- und Rückweg vom Gray Code: https://en.wikipedia.org/wiki/Gray_code#Converting_to_and_from_Gray_code Und ja, es ist Gray, was da aus dem Windfähnchen kommt.
Der Link ist interessant leider funktioniert das nicht. Beispiel ich übergebe binär 2 für NO (45°) und 9 soll kodiert raus kommen. Ergebnis ist aber 3 Und die Funktion habe ich verwendet: // The operator >> is shift right. The operator ^ is exclusive or. unsigned int binaryToGray(unsigned int num) { return num ^ (num >> 1); } Und bei 4 als übergabewert sollte 10 raus kommen, Ergebnis ist aber 6. Scheint doch nicht ganz Geycode zu sein.
Micha R. schrieb: > Scheint doch nicht ganz Geycode zu sein. kannst du mal alle werte von 0-15 posten, die aus der Funktion rauskommen?
Peter II schrieb: > kannst du mal alle werte von 0-15 posten, die aus der Funktion > rauskommen? Ich habe die Tabelle etwas erweitert: Aus dieser Funktion > byte decodeWindDirection(byte b) > { > b ^= (b & 8) >> 1; > b ^= (b & 4) >> 1; > b ^= (b & 2) >> 1; > return -b & 0xf; > } kommen folgende Werte: (Spalte ENC ist Übergabeparameter, Ergebnis in Spalte DEC) ENC Richtung | Winkel | Dec | Enc | BIN N = 0,0° = 0 = 0 0000 NNO = 22,5° = 1 = 8 1000 NO = 45,0° = 2 = 9 1001 ONO = 67,5° = 3 = 11 1011 O = 90,0° = 4 = 10 1010 OSO = 112,5° = 5 = 14 1110 SO = 135,0° = 6 = 15 1111 SSO = 157,5° = 7 = 13 1101 S = 180,0° = 8 = 12 1100 SWS = 202,5° = 9 = 4 0100 SW = 225,0° = 10 = 5 0101 WSW = 247,5° = 11 = 7 0111 W = 270,0° = 12 = 6 0110 WNW = 292,5° = 13 = 2 0010 NW = 315,0° = 14 = 3 0011 NWN = 337,5° = 15 = 1 0001
Das ist normaler Graycode, wenn auch gegen den Uhrzeigersinn - also dem mathematisch positiven Drehsinn.
:
Bearbeitet durch User
16 Werte?! Na also da würde ich ne LookUp machen! Wo siehst du denn da ein Problem? Ob ich den Flash mit ner Berechnung zupflaster oder ner Progmem... da wäre die Entscheidung aber einfach!
Matthias S. schrieb: > Das ist normaler Graycode, wenn auch gegen den Uhrzeigersinn - also dem > mathematisch positiven Drehsinn. Kannst du das in eine C-Funktion packen?
Micha R. schrieb: > Kannst du das in eine C-Funktion packen? Jep, ich nutze die Funktion von Wikpedia:
1 | float gry2deg(uint16_t grey) |
2 | {
|
3 | return 360 - (grayToBinary(grey) * 22.5f); |
4 | }
|
Ich würde normalerweise das Ergebnis nicht als float zurückgeben, sondern intern mit Grad mal 10 rechnen, um die 0.5 Grad loszuwerden. Also
1 | |
2 | uint16_t gry2deg(uint16_t grey) |
3 | {
|
4 | return 3600 - (grayToBinary(grey) * 225); |
5 | }
|
:
Bearbeitet durch User
geht das auch, wenn man nur Werte 0 - 15 (unkodiert) anstelle der Gradzahl übergibt? Ich rechne lieber mit dem 4-Bit Wert. Hintergrund ist, evtl. Windrichtung direkt an Wetterstations-Empfänger zu senden.
Micha R. schrieb: > Hat jemand eine Idee, wie man die Funktion umkehren kann? Eine Tabelle zur Umcodierung benötigt genau 8 Byte. Was willst du denn da für eine großartige Funktion schreiben? Du kannst natürlich die Spiegelsymmetrie im Gray-Code ausnutzen, um das algorithmisch umzukodieren, aber meinst du nicht, dass das übertriebener Ehrgeiz ist. In wage mal zu behaupten, dass das mit 8 Byte (zusätzlich zur Tabellenausleseroutine) nicht kodiert ist. Und schneller ist die Tabellenmethode auch noch.
Micha R. schrieb: > Ich rechne lieber mit dem 4-Bit Wert. Dann definierst du deinen Kram einfach um und setzt eben für 1 nicht NNO sondern NNW.
"Hintergrund ist, evtl. Windrichtung direkt an Wetterstations-Empfänger zu senden." Sende den Code doch ans HAARP-Relay, dann hast du morgen die gewünschte Windrichtung...
Simpel schrieb: > Sende den Code doch ans HAARP-Relay, dann hast du morgen die gewünschte > Windrichtung... Und du bist sicher, dass das Ding wieder läuft? http://www.arrl.org/news/haarp-facility-shuts-down
@Wolfgang Bin nicht mehr up to date... vielleicht ist mei Aluhut oxydiert. :)
Beim dekodieren geht's ja auch ohne Tabelle. Warum sollte es dann umgekehrt nur mit Tabelle gehen? Ich wollte den Algorithmus. Klar geht's mit Tabelle. Wenn ich das gewollt hätte, wäre dieser Thread nie geschrieben worden. Übrigens hat das nichts mit HAARP zu tun. Das ist eine andere Baustelle, über die ich mich hier nicht auslassen will. Und Wenn man Haarp erwähnt sollte man Chemtrail und Geoengeneering auch erwähnen. Ich weis wir werden alle besprüht wie Insekten. Hat aber nichts mit dem Thema zu tun. Trotzdem danke für eure Hilfe.
Micha R. schrieb: > Übrigens hat das nichts mit HAARP zu tun. Das ist eine andere Baustelle, > über die ich mich hier nicht auslassen will. Und Wenn man Haarp erwähnt > sollte man Chemtrail und Geoengeneering auch erwähnen. Ich weis wir > werden alle besprüht wie Insekten. Soooo... und ich bin raus! :'D
Matthias S. schrieb: > Jep, ich nutze die Funktion von Wikpedia:float gry2deg(uint16_t grey) > { > return 360 - (grayToBinary(grey) * 22.5f); > } > Ich würde normalerweise das Ergebnis nicht als float zurückgeben, > sondern intern mit Grad mal 10 rechnen, um die 0.5 Grad loszuwerden. Was soll die Ausgabe mit einer Auflösung von 0.5 Grad. Der Sensor hat eine relative Auflösung von weniger als 6 Prozent vom Messbereich. Eine Ausgabe mit einer Auflösung von besser als 0.2 Prozent ist da wohl ziemlicher Schwachfug. Oder schreibst du vom Taschenrechner auch immer alle 13 angezeigten Stellen ab?
Hallo, ich habe die Lösung! Die entscheidenden Hinweise waren, dass es sich um Greycode handelt und dass der rückwärts geht. Das hat mich auf eine Idee gebracht, die funktioniert: In Assembler sieht die encoder-Routine so aus: in r24 wird der zu codierende Wert übergeben und codiert zurück gegeben encWindDirection: COM r24 Inc r24 MOV r25,r24 ANDI r25,$F LSR r25 EOR r24,r25 ANDI r24,$F Ret Ich hab's mit allen Werten durchgespielt, es funktioniert. in C umgeschrieben sieht die Funktion etwa so aus (auch getestet): byte encWindDirection(byte dir) { byte tmp; dir = (dir ^ 0x0F); dir ++; dir &= 0x0F; dir = dir ^ (dir >>1); return dir & 0x0F; } Hier ein voll lauffähiges Arduino-Programm: byte encWindDirection(byte dir) { byte tmp; dir = (dir ^ 0x0F); dir ++; dir &= 0x0F; dir = dir ^ (dir >>1); return dir & 0x0F; } void setup() { // put your setup code here, to run once: Serial.begin(9600); byte wert, ergebnis; String ausgabe; for (wert=0; ; wert++) { ergebnis=encWindDirection(wert); ausgabe="Wert: " + String(wert,DEC) + " ergibt codiert: " + String(ergebnis,DEC); Serial.println(ausgabe); if (wert==15) break; } } void loop() { // put your main code here, to run repeatedly: } Danke an alle für die konstruktiven Infos.
Wolfgang schrieb: > Was soll die Ausgabe mit einer Auflösung von 0.5 Grad Ich habe nie von einer solchen Auflösung geredet. Der TE hat lediglich diese Tabelle gestellt: Micha R. schrieb: > Richtung | Winkel | Dec | Enc | BIN > N = 0,0° = 0 = 0 0000 > NNO = 22,5° = 1 = 8 1000 > NO = 45,0° = 2 = 9 1001 > ONO = 67,5° = 3 = 11 1011 > O = 90,0° = 4 = 10 1010 > OSO = 112,5° = 5 = 14 1110 > SO = 135,0° = 6 = 15 1111 > SSO = 157,5° = 7 = 13 1101 > S = 180,0° = 8 = 12 1100 > > SWS = 202,5° = 9 = 4 0100 > SW = 225,0° = 10 = 5 0101 > WSW = 247,5° = 11 = 7 0111 > W = 270,0° = 12 = 6 0110 > WNW = 292,5° = 13 = 2 0010 > NW = 315,0° = 14 = 3 0011 > NWN = 337,5° = 15 = 1 0001 Und wenn er solche Ergebnisse wieder haben will, ist nun mal ein ,5 bei jeder zweiten Gradzahl.
Wolfgang schrieb: > Was soll die Ausgabe mit einer Auflösung von 0.5 Grad. Der Sensor hat > eine relative Auflösung von weniger als 6 Prozent vom Messbereich. Eine > Ausgabe mit einer Auflösung von besser als 0.2 Prozent ist da wohl > ziemlicher Schwachfug. Oder schreibst du vom Taschenrechner auch immer > alle 13 angezeigten Stellen ab? Das mit den 0.5° ist nicht von mir, sondern ergibt sich aus dem Windrichtungs-Nibble. Damit lassen sich 16 Positionen darstellen. Zähle mal die Windrichtungen zusammen, es sind exakt 16. Will man die Windrichtung in Grad haben, müsste man den decodierten Wert mit 22.5° multiplizieren. Daher kommt das. Ansonsten gibt der Wert nur die Position an (ähnlich bei einer Uhr mit 1 bis 12). Ich brauchte aber nur die Kodierung und die Dekodierung von dem Nibble. Dir Umrechnung in Grad war klar.
Um welchen Windsensor genau handelt sichs denn da?
Micha R. schrieb: > Will man die Windrichtung in Grad haben, müsste man den decodierten Wert > mit 22.5° multiplizieren. Daher kommt das. Die 0.5 in der Ausgabe ist trotzdem beliebig gelogen. Eine Rückgabe in vollen Grad ist allemal ausreichend. Nichtmal die Schaltflanken am Sensor werden so genau liegen. Aber natürlich kommen dann die Code-Recycler, die Wert drauf legen, dass die Routine auch mit einem 14-Bit Geber noch läuft ;-)
Stefan B. schrieb: > Um welchen Windsensor genau handelt sichs denn da? Bzw. welche Wetterstation soll die Daten empfangen? Just curious.
Wie der Windsensor vom Modell her heißt weis ich nicht. Der Empfänger ist eine TFA Dostmann, ist auch kompatibel mit Cresta. Irgendwas mit WS..., ich habe selbst keine. Die haben so ein merkwürdiges Funkprotokoll. Ehrlich gesagt würden mir solche Merkwürdigkeiten für ein Funkprotokoll nicht einfallen. Alles verkodet und dann noch mal verschlüsselt. Obendrein kuriose Checksummen und eine reicht ja nicht, muss noch ne 2. her, die völlig anders ist. Also sehr merkwürdiges Funkprotokoll würde ich sagen. Also da gibt es einfachere Protokolle.
Ich habe für den WS-Sensor für die Windrichtung eine C-/H-Datei, die die Nibbles richtig auswertet. Ich setze sie morgen mal hier rein, falls von Interesse.... Ich wollte den Sensor damals in meine Wetterstation einbinden, nur verlor ich, nachdem alles fast fertig war die Lust dran. Aber die Auswertung des Windsensors ging super.
Stefan B. schrieb: > Ich habe für den WS-Sensor für die Windrichtung eine C-/H-Datei, die die > Nibbles richtig auswertet. Ich setze sie morgen mal hier rein, falls von > Interesse... Hallo Stefan, natürlich bin ich interessiert, wie das in C gemacht wurde. Kannst es mir auch per Mail schicken, falls du es nicht veröffentlichen willst. Gruß Micha
Hi Micha, anbei die wichtigsten Dateien für Dein Vorhaben. Vielleicht hilfts Dir weiter.... Gruss
Stefan B. schrieb: > Hi Micha, > > anbei die wichtigsten Dateien für Dein Vorhaben. > > Vielleicht hilfts Dir weiter.... > > > Gruss Hallo Stefan, danke für die Dateien. Ich hab mir das mal angeschaut. Aber es ist anders kodiert. Im Speziellen ist die Windrichtung nach dem Grey-Code kodiert. Was ich habe ist nochmal invertiert. Weiterhin wird in deinem Source nur dekodiert soweit ich das überblicken konnte, aber nicht kodiert. Auch die Übertragung und das Funkprotokoll ist anders. Vielleicht hilft mir das später mal weiter, aber nicht für das aktuelle Projekt. Trotzdem danke for den Source. Micha
Micha R. schrieb: > Im Speziellen ist die Windrichtung nach dem > Grey-Code kodiert. Was ich habe ist nochmal invertiert Ist das für dich wirklich so ein unüberwindliches Problem? Georg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.