diff options
| author | Dawsyn Schraiber <[email protected]> | 2025-06-20 00:10:22 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-06-20 00:10:22 -0400 |
| commit | 5375c6d876f115a2bd75ec45796e5333ba928082 (patch) | |
| tree | 51d8701b6e0b10b3171c8a146304a3accf57d150 /include/adxl375.hpp | |
| parent | e07f105022f3ad6e3c6ee2dfe4cc01eb91c1f373 (diff) | |
| download | active-drag-system-5375c6d876f115a2bd75ec45796e5333ba928082.tar.gz active-drag-system-5375c6d876f115a2bd75ec45796e5333ba928082.tar.bz2 active-drag-system-5375c6d876f115a2bd75ec45796e5333ba928082.zip | |
# Dawsyn's Final Commit
This one is a little emotional as this is my final commit in this repository and as a member of Rocketry at Virginia Tech. This merges the changes seen in the branch known as 'big_kahuna' into main. This is the version of the ADS software as seen on [Roadkill](https://drive.google.com/file/d/120BvI-0ntliHo6i9UxcCn2pXAl-JsdP_/view?usp=drive_link) in the 2025 IREC competition. There are bound to be bugs, but I have found it useful to have the final competition version to be the one present on main at the end of every academic year. Hopefully this is useful to the next lead.
## Primary Changes
+ NEW I2C drivers to support sensors present on new ADS custom PCB
+ NEW logging library found in separate repository and pulled in as submodule ([pico-logger](https://github.com/rocketryvt/pico-logger))
+ No longer dependent on different flash chip from one used for code storage! Compile executable as RP2040 'copy-to-ram' type to increase flash read/write speeds!
+ NEW fixed-point libraries to allow for increased performance and sensor sampling speeds on RP2040 that lacks FPU
+ FreeRTOS Simultaneous Multi-processing (SMP) architecture for task handling and easier introduction / testing of new features
+ Serial monitor / command system with task performance monitoring commands
+ WORKING Kalman filter that takes altitude from barometer as measurement and z-axis acceleration from IMU as control to generate state vector containing filtered altitude and vertical velocity
+ NEW CFD equations from the Ben-ogrithm (to replace the Chen-ogrithm) that includes:
+ Apogee prediction model that takes current drag force, altitude, and vertical velocity
+ Current Drag Force equation based on current deployment and vertical velocity to use for Apogee Prediction model
+ Desired Drag force equation based on current altitude and vertical velocity to generate what drag force is needed to reach 10K ft
+ Deployment percentage equation based on current velocity and desired drag force to map to flap deployment percentage
Diffstat (limited to 'include/adxl375.hpp')
| -rw-r--r-- | include/adxl375.hpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/include/adxl375.hpp b/include/adxl375.hpp new file mode 100644 index 0000000..21fe82c --- /dev/null +++ b/include/adxl375.hpp @@ -0,0 +1,265 @@ +#pragma once + +#include <stdint.h> + +#include <hardware/i2c.h> + +#if ( USE_FREERTOS == 1) +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "portmacro.h" +#include "projdefs.h" +#include "serial.hpp" +#include "task.h" +#include "semphr.h" +#endif + +#define ADXL375_I2C_ADDRESS 0x1D + +// DEVID [Validation] +#define R_ADXL375_DEVID 0x00 +#define B_ADXL375_DEVID_VALUE 0xE5 + +// THRESH_SHOCK [Configuration, Threshold for shock interrupt (780mG/LSB)] +#define R_ADXL375_THRESH_SHOCK 0x1D +typedef uint8_t ADXL375_THRESH_SHOCK; + +// OFSX, OFSY, OFSZ [Configuration, User-configured offset of (0.196 g/LSB)] +#define R_ADXL375_OFFSET_X 0x1E +typedef uint8_t ADXL375_OFFSET_X; + +#define R_ADXL375_OFFSET_Y 0x1F +typedef uint8_t ADXL375_OFFSET_Y; + +#define R_ADXL375_OFFSET_Z 0x20 +typedef uint8_t ADXL375_OFFSET_Z; + +// DUR [Configuration, Time above threshold as single shock interrupt (625us/LSB)] +#define R_ADXL375_DUR 0x21 +typedef uint8_t ADXL375_DURATION; + +// LATENT [Configuration, Time after first shock interrupt second can occur (1.25ms/LSB)] +#define R_ADXL375_LATENT 0x22 +typedef uint8_t ADXL375_LATENT; + +// WINDOW [Configuration, Time after latent period second shock can begin (1.25ms/LSB)] +#define R_ADXL375_WINDOW 0x23 +typedef uint8_t ADXL375_WINDOW; + +// THRESH_ACT [Configuration, Threshold value for detecting activity (780mg/LSB)] +#define R_ADXL375_THRESH_ACT 0x24 +typedef uint8_t ADXL375_THRESH_ACT; + +// THRESH_INACT [Configuration, Threshold value for detecting inactivity (780mg/LSB)] +#define R_ADXL375_THRESH_INACT 0x25 +typedef uint8_t ADXL375_THRESH_INACT; + +// TIME_INACT [Configuration, Time below threshold as inactivity (1s/LSB)] +#define R_ADXL375_TIME_INACT 0x26 +typedef uint8_t ADXL375_TIME_INACT; + +// ACT_INACT_CTL [Configuration, Activity/Inactivity interrupts enable and AC/DC coupling] +#define R_ADXL375_ACT_INACT_CTL 0x27 +typedef union { + struct { + bool INACT_Z_ENABLE :1; + bool INACT_Y_ENABLE :1; + bool INACT_X_ENABLE :1; + bool INACT_AC_DC :1; + bool ACT_Z_ENABLE :1; + bool ACT_Y_ENABLE :1; + bool ACT_X_ENABLE :1; + bool ACT_AC_DC :1; + } fields; + uint8_t data; +} ADXL375_ACT_INACT_CTL; + +// SHOCK_AXES [Configuration, axes used in shock interrupt] +#define R_ADXL375_SHOCK_AXES 0x2A +typedef union { + struct { + bool SHOCK_Z_ENABLE :1; //Z-Axis shock interrupt enable + bool SHOCK_Y_ENABLE :1; //Y-Axis shock interrupt enable + bool SHOCK_X_ENABLE :1; //X-Axis shock interrupt enable + bool SUPPRESS :1; //Suppresses double shock detection + uint8_t RESERVED :4; //Reserved + } fields; + uint8_t data; +} ADXL375_SHOCK_AXES; + +// ACT_SHOCK_STATUS [Status, First axis involved in an activity or shock event] +#define R_ADXL375_ACT_SHOCK_STATUS 0x2B +typedef union { + struct { + bool SHOCK_Z_SOURCE :1; + bool SHOCK_Y_SOURCE :1; + bool SHOCK_X_SOURCE :1; + bool ASLEEP :1; + bool ACT_Z_SOURCE :1; + bool ACT_Y_SOURCE :1; + bool ACT_X_SOURCE :1; + bool RESERVED :1; + } fields; + uint8_t data; +} ADXL375_ACT_SHOCK_STATUS; + +// BW_RATE [Configuration, Low Power Mode and ODR] +#define R_ADXL375_BW_RATE 0x2C +typedef union { + struct { + uint8_t RATE :4; //ODR configuration + bool LOW_POWER :1; //Low-power/Normal mode configuration + uint8_t RESERVED :3; //Reserved + } fields; + uint8_t data; +} ADXL375_BW_RATE; +#define B_ADXL375_ODR_100_HZ 0x0A +#define B_ADXL375_ODR_400_HZ 0x0C +#define B_ADXL375_ODR_800_HZ 0x0D +#define B_ADXL375_ODR_3200_HZ 0x0F +#define B_ADXL375_BW_RATE_LOW_POWER_MODE 0b1 +#define B_ADXL375_BW_RATE_NORMAL_POWER_MODE 0b0 + +// POWER_CTL [State Configuration, Measurement mode (and sleep settings)] +#define R_ADXL375_POWER_CTL 0x2D +typedef union { + struct { + uint8_t WAKEUP :2; //Sampling rate control during sleep mode + bool SLEEP :1; //Sleep mode configuration + bool MEASURE :1; //Measurement/Standby mode configuration + bool AUTO_SLEEP :1; //Auto sleep function enable + bool LINK :1; //Link activity and inactivity functions + bool RESERVED :1; //Reserved + } fields; + uint8_t data; +} ADXL375_POWER_CTL; + +// INT_ENABLE [State Configuration, interrupt enabling] +#define R_ADXL375_INT_ENABLE 0x2E +typedef union { + struct { + bool OVERRUN :1; //FIFO buffer overwrite interrupt enable + bool WATERMARK :1; //??? TODO: Figure out watermark bits + bool RESERVED :1; //Reserved + bool INACTIVITY :1; //Inactivity interrupt enable + bool ACTIVITY :1; //Activity interrupt enable + bool DOUBLE_SHOCK :1; //Double shock interrupt enable + bool SINGLE_SHOCK :1; //Single shock interrupt enable + bool DATA_READY :1; //FIFO buffer new data interrupt enable + } fields; + uint8_t data; +} ADXL375_INT_ENABLE; + +// INT_MAP [Configuration, Interrupt --> Pin mapping (0 = INT1, 1 = INT2) */ +#define R_ADXL375_INT_MAP 0x2F +typedef union { + struct { + bool OVERRUN :1; //FIFO buffer overwrite interrupt + bool WATERMARK :1; //??? TODO: Figure out watermark bits + bool RESERVED :1; //Reserved + bool INACTIVITY :1; //Inactivity interrupt + bool ACTIVITY :1; //Activity interrupt + bool DOUBLE_SHOCK :1; //Double shock interrupt + bool SINGLE_SHOCK :1; //Single shock interrupt + bool DATA_READY :1; //FIFO buffer new data interrupt + } fields; + uint8_t data; +} ADXL375_INT_MAP; + +// INT_SOURCE [Status, Source of interrupt (read to clear SINGLE_SHOCK interrupt) */ +#define R_ADXL375_INT_SOURCE 0x30 +typedef union { + struct { + bool OVERRUN :1; //FIFO buffer overwrite interrupt + bool WATERMARK :1; //??? TODO: Figure out watermark bits + bool RESERVED :1; //Reserved + bool INACTIVITY :1; //Inactivity interrupt + bool ACTIVITY :1; //Activity interrupt + bool DOUBLE_SHOCK :1; //Double shock interrupt + bool SINGLE_SHOCK :1; //Single shock interrupt + bool DATA_READY :1; //FIFO buffer new data interrupt + } fields; + uint8_t data; +} ADXL375_INT_SOURCE; + +// DATA_FORMAT [Configuration, Data output style/formatting (variety of things)] */ +#define R_ADXL375_DATA_FORMAT 0x31 +typedef union { + struct { + uint8_t RESERVED :2; //Reserved + bool JUSTIFY :1; //Left(MSB)/Right(LSB, Sign extended) output justification + uint8_t RESERVED_ :2; //Reserved + bool INT_INVERT :1; //Interrupt pin polarity configuration + bool SPI :1; //SPI 3/4 wire mode configuration + bool SELF_TEST :1; //Configure self-test mode + } fields; + uint8_t data; +} ADXL375_DATA_FORMAT; +#define B_ADXL375_DATA_FORMAT_JUSTIFY_RIGHT 0b0 +#define B_ADXL375_DATA_FORMAT_JUSTIFY_LEFT 0b1 +#define B_ADXL375_DATA_FORMAT_INTERRUPT_ACTIVE_HIGH 0b0 +#define B_ADXL375_DATA_FORMAT_INTERRUPT_ACTIVE_LOW 0b1 +#define B_ADXL375_DATA_FORMAT_ENABLE_SELF_TEST 0b1 +#define B_ADXL375_DATA_FORMAT_DISABLE_SELF_TEST 0b0 + +// DATAX0-DATAZ1 [Output, 16b data for X/Y/Z (DATA_1 is MSByte, DATA_0 is LSByte) +#define R_ADXL375_DATAX0 0x32 +#define R_ADXL375_DATAX1 0x33 +#define R_ADXL375_DATAY0 0x34 +#define R_ADXL375_DATAY1 0x35 +#define R_ADXL375_DATAZ0 0x36 +#define R_ADXL375_DATAZ1 0x37 +#define S_ADXL375_SCALE_FACTOR 20.5 // 1 LSB / 20.5 + +#define ADXL375_SAMPLE_RATE_HZ 500 + +class ADXL375 { + public: + ADXL375(i2c_inst_t* i2c) : i2c {i2c} {}; + + void initialize(); + + void sample(); + + int16_t get_ax() { return ax; } + int16_t get_ay() { return ay; } + int16_t get_az() { return az; } + + static float scale(int16_t unscaled) { return ((float) unscaled) / S_ADXL375_SCALE_FACTOR; } + +#if (USE_FREERTOS == 1) + static void update_adxl375_task(void *pvParameters); + + TaskHandle_t update_task_handle = NULL; +#endif + + private: + const uint8_t addr = ADXL375_I2C_ADDRESS; + + i2c_inst_t* i2c; + + uint8_t buffer[16]; + + ADXL375_THRESH_SHOCK shock_threshold; + ADXL375_OFFSET_X offset_ax; + ADXL375_OFFSET_Y offset_ay; + ADXL375_OFFSET_Z offset_az; + ADXL375_DURATION shock_duration; + ADXL375_LATENT latent_shock; + ADXL375_WINDOW window_shock; + ADXL375_THRESH_ACT activity_threshold; + ADXL375_THRESH_INACT inactivity_threshold; + ADXL375_TIME_INACT inactivity_duraction; + ADXL375_ACT_INACT_CTL act_inact_ctl; + ADXL375_SHOCK_AXES shock_axes; + ADXL375_ACT_SHOCK_STATUS act_shock_status; + ADXL375_BW_RATE bw_rate; + ADXL375_POWER_CTL power_ctl; + ADXL375_INT_ENABLE int_enable; + ADXL375_INT_MAP int_map; + ADXL375_INT_SOURCE int_source; + ADXL375_DATA_FORMAT data_format; + + int16_t ax, ay, az; +}; + |
