Warum macht man sowas



  • Hallo zusammen,

    ich habe hier ein Stück Code, wo an einer Stelle etwas gemacht wird, was ich nicht ganz verstehe. Vielleicht könnt ihr mir ja helfen?

    int value[]; 
    
    read(39, &value); //register 39 lesen und in value ablegen
    
    value[1]=(value[1] >> 1) & 0x7F;
    

    Warum macht man dies??

    Für Tips bin ich dankbar. 🙂

    Müller


  • Mod

    Zeig mal den richtigen Code, wie er da steht, nicht deine Interpretation davon.

    P.S.: Falls du dich fragst, was (zahl >> 1) & 0x7F macht: Das gibt einem die Bits 2 bis 8 der Zahl.



  • Wie gewünscht: 🙂

    Ich bezog mich auf die Stelle:

    oldOffsets[i] = (oldOffsets[i] >> 1) & 0x7F; // see datasheet page 44 for more details.

    im Datenblatt steht nicht, warum er da hinten nochmal & 0x7F; macht.

    /**********************************************************************/
    // perform a fine-calibration ---  see datahseet page 44.
    /**********************************************************************/
    bool BMA180::Calibrate()
    {
      uint8_t bitFlags[3] = { en_offset_x, en_offset_y, en_offset_z };
      uint8_t oldOffsets[3];
      uint8_t newOffsets[3];
    
      for( int i = 0; i < 3; i++ )
      {
        ROS_INFO( "BMA180::Calibrate():  BEGIN  Calibrating axis %d", i );
    
        // extract offsets before: 
        // read fine_offset_x
        if( i == 0 )
        {
          if( this->readReg( 0x29, &oldOffsets[i] ) == false )
            return false;
          oldOffsets[i] = (oldOffsets[i] >> 1) & 0x7F; // see datasheet page 44 for more details.
        }
    
        // read fine_offset_y
        if( i == 1 )
        {
          if( this->readReg( 0x26, &oldOffsets[i] ) == false)
            return false;
          oldOffsets[i] = (oldOffsets[i] >> 1) & 0x7F; // see datasheet page 44 for more details.
        }   
    
        // read fine_offset_z:  it's stored in two registers...
        if( i == 2 )
        {
          uint8_t temp_reg1;
          uint8_t temp_reg2;
    
          if( this->readReg( 0x25, &temp_reg1 ) == false )
            return false;
          if( this->readReg( 0x23, &temp_reg2 ) == false )
            return false; 
          oldOffsets[i] = ( (temp_reg1 << 3) | (0x07 & temp_reg2) ) & 0x7F; // see datasheet page 44 for more details.
        } 
    ......
    

    Vielen Dank schonmal!

    Quelle: http://svn.code.sf.net/p/bosch-ros-pkg/code/trunk/stacks/bosch_drivers/bma180_driver/src/bma180.cpp



  • Aber ist:

    oldOffsets[i] = (oldOffsets[i] >> 1) & 0x7F;
    

    nicht das gleiche wie:

    oldOffsets[i] = (oldOffsets[i] >> 1);
    

    Der Schifft füllt doch automatisch vorn eine Null auf. Oder kann ich davon nicht ausgehen???


  • Mod

    So ist das tatsächlich sinnlos, da hier der Datentyp, im Gegensatz zu deinem Eingangsbeitrag, uint8_t ist. Bei int, wie in deinem Eingangsbeitrag, ist das schon ein wichtiger Unterschied.

    Ich würde mir vielleicht mal Seite 44 ansehen. Ansonsten würde ich es ebenfalls erst einmal als sinnlos abstempeln. Soll nicht das erste Mal sein, dass es sinnlosen Code in professionellen Anwendungen gibt 😉 .

    Ich möchte aber auf die Zeile 41 hinweisen, wo das schon einen wichtigen Unterschied macht. Vielleicht ist es aus Symmetriegründen (aka Copy&Paste) überall so. Oder damit ein späterer Entwickler nicht versehentlich etwas falsch machen kann, zum Beispiel bei Änderung des Datentyps oder Abwandlung der Rechnung.



  • Vielen Dank für die Hilfe! Tolles Forum. Wir hatten lange diskutiert, weil wir nicht sicher waren. Danke!!!



  • Herr_Müller schrieb:

    Der Schifft füllt doch automatisch vorn eine Null auf. Oder kann ich davon nicht ausgehen???

    Bei unsigned-Typen ja, bei signed-Typen kommt es drauf an, right-shift für positive signed int Werte ist auch OK.

    BMA180::BMA180( bosch_hardware_interface* hw ) :
      sensor_driver( hw ),
      BMA180Parameters()
    

    Hier versuchen C++ler, doch wieder irgendwas mit Zeigern zu machen, ==> Designschrott.

    double BMA180::getAccelX()  
    {
      uint8_t Data[2];
    
      // Must read LSB first.  MSB and LSB  must be read in one transaction:
      if( this->readSensorData( ADDRESS_ACCLXYZ, Data, 2 ) == false )
      {
        ROS_ERROR("BMA180: cannot read from this protocol.");
        return -9999.9;
      }
      int raw_data = int(( ((int16_t)(Data[1] << 8)) | ( ((int16_t)Data[0]) ) ) >> 2);
      AccelX_ = raw_data * this->getSensitivity();
    
      return AccelX_;
    }
    

    Einen double-Wert -9999.9 als Ersatzfehlercode, sowas machen nur Anfänger.
    Bei Data[1]>127 wird der Teilausdruck höchstwahrscheinlich negativ, das ist bestimmt NICHT im Sinne eines fehlerfreien Programmlaufs.

    //\Author Joshua Vasquez and Philip Roan, Robert Bosch LLC

    Ich hoffe bloß, dass meine Elektrogeräte dieses Teil
    http://www.digikey.de/de/de/ph/Bosch/BMA180.html
    nicht verwenden.



  • Der BMA180 Code hier ist nur für die ROS-Anbindung, in Produkten wirst du den nicht finden.


Anmelden zum Antworten