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: weightscale Projet-BTS-balance Programme_Final_V6
Revision 1:16ae36a95be6, committed 2017-09-18
- Comitter:
- mcm
- Date:
- Mon Sep 18 13:51:20 2017 +0000
- Parent:
- 0:5b0aa77c60ec
- Commit message:
- ADS1231 library was completed and it is ready for testing.
Changed in this revision
ADS1231.cpp | Show annotated file Show diff for this revision Revisions of this file |
ADS1231.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/ADS1231.cpp Mon Sep 18 13:29:39 2017 +0000 +++ b/ADS1231.cpp Mon Sep 18 13:51:20 2017 +0000 @@ -0,0 +1,490 @@ +/** + * @brief ADS1231.h + * @details 24-Bit Analog-to-Digital Converter for Bridge Sensors. + * Function file. + * + * + * @return NA + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN + * @pre This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ). + */ + +#include "ADS1231.h" + + +ADS1231::ADS1231 ( PinName SCLK, PinName DOUT ) + : _SCLK ( SCLK ) + , _DOUT ( DOUT ) +{ + +} + + +ADS1231::~ADS1231() +{ +} + + + +/** + * @brief ADS1231_Reset ( void ) + * + * @details It performs an internal reset. + * + * @param[in] NaN. + * + * @param[out] NaN. + * + * + * @return Status of ADS1231_Reset. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre When SCLK pin changes from low to high and stays at high for + * longer than 26μs, ADS1231 enters power down mode. + * + * When SCLK returns to low, chip will reset and enter normal + * operation mode. + * @warning NaN. + */ +ADS1231::ADS1231_status_t ADS1231::ADS1231_Reset ( void ) +{ + _SCLK = ADS1231_PIN_HIGH; + wait_us ( 52 ); // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us ) + _SCLK = ADS1231_PIN_LOW; + + + + if ( _DOUT == ADS1231_PIN_HIGH ) + return ADS1231_SUCCESS; + else + return ADS1231_FAILURE; +} + + + +/** + * @brief ADS1231_PowerDown ( void ) + * + * @details It puts the device in power-down mode. + * + * @param[in] NaN. + * + * @param[out] NaN. + * + * + * @return Status of ADS1231_PowerDown. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre When SCLK pin changes from low to high and stays at high for + * longer than 26μs, ADS1231 enters power down mode. + * @warning NaN. + */ +ADS1231::ADS1231_status_t ADS1231::ADS1231_PowerDown ( void ) +{ + _SCLK = ADS1231_PIN_HIGH; + wait_us ( 52 ); // Datasheet p15. At least 26us ( Security Factor: 2*26us = 52us ) + + + + if ( _DOUT == ADS1231_PIN_HIGH ) + return ADS1231_SUCCESS; + else + return ADS1231_FAILURE; +} + + + +/** + * @brief ADS1231_ReadRawData ( Vector_count_t*, uint32_t ) + * + * @details It reads the raw data from the device. + * + * @param[in] myAverage: How many measurement we have to get and deliver the average. + * + * @param[out] myNewRawData: The new value from the device. + * + * + * @return Status of ADS1231_ReadRawData. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::ADS1231_status_t ADS1231::ADS1231_ReadRawData ( Vector_count_t* myNewRawData, uint32_t myAverage ) +{ + uint32_t i = 0; // Counter and timeout variable + uint32_t ii = 0; // Counter variable + uint32_t myAuxData = 0; + + + + myNewRawData->myRawValue = 0; // Reset variable at the beginning + + // Start collecting the new measurement as many as myAverage + for ( ii = 0; ii < myAverage; ii++ ) { + // Reset the value + myAuxData = 0; + + // Wait until the device is ready or timeout + i = 23232323; + _SCLK = ADS1231_PIN_LOW; + while ( ( _DOUT == ADS1231_PIN_HIGH ) && ( --i ) ); + + // Check if something is wrong with the device because of the timeout + if ( i < 1 ) + return ADS1231_FAILURE; + + + // Read the data + for ( i = 0; i < 24; i++ ) { + // wait_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns ) + _SCLK = ADS1231_PIN_HIGH; + // wait_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns ) + myAuxData <<= 1; + _SCLK = ADS1231_PIN_LOW; + + // High or Low bit + if ( _DOUT == ADS1231_PIN_HIGH ) + myAuxData++; + } + + // Last bit to release the bus + // wait_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns ) + _SCLK = ADS1231_PIN_HIGH; + // wait_us ( 1 ); // Datasheet p13. t_SCLK ( Min. 100ns ) + _SCLK = ADS1231_PIN_LOW; + + + // Update data to get the average + myAuxData ^= 0x800000; + myNewRawData->myRawValue += myAuxData; + } + + myNewRawData->myRawValue /= ( float )myAverage; + + + + if ( _DOUT == ADS1231_PIN_HIGH ) + return ADS1231_SUCCESS; + else + return ADS1231_FAILURE; +} + + + +/** + * @brief ADS1231_ReadData_WithCalibratedMass ( Vector_count_t* myNewRawData, uint32_t myAverage ) + * + * @details It reads data with a calibrated mass on the load cell. + * + * @param[in] myAverage: How many data to read. + * + * @param[out] myNewRawData: myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ). + * + * + * @return Status of ADS1231_ReadData_WithCalibratedMass. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::ADS1231_status_t ADS1231::ADS1231_ReadData_WithCalibratedMass ( Vector_count_t* myNewRawData, uint32_t myAverage ) +{ + ADS1231_status_t aux; + + // Perform a new bunch of readings + aux = ADS1231_ReadRawData ( myNewRawData, myAverage ); + + + // Update the value with a calibrated mass + myNewRawData->myRawValue_WithCalibratedMass = myNewRawData->myRawValue; + + + + if ( aux == ADS1231_SUCCESS ) + return ADS1231_SUCCESS; + else + return ADS1231_FAILURE; +} + + + +/** + * @brief ADS1231_ReadData_WithoutMass ( Vector_count_t* myNewRawData, uint32_t myAverage ) + * + * @details It reads data without any mass on the load cell. + * + * @param[in] myAverage: How many data to read. + * + * @param[out] myNewRawData: myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ). + * + * + * @return Status of ADS1231_ReadData_WithoutMass. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::ADS1231_status_t ADS1231::ADS1231_ReadData_WithoutMass ( Vector_count_t* myNewRawData, uint32_t myAverage ) +{ + ADS1231_status_t aux; + + // Perform a new bunch of readings + aux = ADS1231_ReadRawData ( myNewRawData, myAverage ); + + + // Update the value without any mass + myNewRawData->myRawValue_WithoutCalibratedMass = myNewRawData->myRawValue; + + + + if ( aux == ADS1231_SUCCESS ) + return ADS1231_SUCCESS; + else + return ADS1231_FAILURE; +} + + + +/** + * @brief ADS1231_CalculateMass ( Vector_count_t* myNewRawData, uint32_t myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass ) + * + * @details It calculates the mass. + * + * @param[in] myNewRawData: It has myRawValue_WithCalibratedMass ( ADC code taken with calibrated mass ), + * myRawValue_WithoutCalibratedMass ( ADC code taken without any mass ) and + * myRawValue ( the current data taken by the system ). + * @param[in] myCalibratedMass: A known value for the calibrated mass when myRawValue_WithCalibratedMass was + * calculated. + * @param[in] myScaleCalibratedMass: The range of the calibrated mass ( kg, g, mg or ug ). + * + * @param[out] NaN. + * + * + * @return The calculated mass. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::Vector_mass_t ADS1231::ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass ) +{ + // Terminology by Texas Instruments: sbau175a.pdf, p8 2.1.1 Calculation of Mass + float m, w_zs; + float c_zs, w_fs, c_fs, w_t; + float c = 0; + float myFactor = 1.0; + + Vector_mass_t w; + + + // Adapt the scale ( kg as reference ) + switch ( myScaleCalibratedMass ) { + default: + case ADS1231_SCALE_kg: + // myFactor = 1.0; + break; + + case ADS1231_SCALE_g: + myFactor /= 1000.0; + break; + + case ADS1231_SCALE_mg: + myFactor /= 1000000.0; + break; + + case ADS1231_SCALE_ug: + myFactor /= 1000000000.0; + break; + + } + + + // Calculate the Calibration Constant ( m ) + w_fs = ( myCalibratedMass / myFactor ); // User-specified calibration mass + c_zs = myNewRawData->myRawValue_WithoutCalibratedMass; // ADC measurement taken with no load + c_fs = myNewRawData->myRawValue_WithCalibratedMass; // ADC code taken with the calibration mass applied + + m = ( float )( w_fs / ( ( c_fs ) - c_zs ) ); // The Calibration Constant + + + // Calculate the zero-scale mass ( w_zs ) + w_zs = - ( m * c_zs ); + + + // Calculate the mass ( w ) + w_t = myNewRawData->myRawValue_TareWeight; // ADC code taken without any mass after the system is calibrated; + c = myNewRawData->myRawValue; // The ADC code + + w.myMass = ( m * c ) + w_zs - w_t; // The mass according to myScaleCalibratedMass + + + // Update Internal Parameters + _ADS1231_USER_CALIBATED_MASS = myCalibratedMass; + _ADS1231_SCALE = myScaleCalibratedMass; + + + + return w; +} + + + +/** + * @brief ADS1231_SetAutoTare ( float ,ADS1231_scale_t ,Vector_count_t* ,float ) + * + * @details It reads data without any mass on the load cell after the system is calibrated to calculate the tare weight. + * + * @param[in] myCalibratedMass: A known value for the calibrated mass when myRawValue_WithCalibratedMass was + * calculated. + * @param[in] myScaleCalibratedMass: The range of the calibrated mass ( kg, g, mg or ug ). + * @param[in] myTime: How long the auto-set lasts. + * + * @param[out] myNewRawData: myRawValue_TareWeight ( ADC code taken without any mass ). + * + * + * @return Status of ADS1231_SetAutoTare. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::ADS1231_status_t ADS1231::ADS1231_SetAutoTare ( float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime ) +{ + ADS1231_status_t aux; + Vector_mass_t myCalculatedMass; + float myAuxData = 0; + uint32_t i = 0; + + + // Perform a new bunch of readings every 1 second + for ( i = 0; i < myTime; i++ ) { + aux = ADS1231_ReadRawData ( myNewRawData, 10 ); + myAuxData += myNewRawData->myRawValue; + wait(1); + } + + myNewRawData->myRawValue = ( float )( myAuxData / myTime ); + + // Turn it into mass + myCalculatedMass = ADS1231_CalculateMass ( myNewRawData, myCalibratedMass, myScaleCalibratedMass ); + + // Update the value without any mass + myNewRawData->myRawValue_TareWeight = myCalculatedMass.myMass; + + + // Update Internal Parameters + _ADS1231_USER_CALIBATED_MASS = myCalibratedMass; + _ADS1231_SCALE = myScaleCalibratedMass; + + + + if ( aux == ADS1231_SUCCESS ) + return ADS1231_SUCCESS; + else + return ADS1231_FAILURE; +} + + + +/** + * @brief ADS1231_SetManualTare ( float myTareWeight ) + * + * @details It sets a tare weight manually. + * + * @param[in] myTareWeight: Tare weight. + * + * @param[out] NaN. + * + * + * @return myRawValue_TareWeight. + * + * + * @author Manuel Caballero + * @date 12/September/2017 + * @version 12/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::Vector_count_t ADS1231::ADS1231_SetManualTare ( float myTareWeight ) +{ + Vector_count_t myNewTareWeight; + + // Update the value defined by the user + myNewTareWeight.myRawValue_TareWeight = myTareWeight; + + + + return myNewTareWeight; +} + + + +/** + * @brief ADS1231_CalculateVoltage ( Vector_count_t* ,float ) + * + * @details It calculates the mass. + * + * @param[in] myNewRawData: myRawValue ( the current data taken by the system ). + * @param[in] myVoltageReference: The voltage at the converter reference input. + * + * @param[out] NaN. + * + * + * @return The calculated voltage. + * + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN. + */ +ADS1231::Vector_voltage_t ADS1231::ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference ) +{ + // Terminology by Texas Instruments: sbau175a.pdf, p12 3.2 Measurement Modes Raw + float x, B, A; + + Vector_voltage_t v; + + + x = myNewRawData->myRawValue; + B = ( 16777216.0 - 1.0 ); + A = 128.0; + + + + // Calculate the voltage ( v ) + v.myVoltage = ( float )( ( x / B ) * ( myVoltageReference / A ) ); // The voltage + + + + + return v; +}
--- a/ADS1231.h Mon Sep 18 13:29:39 2017 +0000 +++ b/ADS1231.h Mon Sep 18 13:51:20 2017 +0000 @@ -0,0 +1,225 @@ +/** + * @brief ADS1231.h + * @details 24-Bit Analog-to-Digital Converter for Bridge Sensors. + * Header file. + * + * + * @return NA + * + * @author Manuel Caballero + * @date 18/September/2017 + * @version 18/September/2017 The ORIGIN + * @pre NaN. + * @warning NaN + * @pre This code belongs to Nimbus Centre ( http://www.nimbus.cit.ie ). + */ +#ifndef ADS1231_H +#define ADS1231_H + +#include "mbed.h" + + +/** + Example: + +#include "mbed.h" +#include "ADS1231.h" + +ADS1231 myWeightSensor ( p5, p6 ); +Serial pc ( USBTX, USBRX ); + +Ticker newReading; +DigitalOut myled1 ( LED1 ); +DigitalOut myled2 ( LED2 ); +DigitalOut myled3 ( LED3 ); +DigitalOut myled4 ( LED4 ); + +ADS1231::ADS1231_status_t aux; +ADS1231::Vector_count_t myData; +ADS1231::Vector_mass_t myCalculatedMass; +ADS1231::Vector_voltage_t myCalculatedVoltage; + + +void readDATA ( void ) +{ + myled4 = 1; + + aux = myWeightSensor.ADS1231_ReadRawData ( &myData, 4 ); + myCalculatedMass = myWeightSensor.ADS1231_CalculateMass ( &myData, 1.0, ADS1231::ADS1231_SCALE_kg ); + myCalculatedVoltage = myWeightSensor.ADS1231_CalculateVoltage ( &myData, 5.0 ); + + pc.printf( "Raw Data: %ld Mass: %0.5f kg Voltage: %0.5f mV\r\n", (uint32_t)myData.myRawValue, myCalculatedMass.myMass, 1000*myCalculatedVoltage.myVoltage ); + + myled4 = 0; +} + + +int main() +{ + pc.baud ( 115200 ); + + + // Reset and wake the device up + aux = myWeightSensor.ADS1231_PowerDown (); + aux = myWeightSensor.ADS1231_Reset (); + wait(1); + + + // CALIBRATION time start! + // 1. REMOVE THE MASS ON THE LOAD CELL ( ALL LEDs OFF ). Read data without any mass on the load cell + aux = myWeightSensor.ADS1231_ReadData_WithoutMass ( &myData, 4 ); + + myled1 = 1; + wait(3); + + + // 2. PUT A KNOWN MASS ON THE LOAD CELL ( JUST LED1 ON ). Read data with an user-specified calibration mass + aux = myWeightSensor.ADS1231_ReadData_WithCalibratedMass ( &myData, 4 ); + // CALIBRATION time end! + + + // [ OPTIONAL ] REMOVE THE MASS ON THE LOAD CELL ( JUST LED2 ON ). Read the device without any mass to calculate the tare weight for 5 seconds + myled1 = 0; + myled2 = 1; + wait(3); + myled2 = 0; + + // Calculating the tare weight ( JUST LED3 ON ) + myled3 = 1; + aux = myWeightSensor.ADS1231_SetAutoTare ( ADS1231::ADS1231_SCALE_kg, &myData, 5 ); + myled3 = 0; + + + newReading.attach( &readDATA, 0.5 ); // the address of the function to be attached ( readDATA ) and the interval ( 0.5s ) ( JUST LED4 BLINKING ) + + // Let the callbacks take care of everything + while(1) + { + sleep(); + } +} + +*/ + + +/*! + Library for the ADS1231 24-Bit Analog-to-Digital Converter for Bridge Sensors. +*/ +class ADS1231 +{ +public: + /** + * @brief READY/BUSY DATA + */ + typedef enum { + ADS1231_DATA_BUSY = 0, /*!< ADS1231 data is NOT ready to be read. */ + ADS1231_DATA_READY = 1 /*!< ADS1231 data is ready to be read. */ + } ADS1231_data_output_status_t; + + + + /** + * @brief SCALE + */ + typedef enum { + ADS1231_SCALE_kg = 0, /*!< ADS1231 Scale in kg. */ + ADS1231_SCALE_g = 1, /*!< ADS1231 Scale in g. */ + ADS1231_SCALE_mg = 2, /*!< ADS1231 Scale in mg. */ + ADS1231_SCALE_ug = 3 /*!< ADS1231 Scale in ug. */ + } ADS1231_scale_t; + + + + +#ifndef VECTOR_STRUCT_H +#define VECTOR_STRUCT_H + typedef struct { + float myRawValue_WithCalibratedMass; + float myRawValue_WithoutCalibratedMass; + float myRawValue_TareWeight; + uint32_t myRawValue; + } Vector_count_t; + + typedef struct { + float myMass; + } Vector_mass_t; + + typedef struct { + float myVoltage; + } Vector_voltage_t; +#endif + + + + /** + * @brief INTERNAL CONSTANTS + */ +#define ADS1231_PIN_HIGH 0x01 /*!< Pin 'HIGH' */ +#define ADS1231_PIN_LOW 0x00 /*!< Pin 'LOW' */ + + typedef enum { + ADS1231_SUCCESS = 0, + ADS1231_FAILURE = 1, + } ADS1231_status_t; + + + + + /** Create an ADS1231 object connected to the specified pins. + * + * @param sclk ADS1231 Power down control (high active) and serial clock input + * @param dout ADS1231 Serial data output + */ + ADS1231 ( PinName SCLK, PinName DOUT ); + + /** Delete ADS1231 object. + */ + ~ADS1231(); + + /** It performs an internal reset. + */ + ADS1231_status_t ADS1231_Reset ( void ); + + /** It puts the device into power-down mode. + */ + ADS1231_status_t ADS1231_PowerDown ( void ); + + /** It reads raw data from the device. + */ + ADS1231_status_t ADS1231_ReadRawData ( Vector_count_t* myNewRawData, uint32_t myAverage ); + + /** It reads raw data with an user-specified calibrated mass. + */ + ADS1231_status_t ADS1231_ReadData_WithCalibratedMass ( Vector_count_t* myNewRawData, uint32_t myAverage ); + + /** It reads raw data without any mass. + */ + ADS1231_status_t ADS1231_ReadData_WithoutMass ( Vector_count_t* myNewRawData, uint32_t myAverage ); + + /** It reads raw data without any mass after the system is calibrated. + */ + ADS1231_status_t ADS1231_SetAutoTare ( float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass, Vector_count_t* myNewRawData, float myTime ); + + /** It sets a tare weight manually. + */ + Vector_count_t ADS1231_SetManualTare ( float myTareWeight ); + + /** It calculates scaled data. + */ + Vector_mass_t ADS1231_CalculateMass ( Vector_count_t* myNewRawData, float myCalibratedMass, ADS1231_scale_t myScaleCalibratedMass ); + + /** It calculates voltage data. + */ + Vector_voltage_t ADS1231_CalculateVoltage ( Vector_count_t* myNewRawData, float myVoltageReference ); + + + + +private: + DigitalOut _SCLK; + DigitalIn _DOUT; + ADS1231_scale_t _ADS1231_SCALE; + float _ADS1231_USER_CALIBATED_MASS; +}; + +#endif