Bob Giesberts / LDC1614

Dependencies:   SHTx

Dependents:   Inductive_Sensor_3

Fork of LDC1101 by Bob Giesberts

Files at this revision

API Documentation at this revision

Comitter:
bobgiesberts
Date:
Wed Dec 16 16:25:33 2015 +0000
Parent:
18:fc9bb81a631f
Child:
20:8e1b1efdbb49
Commit message:
Tweaking the internal settings (RP_Min, Responsetime, divider, etc.) to find the optimal configuration (= highest resolution, highest accuracy, linearity, etc.).

Changed in this revision

LDC1101.cpp Show annotated file Show diff for this revision Revisions of this file
LDC1101.h Show annotated file Show diff for this revision Revisions of this file
--- a/LDC1101.cpp	Wed Dec 16 10:58:31 2015 +0000
+++ b/LDC1101.cpp	Wed Dec 16 16:25:33 2015 +0000
@@ -15,7 +15,7 @@
 LDC1101::LDC1101(PinName mosi, PinName miso, PinName sck, PinName cs, float capacitor, float f_CLKIN, PinName clock_out) : _spiport(mosi,miso,sck, NC), _cs_pin(cs)//, _clock(clock_out,1)
 {
     // settings
-    cap = capacitor;
+    _cap = capacitor;
     _spiport.format(8,3);
     _spiport.frequency(1E6);
     setFrequency(f_CLKIN);
@@ -29,77 +29,28 @@
 void LDC1101::init()
 {
     // Set LDC1101 in configuration modus
-    mode(LDC_MODE_STANDBY);     // STANDBY = 0x01 naar 0x0B  
-    
+    func_mode(LDC_MODE_STANDBY);     // STANDBY = 0x01 naar 0x0B  
     wait(0.1);
-    wait_us(10);
-
 
-    /** --- [LHR modus] --- */
-    // L-Only Measurement
-    writeSPIregister(0x05, 0x01);   // ALT_CONFIG:  0000 0011 --> Shutdown enabled + LHR modus
-    writeSPIregister(0x0C, 0x01);   // D_CONFIG:    Register 0x0C enables a function that can improve L measurements while disabling RP measurements 
-
-
+    // - initialise LHR mode
+    setLHRmode();
 
-    /** --- [Responsetime] --- */
-    // The number of sensor periods used per conversion.
-    // This setting MUST be applied, default does not work.
-    //              Responsetime
-    // t_conv (s) = ------------
-    //              3 x f_sensor
-    // Does NOT apply to the LHR mode!!! (p. 17)
+    // - set ResponseTime to 6144
+    // (This setting MUST be applied, leaving it to default does not work)
     setResponseTime(LDC_RESPONSE_6144); // 6144 = 0x07 naar 0x04
-    //
-    // For LHR mode, the conversion time is set by the reference count LHR_RCOUNT (0x30 & 0x31) (p.34)
-    // The conversion time represents the number of clock cycles used to measure the sensor frequency.
-    // The reference count value must be chosen to support the required number of effective bits (ENOB).
-    // e.g. ENOB 13 bits --> minimum converstion time 2^13 = 8192 clock cycles required. 8192 = 0x2000 = RCOUNT.
-    // Higher values for LHR_COUNT have a higher effective measurement resolution but a lower sample rate
-    // The maximum setting (0xffff) is required for full resolution (p. 35)
-    //              (55 + RCOUNT*16)
-    // t_conv (s) = ----------------
-    //                  f_CLKIN
-    // writeSPIregister(0x30, 0xff);    // LHR_RCOUNT_LSB
-    // writeSPIregister(0x31, 0xff);    // LHR_RCOUNT_MSB
-    // Disable current drive? (RP_SET.RPMAX_DIS - 0x01[7] = 1)(p.15)
-
-
-
+    
+    // - set Reference Count to 8192 (13 ENOB - 2^13)
+    setReferenceCount(0x8192);   //0xffff
     
-    /** --- [RpMIN] --- */
-    // In LHR mode, this sets a fixed current into the sensor
-    // RP_SET.RPMIN (2:0)         (p.35)
-    //       pi * V_amp 
-    // R_p = -----------
-    //       4 * I_drive
-    // This setting can be calibrated with the target closest to the sensor: R_p(d = 0mm)
-    // RPMIN < 0.8 x R_p(d = 0mm)
-    // If R_p < 750 Ohm --> increase distance to target
-    // 000: RPMIN = 96    kOhm | I_drive =   4.7 uA
-    // 001: RPMIN = 48    kOhm | I_drive =   9.4 uA
-    // 010: RPMIN = 24    kOhm | I_drive =  18.7 uA
-    // 011: RPMIN = 12    kOhm | I_drive =  37.5 uA
-    // 100: RPMIN =  6    kOhm | I_drive =  75   uA
-    // 101: RPMIN =  3    kOhm | I_drive = 150   uA
-    // 110: RPMIN =  1.5  kOhm | I_drive = 300   uA
-    // 111: RPMIN =  0.75 kOhm | I_drive = 600   uA    (default)
-    // writeSPIregister(0x01, 0x0?);    // RP_SET
+    // - disable RP_MAX
+    // - set RP_MIN to 3 kOhm
+    setRPsettings(1, RPMIN_12);
 
-
-    
-    /** --- [Divider] --- */
-    // Sensor input divider         (p.35)
-    // Because f_CLKIN > 4*f_sensor is not realisable for higher frequencies, so there is a divider
-    // f_CLKIN > 4 * f_sensor / SENSOR_DIV
+    //  - set Divider to 2
     setDivider(DIVIDER_2);  
 
-
-
- 
-
     // Done configuring settings, set LDC1101 in measuring modus
-    mode(LDC_MODE_ACTIVE);      // ACTIVE = 0x00 naar 0x0B
+    func_mode(LDC_MODE_ACTIVE);      // ACTIVE = 0x00 naar 0x0B
 }
 
 void LDC1101::setResponseTime(LDC_RESPONSE responsetime)
@@ -109,38 +60,56 @@
     writeSPIregister(0x04, responsetime);
 }
 
+void LDC1101::setReferenceCount(uint16_t rcount)
+{
+    _Rcount = rcount;
+    
+    uint8_t LHR_RCOUNT_LSB = (rcount & 0x00ff);
+    uint8_t LHR_RCOUNT_MSB = ((rcount & 0xff00) >> 8);
+    
+    writeSPIregister(0x30, LHR_RCOUNT_LSB);   //LSB
+    writeSPIregister(0x31, LHR_RCOUNT_MSB);   //MSB
+}
+
+void LDC1101::setRPsettings(bool RP_MAX_DIS, RPMIN rpmin)
+{
+    float rpmins[] = {96, 48, 24, 12, 6, 3, 1.5, 0.75};
+    _RPmin = rpmins[rpmin];
+    writeSPIregister(0x01, ((RP_MAX_DIS & 0x80) << 7 | rpmin));
+}
+
 void LDC1101::setDivider(DIVIDER div)
 {
-    uint16_t divs[] = {1, 2, 4, 8};
-    _divider = divs[div];
+    uint8_t divs[] = {1, 2, 4, 8};
+    _divider = divs[div];    
     writeSPIregister(0x34, div);
 }   
 
 
-void LDC1101::setFrequency(float frequency)
+float LDC1101::get_Q(void)
 {
-    _fCLKIN = frequency;
-    //_clock.period(1.0/frequency);
-    //_clock.pulsewidth(0.5/frequency);
-}
+    return _RPmin * sqrt(_cap/_inductance*1000000); 
+}  
 
-float LDC1101::get_fsensor()
+
+float LDC1101::get_fsensor(void)
 {
     _L_data = get_LHR_Data();
     _fsensor = _fCLKIN * _divider * _L_data/16777216;       // (p.26)
     return _fsensor;
-};   
+}   
 
 
-float LDC1101::get_Inductance()
+float LDC1101::get_Inductance(void)
 {  
     _fsensor = get_fsensor();
     
     //               1
     // L = ---------------------        --> p. 34
     //     C * (2*PI*f_sensor)^2
-    return 1./(cap * 4*PI*PI*_fsensor*_fsensor);
-};
+    _inductance = 1./(_cap * 4*PI*PI*_fsensor*_fsensor);
+    return _inductance;
+}
 
 
 uint32_t LDC1101::get_LHR_Data(void)
@@ -185,9 +154,10 @@
 // EXTRA test: Get&print values of all variables to verify (to calculate the induction)
 // The data will be printed on the screen using RealTerm: baud 9600.
 // Begin ***********************************************************
-    // float LDC1101::get_L_data()         {_L_data = get_LHR_Data(); 
-    //                                    return _L_data;};        
-    float LDC1101::get_fCLKIN()      {return _fCLKIN;};    
-    float LDC1101::get_responsetime()   {return _responsetime;};    
-    float LDC1101::get_cap()            {return cap;};
+    float LDC1101::get_fCLKIN()             {return _fCLKIN;};    
+    uint16_t LDC1101::get_responsetime()    {return _responsetime;};    
+    uint16_t LDC1101::get_Rcount()          {return _Rcount;};
+    uint8_t LDC1101::get_divider()          {return _divider;};
+    float LDC1101::get_RPmin()              {return _RPmin;};
+    float LDC1101::get_cap()                {return _cap;};
 // END ***********************************************************
\ No newline at end of file
--- a/LDC1101.h	Wed Dec 16 10:58:31 2015 +0000
+++ b/LDC1101.h	Wed Dec 16 16:25:33 2015 +0000
@@ -21,13 +21,13 @@
 
 typedef enum {  LDC_RESPONSE_192 = 2, \
                 LDC_RESPONSE_384 = 3, \
-                LDC_RESPONSE_768 = 4,  \
+                LDC_RESPONSE_768 = 4, \
                 LDC_RESPONSE_1536= 5, \
                 LDC_RESPONSE_3072= 6, \
                 LDC_RESPONSE_6144= 7} LDC_RESPONSE;
 
-typedef enum {  LDC_MODE_ACTIVE = 0, \
-                LDC_MODE_STANDBY = 1, \
+typedef enum {  LDC_MODE_ACTIVE   = 0, \
+                LDC_MODE_STANDBY  = 1, \
                 LDC_MODE_SHUTDOWN = 2} LDC_MODE;
 
 typedef enum {  DIVIDER_1 = 0, \
@@ -35,6 +35,14 @@
                 DIVIDER_4 = 2, \
                 DIVIDER_8 = 3} DIVIDER;
 
+typedef enum {  RPMIN_96 = 0, \
+                RPMIN_48 = 1, \
+                RPMIN_24 = 2, \
+                RPMIN_12 = 3, \
+                RPMIN_6 = 4, \
+                RPMIN_3 = 5, \
+                RPMIN_1 = 6, \
+                RPMIN_0 = 7} RPMIN;
 
 /**
 * Class for the LDC1101.
@@ -54,7 +62,7 @@
         * The constructor sets the LDC1101 in Active mode.
         * @param mode choose from LDC_MODE_ACTIVE, LDC_MODE STANDBY or LDC_MODE_SHUTDOWN
         **/
-        void mode(LDC_MODE mode) { writeSPI((uint8_t *)(&mode), 0x0B); };
+        void func_mode(LDC_MODE mode) { writeSPI((uint8_t *)(&mode), 0x0B); };
     
         /**
         * @brief initial configurations
@@ -62,56 +70,53 @@
         void init(void);
         
         /**
+        * @brief initialises LHR mode
+        * Also enables shutdown modus
+        **/
+        void setLHRmode(void)
+        {
+            writeSPIregister(0x05, 0x03); // ALT_CONFIG:  0000 0011 --> LHR modus + Shutdown enabled
+            writeSPIregister(0x0C, 0x01); // D_CONFIG:    Enables a function that can improve L measurements while disabling RP measurements 
+        };
+        
+        /**
+        * @brief Settings for RP
+        * @param RPMAX_DIS [7]
+        * 0 - not disabled: RP_MAX is driven
+        * 1 - disabled: RP_MAX is ignored, current drive is off.
+        * @param RPMIN [2:0]
+        *       pi * V_amp 
+        * R_p = -----------
+        *       4 * I_drive
+        * This setting can be calibrated with the target closest to the sensor: R_p(d = 0mm)
+        * RPMIN < 0.8 x R_p(d = 0mm)
+        * If R_p < 750 Ohm --> increase distance to target
+        *  - 000: RPMIN = 96    kOhm | I_drive =   4.7 uA
+        *  - 001: RPMIN = 48    kOhm | I_drive =   9.4 uA
+        *  - 010: RPMIN = 24    kOhm | I_drive =  18.7 uA
+        *  - 011: RPMIN = 12    kOhm | I_drive =  37.5 uA
+        *  - 100: RPMIN =  6    kOhm | I_drive =  75   uA
+        *  - 101: RPMIN =  3    kOhm | I_drive = 150   uA
+        *  - 110: RPMIN =  1.5  kOhm | I_drive = 300   uA
+        *  - 111: RPMIN =  0.75 kOhm | I_drive = 600   uA    (default)
+        **/
+        void setRPsettings(bool RPMAX_DIS, RPMIN rpmin);
+        
+        /**
         * @brief Sensor divider (p.26)
+        * Sensor input divider         (p.35)
+        * Because f_CLKIN > 4*f_sensor is not realisable for higher frequencies, so there is a divider
+        * f_CLKIN > 4 * f_sensor / SENSOR_DIV
         * @param div 
-        * Divides the sensor by a certain amount
         * - DIVIDER_1
         * - DIVIDER_2
         * - DIVIDER_4
         * - DIVIDER_8
         **/
         void setDivider(DIVIDER div);
-        
-        
-        /**
-        * @brief get the calculated value for f_sensor
-        **/        
-        float get_fsensor(void);
-        
-        
-        /**
-        * @brief get the calculated inductance value
-        **/
-        float get_Inductance(void);
-    
-    
-        // EXTRA test get variables values to verify (to calculate the induction)
-        float get_fCLKIN(void);
-        float get_responsetime(void);
-        float get_cap(void);
-        
-    
+     
         /**
-        * @brief Set the value of the external capacitor
-        * This is needed for the calculation of the inductance.
-        **/
-        void  setCapacitor(float c){cap = c;};
-        /**
-        * @brief set the value of the external clock
-        * If PWMout is used to generate a clock signal, this will update the output frequency.s
-        **/
-        void  setFrequency(float frequency);
-
-        /**
-        * @brief Read LHR_Data, the raw 24-bit inductance value.
-        * This is needed for the calculation of the inductance.
-        * It reads from addresses 0x38, 0x39 & 0x3A.
-        **/
-        uint32_t get_LHR_Data(void);
-    
-    
-        /**
-        * @brief Set the Response Time parameters. 
+        * @brief Set the Response Time parameters. Does not apply in LHR mode (p.17)
         * @param responsetime 
         * Larger value increases accuracy, but slows down the output data rate. Choose one of these values:
         * - LDC_RESPONSE_192
@@ -120,26 +125,103 @@
         * - LDC_RESPONSE_1536
         * - LDC_RESPONSE_3072
         * - LDC_RESPONSE_6144
+        *              ResponseTime
+        * t_conv (s) = ------------
+        *              3 x f_sensor
         **/
         void setResponseTime(LDC_RESPONSE responsetime);
         
+        /** 
+        * @brief Set the Reference Count parameter.
+        * @param LHR_Count
+        * For LHR mode, the conversion time is set by the reference count LHR_RCOUNT (0x30 & 0x31) (p.34)
+        * The conversion time represents the number of clock cycles used to measure the sensor frequency.
+        * Higher values for LHR_RCOUNT have a higher effective measurement resolution but a lower sample rate. (p.34)
+        * The maximum setting (0xffff) is required for full resolution (p. 35)
+        * 1) LHR_Count = 1/sample rate [kS/s] - 55/f_CLKIN
+        * 2) The reference count value must be chosen to support the required number of effective bits (ENOB).
+        *    e.g. ENOB 13 bits --> minimum converstion time 2^13 = 8192 clock cycles required. 8192 = 0x2000 = RCOUNT.
+        **/
+        void setReferenceCount(uint16_t LHR_Count);
+        /**
+        * @brief Set the value of the external capacitor
+        * This is needed for the calculation of the inductance.
+        **/
+        void setCapacitor(float c){_cap = c;};
+        /**
+        * @brief set the value of the external clock
+        * If PWMout is used to generate a clock signal, this will update the output frequency.s
+        **/
+        void setFrequency(float frequency){_fCLKIN = frequency;};
+
+
+        /**
+        * @brief Read LHR_Data, the raw 24-bit inductance value.
+        * This is needed for the calculation of the inductance.
+        * It reads from addresses 0x38, 0x39 & 0x3A.
+        **/
+        uint32_t get_LHR_Data(void);
+        /**
+        * @brief get the calculated value for f_sensor
+        **/        
+        float get_fsensor(void);
+        /**
+        * @brief get the calculated inductance value
+        **/
+        float get_Inductance(void);
+        /**
+        * @brief get the reference frequency (f_CLKIN)
+        **/
+        float get_fCLKIN(void);
+        /**
+        * @brief get the responsetime
+        **/
+        uint16_t get_responsetime(void);
+        /**
+        * @brief get RPmin
+        **/
+        float get_RPmin(void);
+        /**
+        * @brief get the reference count
+        **/
+        uint16_t get_Rcount(void);
+        /**
+        * @brief get the divider
+        **/
+        uint8_t get_divider(void);
+        /**
+        * @brief get the capacitance
+        **/
+        float get_cap(void);
+        /**
+        * @brief get the quality
+        **/
+        float get_Q(void);
+        
+
+    
+
+
+        
     private:
         void readSPI(uint8_t *data, uint8_t address, uint8_t num_bytes = 1);
         void writeSPI(uint8_t *data, uint8_t address, uint8_t num_bytes = 1);
         void writeSPIregister(uint8_t reg, uint8_t value){writeSPI(&value,reg);}; // VERKEERD OM?!
         
         uint32_t readINTB(void); // EXTRA UNTB Read register
-        LDC_RESPONSE _responsetime_;
-        DIVIDER _divider_;
-        float _responsetime;
-        float _divider;
-        float _fsensor;
-        float _inductance;
-        float _fCLKIN; //frequency of external clock: 16MHz
-        float cap;    
-        uint32_t _L_data;
         uint32_t INTB; // extra: read register INTB
         
+        uint16_t _responsetime; // Response Time
+        uint8_t _divider;       // divider
+        float _RPmin;           // RP_MIN
+        float _fsensor;         // f_sensor: the calculated frequency of the sensor
+        float _inductance;      // the calculated inductance
+        float _fCLKIN;          // f_CLKIN: frequency of external clock: 16MHz
+        float _cap;             // capacitor: 120 pF
+        uint32_t _L_data;       // The raw measured data for inductance
+        uint16_t _Rcount;       // The reference count
+
+        
         SPI _spiport;
         DigitalOut _cs_pin;