Manuel Caballero / ADS1231

Dependents:   weightscale Projet-BTS-balance Programme_Final_V6

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ADS1231.cpp Source File

ADS1231.cpp

00001 /**
00002  * @brief       ADS1231.h
00003  * @details     24-Bit Analog-to-Digital Converter for Bridge Sensors.
00004  *              Function file.
00005  *
00006  *
00007  * @return      NA
00008  *
00009  * @author      Manuel Caballero
00010  * @date        18/September/2017
00011  * @version     18/September/2017    The ORIGIN
00012  * @pre         NaN.
00013  * @warning     NaN
00014  * @pre         This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ).
00015  */
00016 
00017 #include "ADS1231.h"
00018 
00019 
00020 ADS1231::ADS1231 ( PinName SCLK, PinName DOUT )
00021     : _SCLK                 ( SCLK )
00022     , _DOUT                 ( DOUT )
00023 {
00024 
00025 }
00026 
00027 
00028 ADS1231::~ADS1231()
00029 {
00030 }
00031 
00032 
00033 
00034 /**
00035  * @brief       ADS1231_Reset   ( void )
00036  *
00037  * @details     It performs an internal reset.
00038  *
00039  * @param[in]    NaN.
00040  *
00041  * @param[out]   NaN.
00042  *
00043  *
00044  * @return       Status of ADS1231_Reset.
00045  *
00046  *
00047  * @author      Manuel Caballero
00048  * @date        18/September/2017
00049  * @version     18/September/2017   The ORIGIN
00050  * @pre         When SCLK pin changes from low to high and stays at high for
00051  *              longer than 26μs, ADS1231 enters power down mode.
00052  *
00053  *              When SCLK returns to low, chip will reset and enter normal
00054  *              operation mode.
00055  * @warning     NaN.
00056  */
00057 ADS1231::ADS1231_status_t  ADS1231::ADS1231_Reset   ( void )
00058 {
00059     _SCLK  =  ADS1231_PIN_HIGH;
00060     wait_us ( 52 );                                                             // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
00061     _SCLK  =  ADS1231_PIN_LOW;
00062 
00063 
00064 
00065     if ( _DOUT == ADS1231_PIN_HIGH )
00066         return   ADS1231_SUCCESS;
00067     else
00068         return   ADS1231_FAILURE;
00069 }
00070 
00071 
00072 
00073 /**
00074  * @brief       ADS1231_PowerDown   ( void )
00075  *
00076  * @details     It puts the device in power-down mode.
00077  *
00078  * @param[in]    NaN.
00079  *
00080  * @param[out]   NaN.
00081  *
00082  *
00083  * @return       Status of ADS1231_PowerDown.
00084  *
00085  *
00086  * @author      Manuel Caballero
00087  * @date        18/September/2017
00088  * @version     18/September/2017   The ORIGIN
00089  * @pre         When SCLK pin changes from low to high and stays at high for
00090  *              longer than 26μs, ADS1231 enters power down mode.
00091  * @warning     NaN.
00092  */
00093 ADS1231::ADS1231_status_t  ADS1231::ADS1231_PowerDown   ( void )
00094 {
00095     _SCLK  =  ADS1231_PIN_HIGH;
00096     wait_us ( 52 );                                                             // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us )
00097 
00098 
00099 
00100     if ( _DOUT == ADS1231_PIN_HIGH )
00101         return   ADS1231_SUCCESS;
00102     else
00103         return   ADS1231_FAILURE;
00104 }
00105 
00106 
00107 
00108 /**
00109  * @brief       ADS1231_ReadRawData   ( Vector_count_t*, uint32_t )
00110  *
00111  * @details     It reads the raw data from the device.
00112  *
00113  * @param[in]    myAverage:         How many measurement we have to get and deliver the average.
00114  *
00115  * @param[out]   myNewRawData:      The new value from the device.
00116  *
00117  *
00118  * @return       Status of ADS1231_ReadRawData.
00119  *
00120  *
00121  * @author      Manuel Caballero
00122  * @date        18/September/2017
00123  * @version     18/September/2017   The ORIGIN
00124  * @pre         NaN.
00125  * @warning     NaN.
00126  */
00127 ADS1231::ADS1231_status_t  ADS1231::ADS1231_ReadRawData    ( Vector_count_t* myNewRawData, uint32_t myAverage )
00128 {
00129     uint32_t i           =   0;                                                 // Counter and timeout variable
00130     uint32_t ii          =   0;                                                 // Counter variable
00131     uint32_t myAuxData   =   0;
00132 
00133 
00134 
00135     myNewRawData->myRawValue    =   0;                                          // Reset variable at the beginning
00136 
00137     // Start collecting the new measurement as many as myAverage
00138     for ( ii = 0; ii < myAverage; ii++ ) {
00139         // Reset the value
00140         myAuxData    =   0;
00141 
00142         // Wait until the device is ready or timeout
00143         i        =   23232323;
00144         _SCLK  =  ADS1231_PIN_LOW;
00145         while ( ( _DOUT == ADS1231_PIN_HIGH ) && ( --i ) );
00146 
00147         // Check if something is wrong with the device because of the timeout
00148         if ( i < 1 )
00149             return   ADS1231_FAILURE;
00150 
00151 
00152         // Read the data
00153         for ( i = 0; i < 24; i++ ) {
00154             // wait_us ( 1 );                                                   // Datasheet p13.  t_SCLK ( Min. 100ns )
00155             _SCLK  =  ADS1231_PIN_HIGH;
00156             // wait_us ( 1 );                                                   // Datasheet p13.  t_SCLK ( Min. 100ns )
00157             myAuxData    <<=     1;
00158             _SCLK  =  ADS1231_PIN_LOW;
00159 
00160             // High or Low bit
00161             if ( _DOUT == ADS1231_PIN_HIGH )
00162                 myAuxData++;
00163         }
00164 
00165         // Last bit to release the bus
00166         // wait_us ( 1 );                                                       // Datasheet p13.  t_SCLK ( Min. 100ns )
00167         _SCLK  =  ADS1231_PIN_HIGH;
00168         // wait_us ( 1 );                                                       // Datasheet p13.  t_SCLK ( Min. 100ns )
00169         _SCLK  =  ADS1231_PIN_LOW;
00170 
00171 
00172         // Update data to get the average
00173         myAuxData                  ^=    0x800000;
00174         myNewRawData->myRawValue   +=    myAuxData;
00175     }
00176 
00177     myNewRawData->myRawValue    /=    ( float )myAverage;
00178 
00179 
00180 
00181     if ( _DOUT == ADS1231_PIN_HIGH )
00182         return   ADS1231_SUCCESS;
00183     else
00184         return   ADS1231_FAILURE;
00185 }
00186 
00187 
00188 
00189 /**
00190  * @brief       ADS1231_ReadData_WithCalibratedMass ( Vector_count_t* myNewRawData, uint32_t myAverage )
00191  *
00192  * @details     It reads data with a calibrated mass on the load cell.
00193  *
00194  * @param[in]    myAverage:             How many data to read.
00195  *
00196  * @param[out]   myNewRawData:          myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ).
00197  *
00198  *
00199  * @return       Status of ADS1231_ReadData_WithCalibratedMass.
00200  *
00201  *
00202  * @author      Manuel Caballero
00203  * @date        18/September/2017
00204  * @version     18/September/2017   The ORIGIN
00205  * @pre         NaN.
00206  * @warning     NaN.
00207  */
00208 ADS1231::ADS1231_status_t  ADS1231::ADS1231_ReadData_WithCalibratedMass   ( Vector_count_t* myNewRawData, uint32_t myAverage )
00209 {
00210     ADS1231_status_t        aux;
00211 
00212     // Perform a new bunch of readings
00213     aux  =   ADS1231_ReadRawData ( myNewRawData, myAverage );
00214 
00215 
00216     // Update the value with a calibrated mass
00217     myNewRawData->myRawValue_WithCalibratedMass  =   myNewRawData->myRawValue;
00218 
00219 
00220 
00221     if ( aux == ADS1231_SUCCESS )
00222         return   ADS1231_SUCCESS;
00223     else
00224         return   ADS1231_FAILURE;
00225 }
00226 
00227 
00228 
00229 /**
00230  * @brief       ADS1231_ReadData_WithoutMass ( Vector_count_t* myNewRawData, uint32_t myAverage )
00231  *
00232  * @details     It reads data without any mass on the load cell.
00233  *
00234  * @param[in]    myAverage:             How many data to read.
00235  *
00236  * @param[out]   myNewRawData:          myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ).
00237  *
00238  *
00239  * @return       Status of ADS1231_ReadData_WithoutMass.
00240  *
00241  *
00242  * @author      Manuel Caballero
00243  * @date        18/September/2017
00244  * @version     18/September/2017   The ORIGIN
00245  * @pre         NaN.
00246  * @warning     NaN.
00247  */
00248 ADS1231::ADS1231_status_t  ADS1231::ADS1231_ReadData_WithoutMass   ( Vector_count_t* myNewRawData, uint32_t myAverage )
00249 {
00250     ADS1231_status_t        aux;
00251 
00252     // Perform a new bunch of readings
00253     aux  =   ADS1231_ReadRawData ( myNewRawData, myAverage );
00254 
00255 
00256     // Update the value without any mass
00257     myNewRawData->myRawValue_WithoutCalibratedMass  =   myNewRawData->myRawValue;
00258 
00259 
00260 
00261     if ( aux == ADS1231_SUCCESS )
00262         return   ADS1231_SUCCESS;
00263     else
00264         return   ADS1231_FAILURE;
00265 }
00266 
00267 
00268 
00269 /**
00270  * @brief       ADS1231_CalculateMass ( Vector_count_t* myNewRawData, uint32_t myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass )
00271  *
00272  * @details     It calculates the mass.
00273  *
00274  * @param[in]    myNewRawData:              It has myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ),
00275  *                                          myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ) and
00276  *                                          myRawValue ( the current data taken by the system ).
00277  * @param[in]    myCalibratedMass:          A known value for the calibrated mass when myRawValue_WithCalibratedMass was
00278  *                                          calculated.
00279  * @param[in]    myScaleCalibratedMass:     The range of the calibrated mass ( kg, g, mg or ug ).
00280  *
00281  * @param[out]   NaN.
00282  *
00283  *
00284  * @return       The calculated mass.
00285  *
00286  *
00287  * @author      Manuel Caballero
00288  * @date        18/September/2017
00289  * @version     18/September/2017   The ORIGIN
00290  * @pre         NaN.
00291  * @warning     NaN.
00292  */
00293 ADS1231::Vector_mass_t  ADS1231::ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass )
00294 {
00295     // Terminology by Texas Instruments: sbau175a.pdf, p8 2.1.1 Calculation of Mass
00296     float m, w_zs;
00297     float c_zs, w_fs, c_fs, w_t;
00298     float c = 0;
00299     float myFactor   =   1.0;
00300 
00301     Vector_mass_t w;
00302 
00303 
00304     // Adapt the scale ( kg as reference )
00305     switch ( myScaleCalibratedMass ) {
00306         default:
00307         case ADS1231_SCALE_kg :
00308             // myFactor     =   1.0;
00309             break;
00310 
00311         case ADS1231_SCALE_g :
00312             myFactor     /=   1000.0;
00313             break;
00314 
00315         case ADS1231_SCALE_mg :
00316             myFactor     /=   1000000.0;
00317             break;
00318 
00319         case ADS1231_SCALE_ug :
00320             myFactor     /=   1000000000.0;
00321             break;
00322 
00323     }
00324 
00325 
00326     // Calculate the Calibration Constant ( m )
00327     w_fs    =    ( myCalibratedMass / myFactor );                               // User-specified calibration mass
00328     c_zs    =    myNewRawData->myRawValue_WithoutCalibratedMass;                // ADC measurement taken with no load
00329     c_fs    =    myNewRawData->myRawValue_WithCalibratedMass;                   // ADC code taken with the calibration mass applied
00330 
00331     m       =    ( float )( w_fs / ( ( c_fs ) - c_zs  ) );                      // The Calibration Constant
00332 
00333 
00334     // Calculate the zero-scale mass ( w_zs )
00335     w_zs    =    - ( m * c_zs );
00336 
00337 
00338     // Calculate the mass ( w )
00339     w_t     =    myNewRawData->myRawValue_TareWeight;                           // ADC code taken without any mass after the system is calibrated;
00340     c       =    myNewRawData->myRawValue;                                      // The ADC code
00341 
00342     w.myMass   =    ( m * c ) + w_zs - w_t;                                     // The mass according to myScaleCalibratedMass
00343 
00344 
00345     // Update Internal Parameters
00346     _ADS1231_USER_CALIBATED_MASS   =   myCalibratedMass;
00347     _ADS1231_SCALE                 =   myScaleCalibratedMass;
00348 
00349 
00350 
00351     return   w;
00352 }
00353 
00354 
00355 
00356 /**
00357  * @brief       ADS1231_SetAutoTare ( float ,ADS1231_scale_t ,Vector_count_t* ,float )
00358  *
00359  * @details     It reads data without any mass on the load cell after the system is calibrated to calculate the tare weight.
00360  *
00361  * @param[in]    myCalibratedMass:          A known value for the calibrated mass when myRawValue_WithCalibratedMass was
00362  *                                          calculated.
00363  * @param[in]    myScaleCalibratedMass:     The range of the calibrated mass ( kg, g, mg or ug ).
00364  * @param[in]    myTime:                    How long the auto-set lasts.
00365  *
00366  * @param[out]   myNewRawData:              myRawValue_TareWeight ( ADC code taken without any mass ).
00367  *
00368  *
00369  * @return       Status of ADS1231_SetAutoTare.
00370  *
00371  *
00372  * @author      Manuel Caballero
00373  * @date        18/September/2017
00374  * @version     18/September/2017   The ORIGIN
00375  * @pre         NaN.
00376  * @warning     NaN.
00377  */
00378 ADS1231::ADS1231_status_t  ADS1231::ADS1231_SetAutoTare   ( float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime )
00379 {
00380     ADS1231_status_t      aux;
00381     Vector_mass_t         myCalculatedMass;
00382     float                 myAuxData = 0;
00383     uint32_t              i = 0;
00384 
00385 
00386     // Perform a new bunch of readings every 1 second
00387     for ( i = 0; i < myTime; i++ ) {
00388         aux          =   ADS1231_ReadRawData ( myNewRawData, 10 );
00389         myAuxData   +=   myNewRawData->myRawValue;
00390         wait(1);
00391     }
00392 
00393     myNewRawData->myRawValue    =    ( float )( myAuxData / myTime );
00394 
00395     // Turn it into mass
00396     myCalculatedMass     =   ADS1231_CalculateMass ( myNewRawData, myCalibratedMass, myScaleCalibratedMass );
00397 
00398     // Update the value without any mass
00399     myNewRawData->myRawValue_TareWeight  =   myCalculatedMass.myMass;
00400     
00401     
00402     // Update Internal Parameters
00403     _ADS1231_USER_CALIBATED_MASS   =   myCalibratedMass;
00404     _ADS1231_SCALE                 =   myScaleCalibratedMass;
00405 
00406 
00407 
00408     if ( aux == ADS1231_SUCCESS )
00409         return   ADS1231_SUCCESS;
00410     else
00411         return   ADS1231_FAILURE;
00412 }
00413 
00414 
00415 
00416 /**
00417  * @brief       ADS1231_SetManualTare ( float myTareWeight )
00418  *
00419  * @details     It sets a tare weight manually.
00420  *
00421  * @param[in]    myTareWeight:          Tare weight.
00422  *
00423  * @param[out]   NaN.
00424  *
00425  *
00426  * @return       myRawValue_TareWeight.
00427  *
00428  *
00429  * @author      Manuel Caballero
00430  * @date        12/September/2017
00431  * @version     12/September/2017   The ORIGIN
00432  * @pre         NaN.
00433  * @warning     NaN.
00434  */
00435 ADS1231::Vector_count_t  ADS1231::ADS1231_SetManualTare   ( float myTareWeight )
00436 {
00437     Vector_count_t myNewTareWeight;
00438 
00439     // Update the value defined by the user
00440     myNewTareWeight.myRawValue_TareWeight  =   myTareWeight;
00441 
00442 
00443 
00444     return   myNewTareWeight;
00445 }
00446 
00447 
00448 
00449 /**
00450  * @brief       ADS1231_CalculateVoltage ( Vector_count_t* ,float )
00451  *
00452  * @details     It calculates the mass.
00453  *
00454  * @param[in]    myNewRawData:              myRawValue ( the current data taken by the system ).
00455  * @param[in]    myVoltageReference:        The voltage at the converter reference input.
00456  *
00457  * @param[out]   NaN.
00458  *
00459  *
00460  * @return       The calculated voltage.
00461  *
00462  *
00463  * @author      Manuel Caballero
00464  * @date        18/September/2017
00465  * @version     18/September/2017   The ORIGIN
00466  * @pre         NaN.
00467  * @warning     NaN.
00468  */
00469 ADS1231::Vector_voltage_t  ADS1231::ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference )
00470 {
00471     // Terminology by Texas Instruments: sbau175a.pdf, p12 3.2 Measurement Modes Raw
00472     float x, B, A;
00473 
00474     Vector_voltage_t v;
00475 
00476     
00477     x   =    myNewRawData->myRawValue;
00478     B   =    ( 16777216.0 - 1.0 );
00479     A   =    128.0;
00480 
00481 
00482 
00483     // Calculate the voltage ( v )
00484     v.myVoltage = ( float )( ( x / B ) * ( myVoltageReference / A ) );          // The voltage
00485 
00486 
00487 
00488 
00489     return   v;
00490 }