Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Inductive_Sensor_3
Fork of LDC1101 by
Revision 19:e205ab9142d8, committed 2015-12-16
- 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;
