Print, BIN, DEC Verständnis

Hallo, ich bin an meinem Projekt Arduino-Windmesser TX23 Auswerten an meine Verständnisgrenzen geraten. Das Problem ist nicht die Funktion sondern das Verstehen BIN Decimal Print.

Hab die Frage schon in dem Forum gestellt wo der Code her ist, nur werd ich da bestimmt keine Antwort bekommen wenn ich mir die Datums der Post ansehe.

Der Code stammt von hier
http://forum.abacom-online.de/phpBB3/viewtopic.php?f=91&t=3968

Erklärt wird alles auch hier incl Beispielen
http://www.rd-1000.com/chpm78/lacrosse/Lacrosse_TX23_protocol.html

mein Problem, die Werte für Richtung und Windgeschwindigkeit kommen im BIN Format vom Windmesser.

ein
Serial.println(dataword1, BIN);
Serial.println(dataword1);

gibt folgendes aus
zeigt
1001010000
592

so, eigentlich sollte da doch als dec Wert da 41 stehen? was ich auch am Win Taschenrechner so ablesen kann.
aber andere Converter sagen wieder 592.

in oben genannten 2.Link, da sind ja 4 Beispiele der Windgeschwindigkeit, geht alles im Taschenrechner von Win nachzuvollziehen, nur wieso wird aus dem BIN bei mir und im Inet 592?

Was versteh ich nicht oder falsch?

Danke Heiko

https://www.arduino.cc/en/Serial/Print hast du gesehen ?

592 (dezimal) ist dasselbe wie 0x250 (HEX) oder 1001010000 (BIN)

Kannst du dir auch im Windows-Taschenrechner (Programmierer-Ansicht) anschauen. Das sind nur verschiedene Darstellungsformen derselben Zahl.

Was ist dein Verständnis-Problem ?

Meines ist dein Satz

eigentlich sollte da doch als dec Wert da 41 stehen?

wie kommst du auf 41 ?

Hallo Heiko

Ich verstehe nicht ganz, wo genau am Win-Taschenrechner du für 41 deine von dir oben genannten 1001010000 abliest.... Die 1001010000 sind wirklich 592 41 wäre binär 101001 Also wenn man deine binäre Zahl umdreht (0000101001) dann gibt das 41

Grüsse Peter

siehe Bild im Anhang, habs extra rot eingekreist. genau so wenn man sich die Beispiele im 2.Link ansieht

die m/s werte enstehen beim /10 so stehts auch geschrieben.

100110000 000 ->25 /10=2,5 m/s 110010000 000 ->19 /10=1,9 m/s 001111100 000 ->124 /10=12,4 m/s 101111010 000 ->189 /10=18,9 m/s

meine 592 / 10 würden 59,2m/s ergeben, also 213km/h wind, da würd ich nicht mehr tippen können da wär ich weggeflogen.

oder ich bin mit meinen BINÄR aufm Holzweg, das das eine "Bitfolge" ist?

kollimann: siehe Bild im Anhang, habs extra rot eingekreist. genau so wenn man sich die Beispiele im 2.Link ansieht

und wenn man sich oben die Eingabe ansieht steht dort: DEC 41 und nicht 592 warum sollte dann als Binärergebnis 1001010000 rauskommen?

Wenn das dein Sketch ist:

void loop() {

   int dataword = 0; // Prepare data word

   stat = digitalRead(senspin);  // get the sensor input
   while(stat == HIGH){          // wait for falling edge (sync to startbit)
      stat = digitalRead(senspin); 
   }
   
   delayMicroseconds(half_bit_ms); //wait for MIDDLE of startbit, we are now in sync

   // Skip the start bit, we now it ist there ;-)
   delayMicroseconds(bit_ms);
   
   // Skip four header bits, we don´t want these...
   delayMicroseconds(bit_ms);
   delayMicroseconds(bit_ms);
   delayMicroseconds(bit_ms);
   delayMicroseconds(bit_ms);
   
  // Now the 13 bits we want...
  // *** Dataword [0..3] = WIND DIRECTION (LSB first)
  // *** Dataword [4..12] = WIND SPEED (LSB first)
 
  for (int i=0; i <= 13; i++){
     stat = digitalRead(senspin); 
     if (stat) {
        dataword = dataword + (1 << i);
     } 
      delayMicroseconds(bit_ms); // Wait for next bit
  }

 
  Serial.println(dataword, HEX);  // Print out Dataword as readable ASCII string to PC
 
  digitalWrite(ledpin, HIGH);   // Sensor Data Indicaror LED on
  delay(200);                   // Spens some time, to make sure finished tranmittion
  digitalWrite(ledpin, LOW);    // Sensor Data Indicaror LED on
}

hat er die kleine Unschönheit, dass er 14 statt 13 Bit liest. Aber das scheint hier nicht dein Problem zu sein.

Eigentlich sollten nach 9 Datenbit noch 4 mal 0 kommen: 0x250 wäre also gar nicht möglich.

mein Scetch hat eine kleine Änderung die das Ergebnis nicht beeinflusst

for (int i=0; i <= 13; i++){
     stat = digitalRead(senspin);
     if (stat) {
       if (i <= 3) {
        dataword = dataword + (1 << i);
       } else {
       dataword1 = dataword1 + (1 << i);
     }
   }

damit teile ich schonmal Windrichtung und Windspeed.

ich glaube die Fragestellung bzw meine Art der Interpretierung der Sache ist falsch.

was kommt denn da nun in dataword und dataword1 an. BIN oder BIT oder was ist das?

so wenn ich das verstanden hab, wie wird aus

dataword1 mit Inhalt 1001010000 der die das “konvertierte” neue variableninhalt 41

bzw. siehe Beispiele

100110000 000 → 25
110010000 000 → 19
001111100 000 → 124
101111010 000 → 189

ich kann mit der 1000101011 irgendwas nix anfangen, muss es wandeln/konvertieren was auch immer.

zitat aus einer anderen Anleitung, evtl hilft es bei der “ich stell mich blöd an” Lösung
F – Wind Speed
The wind speed is a 12 bit value. It requires it’s endianness to be reversed.
I’m unsure of the exact units, but it appears to be a factory calibrated value in units of 0.1 metre/sec. The 3 MSB’s are always 000, so only 9 bits are used. With a max value of 511, this relates to 51.1 metres per second, or 183.96 km/h (114.31 miles per hour).

From the example image above, the wind speed is read as 101010100000, then endianness reversed to 000001010101, which is decimal 85, or 8.5 metres per second.

Danke

Die Lösung steht, wenn ich nicht irre, in Deinem Text: “WIND DIRECTION (LSB first)” und “WIND SPEED (LSB first)”. Und “the wind speed is read as 101010100000, then endianness reversed to 000001010101”.

Du mußt also tatsächlich 1001010000 in der Reihenfolge umdrehen zu 0000101001, was die 41 ergibt.

Ein Testprogramm zur Veranschaulichung:

uint16_t dataword = 0, w = 0b100101000; // 000101001 
void setup() {
  Serial.begin(9600);
  Serial.println(w, BIN);
  for (int i = 0; i < 9; i++) {
    bool stat = w & 1;
    if (stat) {
      dataword = dataword | (0b100000000 >> i); // Hier kann man die Richtung umdrehen
    }
    w = w >> 1;
  }
  Serial.print(dataword, BIN);
  Serial.print("\t");
  Serial.println(dataword, DEC);
}

void loop() {
}

EDIT 2.10.16 11:00 Uhr: Programm auf die relevanten 9 Bit verändert.

Was hältst du davon die Werte LSB first einzulesen?

const byte senspin = 2;
void readin() {
  int dataword = 0;
  int dataword1 = 0;
  for (byte i = 0; i <= 13; i++) {
    bool oneBit = digitalRead(senspin);
    if (i <= 3) {
      dataword <<= 1;
      if (oneBit) {
        dataword++;
      }
    } else {
      dataword1 <<= 1;
      if (oneBit) {
        dataword1++;
      }
    }
  }
}

(ungetestet)

Das war natürlich MSB.

LSB sollte so gehen

const byte senspin = 2;
void readin() {
  int dataword = 0;
  int dataword1 = 0;
  for (byte i = 0; i <= 13; i++) {
    bool oneBit = digitalRead(senspin);
    if (i <= 3) {
      dataword >>= 1;
      if (oneBit) {
        dataword |= 8;
      }
    } else {
      dataword1 >>= 1;
      if (oneBit) {
        dataword1 |= 0x800;
      }
    }
  }
}

Wegen diesem Kommentar

// Now the 13 bits we want...
  // *** Dataword [0..3] = WIND DIRECTION (LSB first)
  // *** Dataword [4..12] = WIND SPEED (LSB first)

bin ich für

i < 13

und i < 3

Danke werd es testen.

Was bedeutet MSB und LSB?

Die 13 stimmen, die <= 3 müssen bleiben.

const byte senspin = 2;
void readin() {
  int dataword = 0;
  int dataword1 = 0;
  for (byte i = 0; i < 13; i++) {
    bool oneBit = digitalRead(senspin);
    if (i <= 3) {
      dataword >>= 1;
      if (oneBit) {
        dataword |= 8;
      }
    } else {
      dataword1 >>= 1;
      if (oneBit) {
        dataword1 |= 0x100;
      }
    }
  }
}

Most Significant Bit
Least Significant Bit

hi,

Was bedeutet MSB und LSB

einfach, ob die höherwertigen bits zuerst kommen oder die niederwerigen.

bei einer dezimalzahl würde es bedeuten, daß bei der zahl 1536 entweder erst 1, dann 5, dann 3 und dann die 6 kommt, oder umgekehrte reihenfolge, also 6 - 3 - 5 - 1. mal braucht man’s so, mal andersrum.

gruß stefan

Whandall:
Die 13 stimmen, die <= 3 müssen bleiben.

4 + 9 = 13, ja das paßt :slight_smile:

OK, Danke, ich versteh es so halb in der Theorie um was es geht.

Mein Problem dabei ist, das Teil steht schon eingebaut vor Ort, mitten auf einem Feld ohne Strom ohne alles, 20KM von mir entfernt. Ich kann also zuhause keine Tests machen bezüglich Änderungen. Vor Ort, auf dem Feld hab ich 1Stunde Akku Laptop zum rumspielen und ändern.

Ich gebe zu, ich kann die Code Schnippsel nicht interpretieren, ich schreib die mal so in mein Scetch.

Der Idealfall für mich wäre, ich hab ein CodeSchnippsel Alt und eins neu vereint in einem. Ich weiß ja das mein aktueller Ausleseprozess funktioniert, nur eben die Werte/der Inhalt von dataword1 gespiegelt werden muss. Daher wäre es von Vorteil für mich eine "Print" Ausgabe zu haben mit meinem org. dataword1 und eine mit newdataword1, um zu vergleichen ob wirklich richtig gespiegelt wurde. Oder kann man nicht mein Auslesen so lassen und das nach dem Auslesen erst spiegeln? Das ich alles was das auslesen angeht so lasse, weil ich weis es stimmt soweit, und dann 2 vars hab eine dataword1 und eine newdataword die gespeigelt ist?

Ich stell ja euer können nicht in Frage aber ich hab ja so keinen Vergleich zu vorher. Wenn dummerweise "in der Mitte" 2 falsch getauscht werden, kommt ja DEC wieder was anderes raus, ODER ist das unmöglich?

Danke

also mein Code, mit reverse

for (int i=0; i <13; i++){
     stat = digitalRead(senspin);
     if (stat) {
       if (i <= 3) {
        dataword = dataword + (1 << i);
       } else {
       dataword1 = dataword1 + (1 << i);
     }
   }

//jetzt reverse

uint16_t revdataword = 0, w = dataword1; // 000101001

for (int i = 0; i < 9; i++) {
    bool stat = w & 1;
    if (stat) {
      revdataword = revdataword | (0b100000000 >> i); // Hier kann man die Richtung umdrehen
    }
    w = w >> 1;
  }

Serial.println(dataword1, BIN); // orginal Ausgelesen
Serial.println(revdataword, BIN);//reverse

könnte das so gehen?

kollimann: Vor Ort, auf dem Feld hab ich 1Stunde Akku Laptop zum rumspielen und ändern.

Wenn Du da häufiger bist, wäre hier ein Ansatzpunkt für Verbesserungen. Mein Laptop hält länger, habe ich gerade beim Camping probiert. Sonst eben Stromaggregat, Autobatterie, Sonnensegel ...

Was sagt denn Dein Compiler dazu, denn im trauten Heim kannst Du auch ohne Arduino compilieren:

bool stat = w & 1;

kollimann: Ich stell ja euer können nicht in Frage aber ich hab ja so keinen Vergleich zu vorher. Wenn dummerweise "in der Mitte" 2 falsch getauscht werden, kommt ja DEC wieder was anderes raus, ODER ist das unmöglich?

Ich weiß, was ich kann, daher weiß ich auch, was ich nicht kann, da kannst Du mich nicht aus der Ruhe bringen, sei unbesorgt. Irrtümer gibt es bei mir inklusive. Aber danke für die Empathie :)

Unmöglich ist überhaupt nichts, daher stimme ich Dir vollkommen zu, alle Zwischenschritte möglichst zu dokumentieren, also ausgeben zu lassen. So bekommst Du auch ein Gefühl für das, was da passiert. Das mache ich nicht anders :)

Wenn alles wunschgemäß funktioniert, speichere diese Version Deines Programms und beginne mit den Optimierungen.

Was sagt denn Dein Compiler dazu

nix, läuft ohne Meldung durch......

kollimann: nix, läuft ohne Meldung durch......

Ach so, das verwundert mich. Aber gehen wir mal davon aus, der Compiler weiß, was er tut :)

Dann auf zum Feldversuch oder Versuch im Feld.