Library to communicate with LDC1614

Dependencies:   SHTx

Dependents:   Inductive_Sensor_3

Fork of LDC1101 by Bob Giesberts

Revision:
18:fc9bb81a631f
Parent:
17:a5cf2b4bec13
Child:
19:e205ab9142d8
diff -r a5cf2b4bec13 -r fc9bb81a631f LDC1101.cpp
--- a/LDC1101.cpp	Sat Dec 12 11:26:23 2015 +0000
+++ b/LDC1101.cpp	Wed Dec 16 10:58:31 2015 +0000
@@ -12,15 +12,14 @@
 #include "LDC1101.h"
 
  
-LDC1101::LDC1101(PinName mosi, PinName miso, PinName sck, PinName cs, float capacitor, float f_external, PinName clock_out) : _spiport(mosi,miso,sck, NC), _cs_pin(cs)//, _clock(clock_out,1)
+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;
     _spiport.format(8,3);
     _spiport.frequency(1E6);
-    setFrequency(f_external);
+    setFrequency(f_CLKIN);
     
-    // ---CSB must go low before accessing first address???
     _cs_pin.write(1);
     wait_us(100);
     
@@ -29,75 +28,127 @@
 
 void LDC1101::init()
 {
-    // configuration
-    mode(LDC_MODE_STANDBY);     // 0x01 naar 0x0B  
+    // Set LDC1101 in configuration modus
+    mode(LDC_MODE_STANDBY);     // STANDBY = 0x01 naar 0x0B  
     
     wait(0.1);
     wait_us(10);
 
-    setResponseTime(LDC_RESPONSE_6144);
-    setDivider(DIVIDER_1);
+
+    /** --- [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 
+
+
 
-    // L-Only Measurement
-    writeSPIregister(0x05, 0x03);   // ALT_CONFIG:  clock config >> we get 0x00 if this line is disabled and the cable is reconnected 
-    writeSPIregister(0x0C, 0x01);   // D_CONF:      Register 0x0C enables a function that can improve L measurements while disabling RP measurements 
+    /** --- [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)
+    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)
+
+
 
-    // High Resolution Reference Count
-    // LHR_COUNT_LSB:   0xff naar 0x30 ???
-    // LHR_COUNT_MSB:   0xff naar 0x31 ???
+    
+    /** --- [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
 
-    // Start measuring
-    mode(LDC_MODE_ACTIVE);      // 0x00 naar 0x0B
+
+    
+    /** --- [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
+    setDivider(DIVIDER_2);  
+
+
+
+ 
+
+    // Done configuring settings, set LDC1101 in measuring modus
+    mode(LDC_MODE_ACTIVE);      // ACTIVE = 0x00 naar 0x0B
 }
 
 void LDC1101::setResponseTime(LDC_RESPONSE responsetime)
 {
-    _responsetime = responsetime;
+    uint16_t resps[] = {0, 0, 192, 384, 768, 1536, 3072, 6144};
+    _responsetime = resps[responsetime];
     writeSPIregister(0x04, responsetime);
 }
 
 void LDC1101::setDivider(DIVIDER div)
 {
-    // _divider = (float) pow(2, div);
+    uint16_t divs[] = {1, 2, 4, 8};
+    _divider = divs[div];
     writeSPIregister(0x34, div);
 }   
 
 
 void LDC1101::setFrequency(float frequency)
 {
-    _frequency = frequency;
+    _fCLKIN = frequency;
     //_clock.period(1.0/frequency);
     //_clock.pulsewidth(0.5/frequency);
 }
 
-float LDC1101::getInductance()
+float LDC1101::get_fsensor()
 {
-    uint16_t resp[] = {0,0,192, 384, 768, 1536, 3072, 6144};
-    _raw_l = readRawCounts();
+    _L_data = get_LHR_Data();
+    _fsensor = _fCLKIN * _divider * _L_data/16777216;       // (p.26)
+    return _fsensor;
+};   
+
+
+float LDC1101::get_Inductance()
+{  
+    _fsensor = get_fsensor();
     
-    //            f_CLKIN * RESP_TIME
-    // f_sensor = -------------------
-    //                3 * L_DATA
-    _fsensor = 1 *(_frequency/(_raw_l*3.0))*resp[(uint8_t)(_responsetime)];
-    
-    //            2^SENSORDIV * f_CLKIN(L_DATA + LHROFFSET*2^8)
-    // f_sensor = ---------------------------------------------
-    //                              2^24
-    
-    //            1
-    // ---------------------        --> p. 31
-    // C * (2*PI*f_sensor)^2
-    return 1./(cap*pow(2*PI*_fsensor,2));
+    //               1
+    // L = ---------------------        --> p. 34
+    //     C * (2*PI*f_sensor)^2
+    return 1./(cap * 4*PI*PI*_fsensor*_fsensor);
 };
 
 
-uint32_t LDC1101::readRawCounts(void)
+uint32_t LDC1101::get_LHR_Data(void)
 {
-    uint8_t val[5];
-    
-    // 0x38 + 0x39 + 0x3A
-    readSPI(val, 0x38, 5);
-    uint32_t combinedbytes = (val[4]<<16)| (val[3]<<8) | val[2];  // combine the content of the 3 bytes from registers 23, 24 and 25 
+    // LHR_DATA (p.26 & p.27)
+    uint8_t LHR_DATA[3];
+    readSPI(LHR_DATA, 0x38, 3);     // 0x38 + 0x39 + 0x3A
+    uint32_t combinedbytes = (LHR_DATA[2]<<16) | (LHR_DATA[1]<<8) | LHR_DATA[0];
     return combinedbytes;
 }
 
@@ -134,15 +185,9 @@
 // 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_raw_l()          {_raw_l = readRawCounts(); 
-                                        return _raw_l;};        
-    float LDC1101::get_fsensor()        {
-    uint16_t resp[] = {0, 0, 192, 384, 768, 1536, 3072, 6144};
-    _raw_l = readRawCounts();
-    _fsensor = (_frequency/(_raw_l*3.0))*resp[(uint8_t)(_responsetime)];                
-        return _fsensor;};        
-    
-    float LDC1101::get_frequency()      {return _frequency;};    
+    // 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;};
 // END ***********************************************************
\ No newline at end of file