Library to communicate with LDC1614
Dependents: Inductive_Sensor_3
Fork of LDC1101 by
LDC1101.cpp
- Committer:
- bobgiesberts
- Date:
- 2015-12-16
- Revision:
- 18:fc9bb81a631f
- Parent:
- 17:a5cf2b4bec13
- Child:
- 19:e205ab9142d8
File content as of revision 18:fc9bb81a631f:
/** * @file LDC1101.cpp * @brief this C++ file contains all required * functions to interface with Texas * Instruments' LDC1101. * * @author Victor Sluiter * * @date 2015-12-09 */ #include "LDC1101.h" 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_CLKIN); _cs_pin.write(1); wait_us(100); init(); } void LDC1101::init() { // Set LDC1101 in configuration modus 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 /** --- [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) /** --- [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 /** --- [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) { uint16_t resps[] = {0, 0, 192, 384, 768, 1536, 3072, 6144}; _responsetime = resps[responsetime]; writeSPIregister(0x04, responsetime); } void LDC1101::setDivider(DIVIDER div) { uint16_t divs[] = {1, 2, 4, 8}; _divider = divs[div]; writeSPIregister(0x34, div); } void LDC1101::setFrequency(float frequency) { _fCLKIN = frequency; //_clock.period(1.0/frequency); //_clock.pulsewidth(0.5/frequency); } float LDC1101::get_fsensor() { _L_data = get_LHR_Data(); _fsensor = _fCLKIN * _divider * _L_data/16777216; // (p.26) return _fsensor; }; float LDC1101::get_Inductance() { _fsensor = get_fsensor(); // 1 // L = --------------------- --> p. 34 // C * (2*PI*f_sensor)^2 return 1./(cap * 4*PI*PI*_fsensor*_fsensor); }; uint32_t LDC1101::get_LHR_Data(void) { // 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; } void LDC1101::readSPI(uint8_t *data, uint8_t address, uint8_t num_bytes) { // CSB down _cs_pin.write(0); // makes sure the address starts with 1... Why? _spiport.write(address | 0x80); //read flag for(int i=0; i < num_bytes ; i++) { data[i] = _spiport.write(0xFF); } // CSB up _cs_pin.write(1); } void LDC1101::writeSPI(uint8_t *data, uint8_t address, uint8_t num_bytes) { // CSB down _cs_pin.write(0); _spiport.write(address); for(int i=0; i < num_bytes ; i++) { _spiport.write(data[i]); } // CSB up _cs_pin.write(1); } // 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;}; // END ***********************************************************