Infineon Team
Published © GPL3+

DPS368 going-up and down - more than a rocket!

DIY Rocket not only for fun but learning about barometric pressure with the help of Arduino IDE & Infineon's KIT_DPS368_2GO.

IntermediateFull instructions provided2 hours451
DPS368 going-up and down - more than a rocket!

Things used in this project

Hardware components

Infineon DPS368 2Go
×1
Adafruit NeoPixel Digital RGB LED Strip 144 LED, 1m White
Adafruit NeoPixel Digital RGB LED Strip 144 LED, 1m White
×1

Story

Read more

Custom parts and enclosures

STL: Rocket (outer form)

To be used with your slicer

FreeCAD Rocket 3D-print sources

STL: Rocket (interior 1)

To be used with your slicer

STL: Rocket (interior 2)

To be used with your slicer

Schematics

Schematic - How to connect the LED string to the Board

Code

Arduino code

C/C++
Arduino IDE Version: 2.2.1
+ XENSIV Digital Pressure Sensor v1.0.0 by Infineon Technologies
+ Adafruit NeoPixel v1.12.0 by Adafruit
Hadware: KIT_DPS368_2GO (XMC1100 XMC2Go)
/******************************************************************************
* Description: 
* DPS368 going-up and down - more than a rocket!
* DIY Rocket not only for fun but learning about barometric pressure 
* with the help of Arduino IDE & Infineon's KIT_DPS368_2GO (XMC1100 XMC2Go)
* https://www.hackster.io/projects/e62bd0
* 2023/12, Holger Wech
*
* Disclaimer: 
* THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*******************************************************************************/

#include <Dps3xx.h>
#include <LED.h>
#include <Adafruit_NeoPixel.h>

// Dps3xx Opject
Dps3xx Dps3xxPressureSensor = Dps3xx();

//
// Altimeter
//
#define MOLAR_MASS                  (0.02896) // Mean molar mass of earth's air in kg/mol
#define GRAVITATIONAL_ACCEL         (9.80620) // Acceleration due to gravity in m/(s^2)
#define GAS_CONSTANT                (8.314)   // Universal gas constant in J/Kmol
#define PRESSURE_AT_SEA_LEVEL       (1013)

/* Structure for Altimeter data */
    typedef struct{
        float temperature;
        float pressure;
        float height_base_pressure;
        float height_absolute;
        float height_relative;
    }Altimeter_t;

Altimeter_t stcAltimeter;

/*******************************************************************************
** Function Name: AltimeterReadSensorData()
********************************************************************************
** Summary:
**  The function reads the actual pressure and temperature value from DPS3xx sensor
**  and stores the values to dedicated global variables that can be read by functions
**  AltimeterGetPressure(), AltimeterGetTemperature()
** 
** \retval error code (should be CY_RSLT_SUCCESS)
*******************************************************************************/
uint32_t  AltimeterGetSensorData()
{
  int32_t ret1, ret2;

  /*
   * lets the Dps3xx perform a Single temperature measurement with the last (or standard) configuration
   * The result will be written to the parameter temperature
   * ret = Dps3xxPressureSensor.measureTempOnce(temperature);
   * the commented line below does exactly the same as the one above, but you can also config the precision
   * oversampling can be a value from 0 to 7
   * the Dps 3xx will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision
   * measurements with higher precision take more time, consult datasheet for more information
   */
  ret1 = Dps3xxPressureSensor.measureTempOnce(stcAltimeter.temperature, 7);
  
  /*
   * Pressure measurement behaves like temperature measurement
   * ret = Dps3xxPressureSensor.measurePressureOnce(pressure);
   */
  ret2 = Dps3xxPressureSensor.measurePressureOnce(stcAltimeter.pressure, 7);
  
  if (ret1)
  {
      Serial.println("Sensor Temp error!");    
      return (1);
  }
  
   else if (ret2)
   {
      Serial.println("Sensor Pressure error!");  
      return (2);
   }
   else
   {
    return (0);
   }
}

/*******************************************************************************
** \brief Function AltimeterReadPressure()
**
** The function returns the last read pressure sensor.
**
** \pre Call AltimeterGetSensorData() before reading the data
**
** \param [in]  none
**
** \retval float stcAltimeter.pressure
 *******************************************************************************/
float AltimeterReadPressure()
{
   return (stcAltimeter.pressure);
}

/*******************************************************************************
** \brief Function AltimeterReadTemperature()
**
** The function returns the last read pressure sensor.
**
** \pre Call AltimeterGetSensorData() before reading the data
**
** \param [in]  none
**
** \retval float stcAltimeter.temperature
 *******************************************************************************/
float AltimeterReadTemperature()
{
   return (stcAltimeter.temperature);
}

/*******************************************************************************
** \brief Function AltimeterReadBaseHeightPressure()
**
** The function returns the last saved AltimeterReadBaseHeightPressure.
**
** \pre AltimeterSetBaseHeight before reading the data
**
** \param [in]  none
**
** \retval float stcAltimeter.height_base_pressure
 *******************************************************************************/
float AltimeterReadBaseHeightPressure()
{
    return (stcAltimeter.height_base_pressure); 
}

/*******************************************************************************
** \brief Function AltimeterReadHeightAbsolute()
**
** The function returns the last calculated absolute height
**
** \pre Call AltimeterCalcHeightAbsolute() before reading the data
**
** \param [in]  none
**
** \retval float stcAltimeter.height_absolute
 *******************************************************************************/
float AltimeterReadHeightAbsolute()
{
    return (stcAltimeter.height_absolute);
}

/*******************************************************************************
** \brief Function AltimeterReadHeightRelative()
**
** The function returns the last calculated relative height
**
** \pre Call AltimeterCalcHeightAbsolute() before reading the data
**
** \param [in]  none
**
** \retval float stcAltimeter.height_relative
 *******************************************************************************/
float AltimeterReadHeightRelative()
{
    return (stcAltimeter.height_relative);
}
    
/*******************************************************************************
** \brief Function AltimeterSetBaseHeight()
**
** The function is called when the user chooses the base height
** what refelcts the '0 Meter' reference height and 
** stores the value in stcAltimeter data structure.
** This value is used as a reference for calculation of relative height.
**
** \pre Call AltimeterGetSensorData() before reading the data
**
** \param [in]  none
**
** \retval none
 *******************************************************************************/
void AltimeterSetBaseHeight()
{
    stcAltimeter.height_base_pressure = stcAltimeter.pressure;
}

/*******************************************************************************
** \brief Function AltimeterCalcHeightAbsolute()
**
** The function calculates the height of the sensor above sea level and 
** stores the value in stcAltimeter data structure.
**
** \pre Call AltimeterGetSensorData() before calculating the height
**
** \param [in]  none
**
** \retval none
 *******************************************************************************/
void AltimeterCalcHeightAbsolute()
{
  float pressure_ratio;
    float temp_constant;
    float absolute_height;
  float temp_val;

  /* Convert pressure in pascal to pressure in mbar */
    float pressure_mbar = stcAltimeter.pressure/100;

    /* Calculating the ration of pressure at sea level and current pressure */
  pressure_ratio = (PRESSURE_AT_SEA_LEVEL/pressure_mbar);

  /* Converting temperature from Celcius to Kelvin */
  temp_val = (stcAltimeter.temperature + 273.15f);

    /* Using the Barometric formula. Refer to the Blog mentioned in the readme for further details */
  temp_constant = ((GAS_CONSTANT * temp_val)/(MOLAR_MASS * GRAVITATIONAL_ACCEL));
  stcAltimeter.height_absolute = ((temp_constant * log(pressure_ratio)));
}

/*******************************************************************************
** \brief Function AltimeterCalcHeightRelative()
**
** The function calculates the height of the sensor above or below the
** chosen base height and stores the value in stcAltimeter data structure.
**
** \pre Call AltimeterGetSensorData() before calculating the height
**
** \param [in]  none
**
** \retval none
 *******************************************************************************/
void AltimeterCalcHeightRelative(void)
{
    float pressure_ratio;
    float temp_constant;
    float relative_height;
    float temp_val;

    /* Absolute height difference calculation */
    pressure_ratio = (stcAltimeter.height_base_pressure / stcAltimeter.pressure);

    /* Converting temperature from Celcius to Kelvin */
    temp_val = stcAltimeter.temperature + 273.15f;
    temp_constant = ((GAS_CONSTANT * temp_val)/(MOLAR_MASS * GRAVITATIONAL_ACCEL));
    stcAltimeter.height_relative = ((temp_constant * log(pressure_ratio)) * 100);
}

//
// NEOPIXEL / WS2812
//

#define WS2812_PIN 1
#define NUMPIXELS 14

Adafruit_NeoPixel pixels(NUMPIXELS, WS2812_PIN, NEO_GRB + NEO_KHZ800);

void setAllPixel(uint32_t c)
{
  uint16_t i;
  for (i=0; i<NUMPIXELS; i++)
  {
      pixels.setPixelColor(i, c);
  }
}

void setPixelLeftAll(uint32_t c)
{
  uint16_t i;
  for (i=0; i<NUMPIXELS; i=i+2)
  {
      pixels.setPixelColor(i, c);
  }
}

void setPixelLeft(uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3, uint32_t c4)
{
  pixels.setPixelColor(4, c0);
  pixels.setPixelColor(3, c1);
  pixels.setPixelColor(2, c2);
  pixels.setPixelColor(1, c3);
  pixels.setPixelColor(0, c4);
}

void setPixelRightAll(uint32_t c)
{
  uint16_t i;
  for (i=1; i<NUMPIXELS; i=i+2)
  {
      pixels.setPixelColor(i, c);
  }
}

void setPixelRight(uint32_t c0, uint32_t c1, uint32_t c2, uint32_t c3, uint32_t c4)
{
  pixels.setPixelColor(5, c0);
  pixels.setPixelColor(6, c1);
  pixels.setPixelColor(7, c2);
  pixels.setPixelColor(8, c3);
  pixels.setPixelColor(9, c4);
}

//
// Simple LED just for testing
//
/* Create an LED object just for testing */
LED Led;

//
// GLOBAL VARIABLES
//

typedef enum {
    RS_INIT = 0,
    RS_START,
    RS_FLY,
    RS_BACK,
    } enRocketState_t;

enRocketState_t enRocketState = RS_INIT;

void setup()
{
  Led.Add( LED1 );           // Configure the LEDs
  Led.Off( LED1 );           // Set default state of LEDs
 
  Led.Add( LED2 );           // Configure the LEDs
  Led.On( LED2 );            // Set default state of LEDs

  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pixels.setBrightness(255);

  Serial.begin(115200);
  while (!Serial);

  /*
   * Call begin to initialize Dps3xxPressureSensor
   * The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given.
   * Dps3xxPressureSensor.begin(Wire, 0x76);
   * Use the line below instead of the one above to use the default I2C address.
   * if you are using the Pressure 3 click Board, you need 0x76
   */
  Dps3xxPressureSensor.begin(Wire);

  Serial.println("Init complete!");

  // Initialize Altimeter - Store Ground-Floor '0-meter' value

  delay(200);
  AltimeterGetSensorData();
  delay(200);
  AltimeterGetSensorData();
  delay(200);
  AltimeterGetSensorData();
  delay(200);
  
  if (0 != AltimeterGetSensorData())
  {
      Serial.println("*** ERROR Sensor");
  }
  else
  {
    Serial.print("Pressure   : ");
    Serial.print(AltimeterReadPressure());
    Serial.println(" Pascal");

    Serial.print("Temperature: ");
    Serial.print(AltimeterReadTemperature());
    Serial.println(" Celsius");
  }
  
  AltimeterCalcHeightAbsolute();
  AltimeterSetBaseHeight();         // Store Ground-Floor '0-meter' value
  AltimeterCalcHeightRelative();

  Serial.print("Absolute Height: "); Serial.print(AltimeterReadHeightAbsolute()); Serial.println(" m");
  Serial.print("Relative Height: "); Serial.print(AltimeterReadHeightRelative()); Serial.println(" m");

  delay(200);

  enRocketState = RS_INIT;
}

uint32_t u32Time;
uint32_t u32TimeAltimeter;

uint32_t u32InitLed;

void loop()
{
  uint32_t u32HeightMeter;

  u32Time = u32Time + 1;
  /* 
  // For testing the loop timer
  if (u32Time >= 50)
  {
    u32Time = 0;
    Serial.println("1 sec");
  }
  */

  /*
  u32TimeAltimeter = u32TimeAltimeter + 1;
  if (u32TimeAltimeter >= 10)
  {
    //
    // Altimeter Height calculation
    //
    
    if (0 != AltimeterGetSensorData())
    {
        Serial.println("*** ERROR Sensor");
    }
    else
    {
      AltimeterCalcHeightRelative();
      //Serial.print("Relative Height: "); Serial.print(AltimeterReadHeightRelative()/100); Serial.print(" m  @ Temperature: "); Serial.print(AltimeterReadTemperature()); Serial.println(" Celcius");
    }
  }
  */  

  switch (enRocketState)
  {
    case RS_INIT : // Ignition phase ... wait for take-off

              u32InitLed = u32InitLed + 1;
              //Serial.print(u32InitLed); Serial.println(" : u32InitLed");
              if (2 == u32InitLed) 
              { 
                setPixelLeft (pixels.Color(20, 20, 20), pixels.Color( 50,  50,  50), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20));
                setPixelRight(pixels.Color(20, 20, 20), pixels.Color( 50,  50,  50), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20));
                pixels.show();
              } else
              if (4 == u32InitLed) 
              { 
                setPixelLeft (pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color( 50,  50,  50), pixels.Color(100,100,100), pixels.Color(20, 20, 20));
                setPixelRight(pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color( 50,  50,  50), pixels.Color(50,  50, 50), pixels.Color(20, 20, 20));
                pixels.show();
              } else
              if (6 == u32InitLed) 
              { 
                setPixelLeft (pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(200, 100,  0), pixels.Color(200, 200,   0), pixels.Color(20, 20, 20));
                setPixelRight(pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(200, 100,  0), pixels.Color(200, 200,   0), pixels.Color(20, 20, 20));
                pixels.show();
              } else
              if (10 == u32InitLed) 
              { 
                setPixelLeft (pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(100, 100,   0), pixels.Color(255, 0, 0));
                setPixelRight(pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(100, 100,   0), pixels.Color(255, 0, 0));
                pixels.show();

                if (0 != AltimeterGetSensorData())
                {
                    Serial.println("*** ERROR Sensor");
                }
                else
                {
                  AltimeterCalcHeightRelative();
                  //Serial.print("Relative Height: "); Serial.print(AltimeterReadHeightRelative()/100); Serial.print(" m  @ Temperature: "); Serial.print(AltimeterReadTemperature()); Serial.println(" Celcius");
                }

                if (AltimeterReadHeightRelative() > 35)
                {
                  enRocketState = RS_START;
                }
                
              } else
              if (15 == u32InitLed) 
              { 
                u32InitLed = 0; 
                setPixelLeft (pixels.Color(50,  50,  50), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20));
                setPixelRight(pixels.Color(50,  50,  50), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20), pixels.Color(20, 20, 20));
                pixels.show();
              }
             
              delay(20);
              
              break;
              
    case RS_START : // Ready for start 'hysteresis' Does it fly or not?
                
                if (0 != AltimeterGetSensorData())
                {
                    Serial.println("*** ERROR Sensor");
                }
                else
                {
                  AltimeterCalcHeightRelative();
                  //Serial.print("Relative Height: "); Serial.print(AltimeterReadHeightRelative()/100); Serial.print(" m  @ Temperature: "); Serial.print(AltimeterReadTemperature()); Serial.println(" Celcius");
                }

                if (AltimeterReadHeightRelative() > 40)
                {
                  enRocketState = RS_FLY;
                }
                if (AltimeterReadHeightRelative() < 20)
                {
                  enRocketState = RS_INIT;
                }
                delay(100);
                break;
                
    case RS_FLY : // Change the color depending on the height

                // Get the altitude
                
                if (0 != AltimeterGetSensorData())
                {
                    Serial.println("*** ERROR Sensor");
                }
                else
                {
                  AltimeterCalcHeightRelative();
                  //Serial.print("Relative Height: "); Serial.print(AltimeterReadHeightRelative()/100); Serial.print(" m  @ Temperature: "); Serial.print(AltimeterReadTemperature()); Serial.println(" Celcius");
                }
                
                /* 
                // Height values used for the lift video, 5 floors

                if       (AltimeterReadHeightRelative() > 1640.0f) { setAllPixel(pixels.Color(0xFF, 0xFF, 0xFF)); }
                else  if (AltimeterReadHeightRelative() > 1375.0f) { setAllPixel(pixels.Color(0xFF, 0x00, 0x00)); }
                else  if (AltimeterReadHeightRelative() > 1110.0f) { setAllPixel(pixels.Color(0x00, 0x00, 0xFF)); }
                else  if (AltimeterReadHeightRelative() >  845.0f) { setAllPixel(pixels.Color(0xFF, 0x00, 0xFF)); }
                else  if (AltimeterReadHeightRelative() >  580.0f) { setAllPixel(pixels.Color(0x00, 0xFF, 0x00)); }
                else  if (AltimeterReadHeightRelative() >  315.0f) { setAllPixel(pixels.Color(0x00, 0xFF, 0xFF)); }
                else  if (AltimeterReadHeightRelative() >   50.0f) { setAllPixel(pixels.Color(0xFF, 0xFF, 0x00)); }
                else  if (AltimeterReadHeightRelative() <   20.0f) { setAllPixel(pixels.Color(0xFF, 0xFF, 0xFF)); enRocketState = RS_BACK; }
                */

                if       (AltimeterReadHeightRelative() > 5000.0f) { setAllPixel(pixels.Color(0xFF, 0xFF, 0xFF)); }
                else  if (AltimeterReadHeightRelative() > 4000.0f) { setAllPixel(pixels.Color(0xFF, 0x00, 0x00)); }
                else  if (AltimeterReadHeightRelative() > 3000.0f) { setAllPixel(pixels.Color(0x00, 0x00, 0xFF)); }
                else  if (AltimeterReadHeightRelative() > 2000.0f) { setAllPixel(pixels.Color(0xFF, 0x00, 0xFF)); }
                else  if (AltimeterReadHeightRelative() > 1000.0f) { setAllPixel(pixels.Color(0x00, 0xFF, 0x00)); }
                else  if (AltimeterReadHeightRelative() >  350.0f) { setAllPixel(pixels.Color(0x00, 0xFF, 0xFF)); }
                else  if (AltimeterReadHeightRelative() >   50.0f) { setAllPixel(pixels.Color(0xFF, 0xFF, 0x00)); }
                else  if (AltimeterReadHeightRelative() <   20.0f) { setAllPixel(pixels.Color(0xFF, 0xFF, 0xFF)); enRocketState = RS_BACK; }

                pixels.show();
                delay(50);
                break;

    
    case RS_BACK : // wait for restart (switch off/on)
                    break;
                    
    default : enRocketState = RS_INIT;

  } // switch (enRocketState)

} // void loop()

/* END */

Credits

Infineon Team
100 projects • 157 followers
Contact

Comments

Please log in or sign up to comment.