Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

From the highest level, most sensor drivers (though not all), will belong to 2 independent threads. One is whatever the thread you need the data in, which is, by design, exclusively SensorFusion, while the second is the thread who’s whose exclusive job is to sample the sensor at a regular interval. The reason that second thread is required is that the process of collecting data from the sensor via SPI, I2C or whatever else, takes time. If we were only using a single thread, that thread would have to wait for that transfer to occur before it could move on , which is unacceptable for, for example, the state machines, which need to run at a very strict rate. The second thread ensures we can begin the transaction with the sensor so that by the time the data is needed by the first thread, it can be directly picked up without having to wait. The reason this isn’t the case with all sensors is that some sensors are always spewing data regardless of whether of whether we’re asking for it (gps for example) and others might be analog, meaning their data is always available to read at our ADCs (airspeed for example).The rest of this page details that general design by referring to this sample.

Sample sensor interface

Code Block
breakoutModewide
languagecpp
/**
 * AltimeterIMU Sensor Functions and Part Number Selection.
 * Available IMU driver(s): BMX160
 * AuthorsAuthor(s): Lucy Gong, Dhruv Rawat, SahilAnthony KaleBerbari
 */

#ifndef ALTIMETERIMU_HPP
#define ALTIMETERIMU_HPP

#include <cstdint>

/***********************************************************************************************************************
 * Definitions
 **********************************************************************************************************************/

struct AltimeterDataIMUData_t {

    float pressure, altitude, magx, magy, magz; // TODO although the BMX 160 has a magnetometer, it seems to produce bizarre results.More investigation needs to be done. Figuring out what the RHall register does is likely a part of that.
    float accx, accy, accz;
    float gyrx, gyry, gyrz; 
    float temp; 

    bool isDataNew;
    int statussensorStatus; //TBD but probably 0 = SUCCESS, -1 = FAIL, 1 = BUSY
};

/***********************************************************************************************************************
 * Prototypes
 *********************************************************************************************************************/

class IMU Altimeter{
    public:
        /**
         * Triggers interrupt for new altimeter measurement - stores raw data in variablesBegins a transaction with the IMU.
         * This function is non blocking and returns right away, data will be stored inside the module as it arrives.
         * To achieve synchronous data, this function must be called synchronously.
         * */
        virtual void Begin_Measuring() = 0; 

        /**GetResult should:*
         * Retrieves any data already received by the imu.
         * 1. Reset dataIsNew flag
 If no new data is available, the appropriate flag will be set in the return struct.
         * 2. Transfers raw data from variables to struct All contents of the return struct, apart from the isDataNew flag, are undefined unless isDataNew is set to 1.
         * 3. Updates utcTime and status values in struct as well This function is non blocking and returns right away.
         * @param[in]       Data        reference to the results struct.
         * */
        virtual void GetResult(AltimeterDataIMUData_t *&Data) = 0;
//
};

class MS5637 BMX160: public Altimeter IMU{
    public:

       MS5637(const MS5637*) = delete; //Apparently if you try to copy a singleton this will give you errors? /**
         * This module is built as a singleton. Thus to access a BMX160 object, this function must be called.
         * Only a single BMX160 object will ever be created and will be shared by all callers of this function.
         * @return      IMU        reference to the singleton object.
         static* MS5637*/
GetInstance();        static void Begin_MeasuringIMU& getInstance();

        /**
       void GetResult(AltimeterData_t *Data); Deletes the constructor to private:disallow users to instantiate objects.
    MS5637(); //Constructor can never be called* muwhahaha*/
        staticBMX160(const MS5637BMX160* s_Instance) = delete;

        void beginCollectingTemperatureBegin_Measuring();
        void beginCollectingPressure();GetResult(IMUData_t &Data);

    private:

       uint32_t getNewestMeasurementBMX160();

       uint32_t readFromMS5637(uint8_t commandToWrite void SetAllPowerModesToNormal(void);
        void getRawPressureAndTemperature(float *displayPressure, float *displayTemperature, float *displayAltitudeConfigAcc(void);
        void ConfigGyro(void);
        uint32_tvoid getCurrentTimeConfigMag(void);
        void uint32SetMagConfig(uint8_t timeOfResult;
 regAddr, uint8_t data);
      bool dataIsNew = falsevoid PrepareMagForDataMode(void);

       float altitudeMeasured = 0, pressureMeasured = 0, temperatureMeasured = 0void Bmx160WriteReg(uint8_t reg, uint8_t val);
        void Bmx160ReadReg(uint8_t const regAddr, uint8_t *pData, uint8_t len);

        // various offsets and calibration parameters read from device. Used in internal math but God only knows what each one means. void Calibrate(void);

        //Variables
        uint8_t rawImuData[21];
        uint16IMUData_t c1, c2, c3, c4, c5, c6 ImuCalibration;
        IMUData_t ImuCalibrationFinal;


};

#endif

User’s perspective

If you're the user of a certain sensor driver, there are at most 3 methods of interest to you (and potetially potentially a 4th calibration method). Here is what you have to do:

  1. Instantiate the sensor object in the thread you wish to have the data in. If the particular sensor has a Begin_Measuring method, you’ll need to instantiate a second object in the same way in the second thread. Do this by calling the static GetInstance method of the sensor that interests you (in the sample, there is only the MS5637 altimeter bmx160 imu available, but there may be more) and assign that result to a pointer of the base class type (in this case Altimeter IMU).

  2. (Only if the sensor has a Begin_Measuring method). In the second thread mentioned in (1), call the Begin_Measuring method at a regular interval.

  3. In the data thread, you are free to call GetResult as frequently as you want (it’s non blocking). The contents of the returned struct will not only include the latest available data but will also include an indication of whether the data has been refreshed since last time GetResult was called.

...