OXSENS openXsensor: Hochpräziser Geschwindigkeitsensor SDP3x

Tempo

Erfahrener Benutzer
#41
Hallo Klaus,

hast du den SDP31-500Pa oder den SDP32-125Pa ?

Löten geht am besten, wenn du den Silikonschlauch (ohne Talkum oder Talkum ausspülen) auf beide Druckanschlüsse setzt und den Sensor z.B. "entspannt in einem Miniaturschraubstock fixierst".

Ich verwende 0,2mm teflonisolierten Draht zum Anschließen. Mit einem entisolierten Stück dieses 0,2mm Drahtes habe ich ein passendes "U" gebogen, um alle GND-Kontakte auf dem Chip anzupunkten.
Zugentlastung der verdrillten 4 Leitungen geht sehr gut durch einmal Umwickeln des Sensorgehäuses.

Ich wünsche Dir eine Lupe und eine ruhige Hand beim Löten :geek:


SDP3x_soldering.jpg
 
Zuletzt bearbeitet:

Tempo

Erfahrener Benutzer
#42
...

Jetzt muss ich noch zusehen, wie ich an entsprechende Röhrchen komme.

Viele Grüße,
Klaus

Anhang anzeigen 181440
Silikonschlauch 1,5x2,5mm z.B. hier bei MSI-Industriebedarf
Silikonschlauch Siliconschlauch D1-25mm lebensmittelecht 200° auch Druckschlauch | eBay

Und für das Prandtl-Rohr
Alurohr 4x5mm
Messingrohr 1,5x2mm
Stahldraht 1,4 mm für Biegemaßnahmen in das Messingrohr einsteckbar

aus dem gängigen Modellbauhandel.

Ich habe alles mit dem Klasssiker "UHU-endfest300" verklebt. Der dichtet gut ab, lässt sich rund schleifen und verbindet sich gut mit Metallen.
Aber die Verklebungen selbst sind trickreich zu machen, damit alle Öffnungen offen bleiben.
Alle luftleitenden Querschnitte müssen gut sauber sein, denn durch den SDP3x strömt ein kleiner Luftstrom, der durch den Differenzdruck angetrieben wird.

Viel Erfolg und zeige mir dein Ergebnis mit deinen Lösungen (y)
 
Zuletzt bearbeitet:

fa223

Erfahrener Benutzer
#43
... hast du den SDP31-500Pa oder den SDP32-125Pa ?
Ich habe den SDP32-125PA, da mich aktuell die niedrigeren Geschwindigkeiten interessieren.

... Ich wünsche Dir eine Lupe und eine ruhige Hand beim Löten :geek:
Danke, das wünsche ich mir auch. Ich hatte die Größe überschätzt, so wird das sicherlich ein spannendes Erlebnis. :eek:

... IViel Erfolg und zeige mir dein Ergebnis mit deinen Lösungen
Gerne ... wenn etwas vorzeigbares raus kommt. :unsure:

Grüße,
Klaus
 

Rolf_

Erfahrener Benutzer
#45
Vielen Dank für die Informationen Rund um den SDP3x.

Seit heute sind meine SDP32 da. Falls mir das anlöten gelingt, will ich die Verwendung als Angel-of-Attack Sensor testen. (Mit den SDP33 als Breakout von Drotek bin ich seit über 2 Jahren als Airspeedsensor an Arduplane an verschiedenen VTOLS verbaut sehr zufrieden, da eine Nullpunktkalibrierung nicht erforderlich ist und die Genauigkeit unter 10 m/s - wichtig für die Transition bei den Senkrechtstartern - bereits sehr gut ist.) Verspreche mir daher von den SDP32 eine Menge.

w2.jpg
Rolf
 

Tempo

Erfahrener Benutzer
#46
Vielen Dank für die Informationen Rund um den SDP3x.

Seit heute sind meine SDP32 da. Falls mir das anlöten gelingt, will ich die Verwendung als Angel-of-Attack Sensor testen. (Mit den SDP33 als Breakout von Drotek bin ich seit über 2 Jahren als Airspeedsensor an Arduplane an verschiedenen VTOLS verbaut sehr zufrieden, da eine Nullpunktkalibrierung nicht erforderlich ist und die Genauigkeit unter 10 m/s - wichtig für die Transition bei den Senkrechtstartern - bereits sehr gut ist.) Verspreche mir daher von den SDP32 eine Menge.


Rolf
Hallo Rolf,

finde ich Klasse, daß du auch Anstellwinkel messen willst.

Wenn du nur relative Anstellwinkeländerungen messen willst, dann kannst du den SDP32 sofort einsetzen.

Wenn du den Anstellwinkel in Grad messen willst, musst du noch eine Kalibrierung mit einem Winkelmesser machen. Ich habe dazu z.B. einen klassischen Windfahnen-Strömungswinkelmesser gebaut und parallel für eine Winkel-Kalibrierung zu meinen SDP6x benutzt. Die Kalibrierung erfolgte dann unter realen Bedingungen im Flug.

Ich habe eine sogenannte 5-Lochsonde für Schiebewinkel- und Anstellwinkelmessung angefertigt:

SDP3x_5holeprobe_IMG_20200413_083310.jpg
 

fa223

Erfahrener Benutzer
#47
Hallo Tempo und Rolf,
das wird ja immer interessanter!
Mit dem Löten ist das so eine Sache...
Gemessen an der Größe des Teils, bin ich aber leidlich zufrieden.
SDP32.jpg

Grüße, Klaus.
 

Tempo

Erfahrener Benutzer
#49
Hallo Tempo und Rolf,
das wird ja immer interessanter!
Mit dem Löten ist das so eine Sache...
Gemessen an der Größe des Teils, bin ich aber leidlich zufrieden.
Anhang anzeigen 181544

Grüße, Klaus.
Hallo Klaus,

ja, Ich sehe das wie Ralf, dass du nochmal nachlöten musst. Es ist dann gut, wenn möglichst kleine Lötpunkte entstehen, die glitzern.

Verzinne zuerst die kleinen Lötkontakte auf dem SDP3x mit ganz wenig Lötzinn, bevor du die Drähte auflegst. Die Drähte am besten in Position fixieren, damit du ohne zu wackeln löten kannst und das Lot ohne zu verwackeln erstarrt.

Ausserdem fehlen noch weitere Lötpunkte, die du mit einer Draht-U-Brücke machen kannst.
Siehe mein Foto. :geek:

Nochmal wünsche ich dir eine Lupe und eine ruhige Hand :geek:

SDP32.jpg
 

Tempo

Erfahrener Benutzer
#50
Hallo Klaus,

so habe ich das mit einer U-Drahtbrücke gemacht.

Fange zuerst mit dieser U-Drahtbrücke an, dann schwarzer Draht GND und zum Schluß die anderen 3 Drähte anpunkten.

Der schwarze Draht ist GND und den habe ich sowohl an Pin 6 als auch an dem großen zentrischen Lötpad angepunktet. Dann ist meine U-Drahtbrücke angepunktet an den Pins 1,2,3,9,10,11 und am zentrischen Lötpad. Alles klar ?

SDP3x_solderpoints.jpg
 
Zuletzt bearbeitet:

fa223

Erfahrener Benutzer
#51
Hallo Tempo,

ja, alles klar. :unsure:

Da ich noch kein größeres Zeitfenster hatte und für mich das keine Beschäftigung ist, die ich "schnell" mal mache, hatte ich erst nur eine Seite "bearbeitet". Aber Danke für deinen Tipp mit der Brücke, hätte da ja auch selbst draufkommen können. :rot:

Grüße, Klaus.
 

Rolf_

Erfahrener Benutzer
#52
Fürchterliche Lötkleckse - aber es funktioniert :))))) e2.jpg

Arduplane erkennt den SDP3x sofort - an einem Omnibus F4 pro als Testcontroller angeschlossen.

e1.jpg

Ardupilot biegt allerdings alle Airspeed-Werte - egal wie herum der Luftstrom fließt - auf positive Werte um. Sobald ich Zeit habe, schau ich mal, ob ich den Code so abändern kann, dass positive und negative Werte angezeigt werden, um als AOA-Sensor funktionieren zu können.

Rolf
 

fa223

Erfahrener Benutzer
#53
Hallo Tempo,

ich hatte schon letzes Wochenende alle deine Ratschläge befolgt. Nur in der Taranis wurden keine Werte dargestellt. :cool:
Nun habe ich alle Kontakte nochmals überprüft, alle Pins gehen zu den richtigen auf dem Arduino. Sie gehen durch und es gibt keinen Kurzschluss - sagt das Messgerät.

oxs_SDP32_02.jpg

Der gesamte (Test-)Aufbau sieht dann so aus:

oxs_SDP32_01.jpg

Die Taranis erkennt den Sensor, zeigt aber keine Werte an (wenn man leicht auf die Röhrchen bläst). :cry:

Aktuell gehe ich nochmals alle Einstellungen des oXs durch. Mal sehen.

Grüße, Klaus.
 

RayX

Ein niemand
#58
Mit der Hand geht das mit einer brauchbaren Lötpaste ganz gut finde ich, Lötzinn lässt sich bei sowas deutlich schlechter verarbeiten.
Das nächste mal solltest du vielleicht auch dünnere / Viel dünnere Drähte verwenden, das sieht aus wie die Überbrückungs kabel ( Spaß)
Nein im Ernst die Drähte sind echt Fett, das sieht auch besser aus und die Lötzeit ist entsprechend Kurz / Kürzer.
 

Tempo

Erfahrener Benutzer
#59
Hallo Tempo,

ich hatte schon letzes Wochenende alle deine Ratschläge befolgt. Nur in der Taranis wurden keine Werte dargestellt. :cool:
...
Die Taranis erkennt den Sensor, zeigt aber keine Werte an (wenn man leicht auf die Röhrchen bläst). :cry:
...
Hallo Klaus,

zeig deine Sensoreinstellung der Taranis (Fotos des Asped menues der Taranis machen) und zeig deine oxs_config_advance.cpp zum Vergleichen mit meinen Einstellungen.
 

Tempo

Erfahrener Benutzer
#60
Fürchterliche Lötkleckse - aber es funktioniert :)))))...
Arduplane erkennt den SDP3x sofort - an einem Omnibus F4 pro als Testcontroller angeschlossen.
...
Ardupilot biegt allerdings alle Airspeed-Werte - egal wie herum der Luftstrom fließt - auf positive Werte um. Sobald ich Zeit habe, schau ich mal, ob ich den Code so abändern kann, dass positive und negative Werte angezeigt werden, um als AOA-Sensor funktionieren zu können.

Rolf
Hallo Rolf,

ja, den Code kannst du auf Differenzdruckanzeige abändern.
Schau in oXs_sdp3x.cpp nach.

Zur besseren Übersicht und zum Studium des Codes habe ich oXs_sdp3x.cpp und oXs_sdp3x.h zusammengefasst und alle DEBUG Einfügungen entfernt.
So sieht man schneller, was gemacht wird:

Code:
// * oXs_sdp3x.cpp *** Version, in der die DEBUG Einfügungen entfernt wurden. ****************
// * Damit ist die Datenbearbeitung übersichtlicher erkennbar. ******** Tempo 17.Mai 2020 ****
#include "oXs_sdp3x.h"

extern unsigned long micros( void ) ;
extern unsigned long millis( void ) ;
extern void delay(unsigned long ms) ;

OXS_SDP3X::OXS_SDP3X(uint8_t addr)
  {  // constructor
  _addr=addr;
  }

//***************** Setup the SDP3X sensor **************************************************
void OXS_SDP3X::setup()
  {
    airSpeedData.airSpeed.available = false ;     

    I2c.begin() ;
    I2c.timeOut( 80); //initialise the time out in order to avoid infinite loop

    // set the sensor in continous mode with averaging (send a command 0X3615)
    I2c.write(_addr, (uint8_t) 0X36 , (uint8_t) 0X15);
    delay(20); // wait 20msec in order to get the first data (datasheet says 8 msec)
    // read the sensor to get the initial temperature and the scaling factor
    I2CErrorCodeSdp3x = I2c.read( _addr,  9 ) ; //read 9 bytes from the device;
    nextPressureReadMillis = millis() + 2;    //
    nextAirSpeedMillis  = nextPressureReadMillis + 200 ;
    if (I2CErrorCodeSdp3x == 0)
    {
      data[0] = I2c.receive() ; // discard diffPressure
      data[1] = I2c.receive() ; // discard diffPressure
      //int16_t dp_raw   = (int16_t)data[0] << 8 | data[1];
      data[0] = I2c.receive() ; // discard this byte = CRC
      data[0] = I2c.receive() ;
      data[1] = I2c.receive() ;
      airSpeedData.temperature4525 = ((int16_t)data[0] << 8 | data[1]) / 200.0  ;
      // sdp3x use a scale factor of 200 for temp
      temperatureKelvinSdp3x = 273.15 + airSpeedData.temperature4525 ; // in Kelvin
      data[0] = I2c.receive() ; // discard this byte = CRC
      data[0] = I2c.receive() ;
      data[1] = I2c.receive() ;
      dpScaleSdp3x =  966.0 / 1013.0 / ((int16_t)data[0] << 8 | data[1]);
      // datasheet correction of 966/actual pressure in mbar; it is estimated with 1013
    }

  }  //end of setup

//****** readSensor - Read differential pressure + temperature from the 4525DO    ************
void OXS_SDP3X::readSensor()
  {
    unsigned long airSpeedMillis = millis() ;

    if ( airSpeedMillis >= nextPressureReadMillis)
    {  // do not read the sensor if there is less than 0.5 msec since previous read
       nextPressureReadMillis = airSpeedMillis + 2 ;
       I2CErrorCodeSdp3x = I2c.read( _addr,  2 ) ; //read 2 bytes from the device;

       if( I2CErrorCodeSdp3x == 0)
       { // when no read error, we calculate
           data[0] = I2c.receive() ;
            data[1] = I2c.receive() ;
         airSpeedData.difPressureAdc_zero =  ((int16_t) (data[0] << 8) + data[1] )
                                             * dpScaleSdp3x     ;     // diffPressure in pa 
      
         #define FILTERING_SDP3X_MIN    0.01 // oXs Filter aus, wenn MIN=MAX=1 hier gesetzt.
         #define FILTERING_SDP3X_MAX    0.1  // oXs Filter aus, wenn MIN=MAX=1 hier gesetzt.
         #define FILTERING_SDP3X_MIN_AT 10   // when abs is less than MIN_AT , apply MIN 
         #define FILTERING_SDP3X_MAX_AT 100  // when abs is more than MAX_AT , apply MAX
                                             // (interpolation in between)
         float abs_deltaDifPressure = abs(airSpeedData.difPressureAdc_zero-smoothDifPressure);

         if (abs_deltaDifPressure <= FILTERING_SDP3X_MIN_AT)
         {
           expoSmooth_auto = FILTERING_SDP3X_MIN ; 
         }
         else if (abs_deltaDifPressure >= FILTERING_SDP3X_MAX_AT) 
         {
           expoSmooth_auto = FILTERING_SDP3X_MAX ;
         }
         else
         {
           expoSmooth_auto = FILTERING_SDP3X_MIN + (FILTERING_SDP3X_MAX - FILTERING_SDP3X_MIN)
                             * (abs_deltaDifPressure - FILTERING_SDP3X_MIN_AT)
                             / (FILTERING_SDP3X_MAX_AT - FILTERING_SDP3X_MIN_AT) ;
          }

        smoothDifPressure += expoSmooth_auto
                             * ( airSpeedData.difPressureAdc_zero - smoothDifPressure ) ; //
      
        // calculate airspeed based on pressure, altitude and temperature
        // airspeed (m/sec) = sqr(2 * differential_pressure_in_Pa / air_mass_kg_per_m3)
        // air_mass_kg_per_m3 = pressure_in_pa / (287.05 * (Temp celcius + 273.15))
        // so airspeed m/sec = sqr( 2 * 287.05 * differential_pressure_pa
        //                     * (temperature Celsius + 273.15) / pressure_in_pa )
        // so at 15° and 1013hpa in cm/sec = 127.79 (=sqr(2*287.05*288.15/101300))
        // or rawAirSpeed cm/sec = 2396 * sqrt( (float) abs(smoothDifPressureAdc)
        //                         * temperatureKelvin  /  actualPressure) );
        //            in cm/sec ; actual pressure must be in pa (so 101325 about at sea level)
      #ifdef AIRSPEED_AT_SEA_LEVEL_AND_15C
        airSpeedData.smoothAirSpeed = 127.79 * sqrt( (float) ( abs(smoothDifPressure) ) );
        // indicated airspeed is calculated at 15 Celsius and 101325 pascal
      #else               
        airSpeedData.smoothAirSpeed = 2396.0 * sqrt( (float) ( abs(smoothDifPressure)
                                      * temperatureKelvinSdp3x  /  actualPressure) );
        // in cm/sec ; actual pressure must be in pa (so 101325 about at sea level)
      #endif
              
      if (smoothDifPressure < 0) airSpeedData.smoothAirSpeed = - airSpeedData.smoothAirSpeed;
        // apply the sign
      } // end no error on I2C   
        
      if (airSpeedMillis > nextAirSpeedMillis)
      { // publish airspeed only once every xx ms
        nextAirSpeedMillis = airSpeedMillis + 200 ;

        if ( airSpeedData.smoothAirSpeed >  0)
        { // normally send only if positive and greater than 300 cm/sec,
          // otherwise send 0 but for test we keep all values to check for drift 
          #ifdef AIRSPEED_IN_KMH 
          // uncomment this line if AIR speed has to be in knot instead of km/h
            airSpeedData.airSpeed.value = airSpeedData.smoothAirSpeed * 0.36 ;
          // from cm/sec to 1/10 km/h
          #else
            airSpeedData.airSpeed.value = airSpeedData.smoothAirSpeed * 0.1943844492 ;
          // from cm/sec to 1/10 knot/h
          #endif
        }
        else
        {
          airSpeedData.airSpeed.value = 0 ;
        }   
          airSpeedData.airSpeed.available = true ;
 
      }  // end of process every xx millis

    } // end of process every 2 millis

  } // End of readSensor


**********************************************************************************************
**********************************************************************************************
// * 0Xs_sdp3x.h ***** Version, in der die DEBUG Einfügungen entfernt wurden. ****************
// * Damit ist die Datenbearbeitung übersichtlicher erkennbar. ******** Tempo 17.Mai 2020 ****

#ifndef OXS_sdp3x_h
#define OXS_sdp3x_h

  #include <Arduino.h>
  #include "oXs_config_basic.h"
  #include "oXs_config_advanced.h"
  #include "oXs_config_macros.h"
  #include "I2C.h"
  #include "oXs_4525.h"

  /*
  struct AIRSPEEDDATA
  {
    float temperatureSdp3x;     // in Celsius , used when compensation is calculated
    float difPressure;          // in Pa
    struct ONE_MEASUREMENT airSpeed ;        // in 1/10 km/h or 1/10 knots (no decimal)
    float smoothAirSpeed ;    //cm/sec ; use in glider ratio
    //unsigned long lastCommand2Micros ; // used to avoid some task
    // (reading voltage sensor, currentsensor, ..) when barometric data should
    // be soon available for reading
    // = micro divided by 2 to avoid overflow on comparison 
  };
  */

  extern float actualPressure ;

  class OXS_SDP3X
  {
    public:

      OXS_SDP3X(uint8_t addr) ;

      AIRSPEEDDATA airSpeedData ;
      void setup();
      void  readSensor();

    private:
      uint8_t _addr;
      uint8_t I2CErrorCodeSdp3x ;
      float dpScaleSdp3x;           // differential pressure scale factor
      uint8_t data[2];              // get 2 bytes returned by SDP3X
      float temperatureKelvinSdp3x; // in Kelvin
    //float difPressure;            // in Pa
 
      float smoothDifPressure ;  // in Pa
      float expoSmooth_auto ;
      unsigned long  nextAirSpeedMillis ;     //next time that airspeed must be available
      unsigned long  nextPressureReadMillis ; // next time that pressure can be read
                                              // (datasheet says O.5msec)
 
  }; // end class OXS_SDP3X

  extern int32_t test1Value ;// used in order to test the transmission of any value
  extern bool test1ValueAvailable ;
  extern int32_t test2Value ;// used in order to test the transmission of any value
  extern bool test2ValueAvailable ;
  extern int32_t test3Value ;// used in order to test the transmission of any value
  extern bool test3ValueAvailable ;

#endif // OXS_SDP3X

**********************************************************************************************
**********************************************************************************************
 
FPV1

Banggood

Oben Unten